Переглянути джерело

Merge branch 'master' of http://47.111.81.118:3000/uskycloud/usky-cloud into system-165

fuyuchuan 11 годин тому
батько
коміт
559ec945d0
21 змінених файлів з 956 додано та 89 видалено
  1. 16 3
      base-modules/service-file/src/main/java/com/ruoyi/file/service/impl/FilesServiceImpl.java
  2. 43 1
      base-modules/service-system/service-system-api/src/main/java/com/usky/system/domain/MceRequestVO.java
  3. 13 0
      base-modules/service-system/service-system-biz/pom.xml
  4. 8 1
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/constant/constant.java
  5. 3 2
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/controller/web/MceReceiveController.java
  6. 27 0
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/controller/web/SystemInfoController.java
  7. 68 0
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/domain/Cpu.java
  8. 112 0
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/domain/Jvm.java
  9. 47 0
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/domain/Mem.java
  10. 41 0
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/domain/Sys.java
  11. 53 0
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/domain/SysFile.java
  12. 185 0
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/domain/SystemHardwareInfo.java
  13. 1 2
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/MceReceiveService.java
  14. 39 18
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/SysLoginService.java
  15. 32 0
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/impl/MceContentServiceImpl.java
  16. 108 31
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/impl/MceMbuserServiceImpl.java
  17. 55 8
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/impl/MceReceiveServiceImpl.java
  18. 1 1
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/impl/SysNoticeServiceImpl.java
  19. 48 5
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/util/AsyncFactory.java
  20. 10 17
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/util/AsyncManager.java
  21. 46 0
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/vo/SendWeChatMessageRequestVO.java

+ 16 - 3
base-modules/service-file/src/main/java/com/ruoyi/file/service/impl/FilesServiceImpl.java

@@ -45,7 +45,7 @@ public class FilesServiceImpl extends ServiceImpl<FilesMapper, FilesUpload> impl
 
         // 获取当前日期时间
         LocalDateTime now = LocalDateTime.now();
-        String timestamp = now.format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
+//        String timestamp = now.format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
 
         //文件类型
         String type = originalFilename.substring(originalFilename.lastIndexOf(".") + 1).toLowerCase();
@@ -55,13 +55,26 @@ public class FilesServiceImpl extends ServiceImpl<FilesMapper, FilesUpload> impl
         // 获取每月递增值
         int monthIncrement = getMonthIncrement(yearMonth);
         // 新文件名格式:时间戳+每月递增值+文件类型
-        String fileUuid = timestamp + "A" + String.format("%04d", monthIncrement) + "." + type;
+//        String fileUuid = timestamp + "A" + String.format("%04d", monthIncrement) + "." + type;
 
         // 将相对路径转化为绝对路径
         String destPath = filesUploadPath + "/" + yearMonth;
 
         // 新的文件地址,绝对路径+新的文件名称
-        File uploadFile = new File(destPath + "/" + fileUuid);
+//        File uploadFile = new File(destPath + "/" + fileUuid);
+        File uploadFile;
+        String fileUuid = originalFilename; // 初始使用原文件名
+        int count = 1; // 用于生成重复文件名的序号
+        while (true) {
+            uploadFile = new File(destPath + "/" + fileUuid);
+            if (!uploadFile.exists()) { // 如果文件不存在,直接使用该文件名
+                break;
+            } else { // 如果文件已存在,修改文件名
+                String nameWithoutType = originalFilename.substring(0, originalFilename.lastIndexOf("."));
+                fileUuid = nameWithoutType + "(" + count + ")." + type;
+                count++;
+            }
+        }
 
         // 判断配置的文件目录是否存在,若不存在则创建一个新的文件目录
         File parentFile = uploadFile.getParentFile();

+ 43 - 1
base-modules/service-system/service-system-api/src/main/java/com/usky/system/domain/MceRequestVO.java

