#297 消息类型大类代码删除

已关闭
fuyuchuan 请求将 98 次代码提交从 uskycloud/fu-dev 合并至 uskycloud/system-165
共有 48 个文件被更改,包括 1621 次插入290 次删除
  1. 16 3
      base-modules/service-file/src/main/java/com/ruoyi/file/service/impl/FilesServiceImpl.java
  2. 65 2
      base-modules/service-system/service-system-api/src/main/java/com/usky/system/domain/MceRequestVO.java
  3. 7 0
      base-modules/service-system/service-system-api/src/main/java/com/usky/system/domain/SysOperLogVO.java
  4. 13 0
      base-modules/service-system/service-system-api/src/main/java/com/usky/system/domain/SysUserVO.java
  5. 10 3
      base-modules/service-system/service-system-biz/pom.xml
  6. 8 1
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/constant/constant.java
  7. 13 3
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/controller/web/MceReceiveController.java
  8. 38 28
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/controller/web/SysProfileController.java
  9. 12 8
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/controller/web/SysUserController.java
  10. 21 3
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/controller/web/SysUserPersonController.java
  11. 27 0
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/controller/web/SystemInfoController.java
  12. 68 0
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/domain/Cpu.java
  13. 112 0
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/domain/Jvm.java
  14. 47 0
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/domain/Mem.java
  15. 41 0
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/domain/Sys.java
  16. 53 0
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/domain/SysFile.java
  17. 15 0
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/domain/SysUser.java
  18. 6 0
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/domain/SysUserPerson.java
  19. 185 0
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/domain/SystemHardwareInfo.java
  20. 2 1
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/mapper/SysPostMapper.java
  21. 2 1
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/mapper/SysRoleMapper.java
  22. 2 0
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/mapper/SysTenantMapper.java
  23. 6 2
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/MceReceiveService.java
  24. 39 18
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/SysLoginService.java
  25. 1 0
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/SysUserPersonService.java
  26. 41 0
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/impl/MceContentServiceImpl.java
  27. 125 31
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/impl/MceMbuserServiceImpl.java
  28. 275 107
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/impl/MceReceiveServiceImpl.java
  29. 2 1
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/impl/SysNoticeServiceImpl.java
  30. 39 26
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/impl/SysTenantServiceImpl.java
  31. 2 0
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/impl/SysUserOnlineServiceImpl.java
  32. 35 0
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/impl/SysUserPersonServiceImpl.java
  33. 7 8
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/impl/SysUserServiceImpl.java
  34. 159 14
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/util/AsyncFactory.java
  35. 10 19
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/util/AsyncManager.java
  36. 62 0
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/vo/SendWeChatMessageRequestVO.java
  37. 1 1
      base-modules/service-system/service-system-biz/src/main/resources/mapper/system/SysNoticeMapper.xml
  38. 2 1
      base-modules/service-system/service-system-biz/src/main/resources/mapper/system/SysPostMapper.xml
  39. 5 3
      base-modules/service-system/service-system-biz/src/main/resources/mapper/system/SysRoleMapper.xml
  40. 9 0
      base-modules/service-system/service-system-biz/src/main/resources/mapper/system/SysTenantMapper.xml
  41. 1 0
      base-modules/service-system/service-system-biz/src/main/resources/mapper/system/SysUserPersonMapper.xml
  42. 4 0
      usky-common/usky-common-core/src/main/java/com/usky/common/core/constants/SecurityConstants.java
  43. 9 0
      usky-common/usky-common-log/pom.xml
  44. 3 5
      usky-common/usky-common-log/src/main/java/com/usky/common/log/aspect/AddressUtils.java
  45. 3 0
      usky-common/usky-common-log/src/main/java/com/usky/common/log/aspect/LogAspect.java
  46. 1 1
      usky-common/usky-common-log/src/main/java/com/usky/common/log/service/WjConfig.java
  47. 6 0
      usky-common/usky-common-security/pom.xml
  48. 11 0
      usky-common/usky-common-security/src/main/java/com/usky/common/security/service/TokenService.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();

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

@@ -9,6 +9,7 @@ import lombok.extern.slf4j.Slf4j;
 
 import javax.validation.constraints.NotBlank;
 import javax.validation.constraints.NotNull;
+import java.time.LocalDateTime;
 import java.util.List;
 
 /**
@@ -20,7 +21,7 @@ import java.util.List;
 @EqualsAndHashCode(callSuper = true)
 @Slf4j
 @Data
-public class MceRequestVO  extends BaseEntity {
+public class MceRequestVO extends BaseEntity {
 
     /** 字典标签  */
     private String infoTypeName;
@@ -37,7 +38,9 @@ public class MceRequestVO  extends BaseEntity {
     @NotBlank(message = "消息内容 infoContent 不能为空!")
     private String infoContent;
 
-    /** 消息发布人  */
+    /** 用户名称
+     * 登录账号 loginAccount
+     * */
     @NotBlank(message = "消息发布人 userName 不能为空!")
     private String userName;
 
@@ -49,6 +52,66 @@ 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抄送我的)
+     */
+    private String oaType;
+
+    /**
+     * 设备id
+     */
+    private String deviceId;
+
+    /**
+     * 报警时间
+     */
+    private String alarmTime;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+    /**
+     * 报警发送方式(站内消息通知是默认的,1:APP,2:微信)
+     */
+    private String alarmSendType;
+
     @Override
     public String toString() {
         ObjectMapper objectMapper = new ObjectMapper();

+ 7 - 0
base-modules/service-system/service-system-api/src/main/java/com/usky/system/domain/SysOperLogVO.java

@@ -47,6 +47,9 @@ public class SysOperLogVO extends BaseEntity
     /** 操作地址 */
     private String operIp;
 
+    /** 操作地点 */
+    private String operLocation;
+
     /** 请求参数 */
     private String operParam;
 
@@ -195,6 +198,10 @@ public class SysOperLogVO extends BaseEntity
         this.operIp = operIp;
     }
 
