This commit is contained in:
777
2025-10-20 14:20:46 +08:00
parent 34b6ff3a6c
commit e368d333ef
13 changed files with 194 additions and 7 deletions

2
doc/123.txt Normal file
View File

@@ -0,0 +1,2 @@
im权限
cai:user:im

View File

@@ -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

4
doc/20251017.sql Normal file
View File

@@ -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 '处理时间';

View File

@@ -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<UnreadData> list() {
@@ -31,4 +38,19 @@ public class UnreadController {
boolean checkCount = unreadManager.checkCount();
return R.ok(checkCount?1:0);
}
@GetMapping("/checkNotice")
public R<String> 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<String> ok = R.ok();
ok.setData("最新告警:"+sysNotice.getNoticeTitle());
return ok;
}
}

View File

@@ -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<Void> 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<Void> 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();
}
/**
* 删除通知公告

View File

@@ -0,0 +1,9 @@
package com.ruoyi.cai.enums;
import lombok.Getter;
@Getter
public enum DangerEnum {
PAY_SUCCESS,
PAY_ERROR
}

View File

@@ -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),

View File

@@ -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());
}
}

View File

@@ -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){
try {
PayTrdService payTrdService = getPayTrdService(typeEnum.name());
return payTrdService.createOrderAli(payOrderInfoDTO,payTrdConfig,wx);
PayReturnResp orderAli = payTrdService.createOrderAli(payOrderInfoDTO, payTrdConfig, wx);
dangerManger.successPay(typeEnum);
return orderAli;
}catch (Exception e){
dangerManger.errorPay(typeEnum);
throw e;
}
}
public NotifyResp getNotifyResp(Map<String,String> 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){

View File

@@ -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
<where>
<if test="bo.appid != null and bo.appid != ''">
and t1.appid = #{bo.appid}
</if>
<if test="bo.mobile != null and bo.mobile != ''">
and t2.mobile = #{bo.mobile}
</if>

View File

@@ -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;
/**
* 备注
*/

View File

@@ -0,0 +1,9 @@
package com.ruoyi.system.domain.bo;
import lombok.Data;
@Data
public class SysNoticeDealData {
private Long noticeId;
private String remark;
}

View File

@@ -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<SysNotice> lqw = new LambdaQueryWrapper<SysNotice>()
.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<SysNotice> page = baseMapper.selectPage(pageQuery.build(), lqw);
return TableDataInfo.build(page);
}