@@ -37,7 +37,9 @@ public class MceRequestVO  extends BaseEntity {
     @NotBlank(message = "消息内容 infoContent 不能为空!")
     private String infoContent;
 
-    /** 消息发布人  */
+    /** 用户名称
+     * 登录账号 loginAccount
+     * */
     @NotBlank(message = "消息发布人 userName 不能为空!")
     private String userName;
 
@@ -49,6 +51,46 @@ public class MceRequestVO  extends BaseEntity {
     @NotNull(message = "消息接收人 userIds 不能为空!")
     private List<Long> userIds;
 
+    /**
+     * ip地址
+     */
+    private String ipAddress;
+
+    /**
+     * 登录地址
+     */
+    private String loginAddress;
+
+    /**
+     * 登录方式
+     */
+    private String loginType;
+
+    /**
+     * 审批结果
+     */
+    private String approvalResult;
+
+    /**
+     * 流程名称
+     */
+    private String processName;
+
+    /**
+     * 审批节点
+     */
+    private String approvalNode;
+
+    /**
+     * 真实姓名
+     */
+    private String realName;
+
+    /**
+     * oa跳转类型 (todo我的待办、me我发起的、copy抄送我的)
+     */
+    String oaType;
+
     @Override
     public String toString() {
         ObjectMapper objectMapper = new ObjectMapper();

+ 13 - 0
base-modules/service-system/service-system-biz/pom.xml

@@ -64,6 +64,19 @@
             <artifactId>json</artifactId>
             <version>20210307</version>
         </dependency>
+
+        <!-- 监控服务器资源状态 -->
+        <dependency>
+            <groupId>com.github.oshi</groupId>
+            <artifactId>oshi-core</artifactId>
+            <version>3.9.1</version>
+        </dependency>
+        <dependency>
+            <groupId>net.java.dev.jna</groupId>
+            <artifactId>jna-platform</artifactId>
+            <version>4.5.2</version>
+        </dependency>
+
     </dependencies>
 
     <build>

+ 8 - 1
base-modules/service-system/service-system-biz/src/main/java/com/usky/system/constant/constant.java

@@ -17,11 +17,18 @@ public class constant {
     public static final String WE_CHAT_ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s";
     // 微信公众号消息推送地址
     public static final String WE_CHAT_REQUEST_URL = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=%s";
-    // 微信公众号推送消息模板id
+    // 微信公众号推送-告警-消息模板id
     public static final String WE_CHAT_TEMPLATE_ID = "FmrNuMzgh0E8bWg1j8a2R3zTmRarHYtZ72TSzPrF9Iw";
+    // 微信公众号推送-OA-消息模板id
+    public static final String WE_CHAT_OA_TEMPLATE_ID = "RDahJYyDGpQKEn6vzdifS9u9F-vxA6FOIIDe1cUw8WU";
+    // 微信公众号推送-报告提醒(工单)-消息模板id
+    public static final String WE_CHAT_WORK_TEMPLATE_ID = "0J7pBGkXq5nCEVsc9L6HBmfmUrO4BEOk-3d5WCndWZk";
+    // 微信公众号推送-登录-消息模板id
+    public static final String WE_CHAT_LOGIN_TEMPLATE_ID = "7o6J1_0gi89RsW3sR7Q853KTaWYT7Yu-jXjLnHbcB8M";
     // 微信公众号的消息回调地址(这儿可根据业务需求自定义动作,可选)
     public static final String WE_CHAT_CUSTOMER_CALL_URL = "https://manager.usky.cn/mobile/#/pages/common/appMessage/index?type=%s&typeName=%s&id=%s";
     public static final String WE_CHAT_CUSTOMER_CALL_URL1 = "https://manager.usky.cn/mobile/#/pages/common/appMessage/index?type=%s&id=%s";
+    public static final String WE_CHAT_CUSTOMER_CALL_URL3 = "https://manager.usky.cn/mobile/#/pages/common/appMessage/index?type=%s&typeName=%s&id=%s&oaType=%s";
     // 微信公众号的主题颜色
     public static final String WE_CHAT_TOP_COLOR = "#A349A4";
     // 微信公众号微信用户授权地址

+ 3 - 2
base-modules/service-system/service-system-biz/src/main/java/com/usky/system/controller/web/MceReceiveController.java

@@ -48,9 +48,10 @@ public class MceReceiveController {
                                                  @RequestParam(value = "startTime", required = false) String startTime,
                                                  @RequestParam(value = "endTime", required = false) String endTime,
                                                  @RequestParam(value = "id", required = false) Integer id,
+                                                 @RequestParam(value = "infoId", required = false) Integer infoId,
                                                  @RequestParam(value = "current", required = false, defaultValue = "1") Integer current,
                                                  @RequestParam(value = "size", required = false, defaultValue = "10") Integer size) {
-        return ApiResult.success(mceReceiveService.mceList(infoTitle, infoType, startTime, endTime, id, current, size));
+        return ApiResult.success(mceReceiveService.mceList(infoTitle, infoType, startTime, endTime, id, infoId, current, size));
     }
 
     /**
@@ -131,7 +132,7 @@ public class MceReceiveController {
      * 消息发布-无需token
      * @return
      */
-    @PostMapping("/addMce")
+    @PostMapping("/addMceNew")
     ApiResult<Void> addNoToken(@RequestBody String mceNoToken) {
         mceReceiveService.addNoToken(mceNoToken);
         return ApiResult.success();

+ 27 - 0
base-modules/service-system/service-system-biz/src/main/java/com/usky/system/controller/web/SystemInfoController.java

@@ -0,0 +1,27 @@
+package com.usky.system.controller.web;
+
+import com.usky.system.domain.SystemHardwareInfo;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("/oshi")
+public class SystemInfoController {
+
+    @GetMapping("/list")
+    public SystemHardwareInfo getSystemHardwareInfo() {
+        SystemHardwareInfo systemHardwareInfo = new SystemHardwareInfo();
+        try {
+            // 调用 copyTo() 方法填充数据
+            systemHardwareInfo.copyTo();
+        } catch (Exception e) {
+            // 日志记录异常信息
+            e.printStackTrace();
+            // 可以根据需要返回错误信息或空对象
+            return null;
+        }
+        // 返回填充后的数据
+        return systemHardwareInfo;
+    }
+}

+ 68 - 0
base-modules/service-system/service-system-biz/src/main/java/com/usky/system/domain/Cpu.java

@@ -0,0 +1,68 @@
+package com.usky.system.domain;
+
+import cn.hutool.core.util.NumberUtil;
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class Cpu implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+
+    /**
+     * 核心数
+     */
+    private int cpuNum;
+
+
+    /**
+     * CPU总的使用率
+     */
+    private double total;
+
+
+    /**
+     * CPU系统使用率
+     */
+    private double sys;
+
+
+    /**
+     * CPU用户使用率
+     */
+    private double used;
+
+
+    /**
+     * CPU当前等待率
+     */
+    private double wait;
+
+
+    /**
+     * CPU当前空闲率
+     */
+    private double free;
+
+
+    public double getTotal() {
+        return NumberUtil.round(NumberUtil.mul(total, 100), 2).doubleValue();
+    }
+
+    public double getSys() {
+        return NumberUtil.round(NumberUtil.mul(sys / total, 100), 2).doubleValue();
+    }
+
+    public double getUsed() {
+        return NumberUtil.round(NumberUtil.mul(used / total, 100), 2).doubleValue();
+    }
+
+    public double getWait() {
+        return NumberUtil.round(NumberUtil.mul(wait / total, 100), 2).doubleValue();
+    }
+
+    public double getFree() {
+        return NumberUtil.round(NumberUtil.mul(free / total, 100), 2).doubleValue();
+    }
+}

+ 112 - 0
base-modules/service-system/service-system-biz/src/main/java/com/usky/system/domain/Jvm.java

@@ -0,0 +1,112 @@
+package com.usky.system.domain;
+
+import cn.hutool.core.date.DateUnit;
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.NumberUtil;
+import lombok.Data;
+import java.io.Serializable;
+import java.lang.management.ManagementFactory;
+import java.util.Date;
+
+@Data
+public class Jvm implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+
+    /**
+     * 当前JVM占用的内存总数(M)
+     */
+    private double total;
+
+
+    /**
+     * JVM最大可用内存总数(M)
+     */
+    private double max;
+
+
+    /**
+     * JVM空闲内存(M)
+     */
+    private double free;
+
+
+    /**
+     * JDK版本
+     */
+    private String version;
+
+
+    /**
+     * JDK路径
+     */
+    private String home;
+
+
+    public double getTotal() {
+        return NumberUtil.div(total, (1024 * 1024), 2);
+    }
+
+    public double getMax() {
+        return NumberUtil.div(max, (1024 * 1024), 2);
+    }
+
+    public double getFree() {
+        return NumberUtil.div(free, (1024 * 1024), 2);
+    }
+
+    public double getUsed() {
+        return NumberUtil.div(total - free, (1024 * 1024), 2);
+    }
+
+    public String getVersion() {
+        return version;
+    }
+
+    public String getHome() {
+        return home;
+    }
+
+    public double getUsage() {
+        return NumberUtil.mul(NumberUtil.div(total - free, total, 4), 100);
+    }
+    /**
+     * 获取JDK名称
+     */
+    public String getName() {
+        return ManagementFactory.getRuntimeMXBean().getVmName();
+    }
+
+    /**
+     * JDK启动时间
+     */
+    public String getStartTime() {
+        long time = ManagementFactory.getRuntimeMXBean().getStartTime();
+        Date date = new Date(time);
+        return DateUtil.formatDateTime(date);
+    }
+
+    /**
+     * JDK运行时间
+     */
+    public String getRunTime() {
+        long time = ManagementFactory.getRuntimeMXBean().getStartTime();
+        Date date = new Date(time);
+
+
+        //运行多少分钟
+        long runMS = DateUtil.between(date, new Date(), DateUnit.MS);
+
+
+        long nd = 1000 * 24 * 60 * 60;
+        long nh = 1000 * 60 * 60;
+        long nm = 1000 * 60;
+
+
+        long day = runMS / nd;
+        long hour = runMS % nd / nh;
+        long min = runMS % nd % nh / nm;
+        return day + "天" + hour + "小时" + min + "分钟";
+    }
+}

+ 47 - 0
base-modules/service-system/service-system-biz/src/main/java/com/usky/system/domain/Mem.java

@@ -0,0 +1,47 @@
+package com.usky.system.domain;
+
+import cn.hutool.core.util.NumberUtil;
+import lombok.Data;
+import java.io.Serializable;
+
+
+@Data
+public class Mem implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+
+    /**
+     * 内存总量
+     */
+    private double total;
+
+
+    /**
+     * 已用内存
+     */
+    private double used;
+
+
+    /**
+     * 剩余内存
+     */
+    private double free;
+
+
+    public double getTotal() {
+        return NumberUtil.div(total, (1024 * 1024 * 1024), 2);
+    }
+
+    public double getUsed() {
+        return NumberUtil.div(used, (1024 * 1024 * 1024), 2);
+    }
+
+    public double getFree() {
+        return NumberUtil.div(free, (1024 * 1024 * 1024), 2);
+    }
+
+    public double getUsage() {
+        return NumberUtil.mul(NumberUtil.div(used, total, 4), 100);
+    }
+}

+ 41 - 0
base-modules/service-system/service-system-biz/src/main/java/com/usky/system/domain/Sys.java

@@ -0,0 +1,41 @@
+package com.usky.system.domain;
+
+import lombok.Data;
+import java.io.Serializable;
+
+
+@Data
+public class Sys implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+
+    /**
+     * 服务器名称
+     */
+    private String computerName;
+
+
+    /**
+     * 服务器Ip
+     */
+    private String computerIp;
+
+
+    /**
+     * 项目路径
+     */
+    private String userDir;
+
+
+    /**
+     * 操作系统
+     */
+    private String osName;
+
+
+    /**
+     * 系统架构
+     */
+    private String osArch;
+}

+ 53 - 0
base-modules/service-system/service-system-biz/src/main/java/com/usky/system/domain/SysFile.java

@@ -0,0 +1,53 @@
+package com.usky.system.domain;
+
+import lombok.Data;
+import java.io.Serializable;
+
+
+@Data
+public class SysFile implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+
+    /**
+     * 盘符路径
+     */
+    private String dirName;
+
+
+    /**
+     * 盘符类型
+     */
+    private String sysTypeName;
+
+
+    /**
+     * 文件类型
+     */
+    private String typeName;
+
+
+    /**
+     * 总大小
+     */
+    private String total;
+
+
+    /**
+     * 剩余大小
+     */
+    private String free;
+
+
+    /**
+     * 已经使用量
+     */
+    private String used;
+
+
+    /**
+     * 资源的使用率
+     */
+    private double usage;
+}