+    public String getOperLocation() { return operLocation; }
+
+    public void setOperLocation(String operLocation) { this.operLocation = operLocation; }
+
     public String getOperParam()
     {
         return operParam;

+ 13 - 0
base-modules/service-system/service-system-api/src/main/java/com/usky/system/domain/SysUserVO.java

@@ -133,6 +133,19 @@ public class SysUserVO extends BaseEntity {
      */
     private String fullName;
 
+    /**
+     * 是否打开登录通知(1 表示是,0 表示否,默认 0)
+     */
+    private Integer isLoginNotify;
+
+    public Integer getIsLoginNotify() {
+        return isLoginNotify;
+    }
+
+    public void setIsLoginNotify(Integer isLoginNotify) {
+        this.isLoginNotify = isLoginNotify;
+    }
+
     public String getAddress() {
         return address;
     }

+ 10 - 3
base-modules/service-system/service-system-biz/pom.xml

@@ -59,11 +59,18 @@
             <artifactId>hutool-all</artifactId>
         </dependency>
 
+        <!-- 监控服务器资源状态 -->
         <dependency>
-            <groupId>org.json</groupId>
-            <artifactId>json</artifactId>
-            <version>20210307</version>
+            <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";
     // 微信公众号微信用户授权地址

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

@@ -36,7 +36,6 @@ public class MceReceiveController {
      * 消息列表分页
      * @param infoTitle  消息标题
      * @param infoType  消息类型
-     * @param infoTypeBig  消息类型-大类
      * @param startTime  开始时间
      * @param endTime  开始时间
      * @param current      当前页
@@ -46,13 +45,13 @@ public class MceReceiveController {
     @GetMapping("/mceList")
     public ApiResult<CommonPage<Object>> mceList(@RequestParam(value = "infoTitle", required = false) String infoTitle,
                                                  @RequestParam(value = "infoType", required = false) String infoType,
-                                                 @RequestParam(value = "infoTypeBig", required = false) String infoTypeBig,
                                                  @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, infoTypeBig, startTime, endTime, id, current, size));
+        return ApiResult.success(mceReceiveService.mceList(infoTitle, infoType, startTime, endTime, id, infoId, current, size));
     }
 
     /**
@@ -129,6 +128,17 @@ public class MceReceiveController {
         return ApiResult.success();
     }
 
+    /**
+     * 消息发布-无需token
+     * @return
+     */
+    @PostMapping("/addMceNew")
+    ApiResult<Void> addNoToken(@RequestBody String mceNoToken) {
+        mceReceiveService.addNoToken(mceNoToken);
+        return ApiResult.success();
+    }
+
+
     /**
      * 删除消息及内容,并清空所有的消息接收表数据
      */

+ 38 - 28
base-modules/service-system/service-system-biz/src/main/java/com/usky/system/controller/web/SysProfileController.java

@@ -7,10 +7,12 @@ import com.usky.common.core.util.StringUtils;
 import com.usky.common.security.service.TokenService;
 import com.usky.common.security.utils.SecurityUtils;
 import com.usky.system.domain.SysUser;
+import com.usky.system.domain.SysUserPerson;
 import com.usky.system.domain.SysUserVO;
 import com.usky.system.domain.constants.UserConstants;
 import com.usky.system.model.LoginUser;
 import com.usky.system.service.ISysUserService;
+import com.usky.system.service.SysUserPersonService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 
@@ -21,29 +23,37 @@ import java.util.Map;
 
 /**
  * 个人信息 业务处理
- * 
+ *
  * @author yq
  */
 @RestController
 @RequestMapping("/user/profile")
-public class SysProfileController extends BaseController
-{
+public class SysProfileController extends BaseController {
     @Autowired
     private ISysUserService userService;
 
     @Autowired
     private TokenService tokenService;
 
+    @Autowired
+    private SysUserPersonService sysUserPersonService;
+
     /**
      * 个人信息
      */
     @GetMapping
-    public ApiResult profile()
-    {
+    public ApiResult profile() {
         LoginUser loginUser = SecurityUtils.getLoginUser();
         SysUserVO user = loginUser.getSysUser();
-        Map<String,Object> map = new HashMap<>();
-        map.put("user",user);
+
+        SysUserPerson one = sysUserPersonService.lambdaQuery()
+                .eq(SysUserPerson::getUserId, user.getUserId())
+                .select(SysUserPerson::getIsLoginNotify)
+                .one();
+        user.setIsLoginNotify(one.getIsLoginNotify());
+
+        Map<String, Object> map = new HashMap<>();
+        map.put("user", user);
         map.put("roleGroup", userService.selectUserRoleGroup(loginUser.getUsername()));
         map.put("postGroup", userService.selectUserPostGroup(loginUser.getUsername()));
         return ApiResult.success(map);
@@ -53,24 +63,30 @@ public class SysProfileController extends BaseController
      * 修改用户
      */
     @PutMapping
-    public ApiResult updateProfile(@RequestBody SysUser user)
-    {
+    public ApiResult updateProfile(@RequestBody SysUser user) {
         if (StringUtils.isNotEmpty(user.getPhonenumber())
-                && UserConstants.NOT_UNIQUE.equals(userService.checkPhoneUnique(user)))
-        {
+                && UserConstants.NOT_UNIQUE.equals(userService.checkPhoneUnique(user))) {
             throw new BusinessException("修改用户'" + user.getUserName() + "'失败,手机号码已存在");
         }
         if (StringUtils.isNotEmpty(user.getEmail())
-                && UserConstants.NOT_UNIQUE.equals(userService.checkEmailUnique(user)))
-        {
+                && UserConstants.NOT_UNIQUE.equals(userService.checkEmailUnique(user))) {
             throw new BusinessException("修改用户'" + user.getUserName() + "'失败,邮箱账号已存在");
         }
         LoginUser loginUser = SecurityUtils.getLoginUser();
         SysUserVO sysUser = loginUser.getSysUser();
         user.setUserId(sysUser.getUserId());
         user.setPassword(null);
-        if (userService.updateUserProfile(user) > 0)
-        {
+        if (userService.updateUserProfile(user) > 0) {
+
+            // 更新登录通知设置
+            Integer isLoginNotify = user.getIsLoginNotify();
+            if (isLoginNotify != null) {
+                sysUserPersonService.lambdaUpdate()
+                        .eq(SysUserPerson::getUserId, sysUser.getUserId())
+                        .set(SysUserPerson::getIsLoginNotify, isLoginNotify)
+                        .update();
+            }
+
             // 更新缓存用户信息
             sysUser.setNickName(user.getNickName());
             sysUser.setPhonenumber(user.getPhonenumber());
@@ -86,22 +102,18 @@ public class SysProfileController extends BaseController
      * 重置密码
      */
     @PutMapping("/updatePwd")
-    public ApiResult updatePwd(String oldPassword, String newPassword)
-    {
+    public ApiResult updatePwd(String oldPassword, String newPassword) {
         LoginUser loginUser = SecurityUtils.getLoginUser();
         SysUserVO sysUser = loginUser.getSysUser();
         String userName = sysUser.getUserName();
         String password = sysUser.getPassword();
-        if (!SecurityUtils.matchesPassword(oldPassword, password))
-        {
+        if (!SecurityUtils.matchesPassword(oldPassword, password)) {
             throw new BusinessException("修改密码失败,旧密码错误");
         }
-        if (SecurityUtils.matchesPassword(newPassword, password))
-        {
+        if (SecurityUtils.matchesPassword(newPassword, password)) {
             throw new BusinessException("新密码不能与旧密码相同");
         }
-        if (userService.resetUserPwd(userName, SecurityUtils.encryptPassword(newPassword)) > 0)
-        {
+        if (userService.resetUserPwd(userName, SecurityUtils.encryptPassword(newPassword)) > 0) {
             // 更新缓存用户密码
             sysUser.setPassword(SecurityUtils.encryptPassword(newPassword));
             tokenService.setLoginUser(loginUser);
@@ -114,13 +126,11 @@ public class SysProfileController extends BaseController
      * 头像上传
      */
     @PostMapping("/avatar")
-    public ApiResult avatar(@RequestParam String filePath) throws IOException
-    {
+    public ApiResult avatar(@RequestParam String filePath) throws IOException {
         LoginUser loginUser = SecurityUtils.getLoginUser();
         SysUserVO sysUser = loginUser.getSysUser();
-        if (userService.updateUserAvatar(loginUser.getUsername(), filePath))
-        {
-            Map<String,Object> map = new HashMap<>();
+        if (userService.updateUserAvatar(loginUser.getUsername(), filePath)) {
+            Map<String, Object> map = new HashMap<>();
             map.put("imgUrl", filePath);
             // 更新缓存用户头像
             sysUser.setAvatar(filePath);

+ 12 - 8
base-modules/service-system/service-system-biz/src/main/java/com/usky/system/controller/web/SysUserController.java

@@ -7,16 +7,10 @@ import com.usky.common.security.utils.SecurityUtils;
 import com.usky.common.core.bean.ApiResult;
 import com.usky.common.core.exception.BusinessErrorCode;
 import com.usky.system.controller.web.page.TableDataInfo;
-import com.usky.system.domain.SysDept;
-import com.usky.system.domain.SysRole;
-import com.usky.system.domain.SysUser;
-import com.usky.system.domain.SysUserTenant;
+import com.usky.system.domain.*;
 import com.usky.system.domain.constants.UserConstants;
 import com.usky.system.mapper.SysUserTenantMapper;
-import com.usky.system.service.ISysDeptService;
-import com.usky.system.service.ISysPostService;
-import com.usky.system.service.ISysRoleService;
-import com.usky.system.service.ISysUserService;
+import com.usky.system.service.*;
 import com.usky.system.service.vo.SysUserNewVO;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.transaction.annotation.Transactional;
@@ -53,6 +47,9 @@ public class SysUserController extends BaseController
     @Autowired
     private SysUserTenantMapper sysUserTenantMapper;
 
+    @Autowired
+    private SysUserPersonService sysUserPersonService;
+
     /**
      * 获取用户列表
      */
@@ -155,6 +152,13 @@ public class SysUserController extends BaseController
         user.setCreateBy(SecurityUtils.getUsername());
         user.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
         int row = userService.insertUser(user);
+
+        // 新增用户登录通知设置
+        SysUserPerson sysUserPerson = new SysUserPerson();
+        sysUserPerson.setUserId(user.getUserId());
+        sysUserPerson.setIsLoginNotify(0);
+        sysUserPersonService.save(sysUserPerson);
+
         return toAjax(row);
     }
 

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

@@ -1,9 +1,13 @@
 package com.usky.system.controller.web;
 
-
+import com.usky.common.core.bean.ApiResult;
+import com.usky.system.service.SysUserPersonService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PutMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 
-import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
 
 /**
  * <p>
@@ -13,9 +17,23 @@ import org.springframework.stereotype.Controller;
  * @author JCB
  * @since 2022-08-22
  */
-@Controller
+@RestController
 @RequestMapping("/sysUserPerson")
 public class SysUserPersonController {
 
+    @Autowired
+    private SysUserPersonService sysUserPersonService;
+
+    /**
+     * 修改登录通知开关状态
+     * @param useId 用户id
+     * @param isLoginNotify 1:开启 0:关闭
+     * @return 0:失败
+     */
+    @PutMapping("/upIsLoginNotify")
+    public ApiResult<Integer> upIsLoginNotice(@RequestParam Long userId,
+                                              @RequestParam Integer isLoginNotify) {
+        return ApiResult.success(sysUserPersonService.upIsLoginNotify(userId, isLoginNotify));
+    }
 }
 

+ 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;
+}

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

@@ -100,6 +100,20 @@ public class SysUser extends BaseEntity
     /** 姓名 */
     private String fullName;
 
+    /**
+     * 是否打开登录通知(1 表示是,0 表示否,默认 0)
+     */
+    @TableField(exist = false)
+    private Integer isLoginNotify;
+
+    public Integer getIsLoginNotify() {
+        return isLoginNotify;
+    }
+
+    public void setIsLoginNotify(Integer isLoginNotify) {
+        this.isLoginNotify = isLoginNotify;
+    }
+
     /** 岗位 */
     @TableField(exist = false)
     private String post;
@@ -391,6 +405,7 @@ public class SysUser extends BaseEntity
             .append("updateTime", getUpdateTime())
             .append("remark", getRemark())
             .append("dept", getDept())
+            .append("isLoginNotify",  getIsLoginNotify())
             .toString();
     }
 }

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

@@ -1,6 +1,7 @@
 package com.usky.system.domain;
 
 import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableId;
 import java.io.Serializable;
 import lombok.Data;
@@ -36,5 +37,10 @@ public class SysUserPerson implements Serializable {
      */
     private Integer personId;
 
+    /**
+     * 是否打开登录通知(1 表示是,0 表示否,默认 0)
+     */
+    private Integer isLoginNotify;
+
 
 }

+ 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);
+        }
+    }
+}

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

@@ -53,7 +53,8 @@ public interface SysPostMapper extends CrudMapper<SysPost>
      * @param userName 用户名
      * @return 结果
      */
-    public List<SysPost> selectPostsByUserName(@Param("userName") String userName);
+    public List<SysPost> selectPostsByUserName(@Param("userName") String userName,
+                                               @Param("tenantId") Integer tenantId);
 
     /**
      * 删除岗位信息

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

@@ -62,7 +62,8 @@ public interface SysRoleMapper extends CrudMapper<SysRole>
      * @param userName 用户名
      * @return 角色列表
      */
-    public List<SysRole> selectRolesByUserName(@Param("userName") String userName);
+    public List<SysRole> selectRolesByUserName(@Param("userName") String userName,
+                                               @Param("tenantId") Integer tenantId);
 
     /**
      * 校验角色名称是否唯一

+ 2 - 0
base-modules/service-system/service-system-biz/src/main/java/com/usky/system/mapper/SysTenantMapper.java

@@ -2,6 +2,7 @@ package com.usky.system.mapper;
 
 import com.usky.common.mybatis.core.CrudMapper;
 import com.usky.system.domain.SysTenant;
+import com.usky.system.domain.SysUserRole;
 import com.usky.system.service.vo.SysTenantTwoVo;
 import com.usky.system.service.vo.SysTenantVo;
 import org.apache.ibatis.annotations.Param;
@@ -46,6 +47,7 @@ public interface SysTenantMapper extends CrudMapper<SysTenant> {
     void cloneSysMobileBanner(@Param("originalTenantId") Integer originalTenantId,@Param("tenantId") Integer tenantId,@Param("createBy") String createBy);
     void cloneSysTenantPlatform(@Param("originalTenantId") Integer originalTenantId,@Param("tenantId") Integer tenantId);
     void cloneSysMobileTenantMenu(@Param("originalTenantId") Integer originalTenantId,@Param("tenantId") Integer tenantId);
+    List<SysUserRole> selectSysUserRoleList(@Param("originalTenantId") Integer originalTenantId, @Param("UserId") long UserId);
     void cloneSysRoleMenu(@Param("originalRoleId") long originalRoleId,@Param("roleId") long roleId);
     void insertSysUserRole(@Param("UserId") long UserId,@Param("roleId") long roleId,@Param("tenantId") long tenantId);
 

+ 6 - 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 infoTypeBig, 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,4 +38,9 @@ public interface MceReceiveService extends CrudService<MceReceive> {
 
     CommonPage<MceReceiveResponseVO> getMceReceiveResponseVOList(Integer pageNumber, Integer pageSize);
 
+    /**
+     * 添加消息不带token
+     * @param mceReceive
+     */
+    void addNoToken(String mceReceive);
 }

+ 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);
     }
 
 

+ 1 - 0
base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/SysUserPersonService.java

@@ -13,4 +13,5 @@ import com.usky.common.mybatis.core.CrudService;
  */
 public interface SysUserPersonService extends CrudService<SysUserPerson> {
 
+    public Integer upIsLoginNotify(Long userId, Integer isLoginNotify);
 }

+ 41 - 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,42 @@ 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());
+            }
+            if (StringUtils.isNotEmpty(mceReceiveVO.getDeviceId())) {
+                sendWeChatMessageRequestVO.setDeviceId(mceReceiveVO.getDeviceId());
+            }
+            if (StringUtils.isNotEmpty(mceReceiveVO.getAlarmTime())) {
+                sendWeChatMessageRequestVO.setAlarmTime(mceReceiveVO.getAlarmTime());
+            }
+            if (StringUtils.isNotEmpty(mceReceiveVO.getRemark())) {
+                sendWeChatMessageRequestVO.setRemark(mceReceiveVO.getRemark());
+            }
             mceMbuserService.sendWeChatMessage(sendWeChatMessageRequestVO);
         }
     }

+ 125 - 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,128 @@ 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.getRealName(), "#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.getRealName(), "#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":
+                TemplateMsgEntityVO messageVo = new TemplateMsgEntityVO();
+                messageVo.setTTitle(infoTitle);
+                messageVo.setTKeyword1(infoContent);
+                messageVo.setTKeyword2(infoType);
+                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;
+            case "4":
+                /* 设备预警信息提醒
+                 * {{first.DATA}}
+                 * 设备号:{{keyword1.DATA}}
+                 * 报警类型:{{keyword2.DATA}}
+                 * 时间:{{keyword3.DATA}}
+                 * 备注:{{remark.DATA}}
+                 **/
+                data.put("first", new TemplateData(requestVO.getInfoTitle(), "#44b549"));
+                data.put("keyword1", new TemplateData(requestVO.getDeviceId(), "#173177"));
+                data.put("keyword2", new TemplateData(requestVO.getInfoContent(), "#173177"));
+                data.put("keyword3", new TemplateData(requestVO.getAlarmTime(), "#173177"));
+                data.put("remark", new TemplateData(requestVO.getRemark(), "#173177"));
+
+                // 设置公众号模板消息ID
+                templateId = constant.WE_CHAT_TEMPLATE_ID;
+                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());

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

@@ -63,13 +63,30 @@ public class MceReceiveServiceImpl extends AbstractCrudService<MceReceiveMapper,
     @Autowired
     private MceReceiveMapper mceReceiveMapper;
 
+    @Autowired
+    private SysUserPersonService sysUserPersonService;
+
     @Override
-    public CommonPage<Object> mceList(String infoTitle, String infoType, String infoTypeBig, 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)
-                .eq(id != null, MceContent::getId, id);
+                .eq(id != null, MceContent::getId, id)
+                .eq(MceContent::getTenantId, SecurityUtils.getTenantId());
         List<MceContent> list1 = mceContentService.list(lambdaQuery1);
         IPage<MceReceive> page = new Page<>(current, size);
         List<Integer> contentIds = new ArrayList<>();
@@ -81,7 +98,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)
@@ -89,12 +106,6 @@ public class MceReceiveServiceImpl extends AbstractCrudService<MceReceiveMapper,
                     .in(CollectionUtils.isNotEmpty(contentIds), MceReceive::getContentId, contentIds)
                     .orderByDesc(MceReceive::getId);
 
-            if (StringUtils.isNotBlank(infoTypeBig)) {
-                if ("2".equals(infoTypeBig)) {
-                    lambdaQuery.in(MceReceive::getInfoType, "2", "5");
-                }
-            }
-
 //                .inSql(StringUtils.isNotBlank(infoTitle),MceReceive::getContentId,"SELECT id FROM mce_content WHERE " +
 //                        "info_title like '%" + infoTitle + "%' AND tenant_id = "+SecurityUtils.getTenantId()+"");
             page = this.page(page, lambdaQuery);
@@ -104,20 +115,11 @@ public class MceReceiveServiceImpl extends AbstractCrudService<MceReceiveMapper,
                     Map<String, Object> map = new HashMap<>();
                     map.put("id", page.getRecords().get(i).getId());
                     map.put("infoType", infoType1);
-
-                    switch (infoType1) {
-                        case "2":
-                        case "5":
-                            map.put("infoTypeBig", "2");
-                            break;
-                        default:
-                            map.put("infoTypeBig", infoType1);
-                    }
-
                     map.put("readFlag", page.getRecords().get(i).getReadFlag());
                     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())) {
@@ -266,97 +268,169 @@ public class MceReceiveServiceImpl extends AbstractCrudService<MceReceiveMapper,
     @Async
     @Override
     public void addMceReceive(MceRequestVO mceRequestVO) {
-        // 如果 infoTypeName 为空,则从字典数据中获取
+        log.info("本次发送消息内容: {}", mceRequestVO.toString());
+
+        // 补充信息类型名称
         if (mceRequestVO.getInfoTypeName() == null) {
             String infoTypeName = sysDictDataService.selectDictLabel("message_type", mceRequestVO.getInfoType());
             mceRequestVO.setInfoTypeName(infoTypeName);
         }
 
-        Integer tenantId = userMapper.selectOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUserName, mceRequestVO.getUserName()).select(SysUser::getTenantId)).getTenantId();
+        // 获取发送者租户ID
+        Integer tenantId = getUserTenantId(mceRequestVO.getUserName());
+        if (tenantId == null) {
+            log.error("获取用户租户ID失败,未找到用户: {}", mceRequestVO.getUserName());
+            return;
+        }
 
-        // 获取当前租户的所有用户
-        List<SysUser> userList = userMapper.tenantIdUserList(tenantId);
-        if (CollectionUtils.isEmpty(userList)) {
+        // 获取租户所有用户信息
+        List<SysUser> allUsers = userMapper.tenantIdUserList(tenantId);
+        if (CollectionUtils.isEmpty(allUsers)) {
+            log.warn("租户下未找到任何用户,租户ID: {}", tenantId);
             return;
         }
 
-        // 获取用户昵称与真实姓名的映射
-        Map<String, String> userNameNickNameMap = userList.stream()
+        // 构建用户信息映射
+        Map<Long, SysUser> userIdToUserMap = allUsers.stream()
+                .collect(Collectors.toMap(SysUser::getUserId, user -> user));
+
+        Map<String, String> userNameToNickNameMap = allUsers.stream()
                 .collect(Collectors.toMap(SysUser::getUserName, SysUser::getNickName));
 
-        LocalDateTime currentTime = LocalDateTime.now();
-        List<Long> userIdList = new ArrayList<>();
-        MceContent contentEntity = new MceContent();
-        Integer generatedContentId = 0;
-
-        // 遍历用户列表,处理消息内容
-        for (SysUser user : userList) {
-            userIdList.add(user.getUserId());
-            if (mceRequestVO.getUserName().equals(user.getUserName())) {
-                contentEntity.setInfoTitle(mceRequestVO.getInfoTitle());
-                contentEntity.setInfoContent(mceRequestVO.getInfoContent());
-                contentEntity.setInfoType(mceRequestVO.getInfoType());
-                contentEntity.setCreateBy(user.getUserName());
-                contentEntity.setCreateTime(currentTime);
-                contentEntity.setDeptId(user.getDeptId().intValue());
-                contentEntity.setTenantId(user.getTenantId());
-                mceContentService.save(contentEntity);
-                generatedContentId = contentEntity.getId();
-            }
-        }
 
-        // 筛选符合用户ID条件的用户
+
+        // 筛选目标用户
         List<Long> targetUserIds = mceRequestVO.getUserIds();
-        userIdList.retainAll(targetUserIds);
+        List<Long> validUserIds = allUsers.stream()
+                .map(SysUser::getUserId)
+                .filter(targetUserIds::contains)
+                .collect(Collectors.toList());
+
+        if (CollectionUtils.isEmpty(validUserIds)) {
+            log.error("用户: {} 发送的{},id: {},抄送用户均不存在!消息发送终止",
+                    mceRequestVO.getUserName(), mceRequestVO.getInfoTypeName(), mceRequestVO.getId());
+            return;
+        }
+
+        // 获取用户消息配置
+        List<MceMbuser> mbUserList = mceMbuserService.list(Wrappers.lambdaQuery(MceMbuser.class)
+                .in(MceMbuser::getUserId, validUserIds));
+
+        if (CollectionUtils.isEmpty(mbUserList)) {
+            log.error("消息配置为空!用户id列表为: {},id: {},消息发送终止", validUserIds, mceRequestVO.getId());
+            return;
+        }
+
+        // 构建用户ID到消息配置的映射
+        Map<Long, MceMbuser> userIdToMbUserMap = mbUserList.stream()
+                .collect(Collectors.toMap(MceMbuser::getUserId, mbUser -> mbUser));
+
+        // 获取消息发送设置
+        List<MceSetting> settings = mceSettingService.list(Wrappers.lambdaQuery(MceSetting.class)
+                .eq(MceSetting::getCreateBy, mceRequestVO.getUserName()));
+
+        if (CollectionUtils.isEmpty(settings)) {
+            log.warn("未找到消息发送设置,用户: {}", mceRequestVO.getUserName());
+            return;
+        }
 
-        // 查询符合条件的 MceMbuser 列表
-        List<MceMbuser> mbUserList = mceMbuserService.list(Wrappers.lambdaQuery(MceMbuser.class).in(MceMbuser::getUserId, userIdList));
+        MceSetting setting = settings.get(0);
+        JSONObject appMode = JSONObject.parseObject(setting.getAppMode());
+        JSONObject wcMode = JSONObject.parseObject(setting.getWcMode());
 
-        // 遍历用户列表,处理消息接收记录
-        for (Long userId : userIdList) {
-            if (CollectionUtils.isEmpty(mbUserList)) {
+        // 处理每个目标用户的消息接收和发送
+        for (Long userId : validUserIds) {
+            SysUser user = userIdToUserMap.get(userId);
+            if (user == null) {
                 continue;
             }
 
-            Optional<MceMbuser> mbUserOptional = mbUserList.stream()
-                    .filter(mbUser -> mbUser.getUserId().equals(userId))
-                    .findFirst();
+            // 获取用户消息配置
+            MceMbuser mbUser = userIdToMbUserMap.get(userId);
+            if (mbUser == null) {
+                continue;
+            }
 
+            // 登录不需要新增消息记录
+            if ("0".equals(mceRequestVO.getInfoType())) {
+                handleMessageDelivery(mbUser, mceRequestVO, 0, appMode, wcMode);
+                return;
+            }
 
-            for (SysUser user : userList) {
-                if (user.getUserId().equals(userId)) {
-                    // 创建消息接收记录
-                    List<MceSetting> setting = mceSettingService.list(Wrappers.lambdaQuery(MceSetting.class).eq(MceSetting::getCreateBy, user.getUserName()));
-                    Integer receiveId = 0;
-                    if (CollectionUtils.isNotEmpty(setting)) {
-                        MceReceive mceReceive = createMceReceive(user, generatedContentId, mceRequestVO, userNameNickNameMap);
-                        this.save(mceReceive);
-                        receiveId = mceReceive.getId();
-                    }
+            // 保存消息内容
+            Integer contentId = saveMessageContent(mceRequestVO, userIdToUserMap);
+            if (contentId == null) {
+                log.error("消息内容保存失败,用户: {}", mceRequestVO.getUserName());
+                return;
+            }
 
-                    if (mbUserOptional.isPresent()) {
-                        MceMbuser mbUser = mbUserOptional.get();
-                        // 处理消息发送设置
-                        handleMessageSettings(mbUser, mceRequestVO, receiveId);
-                    }
-                }
+            // 创建消息接收记录
+            MceReceive mceReceive = createMceReceive(user, contentId, mceRequestVO, userNameToNickNameMap);
+            boolean saveResult = this.save(mceReceive);
+            if (!saveResult) {
+                log.error("创建消息接收记录失败,用户ID: {}", userId);
+                continue;
             }
+
+            // 根据消息类型处理消息发送
+            handleMessageDelivery(mbUser, mceRequestVO, mceReceive.getId(), appMode, wcMode);
+        }
+    }
+
+    /**
+     * 获取用户租户ID
+     */
+    private Integer getUserTenantId(String userName) {
+        try {
+            SysUser user = userMapper.selectOne(new LambdaQueryWrapper<SysUser>()
+                    .eq(SysUser::getUserName, userName)
+                    .select(SysUser::getTenantId));
+            return user != null ? user.getTenantId() : null;
+        } catch (Exception e) {
+            log.error("获取用户租户ID失败,报错信息:{}", e.getMessage(), e);
+            return null;
         }
     }
 
-    // 创建消息接收记录
-    private MceReceive createMceReceive(SysUser user, Integer generatedContentId, MceRequestVO mceRequestVO, Map<String, String> userNameNickNameMap) {
+    /**
+     * 保存消息内容
+     */
+    private Integer saveMessageContent(MceRequestVO mceRequestVO, Map<Long, SysUser> userIdToUserMap) {
+        SysUser sender = userIdToUserMap.values().stream()
+                .filter(user -> mceRequestVO.getUserName().equals(user.getUserName()))
+                .findFirst()
+                .orElse(null);
+
+        if (sender == null) {
+            log.error("未找到发送者信息,用户名: {}", mceRequestVO.getUserName());
+            return null;
+        }
+
+        MceContent contentEntity = new MceContent();
+        contentEntity.setInfoTitle(mceRequestVO.getInfoTitle());
+        contentEntity.setInfoContent(mceRequestVO.getInfoContent());
+        contentEntity.setInfoType(mceRequestVO.getInfoType());
+        contentEntity.setCreateBy(sender.getUserName());
+        contentEntity.setCreateTime(LocalDateTime.now());
+        contentEntity.setDeptId(sender.getDeptId().intValue());
+        contentEntity.setTenantId(sender.getTenantId());
+
+        boolean saveResult = mceContentService.save(contentEntity);
+        return saveResult ? contentEntity.getId() : null;
+    }
+
+    /**
+     * 创建消息接收记录
+     */
+    private MceReceive createMceReceive(SysUser user, Integer contentId, MceRequestVO mceRequestVO,
+                                        Map<String, String> userNameToNickNameMap) {
         MceReceive mceReceive = new MceReceive();
         mceReceive.setReceiverId(user.getUserId().intValue());
-        mceReceive.setContentId(generatedContentId);
+        mceReceive.setContentId(contentId);
         mceReceive.setReadFlag(0);
         mceReceive.setInfoType(mceRequestVO.getInfoType());
         mceReceive.setModuleId(mceRequestVO.getId());
-
-        String userName = mceRequestVO.getUserName();
-        String nickName = userNameNickNameMap.get(userName);
-        mceReceive.setIssuerName(nickName);
-
+        mceReceive.setIssuerName(userNameToNickNameMap.get(mceRequestVO.getUserName()));
         mceReceive.setReceiverName(user.getUserName());
         mceReceive.setCreateBy(mceRequestVO.getUserName());
         mceReceive.setCreateTime(LocalDateTime.now());
@@ -365,41 +439,96 @@ public class MceReceiveServiceImpl extends AbstractCrudService<MceReceiveMapper,
         return mceReceive;
     }
 
-    // 处理消息发送设置
-    private void handleMessageSettings(MceMbuser mbUser, MceRequestVO mceRequestVO, Integer mceReceiveId) {
-        List<MceSetting> settingList = mceSettingService.list(Wrappers.lambdaQuery(MceSetting.class).eq(MceSetting::getCreateBy, mceRequestVO.getUserName()));
+    /**
+     * 处理消息发送
+     */
+    private void handleMessageDelivery(MceMbuser mbUser, MceRequestVO mceRequestVO,
+                                       Integer mceReceiveId, JSONObject appMode, JSONObject wcMode) {
+        String infoType = mceRequestVO.getInfoType();
+
+        // 登录成功通知只给登录用户发送微信公众号消息
+        if ("0".equals(infoType)) {
+            SysUserPerson one = sysUserPersonService.lambdaQuery().select(SysUserPerson::getIsLoginNotify).eq(SysUserPerson::getUserId, mbUser.getUserId()).one();
+            Integer isLoginNotify = one.getIsLoginNotify();
+            if (isLoginNotify == 1) {
+                sendWeChatMessage(mbUser, mceRequestVO, wcMode, infoType, mceReceiveId);
+            } else {
+                log.info("用户{}未开启登录通知", mbUser.getUserId());
+            }
+            return;
+        }
 
-        if (CollectionUtils.isNotEmpty(settingList)) {
-            MceSetting setting = settingList.get(0);
-            JSONObject appMode = JSONObject.parseObject(setting.getAppMode());
-            JSONObject wcMode = JSONObject.parseObject(setting.getWcMode());
+        // 处理告警消息
+        if ("4".equals(infoType)) {
+            handleAlarmMessage(mbUser, mceRequestVO, mceReceiveId, appMode, wcMode, infoType);
+            return;
+        }
 
-            String infoType = mceRequestVO.getInfoType();
+        // 处理普通消息(默认APP和微信都通知)
+        handleNormalMessage(mbUser, mceRequestVO, mceReceiveId, appMode, wcMode, infoType);
+    }
 
-            // 处理应用消息发送
-            if (appMode.getBoolean(infoType)) {
-                if (mbUser.getCids() != null) {
-                    try {
-                        mceContentService.sendAppNew(mceRequestVO, mbUser.getCids(), 0, 0);
-                    } catch (Exception e) {
-                        log.error("为用户ID: {} 发送应用消息失败,错误信息: {}", mbUser.getUserId(), e.getMessage(), e);
-                    }
-                }
+    /**
+     * 处理告警消息
+     */
+    private void handleAlarmMessage(MceMbuser mbUser, MceRequestVO mceRequestVO, Integer mceReceiveId,
+                                    JSONObject appMode, JSONObject wcMode, String infoType) {
+        String alarmSendType = mceRequestVO.getAlarmSendType();
+        switch (alarmSendType) {
+            case "1":
+                sendAppMessage(mbUser, mceRequestVO, appMode, infoType);
+                break;
+            case "2":
+                sendWeChatMessage(mbUser, mceRequestVO, wcMode, infoType, mceReceiveId);
+                break;
+            default:
+                log.error("未知的告警发送类型: {}", alarmSendType);
+                break;
+        }
+    }
+
+    /**
+     * 发送普通消息
+     */
+    private void handleNormalMessage(MceMbuser mbUser, MceRequestVO mceRequestVO, Integer mceReceiveId,
+                                     JSONObject appMode, JSONObject wcMode, String infoType) {
+        sendAppMessage(mbUser, mceRequestVO, appMode, infoType);
+        sendWeChatMessage(mbUser, mceRequestVO, wcMode, infoType, mceReceiveId);
+    }
+
+    /**
+     * 发送APP消息
+     */
+    private void sendAppMessage(MceMbuser mbUser, MceRequestVO mceRequestVO, JSONObject mode, String infoType) {
+        if (mode.getBoolean(infoType) && mbUser.getCids() != null) {
+            try {
+                mceContentService.sendAppNew(mceRequestVO, mbUser.getCids(), 0, 0);
+            } catch (Exception e) {
+                log.error("为用户ID: {} 发送应用消息失败,错误信息: {}", mbUser.getUserId(), e.getMessage(), e);
             }
+        }
+    }
 
-            // 处理微信消息发送
-            if (wcMode.getBoolean(infoType)) {
-                if (mbUser.getOpenid() != null) {
-                    try {
-                        mceContentService.sendAppNew(mceRequestVO, mbUser.getOpenid(), mceReceiveId, 1);
-                    } catch (Exception e) {
-                        log.error("为用户ID: {} 发送微信消息失败,错误信息: {}", mbUser.getUserId(), e.getMessage(), e);
-                    }
-                }
+    /**
+     * 推送微信消息
+     */
+    private void sendWeChatMessage(MceMbuser mbUser, MceRequestVO mceRequestVO, JSONObject mode,
+                                   String infoType, Integer mceReceiveId) {
+
+        if (mbUser.getOpenid() == null) {
+            return;
+        }
+
+        if ("0".equals(infoType) || mode.getBoolean(infoType)) {
+            try {
+                mceContentService.sendAppNew(mceRequestVO, mbUser.getOpenid(), mceReceiveId, 1);
+            } catch (Exception e) {
+                log.error("为用户ID: {} 发送微信消息失败,错误信息: {}", mbUser.getUserId(), e.getMessage(), e);
             }
         }
     }
 
+
     /*
     @Async
     @Override
@@ -509,7 +638,12 @@ public class MceReceiveServiceImpl extends AbstractCrudService<MceReceiveMapper,
             mceReceiveVO.put("infoTypeName", infoTypeName);
         }
 
-        Integer tenantId = userMapper.selectOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUserName, mceReceiveVO.get("userName")).select(SysUser::getTenantId)).getTenantId();
+        Integer tenantId = null;
+        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"));
+        }
         List<SysUser> list = userMapper.tenantIdUserList(tenantId);
         // 获取用户昵称与真实姓名Map
         Map<String, String> userNameNickNameMap = list.stream().collect(Collectors.toMap(SysUser::getUserName, SysUser::getNickName));
@@ -657,4 +791,38 @@ public class MceReceiveServiceImpl extends AbstractCrudService<MceReceiveMapper,
 
         return new CommonPage<>(returnList, page.getTotal(), page.getSize(), page.getCurrent());
     }
+
+    /**
+     * 新增消息-无需token
+     * @param mceNoToken
+     */
+    @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();
+        lambdaQuery.select(SysUser::getUserId)
+                .in(SysUser::getUserName, userNames);
+        List<Long> userIdList = userMapper.selectList(lambdaQuery).stream().map(SysUser::getUserId).collect(Collectors.toList());
+
+        MceRequestVO mceRequestVO = new MceRequestVO();
+        mceRequestVO.setUserIds(userIdList);
+        mceRequestVO.setInfoTitle(json.get("infoTitle").toString());
+        mceRequestVO.setInfoContent(json.get("infoContent").toString());
+        mceRequestVO.setInfoType(json.get("infoType").toString());
+        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);
+    }
 }

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

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

+ 39 - 26
base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/impl/SysTenantServiceImpl.java

@@ -2,14 +2,12 @@ package com.usky.system.service.impl;
 
 import cn.hutool.core.date.DateTime;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
 import com.usky.common.core.bean.CommonPage;
 import com.usky.common.core.exception.BusinessException;
 import com.usky.common.mybatis.core.AbstractCrudService;
 import com.usky.common.security.utils.SecurityUtils;
-import com.usky.system.domain.SysDept;
-import com.usky.system.domain.SysRole;
-import com.usky.system.domain.SysTenant;
-import com.usky.system.domain.SysUserTenant;
+import com.usky.system.domain.*;
 import com.usky.system.mapper.SysTenantMapper;
 import com.usky.system.mapper.SysUserTenantMapper;
 import com.usky.system.service.ISysDeptService;
@@ -125,6 +123,12 @@ public class SysTenantServiceImpl extends AbstractCrudService<SysTenantMapper, S
         sysDept.setPhone(sysTenant.getPhoneNumber());
         sysDept.setCreateBy(SecurityUtils.getUsername());
         iSysDeptService.insertDept(sysDept);
+
+        TenantPlatformVo tenantPlatformVo = new TenantPlatformVo();
+        tenantPlatformVo.setPlatformIds(new Integer[]{Integer.parseInt(sysTenant.getSystemName())});
+        tenantPlatformVo.setRequestId(0);
+        tenantPlatformVo.setTenantId(tenantId);
+        sysTenantPlatformService.updateTenantPlatform(tenantPlatformVo);
     }
 
     @Override
@@ -169,25 +173,30 @@ public class SysTenantServiceImpl extends AbstractCrudService<SysTenantMapper, S
         sysTenantMapper.cloneSysMobileTenantMenu(originalTenantId,tenantId);
         //克隆用户角色和租户用户角色
         //sys_role
-        SysRole role = new SysRole();
-        long originalRoleId = SecurityUtils.getLoginUser().getSysUser().getRoles().get(0).getRoleId();
-        LambdaQueryWrapper<SysRole> queryWrapper = new LambdaQueryWrapper<>();
-        queryWrapper.select(SysRole::getRoleName,SysRole::getRoleKey,SysRole::getRoleSort,SysRole::getDataScope,SysRole::getStatus).eq(SysRole::getRoleId, originalRoleId);
-        SysRole one = roleService.getOne(queryWrapper);
-        role.setRoleName(one.getRoleName());
-        role.setRoleKey(one.getRoleKey());
-        role.setRoleSort(one.getRoleSort());
-        role.setDataScope(one.getDataScope());
-        role.setStatus(one.getStatus());
-        role.setCreateBy(SecurityUtils.getUsername());
-        role.setCreateTime(DateTime.now());
-        role.setTenantId(tenantId);
-        roleService.insertRole(role);
-        long roleId = role.getRoleId();
-        //sys_role_menu
-        sysTenantMapper.cloneSysRoleMenu(originalRoleId,roleId);
-        //sys_user_role
-        sysTenantMapper.insertSysUserRole(SecurityUtils.getUserId(),roleId,tenantId);
+        List<SysUserRole> sysUserRoleList = sysTenantMapper.selectSysUserRoleList(originalTenantId,SecurityUtils.getUserId());
+        if(sysUserRoleList.size()>0){
+            for (int i = 0; i < sysUserRoleList.size(); i++) {
+                SysRole role = new SysRole();
+                long originalRoleId = sysUserRoleList.get(i).getRoleId();
+                LambdaQueryWrapper<SysRole> queryWrapper = new LambdaQueryWrapper<>();
+                queryWrapper.select(SysRole::getRoleName,SysRole::getRoleKey,SysRole::getRoleSort,SysRole::getDataScope,SysRole::getStatus).eq(SysRole::getRoleId, originalRoleId);
+                SysRole one = roleService.getOne(queryWrapper);
+                role.setRoleName(one.getRoleName());
+                role.setRoleKey(one.getRoleKey());
+                role.setRoleSort(one.getRoleSort());
+                role.setDataScope(one.getDataScope());
+                role.setStatus(one.getStatus());
+                role.setCreateBy(SecurityUtils.getUsername());
+                role.setCreateTime(DateTime.now());
+                role.setTenantId(tenantId);
+                roleService.insertRole(role);
+                long roleId = role.getRoleId();
+                //sys_role_menu
+                sysTenantMapper.cloneSysRoleMenu(originalRoleId,roleId);
+                //sys_user_role
+                sysTenantMapper.insertSysUserRole(SecurityUtils.getUserId(),roleId,tenantId);
+            }
+        }
 
         //更新默认应用
         TenantPlatformVo tenantPlatformVo = new TenantPlatformVo();
@@ -212,9 +221,13 @@ public class SysTenantServiceImpl extends AbstractCrudService<SysTenantMapper, S
 
         LambdaQueryWrapper<SysRole> queryWrapper = new LambdaQueryWrapper<>();
         queryWrapper.select(SysRole::getRoleId).eq(SysRole::getTenantId, tenantId);
-        SysRole one = roleService.getOne(queryWrapper);
-        long roleId = one.getRoleId();
-        sysTenantMapper.delSysRoleMenu(roleId);
+        List<SysRole> list = roleService.list(queryWrapper);
+        if(CollectionUtils.isNotEmpty(list)){
+            for (int i = 0; i < list.size(); i++) {
+                long roleId = list.get(i).getRoleId();
+                sysTenantMapper.delSysRoleMenu(roleId);
+            }
+        }
         sysTenantMapper.delSysRole(tenantId);
         sysTenantMapper.delSysUserRole(tenantId);
     }

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

@@ -90,6 +90,8 @@ public class SysUserOnlineServiceImpl implements ISysUserOnlineService
         sysUserOnline.setIpaddr(user.getIpaddr());
         sysUserOnline.setLoginTime(user.getLoginTime());
         sysUserOnline.setExpireTime(user.getExpireTime());
+        sysUserOnline.setOs(user.getOs());
+        sysUserOnline.setBrowser(user.getBrowser());
         return sysUserOnline;
     }
 }

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

@@ -1,11 +1,17 @@
 package com.usky.system.service.impl;
 
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.usky.common.core.exception.BusinessException;
+import com.usky.common.security.utils.SecurityUtils;
 import com.usky.system.domain.SysUserPerson;
 import com.usky.system.mapper.SysUserPersonMapper;
 import com.usky.system.service.SysUserPersonService;
 import com.usky.common.mybatis.core.AbstractCrudService;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import java.util.Objects;
+
 /**
  * <p>
  * 用户人员关联 服务实现类
@@ -17,4 +23,33 @@ import org.springframework.stereotype.Service;
 @Service
 public class SysUserPersonServiceImpl extends AbstractCrudService<SysUserPersonMapper, SysUserPerson> implements SysUserPersonService {
 
+    @Autowired
+    private SysUserPersonMapper sysUserPersonMapper;
+
+    @Override
+    public Integer upIsLoginNotify(Long userId, Integer isLoginNotify) {
+
+        // 判断 isLoginNotify 是否为 0 或 1
+        if (isLoginNotify != 0 && isLoginNotify != 1) {
+            throw new BusinessException("参数设置错误");
+        }
+        // 判断要修改的用户是否为登录用户
+        if (!Objects.equals(userId, SecurityUtils.getUserId())) {
+            throw new BusinessException("你不能修改非本人的登录通知设置!");
+        }
+
+        // 更新登录通知设置
+        LambdaUpdateWrapper<SysUserPerson> wrapper = new LambdaUpdateWrapper<>();
+        wrapper.eq(SysUserPerson::getUserId, userId)
+                .set(SysUserPerson::getIsLoginNotify, isLoginNotify);
+        int result = sysUserPersonMapper.update(null, wrapper);
+
+        //  更新失败
+        if (result <= 0) {
+            log.error("用户:{},操作登录通知开关操作失败!");
+            throw new BusinessException("登录通知开关操作失败!请重试");
+        }
+
+        return result;
+    }
 }

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

@@ -3,14 +3,12 @@ package com.usky.system.service.impl;
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
-import com.usky.common.core.bean.ApiResult;
-import com.usky.common.core.exception.BusinessErrorCode;
-import com.usky.common.security.utils.SecurityUtils;
 import com.usky.common.core.bean.CommonPage;
 import com.usky.common.core.exception.BusinessException;
 import com.usky.common.core.util.BeanMapperUtils;
 import com.usky.common.core.util.StringUtils;
 import com.usky.common.mybatis.core.AbstractCrudService;
+import com.usky.common.security.utils.SecurityUtils;
 import com.usky.system.domain.*;
 import com.usky.system.domain.constants.UserConstants;
 import com.usky.system.mapper.*;
@@ -112,9 +110,7 @@ public class SysUserServiceImpl extends AbstractCrudService<SysUserMapper, SysUs
         }
 //        user.setUserType("00");
 //        user.setTenantId(SecurityUtils.getTenantId());
-        if(user.getUserType().equals("00")){
-            user.setDeptId(deptService.deptListByTenant(user.getTenantId()).get(0).getDeptId());
-        }
+        user.setDeptId(deptService.deptListByTenant(user.getTenantId()).get(0).getDeptId());
 
         user.setCreateBy(SecurityUtils.getUsername());
         user.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
@@ -143,6 +139,7 @@ public class SysUserServiceImpl extends AbstractCrudService<SysUserMapper, SysUs
     public List<SysUser> selectDUserList(SysUser user) {
         user.setTenantId(SecurityUtils.getTenantId());
         user.setUserType("00");
+        user.setStatus("0");
         return userMapper.selectUserList(user);
     }
 
@@ -247,7 +244,8 @@ public class SysUserServiceImpl extends AbstractCrudService<SysUserMapper, SysUs
      */
     @Override
     public String selectUserRoleGroup(String userName) {
-        List<SysRole> list = roleMapper.selectRolesByUserName(userName);
+        Integer tenantId = SecurityUtils.getTenantId();
+        List<SysRole> list = roleMapper.selectRolesByUserName(userName, tenantId);
         StringBuffer idsStr = new StringBuffer();
         for (SysRole role : list) {
             idsStr.append(role.getRoleName()).append(",");
@@ -266,7 +264,8 @@ public class SysUserServiceImpl extends AbstractCrudService<SysUserMapper, SysUs
      */
     @Override
     public String selectUserPostGroup(String userName) {
-        List<SysPost> list = postMapper.selectPostsByUserName(userName);
+        Integer tenantId = SecurityUtils.getTenantId();
+        List<SysPost> list = postMapper.selectPostsByUserName(userName, tenantId);
         StringBuffer idsStr = new StringBuffer();
         for (SysPost post : list) {
             idsStr.append(post.getPostName()).append(",");

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

@@ -1,28 +1,45 @@
 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.CacheConstants;
 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.common.log.aspect.AddressUtils;
+import com.usky.common.redis.core.RedisService;
+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.model.LoginUser;
 import com.usky.system.service.ISysLogininforService;
+import com.usky.system.service.MceReceiveService;
 import eu.bitwalker.useragentutils.UserAgent;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Component;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.*;
+import java.util.concurrent.TimeUnit;
 
+import static com.usky.common.core.utils.ip.IpUtils.getIpAddr;
 
 /**
  * @description: 异步工厂(产生任务用)
  * @author: XiaoYu
  * @date: 2024/08/20 13:58
  */
-public class AsyncFactory
-{
+@Component
+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 +49,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 +82,13 @@ 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);
+                // 保留用户相同OS的最新1条token,删除其他所有token
+                SpringContextUtils.getBean(AsyncFactory.class).asyncRetainLatestToken(username);
+            }
         } else if (Constants.LOGIN_FAIL.equals(status)) {
             logininfor.setStatus(String.valueOf(Constants.LOGIN_FAIL_STATUS)); // 使用String.valueOf进行转换
         }
@@ -71,12 +97,131 @@ public class AsyncFactory
         SpringContextUtils.getBean(ISysLogininforService.class).insertLogininfor(logininfor);
     }
 
-    public static String getBlock(Object msg)
-    {
-        if (msg == null)
-        {
+    public static String getBlock(Object msg) {
+        if (msg == null) {
             msg = "";
         }
         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);
+    }
+
+    /**
+     * 异步清理历史token
+     *
+     * @param username 用户名
+     */
+    @Async
+    public void asyncRetainLatestToken(String username) {
+        try {
+            // 等待2秒
+            TimeUnit.SECONDS.sleep(2);
+            // 调用清理token的方法
+            retainLatestToken(username);
+        } catch (InterruptedException e) {
+            Thread.currentThread().interrupt();
+            sys_user_logger.error("异步清理token时发生错误", e);
+        }
+    }
+
+    /**
+     * 保留用户相同OS的最新一个token,删除其他历史token
+     *
+     * @param username 用户名
+     */
+    private static void retainLatestToken(String username) {
+        RedisService redisService = SpringContextUtils.getBean(RedisService.class);
+
+        try {
+            // 获取所有与该用户相关的token键
+            String pattern = CacheConstants.LOGIN_TOKEN_KEY + "*";
+            Collection<String> keys = redisService.keys(pattern);
+            if (keys == null || keys.isEmpty()) {
+                sys_user_logger.warn("Redis密钥为null或为空");
+                return;
+            }
+
+            // 存储该用户的token及其对应的LoginUser对象
+            Map<String, LoginUser> userTokens = new HashMap<>();
+
+            for (String key : keys) {
+                // 检查键是否存在并且未过期
+                if (redisService.hasKey(key)) {
+                    LoginUser user = redisService.getCacheObject(key);
+                    sys_user_logger.info("从Redis获取的LoginUser对象: {}", user);
+                    if (user != null && username.equals(user.getUsername())) {
+                        userTokens.put(key, user);
+                    }
+                }
+            }
+
+            if (userTokens.isEmpty()) {
+                sys_user_logger.warn("未找到用户 {} 的任何token", username);
+                return;
+            }
+
+            // 分组逻辑:根据OS分组
+            Map<String, List<Map.Entry<String, LoginUser>>> groupedTokens = new HashMap<>();
+            for (Map.Entry<String, LoginUser> entry : userTokens.entrySet()) {
+                LoginUser loginUser = entry.getValue();
+                String os = StringUtils.isEmpty(loginUser.getOs()) ? "未知" : loginUser.getOs();
+                groupedTokens.computeIfAbsent(os, k -> new ArrayList<>()).add(entry);
+            }
+
+            // 删除列表
+            List<String> tokensToDelete = new ArrayList<>();
+            for (List<Map.Entry<String, LoginUser>> entryList : groupedTokens.values()) {
+                // 按照登录时间降序排序
+                entryList.sort((e1, e2) ->
+                        e2.getValue().getLoginTime().compareTo(e1.getValue().getLoginTime())
+                );
+
+                // 只保留最新的一个token,其余的都添加到tokensToDelete列表中
+                for (int i = 1; i < entryList.size(); i++) {
+                    String keyToDelete = entryList.get(i).getKey();
+                    tokensToDelete.add(keyToDelete);
+                }
+            }
+
+            // 删除其他token
+            sys_user_logger.info("要删除的token列表: {}", tokensToDelete);
+            for (String keyToDelete : tokensToDelete) {
+                if (keyToDelete != null) {
+                    // 再次检查键是否存在
+                    if (redisService.hasKey(keyToDelete)) {
+                        boolean deleted = redisService.deleteObject(keyToDelete);
+                        sys_user_logger.info("Deleted Token Key: " + keyToDelete + ", Result: " + deleted);
+                    } else {
+                        sys_user_logger.warn("尝试删除的token键 {} 不存在,跳过删除操作", keyToDelete);
+                    }
+                } else {
+                    sys_user_logger.warn("尝试删除的token键为null,跳过删除操作");
+                }
+            }
+
+            sys_user_logger.info("用户 {} 的token已清理,仅保留每种OS的最新token: 已删除{}个", username, tokensToDelete.size());
+        } catch (Exception ex) {
+            sys_user_logger.error("清理用户 {} 的token时发生错误", username, ex);
+        }
+    }
 }

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

@@ -3,10 +3,9 @@ package com.usky.system.service.util;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Component;
-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 +39,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);
+            }
+        });
     }
 }
 

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

