diff --git a/doc/123.txt b/doc/123.txt new file mode 100644 index 00000000..80e6230e --- /dev/null +++ b/doc/123.txt @@ -0,0 +1,2 @@ +im权限 +cai:user:im diff --git a/doc/20251014.sql b/doc/20251014.sql index 28febd7c..613e501d 100644 --- a/doc/20251014.sql +++ b/doc/20251014.sql @@ -48,8 +48,8 @@ CREATE TABLE `cai_ops_count` CREATE TABLE `cai_login_min_log` ( `id` bigint unsigned NOT NULL AUTO_INCREMENT, - `login_date` date not null comment '登录时间', - `user_id` bigint(20) NOT NULL DEFAULT 0 COMMENT '用户', + `login_date` date comment '登录时间', + `user_id` bigint(20) DEFAULT 0 COMMENT '用户', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', PRIMARY KEY (`id`) USING BTREE, INDEX `idx_date` (`user_id`, `login_date`) USING BTREE diff --git a/doc/20251017.sql b/doc/20251017.sql new file mode 100644 index 00000000..20f2810b --- /dev/null +++ b/doc/20251017.sql @@ -0,0 +1,4 @@ +ALTER TABLE sys_notice + ADD COLUMN `business_type` varchar(20) COMMENT '业务类型', + ADD COLUMN `deal_by` varchar(100) COMMENT '处理人', + ADD COLUMN `deal_time` datetime COMMENT '处理时间'; diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/cai/admin/UnreadController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/cai/admin/UnreadController.java index 4f469c45..cbc65853 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/cai/admin/UnreadController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/cai/admin/UnreadController.java @@ -1,8 +1,11 @@ package com.ruoyi.web.controller.cai.admin; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.ruoyi.cai.dto.admin.vo.unread.UnreadData; import com.ruoyi.cai.manager.UnreadManager; import com.ruoyi.common.core.domain.R; +import com.ruoyi.system.domain.SysNotice; +import com.ruoyi.system.mapper.SysNoticeMapper; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.validation.annotation.Validated; @@ -10,6 +13,8 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import javax.annotation.Resource; + @Validated @RequiredArgsConstructor @RestController @@ -18,6 +23,8 @@ public class UnreadController { @Autowired public UnreadManager unreadManager; + @Resource + private SysNoticeMapper sysNoticeMapper; @GetMapping("/data") public R list() { @@ -31,4 +38,19 @@ public class UnreadController { boolean checkCount = unreadManager.checkCount(); return R.ok(checkCount?1:0); } + + @GetMapping("/checkNotice") + public R checkNotice() { + SysNotice sysNotice = sysNoticeMapper.selectOne(Wrappers.lambdaQuery(SysNotice.class) + .eq(SysNotice::getStatus, 0) + .eq(SysNotice::getNoticeType, 3) + .orderByDesc(SysNotice::getNoticeId) + .last("limit 1")); + if(sysNotice == null){ + return R.ok(); + } + R ok = R.ok(); + ok.setData("最新告警:"+sysNotice.getNoticeTitle()); + return ok; + } } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysNoticeController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysNoticeController.java index 54b30d60..b027724c 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysNoticeController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysNoticeController.java @@ -1,18 +1,26 @@ package com.ruoyi.web.controller.system; import cn.dev33.satoken.annotation.SaCheckPermission; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.ruoyi.common.annotation.Log; import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.domain.PageQuery; import com.ruoyi.common.core.domain.R; import com.ruoyi.common.core.page.TableDataInfo; import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.helper.LoginHelper; import com.ruoyi.system.domain.SysNotice; +import com.ruoyi.system.domain.bo.SysNoticeDealData; +import com.ruoyi.system.mapper.SysNoticeMapper; import com.ruoyi.system.service.ISysNoticeService; import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; +import javax.annotation.Resource; +import java.time.LocalDateTime; + /** * 公告 信息操作处理 * @@ -65,6 +73,25 @@ public class SysNoticeController extends BaseController { public R edit(@Validated @RequestBody SysNotice notice) { return toAjax(noticeService.updateNotice(notice)); } + @Resource + private SysNoticeMapper noticeMapper; + + /** + * 修改通知公告 + */ + @SaCheckPermission("system:notice:edit") + @Log(title = "处理公告", businessType = BusinessType.UPDATE) + @PostMapping("deal") + public R deal(@Validated @RequestBody SysNoticeDealData notice) { + noticeMapper.update(Wrappers.lambdaUpdate(SysNotice.class) + .eq(SysNotice::getNoticeId, notice.getNoticeId()) + .set(SysNotice::getStatus, 1) + .set(SysNotice::getRemark, notice.getRemark()) + .set(SysNotice::getNoticeId, notice.getNoticeId()) + .set(SysNotice::getDealBy, LoginHelper.getUsername()) + .set(SysNotice::getDealTime, LocalDateTime.now())); + return R.ok(); + } /** * 删除通知公告 diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/enums/DangerEnum.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/enums/DangerEnum.java new file mode 100644 index 00000000..75de6950 --- /dev/null +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/enums/DangerEnum.java @@ -0,0 +1,9 @@ +package com.ruoyi.cai.enums; + +import lombok.Getter; + +@Getter +public enum DangerEnum { + PAY_SUCCESS, + PAY_ERROR +} diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/enums/SystemConfigEnum.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/enums/SystemConfigEnum.java index a6aa5f8f..4e58cea2 100644 --- a/ruoyi-cai/src/main/java/com/ruoyi/cai/enums/SystemConfigEnum.java +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/enums/SystemConfigEnum.java @@ -135,6 +135,9 @@ public enum SystemConfigEnum { ANCHOR_JOIN_AGREEMENT("/#/agreement/anchor-join", "主播入驻协议地址",SystemConfigGroupEnum.SYSTEM), PAY_CUSTOM("", "支付定向测试",SystemConfigGroupEnum.SYSTEM), WS_SOCKET_URL("ws://localhost:8080/ws?token=%s&room_id=%s", "ws通讯地址",SystemConfigGroupEnum.SYSTEM), + OPEN_NOTICE("1", "是否开启告警",SystemConfigGroupEnum.SYSTEM, new BooleanSystemConfigCheck()), + PAY_ERROR_NUM_NOTICE("2", "连续调用支付失败N次,发起告警",SystemConfigGroupEnum.SYSTEM, new NumberSystemConfigCheck()), + PAY_NOTIFY_ERROR_NUM_NOTICE("5", "连续调用N次支付,但是依旧未支付成功,发起告警",SystemConfigGroupEnum.SYSTEM, new NumberSystemConfigCheck()), V12_PRIVATE_KEY_PATH("/home/server/api/sign/6888803128553.pfx", "V12德商私钥路径",SystemConfigGroupEnum.SYSTEM), V12_PRIVATE_KEY_PASSWORD("926645", "V12德商私钥密码",SystemConfigGroupEnum.SYSTEM), V12_XIAOCHENGXU_ORG_ID("gh_62790d4f9c57", "V12德商小程序原始id",SystemConfigGroupEnum.SYSTEM), diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/manager/DangerManger.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/manager/DangerManger.java new file mode 100644 index 00000000..59702543 --- /dev/null +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/manager/DangerManger.java @@ -0,0 +1,85 @@ +package com.ruoyi.cai.manager; + +import com.ruoyi.cai.enums.DangerEnum; +import com.ruoyi.cai.enums.SystemConfigEnum; +import com.ruoyi.cai.trdpay.TrdPayTypeEnum; +import com.ruoyi.system.domain.SysNotice; +import com.ruoyi.system.mapper.SysNoticeMapper; +import org.apache.commons.lang3.BooleanUtils; +import org.redisson.api.RedissonClient; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; + +@Component +public class DangerManger { + + @Autowired + private RedissonClient redissonClient; + @Autowired + private SystemConfigManager systemConfigManager; + @Resource + private SysNoticeMapper sysNoticeMapper; + + public void resetDanger(DangerEnum dangerEnum, String businessCode) { + Boolean openNotice = systemConfigManager.getSystemConfigOfBool(SystemConfigEnum.OPEN_NOTICE); + if(BooleanUtils.isNotTrue(openNotice)){ + return; + } + String key = String.format("%s:%s",dangerEnum.name(),businessCode); + redissonClient.getAtomicLong(key).set(0); + } + + public void insDanger(DangerEnum dangerEnum, String businessCode) { + Boolean openNotice = systemConfigManager.getSystemConfigOfBool(SystemConfigEnum.OPEN_NOTICE); + if(BooleanUtils.isNotTrue(openNotice)){ + return; + } + String key = String.format("%s:%s",dangerEnum.name(),businessCode); + long num = redissonClient.getAtomicLong(key).incrementAndGet(); + if(dangerEnum == DangerEnum.PAY_ERROR){ + Long payErrorNumNotice = systemConfigManager.getSystemConfigOfLong(SystemConfigEnum.PAY_ERROR_NUM_NOTICE); + if(num >= payErrorNumNotice && num%payErrorNumNotice == 0){ + // 发通知 + SysNotice sysNotice = new SysNotice(); + String noticeTitle = String.format("【%s】连续调用支付失败超过%s,可能出现支付通道异常,需排查!", businessCode, num); + sysNotice.setNoticeTitle(noticeTitle); + sysNotice.setNoticeType("3"); + sysNotice.setBusinessType(DangerEnum.PAY_ERROR.name()); + sysNotice.setNoticeContent(noticeTitle); + sysNotice.setStatus("0"); + sysNoticeMapper.insert(sysNotice); + } + return; + } + if(dangerEnum == DangerEnum.PAY_SUCCESS){ + Long payErrorNumNotice = systemConfigManager.getSystemConfigOfLong(SystemConfigEnum.PAY_NOTIFY_ERROR_NUM_NOTICE); + if(num >= payErrorNumNotice && num%payErrorNumNotice == 0){ + // 发通知 + SysNotice sysNotice = new SysNotice(); + String noticeTitle = String.format("【%s】连续调用支付成功%s次但是未支付成功,可能出现回调异常,需排查!", businessCode, num); + sysNotice.setNoticeTitle(noticeTitle); + sysNotice.setNoticeType("3"); + sysNotice.setBusinessType(DangerEnum.PAY_SUCCESS.name()); + sysNotice.setNoticeContent(noticeTitle); + sysNotice.setStatus("0"); + sysNoticeMapper.insert(sysNotice); + } + return; + } + } + + public void successPay(TrdPayTypeEnum typeEnum) { + this.insDanger(DangerEnum.PAY_SUCCESS,typeEnum.name()); // 支付成功计数 + this.resetDanger(DangerEnum.PAY_ERROR,typeEnum.name()); // 清除支付失败计数 + } + + public void errorPay(TrdPayTypeEnum typeEnum) { + this.insDanger(DangerEnum.PAY_ERROR,typeEnum.name()); + } + + public void notifyPay(TrdPayTypeEnum typeEnum) { + this.resetDanger(DangerEnum.PAY_SUCCESS,typeEnum.name()); + } +} diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/trdpay/TrdPayManager.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/trdpay/TrdPayManager.java index 1d5f6246..e6bf2901 100644 --- a/ruoyi-cai/src/main/java/com/ruoyi/cai/trdpay/TrdPayManager.java +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/trdpay/TrdPayManager.java @@ -5,6 +5,7 @@ import com.alibaba.fastjson2.JSONObject; import com.ruoyi.cai.domain.Account; import com.ruoyi.cai.domain.PayTrdConfig; import com.ruoyi.cai.enums.SystemConfigEnum; +import com.ruoyi.cai.manager.DangerManger; import com.ruoyi.cai.manager.SystemConfigManager; import com.ruoyi.cai.pay.PayOrderInfoDTO; import com.ruoyi.cai.pay.PayReturnResp; @@ -68,15 +69,26 @@ public class TrdPayManager { private AccountService accountService; @Autowired private SystemConfigManager systemConfigManager; + @Autowired + private DangerManger dangerManger; public PayReturnResp createOrderAliMerge(PayOrderInfoDTO payOrderInfoDTO, PayTrdConfig payTrdConfig,TrdPayTypeEnum typeEnum, boolean wx){ - PayTrdService payTrdService = getPayTrdService(typeEnum.name()); - return payTrdService.createOrderAli(payOrderInfoDTO,payTrdConfig,wx); + try { + PayTrdService payTrdService = getPayTrdService(typeEnum.name()); + PayReturnResp orderAli = payTrdService.createOrderAli(payOrderInfoDTO, payTrdConfig, wx); + dangerManger.successPay(typeEnum); + return orderAli; + }catch (Exception e){ + dangerManger.errorPay(typeEnum); + throw e; + } } public NotifyResp getNotifyResp(Map sourceData,TrdPayTypeEnum typeEnum){ PayTrdService payTrdService = getPayTrdService(typeEnum.name()); - return payTrdService.getNotifyResp(sourceData); + NotifyResp notifyResp = payTrdService.getNotifyResp(sourceData); + dangerManger.notifyPay(typeEnum); + return notifyResp; } public JSONObject queryOrder(String orderNo, PayTrdConfig payTrdConfig,TrdPayTypeEnum typeEnum){ diff --git a/ruoyi-cai/src/main/resources/mapper/cai/RechargeOrderMapper.xml b/ruoyi-cai/src/main/resources/mapper/cai/RechargeOrderMapper.xml index 0af6b9fa..a4fe40b1 100644 --- a/ruoyi-cai/src/main/resources/mapper/cai/RechargeOrderMapper.xml +++ b/ruoyi-cai/src/main/resources/mapper/cai/RechargeOrderMapper.xml @@ -25,6 +25,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" from cai_recharge_order t1 left join cai_user t2 on t1.user_id = t2.id + + and t1.appid = #{bo.appid} + and t2.mobile = #{bo.mobile} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysNotice.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysNotice.java index dec401e3..dd9f9100 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysNotice.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysNotice.java @@ -36,10 +36,15 @@ public class SysNotice extends BaseEntity { private String noticeTitle; /** - * 公告类型(1通知 2公告) + * 公告类型(1通知 2公告 3-警告) */ private String noticeType; + /** + * 业务类型 + */ + private String businessType; + /** * 公告内容 */ @@ -50,6 +55,10 @@ public class SysNotice extends BaseEntity { */ private String status; + private String dealBy; + + private String dealTime; + /** * 备注 */ diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysNoticeDealData.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysNoticeDealData.java new file mode 100644 index 00000000..8b872e9e --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/SysNoticeDealData.java @@ -0,0 +1,9 @@ +package com.ruoyi.system.domain.bo; + +import lombok.Data; + +@Data +public class SysNoticeDealData { + private Long noticeId; + private String remark; +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysNoticeServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysNoticeServiceImpl.java index 73a67366..d76e8353 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysNoticeServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysNoticeServiceImpl.java @@ -2,6 +2,7 @@ package com.ruoyi.system.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.ruoyi.common.core.domain.BaseEntity; import com.ruoyi.common.core.domain.PageQuery; import com.ruoyi.common.core.page.TableDataInfo; import com.ruoyi.common.utils.StringUtils; @@ -30,7 +31,8 @@ public class SysNoticeServiceImpl implements ISysNoticeService { LambdaQueryWrapper lqw = new LambdaQueryWrapper() .like(StringUtils.isNotBlank(notice.getNoticeTitle()), SysNotice::getNoticeTitle, notice.getNoticeTitle()) .eq(StringUtils.isNotBlank(notice.getNoticeType()), SysNotice::getNoticeType, notice.getNoticeType()) - .like(StringUtils.isNotBlank(notice.getCreateBy()), SysNotice::getCreateBy, notice.getCreateBy()); + .eq(StringUtils.isNotBlank(notice.getStatus()),SysNotice::getStatus, notice.getStatus()) + .orderByDesc(BaseEntity::getCreateTime); Page page = baseMapper.selectPage(pageQuery.build(), lqw); return TableDataInfo.build(page); }