فهرست منبع

Merge branch 'dev' of GameCenter/game-center into master

Letianhua 1 سال پیش
والد
کامیت
6e8bd1dd00

+ 2 - 0
game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/GameDataApplication.java

@@ -6,12 +6,14 @@ import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
 import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.annotation.EnableScheduling;
 
 @Slf4j
 @EnableDiscoveryClient
 @SpringBootApplication
 @Configuration
 @EnableDubbo
+@EnableScheduling
 public class GameDataApplication {
 
     public static void main(String[] args) {

+ 4 - 0
game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/controller/GameMonitorAlarmController.java

@@ -2,6 +2,8 @@ package com.zanxiang.game.data.serve.controller;
 
 import com.zanxiang.game.data.serve.service.IGameMonitorAlarmService;
 import com.zanxiang.module.util.pojo.ResultVO;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.PutMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
@@ -13,6 +15,7 @@ import org.springframework.web.bind.annotation.RestController;
  * @description: 游戏监控告警控制器
  * @date 2023/12/13 16:20
  */
+@Api(tags = {"游戏监控告警"})
 @RestController
 @RequestMapping("/monitor/alarm")
 public class GameMonitorAlarmController {
@@ -20,6 +23,7 @@ public class GameMonitorAlarmController {
     @Autowired
     private IGameMonitorAlarmService gameMonitorAlarmService;
 
+    @ApiOperation(value = "发送钉钉消息")
     @PutMapping("/sendMsg")
     public ResultVO<Boolean> sendDingMsgToUser() {
         return ResultVO.ok(gameMonitorAlarmService.sendMsgToUser());

+ 101 - 0
game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/pojo/entity/AdsMonitorAlarm.java

@@ -0,0 +1,101 @@
+package com.zanxiang.game.data.serve.pojo.entity;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.nutz.dao.entity.annotation.Column;
+import org.nutz.dao.entity.annotation.PK;
+import org.nutz.dao.entity.annotation.Table;
+
+import java.io.Serializable;
+import java.time.LocalDate;
+
+/**
+ * <p>
+ * 游戏告警监控表
+ * </p>
+ *
+ * @author tianhua
+ * @time 2023/7/11
+ * @Description
+ **/
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder
+@Table(AdsMonitorAlarm.TABLE_NAME)
+@PK({"dt", "id", "gameId", "userId"})
+public class AdsMonitorAlarm implements Serializable {
+    private static final long serialVersionUID = 1L;
+    public static final String TABLE_NAME = "ads_monitor_alarm";
+
+    /**
+     * 告警时间
+     */
+    private LocalDate dt;
+
+    /**
+     * 游戏策略配置表ID
+     */
+    private Long id;
+
+    /**
+     * 游戏ID
+     */
+    private Long gameId;
+
+    /**
+     * 用户ID
+     */
+    private Long userId;
+
+    /**
+     * 区服ID
+     */
+    @Column
+    private Long serverId;
+
+    /**
+     * 角色ID
+     */
+    @Column
+    private Long roleId;
+
+    /**
+     * 投手ID
+     */
+    @Column
+    private Long pitcherId;
+
+    /**
+     * SDK来源
+     */
+    @Column
+    private String sourceSystem;
+
+    /**
+     * 告警内容
+     */
+    @Column
+    private String message;
+
+    /**
+     * 游戏策略配置参数
+     */
+    @Column
+    private String configExplain;
+
+    /**
+     * 策略类型:1-追踪玩家;2-玩家流失;3-新用户追踪
+     */
+    @Column
+    private Integer configType;
+
+    /**
+     * 报警状态,0表示未报警,1标识已报警
+     */
+    @Column
+    private Integer warnStatus;
+
+}

+ 103 - 0
game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/pojo/vo/GameMonitorAlarmVO.java

@@ -0,0 +1,103 @@
+package com.zanxiang.game.data.serve.pojo.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.nutz.dao.entity.annotation.Column;
+
+import java.time.LocalDate;
+
+/**
+ * @author tianhua
+ * @version 1.0
+ * @description: 游戏监控告警实体类
+ * @date 2023/12/14 13:57
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder
+public class GameMonitorAlarmVO {
+
+    /**
+     * 告警时间
+     */
+    private LocalDate dt;
+
+    /**
+     * 游戏策略配置表ID
+     */
+    private Long id;
+
+    /**
+     * SDK来源
+     */
+    private String sourceSystem;
+
+    /**
+     * 用户ID
+     */
+    private Long userId;
+
+    /**
+     * 用户名
+     */
+    private String username;
+
+    /**
+     * 用户昵称
+     */
+    private String nickname;
+
+    /**
+     * 区服ID
+     */
+    private Long serverId;
+
+    /**
+     * 区服名
+     */
+    private String serverName;
+
+    /**
+     * 游戏ID
+     */
+    private Long gameId;
+
+    /**
+     * 游戏名
+      */
+    private String gameName;
+
+    /**
+     * 角色ID
+     */
+    private Long roleId;
+
+    /**
+     * 角色名
+     */
+    private String roleName;
+
+    /**
+     * 投手ID(多个拼成一个字符串)
+     */
+    private String pitcherId;
+
+    /**
+     * 告警内容
+     */
+    private String message;
+
+    /**
+     * 策略内容
+     */
+    private String configExplain;
+
+    /**
+     * 报警状态,0表示未报警,1标识已报警
+     */
+    private Integer warnStatus;
+    
+}

+ 115 - 5
game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/service/impl/GameMonitorAlarmServiceImpl.java

@@ -2,13 +2,22 @@ package com.zanxiang.game.data.serve.service.impl;
 
 import com.zanxiang.erp.base.ErpServer;
 import com.zanxiang.erp.base.rpc.IDingTalkMsgRpc;
+import com.zanxiang.game.data.serve.pojo.entity.AdsMonitorAlarm;
+import com.zanxiang.game.data.serve.pojo.vo.GameMonitorAlarmVO;
 import com.zanxiang.game.data.serve.service.IGameMonitorAlarmService;
+import lombok.extern.slf4j.Slf4j;
 import org.apache.dubbo.config.annotation.DubboReference;
+import org.nutz.dao.Chain;
+import org.nutz.dao.Cnd;
 import org.nutz.dao.Dao;
+import org.nutz.dao.Sqls;
+import org.nutz.dao.sql.Criteria;
+import org.nutz.dao.sql.Sql;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 
-import java.time.LocalDateTime;
+import java.util.List;
 
 /**
  * @author tianhua
@@ -17,6 +26,7 @@ import java.time.LocalDateTime;
  * @date 2023/12/13 16:24
  */
 @Service
+@Slf4j
 public class GameMonitorAlarmServiceImpl implements IGameMonitorAlarmService {
 
     @Autowired
@@ -25,13 +35,113 @@ public class GameMonitorAlarmServiceImpl implements IGameMonitorAlarmService {
     @DubboReference(providedBy = ErpServer.SERVER_DUBBO_NAME)
     private IDingTalkMsgRpc dingTalkMsgRpc;
 
+    @Transactional(rollbackFor = Exception.class)
     public boolean sendMsgToUser() {
-        LocalDateTime now = LocalDateTime.now();
-        String msg = "这是一条测试钉钉消息,发送时间:" + now;
-        dingTalkMsgRpc.sendByUserId(401L, msg);
-
+        //数据库查表
+        Sql sql = Sqls.create(getMonitorAlarmInfoSql());
+        sql.setCallback(Sqls.callback.entities());
+        sql.setEntity(dao.getEntity(GameMonitorAlarmVO.class));
+        dao.execute(sql);
+        //结果
+        try{
+            List<GameMonitorAlarmVO> list = sql.getList(GameMonitorAlarmVO.class).stream().map(vo -> {
+                String[] pitcherIds = vo.getPitcherId().split(",");
+                for (String pitcherId : pitcherIds) {
+                    //发送给多个投手
+                    dingTalkMsgRpc.sendByUserId(Long.valueOf(pitcherId), alarmStr(vo));
+                }
+                //更新的条件
+                Criteria cri = Cnd.cri();
+                if (vo.getId() != null) {
+                    cri.where().andEquals("id", vo.getId());
+                }
+                if (vo.getDt() != null) {
+                    cri.where().andEquals("dt", vo.getDt());
+                }
+                if (vo.getGameId() != null) {
+                    cri.where().andEquals("gameId", vo.getGameId());
+                }
+                if (vo.getUserId() != null) {
+                    cri.where().andEquals("userId", vo.getUserId());
+                }
+                dao.update(AdsMonitorAlarm.class, Chain.make("warn_status", 1), cri);
+                return vo;
+            }).toList();
+        } catch (Exception e) {
+            log.error("游戏监控告警出错,原因:{}", e.getMessage(), e);
+        }
         return true;
     }
 
+    /**
+     * 生成告警信息字符串
+     */
+    private String alarmStr(GameMonitorAlarmVO vo) {
+        StringBuilder msgStr = new StringBuilder(0);
+        msgStr.append("游戏策略响应时间:")
+                .append(vo.getDt())
+                .append(" ;")
+                .append("\n")
+                .append("游戏名称:")
+                .append(vo.getGameName())
+                .append(" ;区服名称:")
+                .append(vo.getServerName())
+                .append(" ;")
+                .append("\n")
+                .append("用户ID:")
+                .append(vo.getUserId())
+                .append(" ;角色名称:")
+                .append(vo.getRoleName())
+                .append(" ;")
+                .append("\n")
+                .append("响应策略内容:")
+                .append(vo.getMessage())
+                .append(" ;")
+                .append("\n")
+                .append("该用户响应的策略属于:")
+                .append(vo.getConfigExplain());
+
+        return msgStr.toString();
+    }
 
+    /**
+     * 游戏监控告警sql
+     * @return String
+     */
+    private String getMonitorAlarmInfoSql() {
+        return """
+                SELECT
+                	a.dt ,
+                	a.id ,
+                	a.source_system ,
+                	a.user_id ,
+                	b.username ,
+                	b.nickname ,
+                	a.server_id ,
+                	e.server_name ,
+                	a.game_id ,
+                	d.game_name ,
+                	a.role_id ,
+                	c.role_name ,
+                	a.pitcher_id ,
+                	a.message ,
+                	a.config_explain ,
+                	a.warn_status
+                FROM game_ads.ads_monitor_alarm a
+                LEFT JOIN dm_game_order.t_game_user b on a.source_system = b.source_system AND a.user_id = b.id
+                LEFT JOIN (
+                	SELECT
+                		source_system ,
+                		role_id ,
+                		role_name ,
+                		ROW_NUMBER()over(partition by role_id , source_system order by update_time desc, user_id desc) as num
+                	FROM dm_game_order.t_game_user_role
+                ) c on a.source_system = c.source_system AND a.role_id = c.role_id AND c.num = 1
+                LEFT JOIN dm_game_order.t_game d on a.source_system = d.source_system AND a.game_id = d.id
+                LEFT JOIN dm_game_order.t_game_server e on a.source_system = e.source_system AND a.game_id = e.game_id AND a.server_id = e.server_id
+                WHERE a.warn_status = 0
+                """;
+    }
+    
+    
 }

+ 44 - 0
game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/task/GameMonitorAlarmTask.java

@@ -0,0 +1,44 @@
+package com.zanxiang.game.data.serve.task;
+
+import com.zanxiang.game.data.serve.service.IGameMonitorAlarmService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.cloud.context.config.annotation.RefreshScope;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+/**
+ * @author tianhua
+ * @version 1.0
+ * @description: 游戏监控告警定时任务
+ * @date 2023/12/13 19:08
+ */
+@Slf4j
+@Component
+@RefreshScope
+public class GameMonitorAlarmTask {
+
+    @Autowired
+    private IGameMonitorAlarmService gameMonitorAlarmService;
+
+    @Value("${sys-config.task_is_run}")
+    private boolean run;
+
+    /**
+     * 任务每5分钟运行一次
+     */
+    @Scheduled(cron = "0 0/5 * * * ? ")
+    public void run() {
+        if (!run) {
+            return;
+        }
+        log.error("游戏监控告警定时任务开始.");
+        try {
+            gameMonitorAlarmService.sendMsgToUser();
+        } catch (Exception e) {
+            log.error("定时任务游戏监控告警出错", e);
+        }
+    }
+
+}

+ 45 - 0
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/enums/ExcludeTagsEnum.java

@@ -0,0 +1,45 @@
+package com.zanxiang.game.module.manage.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * @author : tianhua
+ * @time : 2023-12-27
+ * @description : 排除标签
+ */
+@Getter
+@AllArgsConstructor
+public enum ExcludeTagsEnum {
+
+    /**
+     * 已退游标签
+     */
+    REMOVE_GAME(1, "已退游"),
+
+    /**
+     * 已添加企微标签
+     */
+    ADD_CORP_WECHAT(2, "已添加企微");
+
+    /**
+     * 标签ID
+     */
+    private Integer tagId;
+
+    /**
+     * 标签名称
+     */
+    private String tagName;
+
+    public static String getTagName(Integer tagID) {
+        for (ExcludeTagsEnum excludeTagsEnum : ExcludeTagsEnum.values()) {
+            if (tagID == excludeTagsEnum.tagId) {
+                return excludeTagsEnum.getTagName();
+            }
+        }
+        return null;
+    }
+
+
+}

+ 14 - 0
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/pojo/params/GamePolicyConfigAddOrUpdateParam.java

@@ -4,6 +4,7 @@ import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
 import javax.validation.constraints.NotNull;
+import java.util.List;
 
 /**
  * @author tianhua
@@ -65,4 +66,17 @@ public class GamePolicyConfigAddOrUpdateParam {
     @ApiModelProperty("配置说明:请写出具体的配置细节。如:首次充值金额大于500并且注册时间24小时内的用户,发送钉钉消息")
     private String configExplain;
 
+    /**
+     * 通知人
+     */
+    @NotNull(message = "策略响应时发送消息的对象(不填写,默认发送消息给角色归因的投手)")
+    @ApiModelProperty("告警人员ID")
+    private List<Long> userIds;
+
+    /**
+     * 排除指标标签
+     */
+    @ApiModelProperty("排除指标标签:1-已退游;2-已添加企微(选择标签后,会根据标签信息去排除角色不再告警)")
+    private List<Long> tagIds;
+
 }

+ 10 - 0
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/pojo/vo/GamePolicyConfigListVO.java

@@ -77,6 +77,16 @@ public class GamePolicyConfigListVO {
      */
     private String configExplain;
 
+    /**
+     * 告警人员名称
+     */
+    private String userNameStr;
+
+    /**
+     * 排除标签名字符串
+     */
+    private String tagsNameStr;
+
     /**
      * 创建时间
      */

+ 28 - 0
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/impl/GamePolicyConfigServiceImpl.java

@@ -7,6 +7,7 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.zanxiang.erp.base.ErpServer;
 import com.zanxiang.erp.base.rpc.ISysUserRpc;
 import com.zanxiang.erp.security.util.SecurityUtil;
+import com.zanxiang.game.module.manage.enums.ExcludeTagsEnum;
 import com.zanxiang.game.module.manage.pojo.dto.GameDTO;
 import com.zanxiang.game.module.manage.pojo.params.GamePolicyConfigAddOrUpdateParam;
 import com.zanxiang.game.module.manage.pojo.params.GamePolicyConfigListParam;
@@ -21,6 +22,7 @@ import com.zanxiang.game.module.mybatis.mapper.GamePolicyConfigMapper;
 import com.zanxiang.module.util.JsonUtil;
 import com.zanxiang.module.util.exception.BaseException;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.dubbo.config.annotation.DubboReference;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -83,6 +85,8 @@ public class GamePolicyConfigServiceImpl extends ServiceImpl<GamePolicyConfigMap
                 .type(param.getType())
                 .configParam(configParam)
                 .configExplain(param.getConfigExplain())
+                .userIds(CollectionUtils.isEmpty(param.getUserIds()) ? null : StringUtils.join(param.getUserIds().toArray(), ","))
+                .tagIds(CollectionUtils.isEmpty(param.getTagIds()) ? null : StringUtils.join(param.getTagIds().toArray(), ","))
                 .updateBy(sysUserId)
                 .updateTime(now)
                 .build();
@@ -130,6 +134,28 @@ public class GamePolicyConfigServiceImpl extends ServiceImpl<GamePolicyConfigMap
         GameSupper gameSupper = gameSupperService.getById(vo.getSuperGameId());
         GameDTO game = gameService.getById(vo.getSuperGameId());
         String superGameName = null == gameSupper ? (null == game ? null : game.getName()) : gameSupper.getName();
+        //告警人员名称
+        StringBuilder userNameStr = new StringBuilder();
+        if (StringUtils.isNotBlank(vo.getUserIds())) {
+            String[] userIds = vo.getUserIds().split(",");
+            for (int i = 0; i < userIds.length; i++) {
+                userNameStr.append(sysUserRpc.getById(Long.valueOf(userIds[i])).getData().getNickname());
+                if (i != userIds.length -1) {
+                    userNameStr.append(",");
+                }
+            }
+        }
+        //排除标签名称
+        StringBuilder tagNameStr = new StringBuilder();
+        if (StringUtils.isNotBlank(vo.getTagIds())) {
+            String[] tagIds = vo.getTagIds().split(",");
+            for (int i = 0; i < tagIds.length; i++) {
+                tagNameStr.append(ExcludeTagsEnum.getTagName(Integer.valueOf(tagIds[i])));
+                if (i != tagIds.length -1) {
+                    tagNameStr.append(",");
+                }
+            }
+        }
         return GamePolicyConfigListVO.builder()
                 .id(vo.getId())
                 .superGameId(vo.getSuperGameId())
@@ -140,6 +166,8 @@ public class GamePolicyConfigServiceImpl extends ServiceImpl<GamePolicyConfigMap
                 .time(StringUtils.isBlank(time) ? null : Long.valueOf(time))
                 .timeCondition(StringUtils.isBlank(timeCondition) ? null : timeCondition)
                 .configExplain(vo.getConfigExplain())
+                .userNameStr(StringUtils.isBlank(userNameStr.toString()) ? null : userNameStr.toString())
+                .tagsNameStr(StringUtils.isBlank(tagNameStr.toString()) ? null : tagNameStr.toString())
                 .createBy(vo.getCreateBy())
                 .createName(sysUserRpc.getById(vo.getCreateBy()).getData().getNickname())
                 .createTime(vo.getCreateTime())

+ 10 - 0
game-module/game-module-mybatis/src/main/java/com/zanxiang/game/module/mybatis/entity/GamePolicyConfig.java

@@ -47,6 +47,16 @@ public class GamePolicyConfig {
      */
     private String configExplain;
 
+    /**
+     * 告警人员(字符串)
+     */
+    private String userIds;
+
+    /**
+     * 排除标签ID(字符串)
+     */
+    private String tagIds;
+
     /**
      * 创建时间
      */