+ 185 - 0
base-modules/service-system/service-system-biz/src/main/java/com/usky/system/domain/SystemHardwareInfo.java

@@ -0,0 +1,185 @@
+package com.usky.system.domain;
+
+import cn.hutool.core.net.NetUtil;
+import cn.hutool.core.util.NumberUtil;
+import lombok.Data;
+import oshi.SystemInfo;
+import oshi.hardware.CentralProcessor;
+import oshi.hardware.CentralProcessor.TickType;
+import oshi.hardware.GlobalMemory;
+import oshi.hardware.HardwareAbstractionLayer;
+import oshi.software.os.FileSystem;
+import oshi.software.os.OSFileStore;
+import oshi.software.os.OperatingSystem;
+import oshi.util.Util;
+import java.io.Serializable;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Properties;
+
+
+@Data
+public class SystemHardwareInfo  implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+
+    private static final int OSHI_WAIT_SECOND = 1000;
+
+
+    /**
+     * CPU相关信息
+     */
+    private Cpu cpu = new Cpu();
+
+
+    /**
+     * 內存相关信息
+     */
+    private Mem mem = new Mem();
+
+
+    /**
+     * JVM相关信息
+     */
+    private Jvm jvm = new Jvm();
+
+
+    /**
+     * 服务器相关信息
+     */
+    private Sys sys = new Sys();
+
+
+    /**
+     * 磁盘相关信息
+     */
+    private List<SysFile> sysFiles = new LinkedList<SysFile>();
+
+
+    public void copyTo() throws Exception {
+        SystemInfo si = new SystemInfo();
+        HardwareAbstractionLayer hal = si.getHardware();
+
+
+        setCpuInfo(hal.getProcessor());
+
+
+        setMemInfo(hal.getMemory());
+
+
+        setSysInfo();
+
+
+        setJvmInfo();
+
+
+        setSysFiles(si.getOperatingSystem());
+    }
+
+    /**
+     * 设置CPU信息
+     */
+    private void setCpuInfo(CentralProcessor processor) {
+        // CPU信息
+        long[] prevTicks = processor.getSystemCpuLoadTicks();
+        Util.sleep(OSHI_WAIT_SECOND);
+        long[] ticks = processor.getSystemCpuLoadTicks();
+        long nice = ticks[TickType.NICE.getIndex()] - prevTicks[TickType.NICE.getIndex()];
+        long irq = ticks[TickType.IRQ.getIndex()] - prevTicks[TickType.IRQ.getIndex()];
+        long softirq = ticks[TickType.SOFTIRQ.getIndex()] - prevTicks[TickType.SOFTIRQ.getIndex()];
+        long steal = ticks[TickType.STEAL.getIndex()] - prevTicks[TickType.STEAL.getIndex()];
+        long cSys = ticks[TickType.SYSTEM.getIndex()] - prevTicks[TickType.SYSTEM.getIndex()];
+        long user = ticks[TickType.USER.getIndex()] - prevTicks[TickType.USER.getIndex()];
+        long iowait = ticks[TickType.IOWAIT.getIndex()] - prevTicks[TickType.IOWAIT.getIndex()];
+        long idle = ticks[TickType.IDLE.getIndex()] - prevTicks[TickType.IDLE.getIndex()];
+        long totalCpu = user + nice + cSys + idle + iowait + irq + softirq + steal;
+        cpu.setCpuNum(processor.getLogicalProcessorCount());
+        cpu.setTotal(totalCpu);
+        cpu.setSys(cSys);
+        cpu.setUsed(user);
+        cpu.setWait(iowait);
+        cpu.setFree(idle);
+    }
+
+    /**
+     * 设置内存信息
+     */
+    private void setMemInfo(GlobalMemory memory) {
+        mem.setTotal(memory.getTotal());
+        mem.setUsed(memory.getTotal() - memory.getAvailable());
+        mem.setFree(memory.getAvailable());
+    }
+
+    /**
+     * 设置服务器信息
+     */
+    private void setSysInfo() {
+        Properties props = System.getProperties();
+        SystemInfo si = new SystemInfo();
+        OperatingSystem os = si.getOperatingSystem();
+        // 使用 oshi 获取主机名
+        sys.setComputerName(os.getNetworkParams().getHostName());
+        sys.setComputerIp(NetUtil.getLocalhostStr());
+        sys.setOsName(props.getProperty("os.name"));
+        sys.setOsArch(props.getProperty("os.arch"));
+        sys.setUserDir(props.getProperty("user.dir"));
+    }
+
+    /**
+     * 设置Java虚拟机
+     */
+    private void setJvmInfo() {
+        Properties props = System.getProperties();
+        jvm.setTotal(Runtime.getRuntime().totalMemory());
+        jvm.setMax(Runtime.getRuntime().maxMemory());
+        jvm.setFree(Runtime.getRuntime().freeMemory());
+        jvm.setVersion(props.getProperty("java.version"));
+        jvm.setHome(props.getProperty("java.home"));
+    }
+
+    /**
+     * 设置磁盘信息
+     */
+    private void setSysFiles(OperatingSystem os) {
+        FileSystem fileSystem = os.getFileSystem();
+        OSFileStore[] fsArray = fileSystem.getFileStores();
+        for (OSFileStore fs : fsArray) {
+            long free = fs.getUsableSpace();
+            long total = fs.getTotalSpace();
+            long used = total - free;
+            SysFile sysFile = new SysFile();
+            sysFile.setDirName(fs.getMount());
+            sysFile.setSysTypeName(fs.getType());
+            sysFile.setTypeName(fs.getName());
+            sysFile.setTotal(convertFileSize(total));
+            sysFile.setFree(convertFileSize(free));
+            sysFile.setUsed(convertFileSize(used));
+            sysFile.setUsage(NumberUtil.round(NumberUtil.mul(used, total, 4), 100).doubleValue());
+            sysFiles.add(sysFile);
+        }
+    }
+
+    /**
+     * 字节转换
+     *
+     * @param size 字节大小
+     * @return 转换后值
+     */
+    public String convertFileSize(long size) {
+        long kb = 1024;
+        long mb = kb * 1024;
+        long gb = mb * 1024;
+        if (size >= gb) {
+            return String.format("%.1f GB" , (float) size / gb);
+        } else if (size >= mb) {
+            float f = (float) size / mb;
+            return String.format(f > 100 ? "%.0f MB" : "%.1f MB" , f);
+        } else if (size >= kb) {
+            float f = (float) size / kb;
+            return String.format(f > 100 ? "%.0f KB" : "%.1f KB" , f);
+        } else {
+            return String.format("%d B" , size);
+        }
+    }
+}

+ 1 - 2
base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/MceReceiveService.java

@@ -6,7 +6,6 @@ import com.usky.common.mybatis.core.CrudService;
 import com.usky.system.domain.MceRequestVO;
 import com.usky.system.service.vo.MceReceiveResponseVO;
 