@@ -33,4 +33,66 @@ 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;
+
+    /**
+     * 设备id
+     */
+    private String deviceId;
+
+
+    /**
+     * 报警时间
+     */
+    private String alarmTime;
+
+    /**
+     * 备注
+     */
+    private String remark;
 }

+ 1 - 1
base-modules/service-system/service-system-biz/src/main/resources/mapper/system/SysNoticeMapper.xml

@@ -68,7 +68,7 @@
             </if>
             AND FIND_IN_SET(#{deptId}, dept_id) > 0
         </where>
-        order by notice_id desc
+        order by create_time desc
     </select>
 
     <insert id="insertNotice" useGeneratedKeys="true" keyProperty="noticeId"

+ 2 - 1
base-modules/service-system/service-system-biz/src/main/resources/mapper/system/SysPostMapper.xml

@@ -62,12 +62,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 	    where u.user_id = #{userId}
 	</select>
 	
-	<select id="selectPostsByUserName" parameterType="String" resultMap="SysPostResult">
+	<select id="selectPostsByUserName" parameterType="Map" resultMap="SysPostResult">
 		select p.post_id, p.post_name, p.post_code
 		from sys_post p
 			 left join sys_user_post up on up.post_id = p.post_id
 			 left join sys_user u on u.user_id = up.user_id
 		where u.user_name = #{userName}
+		and p.tenant_id = #{tenantId, jdbcType=INTEGER}
 	</select>
 	
 	<select id="checkPostNameUnique" parameterType="String" resultMap="SysPostResult">

+ 5 - 3
base-modules/service-system/service-system-biz/src/main/resources/mapper/system/SysRoleMapper.xml

@@ -24,7 +24,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 	
 	<sql id="selectRoleVo">
 	    select distinct r.role_id, r.role_name, r.role_key, r.role_sort, r.data_scope, r.menu_check_strictly, r.dept_check_strictly,
-            r.status, r.del_flag, r.create_time, r.remark 
+            r.status, r.del_flag, r.create_time, r.remark
         from sys_role r
 	        left join sys_user_role ur on ur.role_id = r.role_id
 	        left join sys_user u on u.user_id = ur.user_id
@@ -82,9 +82,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 		where r.role_id = #{roleId}
 	</select>
 	
-	<select id="selectRolesByUserName" parameterType="String" resultMap="SysRoleResult">
+	<select id="selectRolesByUserName" parameterType="Map" resultMap="SysRoleResult">
 		<include refid="selectRoleVo"/>
-		WHERE r.del_flag = '0' and u.user_name = #{userName}
+		WHERE r.del_flag = '0'
+		and u.user_name = #{userName}
+		and r.tenant_id = #{tenantId, jdbcType=INTEGER}
 	</select>
 	
 	<select id="checkRoleNameUnique" parameterType="String" resultMap="SysRoleResult">

+ 9 - 0
base-modules/service-system/service-system-biz/src/main/resources/mapper/system/SysTenantMapper.xml

@@ -147,6 +147,15 @@
             tenant_id = #{originalTenantId}
         </where>
     </insert>
+    <select id="selectSysUserRoleList" resultType="com.usky.system.domain.SysUserRole">
+        SELECT
+        a.*
+        FROM
+        sys_user_role AS a
+        <where>
+            a.tenant_id = #{originalTenantId} and a.user_id = #{UserId}
+        </where>
+    </select>
     <insert id="cloneSysRoleMenu">
         insert into sys_role_menu (role_id,menu_id,menu_alias_name)
         select  #{roleId},menu_id,menu_alias_name

+ 1 - 0
base-modules/service-system/service-system-biz/src/main/resources/mapper/system/SysUserPersonMapper.xml

@@ -7,6 +7,7 @@
         <id column="id" property="id" />
         <result column="user_id" property="userId" />
         <result column="person_id" property="personId" />
+        <result column="is_login_notify" property="isLoginNotify" />
     </resultMap>
 
 </mapper>

+ 4 - 0
usky-common/usky-common-core/src/main/java/com/usky/common/core/constants/SecurityConstants.java

@@ -43,4 +43,8 @@ public class SecurityConstants
     public static final String LOGIN_USER = "login_user";
 
     public static final String DETAILS_TENANT_ID = "";
+
+    public static final String DETAILS_OS =  "osInfo";
+
+    public static final String DETAILS_BROWSER = "browserInfo";
 }

+ 9 - 0
usky-common/usky-common-log/pom.xml

@@ -24,6 +24,15 @@
             <groupId>com.usky</groupId>
             <artifactId>usky-common-security</artifactId>
         </dependency>
+        <dependency>
+            <groupId>com.usky</groupId>
+            <artifactId>ruoyi-common-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.json</groupId>
+            <artifactId>json</artifactId>
+            <version>20210307</version>
+        </dependency>
 
     </dependencies>
 </project>

+ 3 - 5
base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/util/AddressUtils.java → usky-common/usky-common-log/src/main/java/com/usky/common/log/aspect/AddressUtils.java

@@ -1,14 +1,12 @@
-package com.usky.system.service.util;
+package com.usky.common.log.aspect;
 
 import cn.hutool.http.HttpUtil;
-import com.alibaba.nacos.shaded.com.google.common.base.Strings;
 import com.ruoyi.common.core.utils.ip.IpUtils;
-import com.usky.system.domain.WjConfig;
+import com.usky.common.log.service.WjConfig;
 import org.json.JSONException;
+import org.json.JSONObject;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.springframework.util.StringUtils;
-import org.json.JSONObject;
 
 
 /*

+ 3 - 0
usky-common/usky-common-log/src/main/java/com/usky/common/log/aspect/LogAspect.java

@@ -103,6 +103,9 @@ public class LogAspect {
             operLog.setConsumingTime(consumingTime); // 存储耗时
             operLog.setConsumingTimeWithUnit(consumingTimeWithUnit); // 存储带有单位的字符串
 
+            String operLocation = AddressUtils.getRealAddressByIP(ip);
+            operLog.setOperLocation(operLocation);
+
             // 保存数据库
             asyncLogService.saveSysLog(operLog);
         } catch (Exception exp) {

+ 1 - 1
base-modules/service-system/service-system-biz/src/main/java/com/usky/system/domain/WjConfig.java → usky-common/usky-common-log/src/main/java/com/usky/common/log/service/WjConfig.java

@@ -1,4 +1,4 @@
-package com.usky.system.domain;
+package com.usky.common.log.service;
 
 import lombok.Data;
 import org.springframework.boot.context.properties.ConfigurationProperties;

+ 6 - 0
usky-common/usky-common-security/pom.xml

@@ -36,6 +36,12 @@
             <groupId>com.usky</groupId>
             <artifactId>usky-common-redis</artifactId>
         </dependency>
+        <dependency>
+            <groupId>eu.bitwalker</groupId>
+            <artifactId>UserAgentUtils</artifactId>
+            <version>1.21</version>
+            <scope>compile</scope>
+        </dependency>
 
     </dependencies>
 

+ 11 - 0
usky-common/usky-common-security/src/main/java/com/usky/common/security/service/TokenService.java

@@ -6,6 +6,7 @@ import com.usky.common.core.util.*;
 import com.usky.common.redis.core.RedisHelper;
 import com.usky.common.security.utils.SecurityUtils;
 import com.usky.system.model.LoginUser;
+import eu.bitwalker.useragentutils.UserAgent;
 import org.springframework.cloud.commons.util.IdUtils;
 import org.springframework.stereotype.Component;
 
@@ -50,6 +51,14 @@ public class TokenService {
         loginUser.setUserid(userId);
         loginUser.setUsername(userName);
         loginUser.setIpaddr(IpUtils.getIpAddr(ServletUtils.getRequest()));
+        // 获取操作系统信息
+        String userAgentString = ServletUtils.getRequest().getHeader("User-Agent");
+        UserAgent userAgent = UserAgent.parseUserAgentString(userAgentString);
+        String osInfo = userAgent.getOperatingSystem().getName();
+        String browserInfo = userAgent.getBrowser().getName();
+        loginUser.setOs(osInfo);
+        loginUser.setBrowser(browserInfo);
+
         refreshToken(loginUser);
 
         // Jwt存储信息
@@ -58,6 +67,8 @@ public class TokenService {
         claimsMap.put(SecurityConstants.DETAILS_USER_ID, userId);
         claimsMap.put(SecurityConstants.DETAILS_USERNAME, userName);
         claimsMap.put(SecurityConstants.DETAILS_TENANT_ID, tenantId);
+        claimsMap.put(SecurityConstants.DETAILS_OS, osInfo);
+        claimsMap.put(SecurityConstants.DETAILS_BROWSER, browserInfo);
 
         // 接口返回信息
         Map<String, Object> rspMap = new HashMap<String, Object>();