-import java.util.List;
 import java.util.Map;
 
 /**
@@ -19,7 +18,7 @@ import java.util.Map;
  */
 public interface MceReceiveService extends CrudService<MceReceive> {
 
-    CommonPage<Object> mceList(String infoTitle, String infoType, String startTime, String endTime, Integer id, Integer current, Integer size);
+    CommonPage<Object> mceList(String infoTitle, String infoType, String startTime, String endTime, Integer id, Integer infoId, Integer current, Integer size);
 
     CommonPage<Object> mceManageList(String infoTitle, String infoType, String startTime, String endTime, Integer current, Integer size);
 

+ 39 - 18
base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/SysLoginService.java

@@ -18,7 +18,10 @@ import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
 
+import javax.servlet.http.HttpServletRequest;
 import java.util.List;
 import java.util.Objects;
 import java.util.Random;
@@ -62,19 +65,22 @@ public class SysLoginService {
 
         // 用户名或密码为空 错误
         if (StringUtils.isAnyBlank(username, password)) {
-            asyncManager.insertLog(tenantId,username,Constants.LOGIN_FAIL, "用户/密码必须填写", null);
+            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
+            asyncManager.insertLog(request, tenantId,username,Constants.LOGIN_FAIL, "用户/密码必须填写", null);
             throw new BusinessException("用户/密码必须填写");
         }
         // 密码如果不在指定范围内 错误
         if (password.length() < UserConstants.PASSWORD_MIN_LENGTH
                 || password.length() > UserConstants.PASSWORD_MAX_LENGTH) {
-            asyncManager.insertLog(tenantId,username, Constants.LOGIN_FAIL, "用户密码不在指定范围", null);
+            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
+            asyncManager.insertLog(request, tenantId,username, Constants.LOGIN_FAIL, "用户密码不在指定范围", null);
             throw new BusinessException("用户密码不在指定范围");
         }
         // 用户名不在指定范围内 错误
         if (username.length() < UserConstants.USERNAME_MIN_LENGTH
                 || username.length() > UserConstants.USERNAME_MAX_LENGTH) {
-            asyncManager.insertLog(tenantId,username, Constants.LOGIN_FAIL, "用户名不在指定范围", null);
+            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
+            asyncManager.insertLog(request, tenantId,username, Constants.LOGIN_FAIL, "用户名不在指定范围", null);
             throw new BusinessException("用户名不在指定范围");
         }
 
@@ -88,15 +94,18 @@ public class SysLoginService {
 
         SysUserVO user = loginUser.getSysUser();
         if (UserStatus.DELETED.getCode().equals(user.getDelFlag())) {
-            asyncManager.insertLog(tenantId,username, Constants.LOGIN_FAIL, "对不起,您的账号已被删除", null);
+            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
+            asyncManager.insertLog(request, tenantId,username, Constants.LOGIN_FAIL, "对不起,您的账号已被删除", null);
             throw new BusinessException("对不起,您的账号:" + username + " 已被删除");
         }
         if (UserStatus.DISABLE.getCode().equals(user.getStatus())) {
-            asyncManager.insertLog(tenantId,username, Constants.LOGIN_FAIL, "用户已停用,请联系管理员", null);
+            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
+            asyncManager.insertLog(request, tenantId,username, Constants.LOGIN_FAIL, "用户已停用,请联系管理员", null);
             throw new BusinessException("对不起,您的账号:" + username + " 已停用");
         }
         if (!SecurityUtils.matchesPassword(password, user.getPassword())) {
-            asyncManager.insertLog(tenantId,username, Constants.LOGIN_FAIL, "用户密码错误", null);
+            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
+            asyncManager.insertLog(request, tenantId,username, Constants.LOGIN_FAIL, "用户密码错误", null);
             throw new BusinessException("用户不存在/密码错误");
         }
 
@@ -109,7 +118,8 @@ public class SysLoginService {
             String status = list.get(0).getStatus();
             String domain = list.get(0).getDomain();
             if(status.equals("1")){
-                asyncManager.insertLog(tenantId,username, Constants.LOGIN_FAIL, "系统已停用,请联系管理员", null);
+                HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
+                asyncManager.insertLog(request, tenantId,username, Constants.LOGIN_FAIL, "系统已停用,请联系管理员", null);
                 throw new BusinessException("对不起,系统已停用,请联系管理员");
             }
         }
@@ -128,7 +138,8 @@ public class SysLoginService {
 
         SysPerson sysPerson = sysPersonService.getsysPerson(user.getUserId());
         loginUser.setSysPerson(sysPerson);
-        asyncManager.insertLog(tenantId,username, Constants.LOGIN_SUCCESS, "登录成功", deptId);
+        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
+        asyncManager.insertLog(request, tenantId,username, Constants.LOGIN_SUCCESS, "登录成功", deptId);
         return loginUser;
     }
 
@@ -139,31 +150,36 @@ public class SysLoginService {
         if (!StringUtils.isBlank(username) && !StringUtils.isBlank(password)) {
             // 用户名或密码为空 错误
             if (StringUtils.isAnyBlank(username, password)) {
-                asyncManager.insertLog(tenantId,loginUser.getUserName(), Constants.LOGIN_FAIL, "用户/密码必须填写", null);
+                HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
+                asyncManager.insertLog(request, tenantId,loginUser.getUserName(), Constants.LOGIN_FAIL, "用户/密码必须填写", null);
                 throw new BusinessException("用户/密码必须填写");
             }
 
             // 密码如果不在指定范围内 错误
             if (password.length() < UserConstants.PASSWORD_MIN_LENGTH
                     || password.length() > UserConstants.PASSWORD_MAX_LENGTH) {
-                asyncManager.insertLog(tenantId,loginUser.getUserName(), Constants.LOGIN_FAIL, "用户密码不在指定范围", null);
+                HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
+                asyncManager.insertLog(request, tenantId,loginUser.getUserName(), Constants.LOGIN_FAIL, "用户密码不在指定范围", null);
                 throw new BusinessException("用户密码不在指定范围");
             }
 
             // 用户名不在指定范围内 错误
             if (username.length() < UserConstants.USERNAME_MIN_LENGTH
                     || username.length() > UserConstants.USERNAME_MAX_LENGTH) {
-                asyncManager.insertLog(tenantId,loginUser.getUserName(), Constants.LOGIN_FAIL, "用户名不在指定范围", null);
+                HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
+                asyncManager.insertLog(request, tenantId,loginUser.getUserName(), Constants.LOGIN_FAIL, "用户名不在指定范围", null);
                 throw new BusinessException("用户名不在指定范围");
             }
             loginUser = sysUserService.getAppUserInfo(username, tenantId, null, method);
             if (Objects.isNull(loginUser)) {
-                asyncManager.insertLog(tenantId,loginUser.getUserName(), Constants.LOGIN_FAIL, "用户不存在", null);
+                HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
+                asyncManager.insertLog(request, tenantId,loginUser.getUserName(), Constants.LOGIN_FAIL, "用户不存在", null);
                 throw new BusinessException("用户不存在");
             }
 
             if (!SecurityUtils.matchesPassword(password, loginUser.getPassword())) {
-                asyncManager.insertLog(tenantId,loginUser.getUserName(), Constants.LOGIN_FAIL, "用户密码错误", null);
+                HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
+                asyncManager.insertLog(request, tenantId,loginUser.getUserName(), Constants.LOGIN_FAIL, "用户密码错误", null);
                 throw new BusinessException("用户不存在/密码错误");
             }
         } else if(!StringUtils.isBlank(phone) && !StringUtils.isBlank(verify)) {
@@ -212,11 +228,13 @@ public class SysLoginService {
             deptId = sysUser.getDeptId().intValue(); // 将Long转换为Integer
         }
         if (UserStatus.DELETED.getCode().equals(loginUser.getDelFlag())) {
-            asyncManager.insertLog(tenantId,loginUser.getUserName(), Constants.LOGIN_FAIL, "对不起,您的账号已被删除", null);
+            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
+            asyncManager.insertLog(request, tenantId,loginUser.getUserName(), Constants.LOGIN_FAIL, "对不起,您的账号已被删除", null);
             throw new BusinessException("对不起,您的账号:" + username + " 已被删除");
         }
         if (UserStatus.DISABLE.getCode().equals(loginUser.getStatus())) {
-            asyncManager.insertLog(tenantId,loginUser.getUserName(), Constants.LOGIN_FAIL, "用户已停用,请联系管理员", null);
+            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
+            asyncManager.insertLog(request, tenantId,loginUser.getUserName(), Constants.LOGIN_FAIL, "用户已停用,请联系管理员", null);
             throw new BusinessException("对不起,您的账号:" + loginUser.getUserName() + " 已停用");
         }
 
@@ -225,13 +243,15 @@ public class SysLoginService {
         if (loginUser != null && loginUser.getDeptId() != null) {
             deptId = loginUser.getDeptId().intValue();
         }
-        asyncManager.insertLog(tenantId,loginUser.getUserName(), Constants.LOGIN_SUCCESS, "登录成功", deptId);
+        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
+        asyncManager.insertLog(request, tenantId,loginUser.getUserName(), Constants.LOGIN_SUCCESS, "登录成功", deptId);
         return loginUser;
     }
 
 
     public void logout(Integer tenantId,String loginName) {
-        asyncManager.insertLog(tenantId,loginName, Constants.LOGOUT, "退出成功", null);
+        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
+        asyncManager.insertLog(request, tenantId,loginName, Constants.LOGOUT, "退出成功", null);
     }
 
     /**
@@ -257,7 +277,8 @@ public class SysLoginService {
         sysUser.setNickName(username);
         sysUser.setPassword(SecurityUtils.encryptPassword(password));
         sysUserService.register(BeanMapperUtils.map(sysUser, SysUser.class));
-        asyncManager.insertLog(SecurityUtils.getTenantId(),username, Constants.REGISTER, "注册成功", null);
+        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
+        asyncManager.insertLog(request, SecurityUtils.getTenantId(),username, Constants.REGISTER, "注册成功", null);
     }
 
 

+ 32 - 0
base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/impl/MceContentServiceImpl.java

@@ -36,6 +36,7 @@ public class MceContentServiceImpl extends AbstractCrudService<MceContentMapper,
     private String appUrl;
 
     // 异步多线程调用
+    @Override
     @Async
     public void sendApp(JSONObject mceReceiveVO, String cids, Integer mceReceiveId, Integer sendType) {
         if (sendType.equals(0)) {
@@ -62,6 +63,7 @@ public class MceContentServiceImpl extends AbstractCrudService<MceContentMapper,
         }
     }
 
+    @Override
     @Async
     public void sendAppNew(MceRequestVO mceReceiveVO, String cids, Integer mceReceiveId, Integer sendType) {
         if (sendType.equals(0)) {
@@ -71,6 +73,9 @@ public class MceContentServiceImpl extends AbstractCrudService<MceContentMapper,
             jsonObject1.addProperty("moduleId", mceReceiveVO.getId());
             jsonObject.addProperty("cids", cids);
             jsonObject.addProperty("title", mceReceiveVO.getInfoTitle());
+            if ("3".equals(mceReceiveVO.getInfoType())){
+                jsonObject.addProperty("content", mceReceiveVO.getInfoContent().split("-")[0]);
+            }
             jsonObject.addProperty("content", mceReceiveVO.getInfoContent());
             jsonObject.add("payload", jsonObject1);
             String resultString = HttpClientUtils.doPostJson(appUrl, jsonObject.toString());
@@ -84,6 +89,33 @@ public class MceContentServiceImpl extends AbstractCrudService<MceContentMapper,
             if (StringUtils.isNotEmpty(mceReceiveVO.getInfoTypeName())) {
                 sendWeChatMessageRequestVO.setInfoTypeName(mceReceiveVO.getInfoTypeName());
             }
+            if (StringUtils.isNotEmpty(mceReceiveVO.getIpAddress())) {
+                sendWeChatMessageRequestVO.setIpAddress(mceReceiveVO.getIpAddress());
+            }
+            if (StringUtils.isNotEmpty(mceReceiveVO.getUserName())) {
+                sendWeChatMessageRequestVO.setUserName(mceReceiveVO.getUserName());
+            }
+            if (StringUtils.isNotEmpty(mceReceiveVO.getLoginAddress())) {
+                sendWeChatMessageRequestVO.setLoginAddress(mceReceiveVO.getLoginAddress());
+            }
+            if (StringUtils.isNotEmpty(mceReceiveVO.getLoginType())) {
+                sendWeChatMessageRequestVO.setLoginType(mceReceiveVO.getLoginType());
+            }
+            if (StringUtils.isNotEmpty(mceReceiveVO.getApprovalResult())) {
+                sendWeChatMessageRequestVO.setApprovalResult(mceReceiveVO.getApprovalResult());
+            }
+            if (StringUtils.isNotEmpty(mceReceiveVO.getProcessName())) {
+                sendWeChatMessageRequestVO.setProcessName(mceReceiveVO.getProcessName());
+            }
+            if (StringUtils.isNotEmpty(mceReceiveVO.getApprovalNode())) {
+                sendWeChatMessageRequestVO.setApprovalNode(mceReceiveVO.getApprovalNode());
+            }
+            if (StringUtils.isNotEmpty(mceReceiveVO.getRealName())) {
+                sendWeChatMessageRequestVO.setRealName(mceReceiveVO.getRealName());
+            }
+            if (StringUtils.isNotEmpty(mceReceiveVO.getOaType())) {
+                sendWeChatMessageRequestVO.setOaType(mceReceiveVO.getOaType());
+            }
             mceMbuserService.sendWeChatMessage(sendWeChatMessageRequestVO);
         }
     }

+ 108 - 31
base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/impl/MceMbuserServiceImpl.java

@@ -7,14 +7,12 @@ import com.usky.common.core.exception.BusinessException;
 import com.usky.common.redis.core.RedisHelper;
 import com.usky.system.domain.MceMbuser;
 import com.usky.system.mapper.MceMbuserMapper;
-import com.usky.system.service.ISysDictDataService;
 import com.usky.system.service.MceMbuserService;
 import com.usky.system.constant.constant;
 import com.usky.common.mybatis.core.AbstractCrudService;
-import com.usky.system.service.vo.SendWeChatMessageRequestVO;
-import com.usky.system.service.vo.TemplateData;
-import com.usky.system.service.vo.TemplateMsgEntityVO;
+import com.usky.system.service.vo.*;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.ResponseEntity;
 import org.springframework.stereotype.Service;
@@ -78,17 +76,20 @@ public class MceMbuserServiceImpl extends AbstractCrudService<MceMbuserMapper, M
         String infoContent = requestVO.getInfoContent();
         Integer infoId = requestVO.getInfoId();
         String openId = requestVO.getOpenId();
-
+        String infoType = requestVO.getInfoType();
+        String infoTypeName = requestVO.getInfoTypeName();
+        String oaType = requestVO.getOaType();
         // access_token时效校验,判断获取access_token获取时间是否超过有效时间,超过就调用更新,保证一直有效
         if (!redisHelper.hasKey("access_key")) {
             redisHelper.set("access_time", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
             redisHelper.set("access_key", this.getWeChatAccessToken());
         } else {
             try {
-                String access_time = redisHelper.get("access_time").toString();
-                String now_time = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
-                long i = getTimeDifference(access_time, now_time);
-                if (i > 115) { // 大于115分钟
+                String accessTime = redisHelper.get("access_time").toString();
+                String nowTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
+                long i = getTimeDifference(accessTime, nowTime);
+                // 大于115分钟
+                if (i > 115) {
                     redisHelper.set("access_time", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
                     redisHelper.set("access_key", this.getWeChatAccessToken());
                 }
@@ -104,35 +105,111 @@ public class MceMbuserServiceImpl extends AbstractCrudService<MceMbuserMapper, M
             return null;
         }
 
-        String token = obj.toString();
+        String tUrl;
+        String templateId = "";
 
-        TemplateMsgEntityVO messageVo = new TemplateMsgEntityVO();
-        messageVo.setTTitle(infoTitle);
-        messageVo.setTKeyword1(infoContent);
-        messageVo.setTKeyword3(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
-        messageVo.setTRemark(infoContent);
-        if (Objects.nonNull(requestVO.getInfoTypeName())) {
-            messageVo.setTUrl(String.format(constant.WE_CHAT_CUSTOMER_CALL_URL, requestVO.getInfoType(), requestVO.getInfoTypeName(), infoId));
-            messageVo.setTKeyword2(requestVO.getInfoTypeName());
-        } else {
-            messageVo.setTUrl(String.format(constant.WE_CHAT_CUSTOMER_CALL_URL1, requestVO.getInfoType(), infoId));
-            messageVo.setTKeyword2("");
+        Map<String, TemplateData> data = new HashMap<>();
+        String nowTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
+
+        switch (requestVO.getInfoType()) {
+            // 登录成功通知
+            case "0":
+                // 登录时间
+                data.put("time3", new TemplateData(nowTime, "#173177"));
+                // 登录账号 userName
+                data.put("thing6", new TemplateData(requestVO.getUserName(), "#173177"));
+                // 登录IP
+                data.put("character_string8", new TemplateData(requestVO.getIpAddress(), "#173177"));
+                // 登录地点
+                data.put("thing9", new TemplateData(requestVO.getLoginAddress(), "#173177"));
+                // 登录方式
+                data.put("thing10", new TemplateData(requestVO.getLoginType(), "#173177"));
+                // 设置公众号模板消息ID
+                templateId = constant.WE_CHAT_LOGIN_TEMPLATE_ID;
+                break;
+
+            /* 通知公告&工作报告通知(工单已完成通知)
+             * 工单标题{{thing9.DATA}}
+             * 发起人{{thing8.DATA}}
+             * 完成时间{{time12.DATA}}
+             **/
+            case "1":
+                data.put("thing9", new TemplateData("通知公告-" + requestVO.getInfoContent(), "#173177"));
+                data.put("thing8", new TemplateData(requestVO.getUserName(), "#173177"));
+                data.put("time12", new TemplateData(nowTime, "#173177"));
+                templateId = constant.WE_CHAT_WORK_TEMPLATE_ID;
+                break;
+            case "5":
+                data.put("thing9", new TemplateData("报告提醒-" + requestVO.getInfoContent(), "#173177"));
+                data.put("thing8", new TemplateData(requestVO.getUserName(), "#173177"));
+                data.put("time12", new TemplateData(nowTime, "#173177"));
+                // 设置公众号模板消息ID
+                templateId = constant.WE_CHAT_WORK_TEMPLATE_ID;
+                break;
+
+            case "3":
+                /* OA系统流程审批通知
+                 * 流程名称{{thing7.DATA}}
+                 * 审批节点{{thing8.DATA}}
+                 * 发起人{{thing13.DATA}}
+                 * 发起时间{{time10.DATA}}
+                 * 审批结果{{const21.DATA}}
+                 **/
+                data.put("thing7", new TemplateData(requestVO.getProcessName(), "#173177"));
+                data.put("thing8", new TemplateData(requestVO.getApprovalNode(), "#173177"));
+                data.put("thing13", new TemplateData(requestVO.getRealName(), "#173177"));
+                data.put("time10", new TemplateData(nowTime, "#173177"));
+                data.put("const21", new TemplateData(requestVO.getApprovalResult(), "#173177"));
+
+                // 设置公众号模板消息ID
+                templateId = constant.WE_CHAT_OA_TEMPLATE_ID;
+                break;
+
+            case "2":
+            case "4":
+                TemplateMsgEntityVO messageVo = new TemplateMsgEntityVO();
+                messageVo.setTTitle(infoTitle);
+                messageVo.setTKeyword1(infoContent);
+                messageVo.setTKeyword3(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
+                messageVo.setTRemark(infoContent);
+                /* 设备预警信息提醒
+                 * {{first.DATA}}
+                 * 设备号:{{keyword1.DATA}}
+                 * 报警类型:{{keyword2.DATA}}
+                 * 时间:{{keyword3.DATA}}
+                 * {{remark.DATA}}
+                 **/
+                messageVo.setTemplateId(constant.WE_CHAT_TEMPLATE_ID);
+                data.put("first", new TemplateData(messageVo.getTTitle(), "#44b549"));
+                data.put("keyword1", new TemplateData(messageVo.getTKeyword1(), "#173177"));
+                data.put("keyword2", new TemplateData(messageVo.getTKeyword2(), "#173177"));
+                data.put("keyword3", new TemplateData(messageVo.getTKeyword3(), "#173177"));
+                data.put("remark", new TemplateData(messageVo.getTRemark(), "#173177"));
+
+                templateId = messageVo.getTemplateId();
+                break;
         }
 
-        messageVo.setTemplateId(constant.WE_CHAT_TEMPLATE_ID);
+        log.info("oaType:{}",oaType);
+        // 回调地址
+        if ("3".equals(requestVO.getInfoType())) {
+            tUrl = String.format(constant.WE_CHAT_CUSTOMER_CALL_URL3, infoType, infoTypeName, infoId, oaType);
+        } else if (Objects.nonNull(infoTypeName)) {
+            tUrl = String.format(constant.WE_CHAT_CUSTOMER_CALL_URL, infoType, infoTypeName, infoId);
+        } else {
+            tUrl = String.format(constant.WE_CHAT_CUSTOMER_CALL_URL1, infoType, infoId);
+        }
 
+        String token = obj.toString();
         String requestUrl = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + token;
         Map<String, Object> content = new HashMap<>();
-        Map<String, TemplateData> data = new HashMap<>();
-        data.put("first", new TemplateData(messageVo.getTTitle(), "#44b549"));
-        data.put("keyword1", new TemplateData(messageVo.getTKeyword1(), "#173177"));
-        data.put("keyword2", new TemplateData(messageVo.getTKeyword2(), "#173177"));
-        data.put("keyword3", new TemplateData(messageVo.getTKeyword3(), "#173177"));
-        data.put("remark", new TemplateData(messageVo.getTRemark(), "#173177"));
-
         content.put("touser", openId);
-        content.put("url", messageVo.getTUrl());
-        content.put("template_id", messageVo.getTemplateId());
+        if (!"0".equals(requestVO.getInfoType())) {
+            content.put("url", tUrl);
+        }
+        if (StringUtils.isNotBlank(templateId)) {
+            content.put("template_id", templateId);
+        }
         content.put("data", data);
         String resp = HttpUtil.post(requestUrl, JSONUtil.parseObj(content).toString());
         System.out.println(content.toString());

+ 55 - 8
base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/impl/MceReceiveServiceImpl.java

@@ -64,8 +64,21 @@ public class MceReceiveServiceImpl extends AbstractCrudService<MceReceiveMapper,
     private MceReceiveMapper mceReceiveMapper;
 
     @Override
-    public CommonPage<Object> mceList(String infoTitle, String infoType, String startTime, String endTime, Integer id, Integer current, Integer size) {
+    public CommonPage<Object> mceList(String infoTitle, String infoType, String startTime, String endTime, Integer id, Integer infoId, Integer current, Integer size) {
         List<Object> list = new ArrayList<>();
+
+        if (infoId != null) {
+            LambdaQueryWrapper<MceReceive> query = Wrappers.lambdaQuery();
+            query.select(MceReceive::getContentId).eq(MceReceive::getId, infoId);
+            MceReceive mceReceive = mceReceiveMapper.selectOne(query);
+            if (mceReceive != null) {
+                id = mceReceive.getContentId();
+            } else {
+                log.error("消息内容已不存在!消息id:{}", infoId);
+                throw new BusinessException("消息内容已不存在!");
+            }
+        }
+
         LambdaQueryWrapper<MceContent> lambdaQuery1 = Wrappers.lambdaQuery();
         lambdaQuery1.select(MceContent::getId, MceContent::getInfoTitle, MceContent::getInfoContent)
                 .like(StringUtils.isNotBlank(infoTitle), MceContent::getInfoTitle, infoTitle)
@@ -82,7 +95,7 @@ public class MceReceiveServiceImpl extends AbstractCrudService<MceReceiveMapper,
             LambdaQueryWrapper<MceReceive> lambdaQuery = Wrappers.lambdaQuery();
             lambdaQuery.select(MceReceive::getId, MceReceive::getInfoType,
                             MceReceive::getContentId, MceReceive::getReadFlag, MceReceive::getCreateTime,
-                            MceReceive::getReceiverId, MceReceive::getModuleId, MceReceive::getCreateBy)
+                            MceReceive::getReceiverId, MceReceive::getModuleId, MceReceive::getCreateBy, MceReceive::getIssuerName)
                     .between(StringUtils.isNotBlank(startTime) && StringUtils.isNotBlank(endTime), MceReceive::getCreateTime,
                             startTime, endTime)
                     .eq(StringUtils.isNotBlank(infoType), MceReceive::getInfoType, infoType)
@@ -103,6 +116,7 @@ public class MceReceiveServiceImpl extends AbstractCrudService<MceReceiveMapper,
                     map.put("moduleId", page.getRecords().get(i).getModuleId());
                     map.put("createTime", page.getRecords().get(i).getCreateTime());
                     map.put("createBy", page.getRecords().get(i).getCreateBy());
+                    map.put("issuerName", page.getRecords().get(i).getIssuerName());
                     if (CollectionUtils.isNotEmpty(list1)) {
                         for (int j = 0; j < list1.size(); j++) {
                             if (page.getRecords().get(i).getContentId().equals(list1.get(j).getId())) {
@@ -251,6 +265,17 @@ public class MceReceiveServiceImpl extends AbstractCrudService<MceReceiveMapper,
     @Async
     @Override
     public void addMceReceive(MceRequestVO mceRequestVO) {
+
+        log.info("本次发送消息内容{}", mceRequestVO.toString());
+
+        // 登录成功 infoType 为 0,只给登录用户发送公众号消息
+        if ("0".equals(mceRequestVO.getInfoType())) {
+            List<MceMbuser> mbuserList = mceMbuserService.list(Wrappers.lambdaQuery(MceMbuser.class).in(MceMbuser::getUserId, mceRequestVO.getUserIds()));
+            String openid = mbuserList.get(0).getOpenid();
+            mceContentService.sendAppNew(mceRequestVO, openid, 0, 1);
+            return;
+        }
+
         // 如果 infoTypeName 为空,则从字典数据中获取
         if (mceRequestVO.getInfoTypeName() == null) {
             String infoTypeName = sysDictDataService.selectDictLabel("message_type", mceRequestVO.getInfoType());
@@ -261,7 +286,8 @@ public class MceReceiveServiceImpl extends AbstractCrudService<MceReceiveMapper,
         try {
             tenantId = userMapper.selectOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUserName, mceRequestVO.getUserName()).select(SysUser::getTenantId)).getTenantId();
         } catch (Exception e) {
-            log.error("获取用户租户ID失败,报错信息:{}, 未找到用户-{}-的租户",e.getMessage(), mceRequestVO.getUserName());
+            log.error("获取用户租户ID失败,报错信息:{}, 未找到用户-{}-的租户", e.getMessage(), mceRequestVO.getUserName());
+            return;
         }
 
         // 获取当前租户的所有用户
@@ -276,13 +302,13 @@ public class MceReceiveServiceImpl extends AbstractCrudService<MceReceiveMapper,
 
         LocalDateTime currentTime = LocalDateTime.now();
         List<Long> userIdList = new ArrayList<>();
-        MceContent contentEntity = new MceContent();
-        Integer generatedContentId = 0;
+        Integer generatedContentId = null;
 
         // 遍历用户列表,处理消息内容
         for (SysUser user : userList) {
             userIdList.add(user.getUserId());
             if (mceRequestVO.getUserName().equals(user.getUserName())) {
+                MceContent contentEntity = new MceContent();
                 contentEntity.setInfoTitle(mceRequestVO.getInfoTitle());
                 contentEntity.setInfoContent(mceRequestVO.getInfoContent());
                 contentEntity.setInfoType(mceRequestVO.getInfoType());
@@ -290,15 +316,28 @@ public class MceReceiveServiceImpl extends AbstractCrudService<MceReceiveMapper,
                 contentEntity.setCreateTime(currentTime);
                 contentEntity.setDeptId(user.getDeptId().intValue());
                 contentEntity.setTenantId(user.getTenantId());
-                mceContentService.save(contentEntity);
+                boolean save = mceContentService.save(contentEntity);
+                if (!save) {
+                    log.error("消息内容保存失败,用户:{},消息内容:{}", user.getUserName(), contentEntity);
+                    continue;
+                }
                 generatedContentId = contentEntity.getId();
             }
         }
 
+
         // 筛选符合用户ID条件的用户
         List<Long> targetUserIds = mceRequestVO.getUserIds();
         userIdList.retainAll(targetUserIds);
 
+        if (CollectionUtils.isEmpty(userIdList)) {
+            log.error("用户:" + mceRequestVO.getUserName() +
+                    ",发送的" + mceRequestVO.getInfoTypeName() +
+                    ",id:" + mceRequestVO.getId() +
+                    ",抄送用户均未找到消息配置,消息发送终止");
+            return;
+        }
+
         // 查询符合条件的 MceMbuser 列表
         List<MceMbuser> mbUserList = mceMbuserService.list(Wrappers.lambdaQuery(MceMbuser.class).in(MceMbuser::getUserId, userIdList));
 
@@ -312,7 +351,6 @@ public class MceReceiveServiceImpl extends AbstractCrudService<MceReceiveMapper,
                     .filter(mbUser -> mbUser.getUserId().equals(userId))
                     .findFirst();
 
-
             for (SysUser user : userList) {
                 if (user.getUserId().equals(userId)) {
                     // 创建消息接收记录
@@ -503,7 +541,7 @@ public class MceReceiveServiceImpl extends AbstractCrudService<MceReceiveMapper,
         try {
             tenantId = userMapper.selectOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUserName, mceReceiveVO.get("userName")).select(SysUser::getTenantId)).getTenantId();
         } catch (Exception e) {
-            log.error("获取用户租户ID失败,报错信息:{}, 未找到用户-{}-的租户",e.getMessage(), mceReceiveVO.get("userName"));
+            log.error("获取用户租户ID失败,报错信息:{}, 未找到用户-{}-的租户", e.getMessage(), mceReceiveVO.get("userName"));
         }
         List<SysUser> list = userMapper.tenantIdUserList(tenantId);
         // 获取用户昵称与真实姓名Map
@@ -666,6 +704,10 @@ public class MceReceiveServiceImpl extends AbstractCrudService<MceReceiveMapper,
     @Override
     public void addNoToken(String mceNoToken) {
         JSONObject json = JSONObject.parseObject(mceNoToken);
+        String infoTypeName = sysDictDataService.selectDictLabel("message_type", json.get("infoType").toString());
+        if (!json.containsKey("infoTypeName")) {
+            json.put("infoTypeName", infoTypeName);
+        }
         List<String> userNames = JSONObject.parseArray(json.get("userNames").toString(), String.class);
 
         LambdaQueryWrapper<SysUser> lambdaQuery = Wrappers.lambdaQuery();
@@ -681,6 +723,11 @@ public class MceReceiveServiceImpl extends AbstractCrudService<MceReceiveMapper,
         mceRequestVO.setInfoTypeName(json.get("infoTypeName").toString());
         mceRequestVO.setId((Integer) json.get("id"));
         mceRequestVO.setUserName(json.get("userName").toString());
+        mceRequestVO.setApprovalResult(json.get("approvalResult").toString());
+        mceRequestVO.setProcessName(json.get("processName").toString());
+        mceRequestVO.setApprovalNode(json.get("approvalNode").toString());
+        mceRequestVO.setRealName(json.get("realName").toString());
+        mceRequestVO.setOaType(json.get("oaType").toString());
         addMceReceive(mceRequestVO);
     }
 }

+ 1 - 1
base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/impl/SysNoticeServiceImpl.java

@@ -108,7 +108,7 @@ public class SysNoticeServiceImpl extends AbstractCrudService<SysNoticeMapper, S
         mceRequestVO.setUserName(userName);
         mceRequestVO.setUserIds(userIds);
         try {
-            //mceReceiveService.add(jsonObject.toString());
+            // mceReceiveService.add(jsonObject.toString());
             mceReceiveService.addMceReceive(mceRequestVO);
         } catch (Exception e) {
             log.error(String.format("公告:%d,消息发送失败:%s", id, e.getMessage()));

+ 48 - 5
base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/util/AsyncFactory.java

@@ -2,17 +2,27 @@ package com.usky.system.service.util;
 
 
 import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.ruoyi.common.core.constant.Constants;
 import com.ruoyi.common.core.utils.ServletUtils;
 import com.ruoyi.common.core.utils.StringUtils;
 import com.ruoyi.common.core.utils.ip.IpUtils;
 import com.usky.common.core.util.SpringContextUtils;
+import com.usky.system.domain.MceRequestVO;
 import com.usky.system.domain.SysLogininfor;
+import com.usky.system.domain.SysUser;
+import com.usky.system.mapper.SysUserMapper;
 import com.usky.system.service.ISysLogininforService;
+import com.usky.system.service.ISysUserService;
+import com.usky.system.service.MceReceiveService;
 import eu.bitwalker.useragentutils.UserAgent;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import javax.servlet.http.HttpServletRequest;
+import java.util.Collections;
+
+import static com.usky.common.core.utils.ip.IpUtils.getIpAddr;
 
 /**
  * @description: 异步工厂(产生任务用)
@@ -23,6 +33,10 @@ public class AsyncFactory
 {
     private static final Logger sys_user_logger = LoggerFactory.getLogger("sys-user");
 
+    private static final MceReceiveService mceReceiveService = SpringContextUtils.getBean(MceReceiveService.class);
+
+    public static final SysUserMapper SYS_USER_MAPPER = SpringContextUtils.getBean(SysUserMapper.class);
+
     /**
      * 记录登录信息
      *
@@ -32,11 +46,13 @@ public class AsyncFactory
      * @param args 列表
      * @return 任务task
      */
-    public static void recordLoginInfo(final Integer tenantId,final String username,final String status, final String message, final Integer deptId,
-                                       final Object... args) {
-        final eu.bitwalker.useragentutils.UserAgent userAgent = UserAgent.parseUserAgentString(ServletUtils.getRequest().getHeader("User-Agent"));
-        final String ip = IpUtils.getIpAddr(ServletUtils.getRequest());
-        String address = AddressUtils.getRealAddressByIP(ip);
+    public static void recordLoginInfo(HttpServletRequest request, final Integer tenantId, final String username, final String status, final String message, final Integer deptId, final Object... args) {
+        final UserAgent userAgent = UserAgent.parseUserAgentString(request.getHeader("User-Agent"));
+        final String ip = request != null ? getIpAddr(request) : "未知";
+        String address = "未知"; // 默认地址为未知
+        if (request != null) {
+            address = AddressUtils.getRealAddressByIP(ip);
+        }
         StringBuilder s = new StringBuilder();
         s.append(getBlock(ip));
         s.append(address);
@@ -63,6 +79,11 @@ public class AsyncFactory
         // 日志状态
         if (StringUtils.equalsAny(status, Constants.LOGIN_SUCCESS, Constants.LOGOUT, Constants.REGISTER)) {
             logininfor.setStatus(String.valueOf(Constants.LOGIN_SUCCESS_STATUS)); // 使用String.valueOf进行转换
+
+        // 如果登录成功,发送微信公众号消息
+            if (Constants.LOGIN_SUCCESS.equals(status)) {
+                sendWeChatMessage(logininfor);
+            }
         } else if (Constants.LOGIN_FAIL.equals(status)) {
             logininfor.setStatus(String.valueOf(Constants.LOGIN_FAIL_STATUS)); // 使用String.valueOf进行转换
         }
@@ -79,4 +100,26 @@ public class AsyncFactory
         }
         return "[" + msg.toString() + "]";
     }
+
+    private static void sendWeChatMessage(SysLogininfor logininfor) {
+        MceRequestVO mceRequestVO = new MceRequestVO();
+        mceRequestVO.setInfoTitle("登录成功通知");
+        mceRequestVO.setInfoContent("用户 "+logininfor.getUserName() +" 登录成功!");
+        mceRequestVO.setInfoType("0");
+        mceRequestVO.setInfoTypeName("登录通知");
+        mceRequestVO.setUserName(logininfor.getUserName());
+
+        LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.select(SysUser::getUserId)
+                .eq(SysUser::getUserName, logininfor.getUserName());
+        SysUser sysUser = SYS_USER_MAPPER.selectOne(queryWrapper);
+
+        mceRequestVO.setUserIds(Collections.singletonList(sysUser.getUserId()));
+
+        mceRequestVO.setUserName(logininfor.getUserName());
+        mceRequestVO.setLoginAddress(logininfor.getLoginLocation());
+        mceRequestVO.setLoginType(logininfor.getOs() + "-" + logininfor.getBrowser());
+        mceRequestVO.setIpAddress(logininfor.getIpaddr());
+        mceReceiveService.addMceReceive(mceRequestVO);
+    }
 }

+ 10 - 17
base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/util/AsyncManager.java

@@ -7,6 +7,7 @@ import org.springframework.web.context.request.RequestContextHolder;
 import org.springframework.web.context.request.ServletRequestAttributes;
 
 import javax.annotation.PreDestroy;
+import javax.servlet.http.HttpServletRequest;
 import java.util.concurrent.ArrayBlockingQueue;
 import java.util.concurrent.ThreadPoolExecutor;
 import java.util.concurrent.TimeUnit;
@@ -40,23 +41,15 @@ public class AsyncManager {
         }
     }
 
-    public void insertLog(Integer tenantId, final String username, final String status, final String message, final Integer deptId) {
-        ServletRequestAttributes sra = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
-        if (sra != null) {
-            executorEvent.execute(() -> {
-                try {
-                    RequestContextHolder.setRequestAttributes(sra, true);
-                    logger.info("new Log is {} , {}", username, message);
-                    AsyncFactory.recordLoginInfo(tenantId, username, status, message, deptId);
-                } catch (Exception e) {
-                    logger.error("记录登录信息异常", e);
-                } finally {
-                    RequestContextHolder.resetRequestAttributes();
-                }
-            });
-        } else {
-            logger.warn("当前线程没有RequestContext,无法记录登录信息");
-        }
+    public void insertLog(HttpServletRequest request, Integer tenantId, final String username, final String status, final String message, final Integer deptId) {
+        executorEvent.execute(() -> {
+            try {
+                // 直接使用传入的request参数
+                AsyncFactory.recordLoginInfo(request, tenantId, username, status, message, deptId);
+            } catch (Exception e) {
+                logger.error("记录登录信息异常", e);
+            }
+        });
     }
 }
 

+ 46 - 0
base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/vo/SendWeChatMessageRequestVO.java

@@ -33,4 +33,50 @@ public class SendWeChatMessageRequestVO {
      * openId
      */
     String openId;
+
+    /**
+     * ip地址
+     */
+    String ipAddress;
+
+    /**
+     * 登录地址
+     */
+    String loginAddress;
+
+    /**
+     * 登录方式
+     */
+    String loginType;
+
+    /**
+     * 用户名
+     * 登录账号
+     */
+    String userName;
+
+    /**
+     * 审批结果
+     */
+    String approvalResult;
+
+    /**
+     * 流程名称
+     */
+    String processName;
+
+    /**
+     * 审批节点
+     */
+    String approvalNode;
+
+    /**
+     * 登录人真实姓名
+     */
+    String realName;
+
+    /**
+     * oa跳转类型 (todo我的待办、me我发起的、copy抄送我的)
+     */
+    String oaType;
 }