Browse Source

Merge branch 'master' into system-zyj

# Conflicts:
#	base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/impl/MceReceiveServiceImpl.java
james 5 months ago
parent
commit
b10e135658
85 changed files with 2775 additions and 521 deletions
  1. 80 147
      base-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/ip/IpUtils.java
  2. 28 0
      base-modules/service-system/service-system-api/src/main/java/com/usky/system/domain/SysOperLogVO.java
  3. 26 0
      base-modules/service-system/service-system-api/src/main/java/com/usky/system/model/LoginUser.java
  4. 16 0
      base-modules/service-system/service-system-biz/pom.xml
  5. 5 5
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/MybatisGeneratorUtils.java
  6. 4 0
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/controller/web/MceReceiveController.java
  7. 5 0
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/controller/web/SysConfigController.java
  8. 15 0
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/controller/web/SysDeptController.java
  9. 5 0
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/controller/web/SysDictDataController.java
  10. 5 0
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/controller/web/SysDictTypeController.java
  11. 5 3
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/controller/web/SysLogininforController.java
  12. 34 4
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/controller/web/SysMenuController.java
  13. 5 0
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/controller/web/SysNoticeController.java
  14. 2 1
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/controller/web/SysOperlogController.java
  15. 26 2
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/controller/web/SysPlatformController.java
  16. 5 0
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/controller/web/SysPostController.java
  17. 7 0
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/controller/web/SysRoleController.java
  18. 4 2
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/controller/web/SysTenantConfigController.java
  19. 64 0
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/controller/web/SysTenantPlatformController.java
  20. 44 6
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/controller/web/SysUserController.java
  21. 167 52
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/controller/web/SysUserOnlineController.java
  22. 66 0
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/controller/web/SysUserTenantController.java
  23. 1 0
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/controller/web/TokenController.java
  24. 5 3
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/controller/web/UserConfigController.java
  25. 39 0
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/controller/web/page/TableDataInfo.java
  26. 42 0
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/domain/SysLogininfor.java
  27. 28 0
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/domain/SysOperLog.java
  28. 5 0
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/domain/SysPlatform.java
  29. 5 0
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/domain/SysTenantConfig.java
  30. 37 0
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/domain/SysTenantPlatform.java
  31. 69 29
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/domain/SysUserOnline.java
  32. 39 0
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/domain/SysUserTenant.java
  33. 131 0
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/domain/WjConfig.java
  34. 2 0
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/mapper/SysDeptMapper.java
  35. 13 0
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/mapper/SysMenuMapper.java
  36. 7 0
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/mapper/SysPlatformMapper.java
  37. 27 0
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/mapper/SysTenantPlatformMapper.java
  38. 15 0
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/mapper/SysUserMapper.java
  39. 36 0
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/mapper/SysUserTenantMapper.java
  40. 2 0
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/ISysDeptService.java
  41. 24 3
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/ISysMenuService.java
  42. 32 0
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/ISysUserService.java
  43. 67 60
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/SysLoginService.java
  44. 10 0
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/SysPlatformService.java
  45. 26 0
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/SysTenantPlatformService.java
  46. 42 0
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/SysUserTenantService.java
  47. 4 0
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/impl/MceContentServiceImpl.java
  48. 20 6
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/impl/MceReceiveServiceImpl.java
  49. 4 3
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/impl/MceSettingServiceImpl.java
  50. 12 23
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/impl/SysDeptServiceImpl.java
  51. 184 4
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/impl/SysMenuServiceImpl.java
  52. 22 4
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/impl/SysPlatformServiceImpl.java
  53. 150 0
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/impl/SysTenantPlatformServiceImpl.java
  54. 2 0
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/impl/SysUserOnlineServiceImpl.java
  55. 110 29
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/impl/SysUserServiceImpl.java
  56. 96 0
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/impl/SysUserTenantServiceImpl.java
  57. 115 0
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/util/AddressUtils.java
  58. 82 0
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/util/AsyncFactory.java
  59. 62 0
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/util/AsyncManager.java
  60. 5 0
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/vo/PlatformMenuVo.java
  61. 41 0
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/vo/PlatformRouterVo.java
  62. 16 0
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/vo/SysLoginExportVO.java
  63. 16 0
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/vo/SysOperLogExportVO.java
  64. 5 0
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/vo/SysPlatformVo.java
  65. 43 0
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/vo/SysUserNewVO.java
  66. 47 0
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/vo/TenantPlatformListVo.java
  67. 39 0
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/vo/TenantPlatformMenuVo.java
  68. 38 0
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/vo/TenantPlatformVo.java
  69. 1 25
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/vo/TreeNode.java
  70. 20 5
      base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/vo/UserTreeNode.java
  71. 9 0
      base-modules/service-system/service-system-biz/src/main/resources/mapper/system/SysDeptMapper.xml
  72. 35 18
      base-modules/service-system/service-system-biz/src/main/resources/mapper/system/SysLogininforMapper.xml
  73. 80 0
      base-modules/service-system/service-system-biz/src/main/resources/mapper/system/SysMenuMapper.xml
  74. 15 3
      base-modules/service-system/service-system-biz/src/main/resources/mapper/system/SysOperLogMapper.xml
  75. 28 0
      base-modules/service-system/service-system-biz/src/main/resources/mapper/system/SysPlatformMapper.xml
  76. 1 0
      base-modules/service-system/service-system-biz/src/main/resources/mapper/system/SysTenantConfigMapper.xml
  77. 16 0
      base-modules/service-system/service-system-biz/src/main/resources/mapper/system/SysTenantPlatformMapper.xml
  78. 26 2
      base-modules/service-system/service-system-biz/src/main/resources/mapper/system/SysUserMapper.xml
  79. 19 0
      base-modules/service-system/service-system-biz/src/main/resources/mapper/system/SysUserTenantMapper.xml
  80. 4 0
      usky-common/usky-common-core/src/main/java/com/usky/common/core/bean/ApiResult.java
  81. 58 75
      usky-common/usky-common-log/src/main/java/com/usky/common/log/aspect/LogAspect.java
  82. 6 0
      usky-common/usky-common-log/src/main/java/com/usky/common/log/enums/BusinessType.java
  83. 3 1
      usky-common/usky-common-log/src/main/java/com/usky/common/log/service/AsyncLogService.java
  84. 17 4
      usky-common/usky-common-security/src/main/java/com/usky/common/security/auth/AuthLogic.java
  85. 2 2
      usky-common/usky-common-security/src/main/java/com/usky/common/security/auth/AuthUtil.java

+ 80 - 147
base-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/ip/IpUtils.java

@@ -2,103 +2,103 @@ package com.ruoyi.common.core.utils.ip;
 
 import java.net.InetAddress;
 import java.net.UnknownHostException;
+import java.util.Objects;
 import javax.servlet.http.HttpServletRequest;
 import com.ruoyi.common.core.utils.StringUtils;
 
 /**
  * 获取IP方法
- * 
+ *
  * @author ruoyi
  */
-public class IpUtils
-{
-    /**
-     * 获取客户端IP
-     * 
-     * @param request 请求对象
-     * @return IP地址
-     */
-    public static String getIpAddr(HttpServletRequest request)
-    {
-        if (request == null)
-        {
+public final class IpUtils {
+
+    private IpUtils() {
+    }
+
+    public static String getIpAddr(HttpServletRequest request) {
+        if (request == null) {
             return "unknown";
         }
         String ip = request.getHeader("x-forwarded-for");
-        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
-        {
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
             ip = request.getHeader("Proxy-Client-IP");
         }
-        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
-        {
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
             ip = request.getHeader("X-Forwarded-For");
         }
-        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
-        {
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
             ip = request.getHeader("WL-Proxy-Client-IP");
         }
-        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
-        {
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
             ip = request.getHeader("X-Real-IP");
         }
-
-        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
-        {
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
             ip = request.getRemoteAddr();
         }
-
-        return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : getMultistageReverseProxyIp(ip);
+        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
+            ip = request.getRemoteAddr();
+            if ("127.0.0.1".equals(ip) || "0:0:0:0:0:0:0:1".equals(ip)) {
+                // 根据网卡取本机配置的IP
+                InetAddress inet = null;
+                try {
+                    inet = InetAddress.getLocalHost();
+                } catch (UnknownHostException e) {
+                    e.printStackTrace();
+                }
+                assert inet != null;
+                ip = inet.getHostAddress();
+            }
+        }
+        if ("0:0:0:0:0:0:0:1".equals(ip)) {
+            ip = "127.0.0.1";
+        } else {
+            String[] split = ip.split(",");
+            if (split.length > 1) {
+                for (String strIp : split) {
+                    if (!"127.0.0.1".equals(strIp)) {
+                        ip = strIp;
+                        break;
+                    }
+                }
+            }
+        }
+        return ip;
     }
 
-    /**
-     * 检查是否为内部IP地址
-     * 
-     * @param ip IP地址
-     * @return 结果
-     */
-    public static boolean internalIp(String ip)
-    {
+    public static boolean internalIp(String ip) {
         byte[] addr = textToNumericFormatV4(ip);
         return internalIp(addr) || "127.0.0.1".equals(ip);
     }
 
-    /**
-     * 检查是否为内部IP地址
-     * 
-     * @param addr byte地址
-     * @return 结果
-     */
-    private static boolean internalIp(byte[] addr)
-    {
-        if (StringUtils.isNull(addr) || addr.length < 2)
-        {
+    private static boolean internalIp(byte[] addr) {
+        if (Objects.isNull(addr) || addr.length < 2) {
             return true;
         }
         final byte b0 = addr[0];
         final byte b1 = addr[1];
         // 10.x.x.x/8
-        final byte SECTION_1 = 0x0A;
+        final byte section1 = 0x0A;
         // 172.16.x.x/12
-        final byte SECTION_2 = (byte) 0xAC;
-        final byte SECTION_3 = (byte) 0x10;
-        final byte SECTION_4 = (byte) 0x1F;
+        final byte section2 = (byte) 0xAC;
+        final byte section3 = (byte) 0x10;
+        final byte section4 = (byte) 0x1F;
         // 192.168.x.x/16
-        final byte SECTION_5 = (byte) 0xC0;
-        final byte SECTION_6 = (byte) 0xA8;
-        switch (b0)
-        {
-            case SECTION_1:
+        final byte section5 = (byte) 0xC0;
+        final byte section6 = (byte) 0xA8;
+        switch (b0) {
+            case section1:
                 return true;
-            case SECTION_2:
-                if (b1 >= SECTION_3 && b1 <= SECTION_4)
-                {
+            case section2:
+                if (b1 >= section3 && b1 <= section4) {
                     return true;
                 }
-            case SECTION_5:
-                switch (b1)
-                {
-                    case SECTION_6:
+            case section5:
+                switch (b1) {
+                    case section6:
                         return true;
+                    default:
+                        return false;
                 }
             default:
                 return false;
@@ -107,29 +107,24 @@ public class IpUtils
 
     /**
      * 将IPv4地址转换成字节
-     * 
+     *
      * @param text IPv4地址
      * @return byte 字节
      */
-    public static byte[] textToNumericFormatV4(String text)
-    {
-        if (text.length() == 0)
-        {
+    public static byte[] textToNumericFormatV4(String text) {
+        if (text.length() == 0) {
             return null;
         }
 
         byte[] bytes = new byte[4];
         String[] elements = text.split("\\.", -1);
-        try
-        {
+        try {
             long l;
             int i;
-            switch (elements.length)
-            {
+            switch (elements.length) {
                 case 1:
                     l = Long.parseLong(elements[0]);
-                    if ((l < 0L) || (l > 4294967295L))
-                    {
+                    if ((l < 0L) || (l > 4294967295L)) {
                         return null;
                     }
                     bytes[0] = (byte) (int) (l >> 24 & 0xFF);
@@ -139,14 +134,12 @@ public class IpUtils
                     break;
                 case 2:
                     l = Integer.parseInt(elements[0]);
-                    if ((l < 0L) || (l > 255L))
-                    {
+                    if ((l < 0L) || (l > 255L)) {
                         return null;
                     }
                     bytes[0] = (byte) (int) (l & 0xFF);
                     l = Integer.parseInt(elements[1]);
-                    if ((l < 0L) || (l > 16777215L))
-                    {
+                    if ((l < 0L) || (l > 16777215L)) {
                         return null;
                     }
                     bytes[1] = (byte) (int) (l >> 16 & 0xFF);
@@ -154,29 +147,24 @@ public class IpUtils
                     bytes[3] = (byte) (int) (l & 0xFF);
                     break;
                 case 3:
-                    for (i = 0; i < 2; ++i)
-                    {
+                    for (i = 0; i < 2; ++i) {
                         l = Integer.parseInt(elements[i]);
-                        if ((l < 0L) || (l > 255L))
-                        {
+                        if ((l < 0L) || (l > 255L)) {
                             return null;
                         }
                         bytes[i] = (byte) (int) (l & 0xFF);
                     }
                     l = Integer.parseInt(elements[2]);
-                    if ((l < 0L) || (l > 65535L))
-                    {
+                    if ((l < 0L) || (l > 65535L)) {
                         return null;
                     }
                     bytes[2] = (byte) (int) (l >> 8 & 0xFF);
                     bytes[3] = (byte) (int) (l & 0xFF);
                     break;
                 case 4:
-                    for (i = 0; i < 4; ++i)
-                    {
+                    for (i = 0; i < 4; ++i) {
                         l = Integer.parseInt(elements[i]);
-                        if ((l < 0L) || (l > 255L))
-                        {
+                        if ((l < 0L) || (l > 255L)) {
                             return null;
                         }
                         bytes[i] = (byte) (int) (l & 0xFF);
@@ -185,80 +173,25 @@ public class IpUtils
                 default:
                     return null;
             }
-        }
-        catch (NumberFormatException e)
-        {
+        } catch (NumberFormatException e) {
             return null;
         }
         return bytes;
     }
 
-    /**
-     * 获取IP地址
-     * 
-     * @return 本地IP地址
-     */
-    public static String getHostIp()
-    {
-        try
-        {
+    public static String getHostIp() {
+        try {
             return InetAddress.getLocalHost().getHostAddress();
-        }
-        catch (UnknownHostException e)
-        {
+        } catch (UnknownHostException e) {
         }
         return "127.0.0.1";
     }
 
-    /**
-     * 获取主机名
-     * 
-     * @return 本地主机名
-     */
-    public static String getHostName()
-    {
-        try
-        {
+    public static String getHostName() {
+        try {
             return InetAddress.getLocalHost().getHostName();
-        }
-        catch (UnknownHostException e)
-        {
+        } catch (UnknownHostException e) {
         }
         return "未知";
     }
-
-    /**
-     * 从多级反向代理中获得第一个非unknown IP地址
-     *
-     * @param ip 获得的IP地址
-     * @return 第一个非unknown IP地址
-     */
-    public static String getMultistageReverseProxyIp(String ip)
-    {
-        // 多级反向代理检测
-        if (ip != null && ip.indexOf(",") > 0)
-        {
-            final String[] ips = ip.trim().split(",");
-            for (String subIp : ips)
-            {
-                if (false == isUnknown(subIp))
-                {
-                    ip = subIp;
-                    break;
-                }
-            }
-        }
-        return ip;
-    }
-
-    /**
-     * 检测给定字符串是否为未知,多用于检测HTTP请求相关
-     *
-     * @param checkString 被检测的字符串
-     * @return 是否未知
-     */
-    public static boolean isUnknown(String checkString)
-    {
-        return StringUtils.isBlank(checkString) || "unknown".equalsIgnoreCase(checkString);
-    }
 }

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

@@ -63,6 +63,18 @@ public class SysOperLogVO extends BaseEntity
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private Date operTime;
 
+    /** 执行开始时间 */
+    private Date startTime;
+
+    /** 执行结束时间 */
+    private Date endTime;
+
+    /** 执行耗时时间 */
+    private Long consumingTime;
+
+    /** 执行耗时时间(带单位) */
+    private String consumingTimeWithUnit;
+
     public Long getOperId()
     {
         return operId;
@@ -222,4 +234,20 @@ public class SysOperLogVO extends BaseEntity
     {
         this.operTime = operTime;
     }
+
+    public Date getStartTime() {return startTime;}
+
+    public void setStartTime(Date startTime) {this.startTime = startTime;}
+
+    public Date getEndTime() {return endTime;}
+
+    public void setEndTime(Date endTime) {this.endTime = endTime;}
+
+    public Long getConsumingTime() {return consumingTime;}
+
+    public void setConsumingTime(Long consumingTime) {this.consumingTime = consumingTime;}
+
+    public String getConsumingTimeWithUnit() {return consumingTimeWithUnit;}
+
+    public void setConsumingTimeWithUnit(String consumingTimeWithUnit) {this.consumingTimeWithUnit = consumingTimeWithUnit;}
 }

+ 26 - 0
base-modules/service-system/service-system-api/src/main/java/com/usky/system/model/LoginUser.java

@@ -69,6 +69,15 @@ public class LoginUser implements Serializable {
      */
     private String userType;
 
+    /**
+     * 浏览器类型
+     */
+    private String browser;
+
+    /**
+     * 操作系统
+     */
+    private String os;
 
     /**
      * 用户人员信息
@@ -170,4 +179,21 @@ public class LoginUser implements Serializable {
     public void setSysUser(SysUserVO sysUser) {
         this.sysUser = sysUser;
     }
+
+    public String getBrowser() {
+        return browser;
+    }
+
+    public void setBrowser(String browser) {
+        this.browser = browser;
+    }
+
+    public String getOs() {
+        return os;
+    }
+
+    public void setOs(String os)
+    {
+        this.os = os;
+    }
 }

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

@@ -48,6 +48,22 @@
             <artifactId>ruoyi-common-swagger</artifactId>
         </dependency>
 
+        <!-- 解析客户端操作系统、浏览器等 -->
+        <dependency>
+            <groupId>eu.bitwalker</groupId>
+            <artifactId>UserAgentUtils</artifactId>
+            <version>1.21</version>
+        </dependency>
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-all</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.json</groupId>
+            <artifactId>json</artifactId>
+            <version>20210307</version>
+        </dependency>
     </dependencies>
 
     <build>

+ 5 - 5
base-modules/service-system/service-system-biz/src/main/java/com/usky/system/MybatisGeneratorUtils.java

@@ -17,7 +17,7 @@ import java.util.List;
 public class MybatisGeneratorUtils {
     public static void main(String[] args) {
 
-        shell("service-system", "service-system-biz");
+        shell("base-modules/service-system", "service-system-biz");
     }
 
     private static void shell(String parentName, String model) {
@@ -42,10 +42,10 @@ public class MybatisGeneratorUtils {
         //2、数据源配置
         //修改数据源
         DataSourceConfig dsc = new DataSourceConfig();
-        dsc.setUrl("jdbc:mysql://172.16.120.165:3306/usky-cloud?useUnicode=true&serverTimezone=GMT&useSSL=false&characterEncoding=utf8");
+        dsc.setUrl("jdbc:mysql://usky-cloud-mysql:3306/usky-cloud?useUnicode=true&serverTimezone=GMT&useSSL=false&characterEncoding=utf8");
         dsc.setDriverName("com.mysql.cj.jdbc.Driver");
-        dsc.setUsername("usky");
-        dsc.setPassword("Yt#75Usky");
+        dsc.setUsername("root");
+        dsc.setPassword("yt123456");
         mpg.setDataSource(dsc);
 
         // 3、包配置
@@ -70,7 +70,7 @@ public class MybatisGeneratorUtils {
         // strategy.setTablePrefix("t_"); // 表名前缀
         strategy.setEntityLombokModel(true); //使用lombok
         //修改自己想要生成的表
-        strategy.setInclude("sys_mobile_banner");  // 逆向工程使用的表   如果要生成多个,这里可以传入String[]
+        strategy.setInclude("sys_user_tenant");  // 逆向工程使用的表   如果要生成多个,这里可以传入String[]
         mpg.setStrategy(strategy);
 
         // 关闭默认 xml 生成,调整生成 至 根目录

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

@@ -3,6 +3,8 @@ package com.usky.system.controller.web;
 
 import com.usky.common.core.bean.ApiResult;
 import com.usky.common.core.bean.CommonPage;
+import com.usky.common.log.annotation.Log;
+import com.usky.common.log.enums.BusinessType;
 import com.usky.system.domain.MceReceive;
 import com.usky.system.service.MceReceiveService;
 import io.swagger.models.auth.In;
@@ -110,6 +112,7 @@ public class MceReceiveController {
      * 消息接收接口
      * @return
      */
+    @Log(title = "新增发布消息", businessType = BusinessType.INSERT)
     @PostMapping("/mceAdd")
     ApiResult<Void> add(@RequestBody String mceReceive){
         mceReceiveService.add(mceReceive);
@@ -119,6 +122,7 @@ public class MceReceiveController {
     /**
      * 删除
      */
+    @Log(title = "删除已发布消息", businessType = BusinessType.DELETE)
     @DeleteMapping("/{id}")
     public ApiResult<Void> removeById(@PathVariable("id") Integer id)
     {

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

@@ -3,6 +3,8 @@ package com.usky.system.controller.web;
 
 import com.usky.common.core.bean.ApiResult;
 import com.usky.common.core.exception.BusinessErrorCode;
+import com.usky.common.log.annotation.Log;
+import com.usky.common.log.enums.BusinessType;
 import com.usky.common.security.utils.SecurityUtils;
 import com.usky.system.controller.web.page.TableDataInfo;
 import com.usky.system.domain.SysConfig;
@@ -58,6 +60,7 @@ public class SysConfigController extends BaseController
     /**
      * 新增参数配置
      */
+    @Log(title = "新增-参数配置", businessType = BusinessType.INSERT)
     @PostMapping
     public ApiResult add(@Validated @RequestBody SysConfig config)
     {
@@ -72,6 +75,7 @@ public class SysConfigController extends BaseController
     /**
      * 修改参数配置
      */
+    @Log(title = "修改-参数配置", businessType = BusinessType.UPDATE)
     @PutMapping
     public ApiResult edit(@Validated @RequestBody SysConfig config)
     {
@@ -86,6 +90,7 @@ public class SysConfigController extends BaseController
     /**
      * 删除参数配置
      */
+    @Log(title = "删除-参数配置", businessType = BusinessType.DELETE)
     @DeleteMapping("/{configIds}")
     public ApiResult remove(@PathVariable Long[] configIds)
     {

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

@@ -4,6 +4,8 @@ package com.usky.system.controller.web;
 import com.usky.common.core.bean.ApiResult;
 import com.usky.common.core.exception.BusinessErrorCode;
 import com.usky.common.core.util.StringUtils;
+import com.usky.common.log.annotation.Log;
+import com.usky.common.log.enums.BusinessType;
 import com.usky.common.security.utils.SecurityUtils;
 import com.usky.system.domain.SysDept;
 import com.usky.system.domain.SysUser;
@@ -84,6 +86,16 @@ public class SysDeptController extends BaseController {
     @GetMapping("/deptUserTreeSelect")
     public ApiResult treeselect(SysDept dept, SysUser user) {
         List<SysDept> depts = deptService.deptList(dept);
+        List<SysUser> users = iSysUserService.selectDUserList(user);
+        return ApiResult.success(deptService.buildDeptUserTreeSelect(depts, users));
+    }
+
+    /**
+     * 部门人员下拉树-工时统计
+     */
+    @GetMapping("/jurisdictionDeptUserTree")
+    public ApiResult jurisdictionDeptUserTree(SysDept dept, SysUser user) {
+        List<SysDept> depts = deptService.selectDeptList(dept);
         List<SysUser> users = iSysUserService.selectUserList(user);
         return ApiResult.success(deptService.buildDeptUserTreeSelect(depts, users));
     }
@@ -103,6 +115,7 @@ public class SysDeptController extends BaseController {
     /**
      * 新增部门
      */
+    @Log(title = "新增-部门", businessType = BusinessType.INSERT)
     @PostMapping
     public ApiResult add(@Validated @RequestBody SysDept dept) {
         if (UserConstants.NOT_UNIQUE.equals(deptService.checkDeptNameUnique(dept))) {
@@ -116,6 +129,7 @@ public class SysDeptController extends BaseController {
     /**
      * 修改部门
      */
+    @Log(title = "修改-部门", businessType = BusinessType.UPDATE)
     @PutMapping
     public ApiResult edit(@Validated @RequestBody SysDept dept) {
         if (UserConstants.NOT_UNIQUE.equals(deptService.checkDeptNameUnique(dept))) {
@@ -133,6 +147,7 @@ public class SysDeptController extends BaseController {
     /**
      * 删除部门
      */
+    @Log(title = "删除-部门", businessType = BusinessType.DELETE)
     @DeleteMapping("/{deptId}")
     public ApiResult remove(@PathVariable Long deptId) {
         if (deptService.hasChildByDeptId(deptId)) {

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

@@ -1,6 +1,8 @@
 package com.usky.system.controller.web;
 
 
+import com.usky.common.log.annotation.Log;
+import com.usky.common.log.enums.BusinessType;
 import com.usky.common.security.utils.SecurityUtils;
 import com.usky.common.core.bean.ApiResult;
 import com.usky.system.controller.web.page.TableDataInfo;
@@ -65,6 +67,7 @@ public class SysDictDataController extends BaseController
     /**
      * 新增字典类型
      */
+    @Log(title = "新增-字典数据", businessType = BusinessType.INSERT)
     @PostMapping
     public ApiResult add(@Validated @RequestBody SysDictData dict)
     {
@@ -75,6 +78,7 @@ public class SysDictDataController extends BaseController
     /**
      * 修改保存字典类型
      */
+    @Log(title = "修改-字典数据", businessType = BusinessType.UPDATE)
     @PutMapping
     public ApiResult edit(@Validated @RequestBody SysDictData dict)
     {
@@ -85,6 +89,7 @@ public class SysDictDataController extends BaseController
     /**
      * 删除字典类型
      */
+    @Log(title = "删除-字典数据", businessType = BusinessType.DELETE)
     @DeleteMapping("/{dictCodes}")
     public ApiResult remove(@PathVariable Long[] dictCodes)
     {

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

@@ -1,6 +1,8 @@
 package com.usky.system.controller.web;
 
 
+import com.usky.common.log.annotation.Log;
+import com.usky.common.log.enums.BusinessType;
 import com.usky.common.security.utils.SecurityUtils;
 import com.usky.common.core.bean.ApiResult;
 import com.usky.common.core.exception.BusinessErrorCode;
@@ -47,6 +49,7 @@ public class SysDictTypeController extends BaseController
     /**
      * 新增字典类型
      */
+    @Log(title = "新增-字典类型", businessType = BusinessType.INSERT)
     @PostMapping
     public ApiResult add(@Validated @RequestBody SysDictType dict)
     {
@@ -62,6 +65,7 @@ public class SysDictTypeController extends BaseController
     /**
      * 修改字典类型
      */
+    @Log(title = "修改-字典类型", businessType = BusinessType.UPDATE)
     @PutMapping
     public ApiResult edit(@Validated @RequestBody SysDictType dict)
     {
@@ -76,6 +80,7 @@ public class SysDictTypeController extends BaseController
     /**
      * 删除字典类型
      */
+    @Log(title = "删除-字典类型", businessType = BusinessType.DELETE)
     @DeleteMapping("/{dictIds}")
     public ApiResult remove(@PathVariable Long[] dictIds)
     {

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

@@ -1,9 +1,10 @@
 package com.usky.system.controller.web;
 
 
-import com.ruoyi.common.core.annotation.Excel;
 import com.ruoyi.common.core.utils.poi.ExcelUtil;
 import com.usky.common.core.bean.ApiResult;
+import com.usky.common.log.annotation.Log;
+import com.usky.common.log.enums.BusinessType;
 import com.usky.system.controller.web.page.TableDataInfo;
 import com.usky.system.domain.SysLogininfor;
 import com.usky.system.service.ISysLogininforService;
@@ -27,7 +28,7 @@ public class SysLogininforController extends BaseController
     @Autowired
     private ISysLogininforService logininforService;
 
-
+//    @Log(title = "查询登录日志", businessType = BusinessType.SELECT)
     @GetMapping("/list")
     public ApiResult<TableDataInfo> list(SysLogininfor logininfor)
     {
@@ -36,6 +37,7 @@ public class SysLogininforController extends BaseController
         return ApiResult.success(getDataTable(list));
     }
 
+    @Log(title = "导出登录日志", businessType = BusinessType.EXPORT)
     @PostMapping("/listExport")
     public void export(HttpServletResponse response,
                        @RequestParam(value = "exportTitle") String exportTitle,
@@ -51,7 +53,7 @@ public class SysLogininforController extends BaseController
         return toAjax(logininforService.deleteLogininforByIds(infoIds));
     }
 
-
+    @Log(title = "清空登录日志", businessType = BusinessType.CLEAN)
     @DeleteMapping("/clean")
     public ApiResult<Void> clean()
     {

+ 34 - 4
base-modules/service-system/service-system-biz/src/main/java/com/usky/system/controller/web/SysMenuController.java

@@ -2,6 +2,8 @@ package com.usky.system.controller.web;
 
 
 import com.usky.common.core.util.ServletUtils;
+import com.usky.common.log.annotation.Log;
+import com.usky.common.log.enums.BusinessType;
 import com.usky.common.security.service.TokenService;
 import com.usky.common.security.utils.SecurityUtils;
 import com.usky.common.core.bean.ApiResult;
@@ -68,11 +70,9 @@ public class SysMenuController extends BaseController
      * 获取菜单下拉树列表
      */
     @GetMapping("/treeselect")
-    public ApiResult treeselect(SysMenu menu)
+    public ApiResult treeselect()
     {
-//        Long userId = SecurityUtils.getUserId();
-        List<SysMenu> menus = menuService.selectMenuListTwo(menu);
-        return ApiResult.success(menuService.buildMenuTreeSelect(menus));
+        return ApiResult.success(menuService.selectRolePlatformMenu());
     }
 
     /**
@@ -90,9 +90,25 @@ public class SysMenuController extends BaseController
         return ApiResult.success(ajax);
     }
 
+    /**
+     * 加载对应角色菜单列表树
+     */
+    @GetMapping(value = "/roleMenuTreeselect1/{roleId}")
+    public ApiResult roleMenuTreeselect1(@PathVariable("roleId") Long roleId)
+    {
+//        Long userId = SecurityUtils.getUserId();
+        SysMenu menu = new SysMenu();
+        List<SysMenu> menus = menuService.selectMenuListTwo(menu);
+        Map<String,Object> ajax = new HashMap<>();
+        ajax.put("checkedKeys", menuService.selectMenuListByRoleId(roleId));
+        ajax.put("menus", menuService.selectRolePlatformMenu());
+        return ApiResult.success(ajax);
+    }
+
     /**
      * 新增菜单
      */
+    @Log(title = "新增-菜单", businessType = BusinessType.INSERT)
     @PostMapping
     public ApiResult add(@Validated @RequestBody SysMenu menu)
     {
@@ -112,6 +128,7 @@ public class SysMenuController extends BaseController
     /**
      * 修改菜单
      */
+    @Log(title = "修改-菜单", businessType = BusinessType.UPDATE)
     @PutMapping
     public ApiResult edit(@Validated @RequestBody SysMenu menu)
     {
@@ -135,6 +152,7 @@ public class SysMenuController extends BaseController
     /**
      * 删除菜单
      */
+    @Log(title = "删除-菜单", businessType = BusinessType.DELETE)
     @DeleteMapping("/{menuId}")
     public ApiResult remove(@PathVariable("menuId") Long menuId)
     {
@@ -150,6 +168,17 @@ public class SysMenuController extends BaseController
     }
 
 
+    /**
+     * 获取路由信息(应用级改造)
+     *
+     * @return 路由信息
+     */
+    @GetMapping("getRouters1")
+    public ApiResult getRouters1()
+    {
+        return ApiResult.success(menuService.buildPlatformMenus());
+    }
+
     /**
      * 获取路由信息
      *
@@ -192,6 +221,7 @@ public class SysMenuController extends BaseController
      * @param tenantMenu
      * @return
      */
+    @Log(title = "修改-菜单昵称", businessType = BusinessType.UPDATE)
     @PutMapping("/updateTenantMenu")
     public ApiResult<Void> updateTenantMenu(@RequestBody SysTenantMenu tenantMenu)
     {

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

@@ -1,5 +1,7 @@
 package com.usky.system.controller.web;
 
+import com.usky.common.log.annotation.Log;
+import com.usky.common.log.enums.BusinessType;
 import com.usky.common.security.annotation.RequiresPermissions;
 import com.usky.common.security.utils.SecurityUtils;
 import com.usky.common.core.bean.ApiResult;
@@ -47,6 +49,7 @@ public class SysNoticeController extends BaseController
     /**
      * 新增通知公告
      */
+    @Log(title = "新增-通知公告", businessType = BusinessType.INSERT)
     @PostMapping
     public ApiResult add(@Validated @RequestBody SysNotice notice)
     {
@@ -57,6 +60,7 @@ public class SysNoticeController extends BaseController
     /**
      * 修改通知公告
      */
+    @Log(title = "修改-通知公告", businessType = BusinessType.UPDATE)
     @PutMapping
     public ApiResult edit(@Validated @RequestBody SysNotice notice)
     {
@@ -67,6 +71,7 @@ public class SysNoticeController extends BaseController
     /**
      * 删除通知公告
      */
+    @Log(title = "删除-通知公告", businessType = BusinessType.DELETE)
     @DeleteMapping("/{noticeIds}")
     public ApiResult remove(@PathVariable Long[] noticeIds)
     {

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

@@ -43,6 +43,7 @@ public class SysOperlogController extends BaseController
      * @param operLog
      * @throws IOException
      */
+    @Log(title = "操作日志-导出", businessType = BusinessType.EXPORT)
     @PostMapping("listExport")
     public void export(HttpServletResponse response,
                        @RequestParam(value = "exportTitle") String exportTitle,
@@ -62,7 +63,7 @@ public class SysOperlogController extends BaseController
 
 
     @DeleteMapping("/clean")
-    @Log(title = "操作日志-清空", businessType = BusinessType.DELETE)
+    @Log(title = "操作日志-清空", businessType = BusinessType.CLEAN)
     public ApiResult<Void> clean()
     {
         operLogService.cleanOperLog();

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

@@ -3,10 +3,16 @@ package com.usky.system.controller.web;
 
 import com.usky.common.core.bean.ApiResult;
 import com.usky.common.core.bean.CommonPage;
+import com.usky.common.core.exception.BusinessErrorCode;
+import com.usky.common.core.exception.BusinessException;
+import com.usky.common.log.annotation.Log;
+import com.usky.common.log.enums.BusinessType;
 import com.usky.common.security.utils.SecurityUtils;
 import com.usky.system.domain.SysMenu;
 import com.usky.system.domain.SysMobileMenu;
 import com.usky.system.domain.SysMobilePlatformMenu;
+import com.usky.system.domain.constants.UserConstants;
+import com.usky.system.mapper.SysTenantPlatformMapper;
 import com.usky.system.service.ISysMenuService;
 import com.usky.system.service.SysPlatformService;
 import com.usky.system.service.vo.PlatformMenuVo;
@@ -34,6 +40,9 @@ public class SysPlatformController {
     @Autowired
     private ISysMenuService menuService;
 
+    @Autowired
+    private SysTenantPlatformMapper tenantPlatformMapper;
+
     /**
      * 平台挂管理-列表查询
      *
@@ -96,7 +105,7 @@ public class SysPlatformController {
      * @param platformMenuVo
      * @return
      */
-//    @Log(title = "平台挂管理", businessType = BusinessType.INSERT)
+    @Log(title = "PC端应用菜单编辑", businessType = BusinessType.INSERT)
     @PostMapping("updatePlatformMenu")
     public ApiResult<Void> updatePlatformMenu(@RequestBody PlatformMenuVo platformMenuVo) {
         sysPlatformService.updatePlatformMenu(platformMenuVo);
@@ -110,11 +119,26 @@ public class SysPlatformController {
      * @param mobilePlatformMenuVO
      * @return
      */
-//    @Log(title = "平台挂管理", businessType = BusinessType.INSERT)
+    @Log(title = "移动端应用菜单编辑", businessType = BusinessType.INSERT)
     @PostMapping("updateMobilePlatformMenu")
     public ApiResult<Void> updateMobilePlatformMenu(@RequestBody MobilePlatformMenuVO mobilePlatformMenuVO) {
         sysPlatformService.updateMobilePlatformMenu(mobilePlatformMenuVO);
         return ApiResult.success();
     }
+
+    /**
+     * 删除应用
+     */
+    @Log(title = "删除应用", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{platformId}")
+    public ApiResult<Void> remove(@PathVariable Integer platformId)
+    {
+        if (tenantPlatformMapper.checkPlatformUnique(platformId)>0)
+        {
+            return ApiResult.error("500", "删除应用失败,存在在用的租户单位");
+        }
+        sysPlatformService.deletePlatformById(platformId);
+        return ApiResult.success();
+    }
 }
 

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

@@ -1,6 +1,8 @@
 package com.usky.system.controller.web;
 
 
+import com.usky.common.log.annotation.Log;
+import com.usky.common.log.enums.BusinessType;
 import com.usky.common.security.utils.SecurityUtils;
 import com.usky.common.core.bean.ApiResult;
 import com.usky.common.core.exception.BusinessErrorCode;
@@ -50,6 +52,7 @@ public class SysPostController extends BaseController
     /**
      * 新增岗位
      */
+    @Log(title = "新增-菜单", businessType = BusinessType.INSERT)
     @PostMapping
     public ApiResult add(@Validated @RequestBody SysPost post)
     {
@@ -70,6 +73,7 @@ public class SysPostController extends BaseController
      * 修改岗位
      */
 //    @PreAuthorize("@ss.hasPermi('system:post:edit')")
+    @Log(title = "修改-菜单", businessType = BusinessType.UPDATE)
     @PutMapping
     public ApiResult edit(@Validated @RequestBody SysPost post)
     {
@@ -88,6 +92,7 @@ public class SysPostController extends BaseController
     /**
      * 删除岗位
      */
+    @Log(title = "删除-菜单", businessType = BusinessType.DELETE)
     @DeleteMapping("/{postIds}")
     public ApiResult remove(@PathVariable Long[] postIds)
     {

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

@@ -1,6 +1,8 @@
 package com.usky.system.controller.web;
 
 
+import com.usky.common.log.annotation.Log;
+import com.usky.common.log.enums.BusinessType;
 import com.usky.common.security.utils.SecurityUtils;
 import com.usky.common.core.bean.ApiResult;
 import com.usky.common.core.exception.BusinessErrorCode;
@@ -57,6 +59,7 @@ public class SysRoleController extends BaseController
     /**
      * 新增角色
      */
+    @Log(title = "新增-角色", businessType = BusinessType.INSERT)
     @PostMapping
     public ApiResult add(@Validated @RequestBody SysRole role)
     {
@@ -77,6 +80,7 @@ public class SysRoleController extends BaseController
     /**
      * 修改保存角色
      */
+    @Log(title = "修改-角色", businessType = BusinessType.UPDATE)
     @PutMapping
     public ApiResult edit(@Validated @RequestBody SysRole role)
     {
@@ -96,6 +100,7 @@ public class SysRoleController extends BaseController
     /**
      * 修改保存数据权限
      */
+    @Log(title = "修改-角色", businessType = BusinessType.UPDATE)
     @PutMapping("/dataScope")
     public ApiResult dataScope(@RequestBody SysRole role)
     {
@@ -106,6 +111,7 @@ public class SysRoleController extends BaseController
     /**
      * 状态修改
      */
+    @Log(title = "修改-角色", businessType = BusinessType.UPDATE)
     @PutMapping("/changeStatus")
     public ApiResult changeStatus(@RequestBody SysRole role)
     {
@@ -117,6 +123,7 @@ public class SysRoleController extends BaseController
     /**
      * 删除角色
      */
+    @Log(title = "删除-角色", businessType = BusinessType.DELETE)
     @DeleteMapping("/{roleIds}")
     public ApiResult remove(@PathVariable Long[] roleIds)
     {

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

@@ -3,6 +3,8 @@ package com.usky.system.controller.web;
 
 import com.usky.common.core.bean.ApiResult;
 import com.usky.common.core.bean.CommonPage;
+import com.usky.common.log.annotation.Log;
+import com.usky.common.log.enums.BusinessType;
 import com.usky.system.domain.SysMenu;
 import com.usky.system.domain.SysTenantConfig;
 import com.usky.system.service.SysTenantConfigService;
@@ -82,7 +84,7 @@ public class SysTenantConfigController {
      * @param sysTenantConfig
      * @return
      */
-//    @Log(title = "租户管理-系统配置", businessType = BusinessType.INSERT)
+    @Log(title = "新增租户信息", businessType = BusinessType.INSERT)
     @PostMapping("addMiddleConfig")
     public ApiResult<Void> addMiddleConfig(@RequestBody SysTenantConfig sysTenantConfig) {
         sysTenantConfigService.addMiddleConfig(sysTenantConfig);
@@ -95,7 +97,7 @@ public class SysTenantConfigController {
      * @param sysTenantConfig
      * @return
      */
-//    @Log(title = "租户管理-系统配置", businessType = BusinessType.UPDATE)
+    @Log(title = "修改租户信息", businessType = BusinessType.UPDATE)
     @PostMapping("updaMiddleConfig")
     public ApiResult<Void> updaMiddleConfig(@RequestBody SysTenantConfig sysTenantConfig) {
         sysTenantConfigService.updaMiddleConfig(sysTenantConfig);

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

@@ -0,0 +1,64 @@
+package com.usky.system.controller.web;
+
+import com.usky.common.core.bean.ApiResult;
+import com.usky.system.domain.SysTenantConfig;
+import com.usky.system.domain.SysTenantPlatform;
+import com.usky.system.service.SysPlatformService;
+import com.usky.system.service.SysTenantPlatformService;
+import com.usky.system.service.vo.TenantPlatformListVo;
+import com.usky.system.service.vo.TenantPlatformVo;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 租户和应用关联表
+ *
+ * @author han
+ * @since 2024-08-14
+ */
+@RestController
+@RequestMapping("/sysTenantPlatform")
+public class SysTenantPlatformController {
+
+    @Autowired
+    private SysTenantPlatformService sysTenantPlatformService;
+
+    /**
+     * PC租户管理-应用编辑
+     *
+     * @param tenantPlatformVo
+     * @return
+     */
+//    @Log(title = "平台挂管理", businessType = BusinessType.INSERT)
+    @PostMapping("updateTenantPlatform")
+    public ApiResult<Void> updateTenantPlatform(@RequestBody TenantPlatformVo tenantPlatformVo) {
+        sysTenantPlatformService.updateTenantPlatform(tenantPlatformVo);
+        return ApiResult.success();
+    }
+
+    /**
+     * 租户应用关联查询
+     *
+     * @param tenantId 租户ID
+     * @return
+     */
+    @GetMapping("/getTenantPlatformList")
+    public ApiResult<List<TenantPlatformListVo>> getTenantPlatformList(@RequestParam Integer tenantId) {
+        return ApiResult.success(sysTenantPlatformService.getTenantPlatformList(tenantId));
+    }
+
+    /**
+     * 应用菜单关联查询
+     *
+     * @param tenantId 租户ID
+     * @return
+     */
+    @GetMapping("/getPlatformMenuList")
+    public ApiResult<Map<String, Object>> getPlatformMenuList(@RequestParam Integer tenantId) {
+        return ApiResult.success(sysTenantPlatformService.selectTenantPlatform(tenantId));
+    }
+}

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

@@ -1,16 +1,21 @@
 package com.usky.system.controller.web;
 
 
+import com.usky.common.log.annotation.Log;
+import com.usky.common.log.enums.BusinessType;
 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.constants.UserConstants;
+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.vo.SysUserNewVO;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.validation.annotation.Validated;
@@ -40,10 +45,13 @@ public class SysUserController extends BaseController
     @Autowired
     private ISysPostService postService;
 
+    @Autowired
+    private ISysDeptService deptService;
+
     /**
      * 获取用户列表
      */
-//    @Log(title = "用户管理", businessType = BusinessType.OTHER)
+//    @Log(title = "用户列表", businessType = BusinessType.SELECT)
     @GetMapping("/list")
     public ApiResult<TableDataInfo> list(SysUser user)
     {
@@ -52,6 +60,17 @@ public class SysUserController extends BaseController
         return ApiResult.success(getDataTable(list));
     }
 
+    /**
+     * 获取用户列表
+     */
+//    @Log(title = "用户管理", businessType = BusinessType.OTHER)
+    @GetMapping("/dUserList")
+    public ApiResult<List<SysUserNewVO>> dUserList(SysUser user)
+    {
+        List<SysUserNewVO> list = userService.dUserList(user);
+        return ApiResult.success(list);
+    }
+
     /**
      * 根据用户编号获取详细信息
      */
@@ -74,18 +93,21 @@ public class SysUserController extends BaseController
     /**
      * 新增用户
      */
-//    @Log(title = "用户管理", businessType = BusinessType.INSERT)
+    @Log(title = "新增用户", businessType = BusinessType.INSERT)
     @Transactional
     @PostMapping
     public ApiResult<Void> add(@Validated @RequestBody SysUser user)
     {
-        if (UserConstants.NOT_UNIQUE.equals(userService.checkUserNameUnique(user.getUserName(),SecurityUtils.getTenantId())))
+        if (UserConstants.NOT_UNIQUE.equals(userService.checkUserNameUnique(user.getUserName(),0)))
         {
             return ApiResult.error(BusinessErrorCode.BIZ_BUSINESS_ERROR.getCode(), "新增用户'" + user.getUserName() + "'失败,登录账号已存在");
         }
-        if(UserConstants.NOT_UNIQUE.equals(userService.checkPhoneUnique1(user.getPhonenumber(),SecurityUtils.getTenantId()))){
+        if(UserConstants.NOT_UNIQUE.equals(userService.checkPhoneUnique1(user.getPhonenumber(),0))){
             return ApiResult.error(BusinessErrorCode.BIZ_BUSINESS_ERROR.getCode(), "新增手机号'" + user.getPhonenumber() + "'失败,手机号已存在");
         }
+        if(UserConstants.NOT_UNIQUE.equals(userService.checkEmailUnique1(user.getEmail(),0))){
+            return ApiResult.error(BusinessErrorCode.BIZ_BUSINESS_ERROR.getCode(), "新增邮箱'" + user.getEmail() + "'失败,邮箱已存在");
+        }
         user.setUserType("00");
         user.setTenantId(SecurityUtils.getTenantId());
         user.setCreateBy(SecurityUtils.getUsername());
@@ -109,6 +131,10 @@ public class SysUserController extends BaseController
         if(UserConstants.NOT_UNIQUE.equals(userService.checkPhoneUnique1(user.getPhonenumber(),user.getTenantId()))){
             return ApiResult.error(BusinessErrorCode.BIZ_BUSINESS_ERROR.getCode(), "新增手机号'" + user.getPhonenumber() + "'失败,手机号已存在");
         }
+        List<SysDept> list = deptService.deptListByTenant(user.getTenantId());
+        if (list.size() > 0){
+            user.setDeptId(list.get(0).getDeptId());
+        }
         user.setUserType("00");
         user.setTenantId(user.getTenantId());
         user.setCreateBy(user.getUserName());
@@ -120,7 +146,7 @@ public class SysUserController extends BaseController
     /**
      * 修改用户
      */
-//    @Log(title = "用户管理", businessType = BusinessType.UPDATE)
+    @Log(title = "修改用户", businessType = BusinessType.UPDATE)
     @Transactional
     @PutMapping
     public ApiResult<Void> edit(@Validated @RequestBody SysUser user)
@@ -133,7 +159,7 @@ public class SysUserController extends BaseController
     /**
      * 删除用户
      */
-//    @Log(title = "用户管理", businessType = BusinessType.DELETE)
+    @Log(title = "删除用户", businessType = BusinessType.DELETE)
     @DeleteMapping("/{userIds}")
     public ApiResult<Void> remove(@PathVariable Long[] userIds)
     {
@@ -154,6 +180,7 @@ public class SysUserController extends BaseController
     /**
      * 重置密码
      */
+    @Log(title = "重置密码", businessType = BusinessType.UPDATE)
     @PutMapping("/resetPwd")
     public ApiResult<Void> resetPwd(@RequestBody SysUser user)
     {
@@ -197,4 +224,15 @@ public class SysUserController extends BaseController
         userService.insertUserAuth(userId, roleIds);
         return ApiResult.success();
     }
+
+    /**
+     * 根据用户编号获取授权角色
+     */
+    @GetMapping("/selectUserOne")
+    public ApiResult selectUserOne(@RequestParam(value = "phonenumber", required = false) String phonenumber,
+                                 @RequestParam(value = "userName", required = false) String userName,
+                                 @RequestParam(value = "email", required = false) String email)
+    {
+        return ApiResult.success(userService.selectUserOne(phonenumber,userName,email));
+    }
 }

+ 167 - 52
base-modules/service-system/service-system-biz/src/main/java/com/usky/system/controller/web/SysUserOnlineController.java

@@ -1,27 +1,20 @@
 package com.usky.system.controller.web;
 
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
+import java.util.*;
 import java.util.List;
-
+import java.util.stream.Collectors;
 import com.usky.common.core.bean.ApiResult;
 import com.usky.common.core.constants.CacheConstants;
-import com.usky.common.log.annotation.Log;
-import com.usky.common.log.enums.BusinessType;
+import com.usky.common.core.utils.StringUtils;
 import com.usky.common.redis.core.RedisService;
-import com.usky.common.security.annotation.RequiresPermissions;
 import com.usky.system.controller.web.page.TableDataInfo;
 import com.usky.system.domain.SysUserOnline;
 import com.usky.system.model.LoginUser;
 import com.usky.system.service.ISysUserOnlineService;
-import org.apache.commons.lang3.StringUtils;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.DeleteMapping;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
+import org.slf4j.Logger;
 
 /**
  * 在线用户监控
@@ -29,63 +22,185 @@ import org.springframework.web.bind.annotation.RestController;
  */
 @RestController
 @RequestMapping("/online")
-public class SysUserOnlineController extends BaseController
-{
+public class SysUserOnlineController {
+    private final Logger logger = LoggerFactory.getLogger(SysUserOnlineController.class);
+
     @Autowired
     private ISysUserOnlineService userOnlineService;
 
     @Autowired
     private RedisService redisService;
 
-    @RequiresPermissions("monitor:online:list")
+    private TableDataInfo getDataTable(List<SysUserOnline> userOnlineList, int pageNum, int pageSize, long total) {
+        TableDataInfo dataInfo = new TableDataInfo();
+        dataInfo.setRows(userOnlineList);
+        dataInfo.setTotal(total);
+        dataInfo.setPageNum(pageNum);
+        dataInfo.setPageSize(pageSize);
+        dataInfo.setPages((int) Math.ceil((double) total / pageSize));
+        return dataInfo;
+    }
+
     @GetMapping("/list")
-    public ApiResult<TableDataInfo> list(String ipaddr, String userName)
-    {
-        Collection<String> keys = redisService.keys(CacheConstants.LOGIN_TOKEN_KEY + "*");
-        List<SysUserOnline> userOnlineList = new ArrayList<SysUserOnline>();
-        for (String key : keys)
-        {
-            LoginUser user = redisService.getCacheObject(key);
-            if (StringUtils.isNotEmpty(ipaddr) && StringUtils.isNotEmpty(userName))
-            {
-                if (StringUtils.equals(ipaddr, user.getIpaddr()) && StringUtils.equals(userName, user.getUsername()))
-                {
-                    userOnlineList.add(userOnlineService.selectOnlineByInfo(ipaddr, userName, user));
-                }
+    public ApiResult<TableDataInfo> list(@RequestParam(required = false, defaultValue = "1") Integer page,
+                                         @RequestParam(required = false, defaultValue = "10") Integer size,
+                                         @RequestParam(required = false) String ipaddr,
+                                         @RequestParam(required = false) String userName) {
+        try {
+            Collection<String> keys = redisService.keys(CacheConstants.LOGIN_TOKEN_KEY + "*");
+            if (keys == null || keys.isEmpty()) {
+                logger.error("Redis密钥为null或为空");
+                return ApiResult.error("SYS-0000", "Redis密钥为null或为空");
             }
-            else if (StringUtils.isNotEmpty(ipaddr))
-            {
-                if (StringUtils.equals(ipaddr, user.getIpaddr()))
-                {
-                    userOnlineList.add(userOnlineService.selectOnlineByIpaddr(ipaddr, user));
+            Map<String, List<SysUserOnline>> userOnlineMap = new HashMap<>();
+
+            for (String key : keys) {
+                // 检查键是否存在并且未过期
+                if (redisService.hasKey(key)) {
+                    LoginUser user = redisService.getCacheObject(key);
+                    if (user != null) {
+                        if (ipaddr != null && !ipaddr.equals(user.getIpaddr())) {
+                            continue;
+                        }
+                        if (userName != null && !userName.equals(user.getUsername())) {
+                            continue;
+                        }
+                        SysUserOnline online = userOnlineService.loginUserToUserOnline(user);
+                        if (online != null) {
+                            List<SysUserOnline> list = userOnlineMap.computeIfAbsent(user.getUsername(), k -> new ArrayList<>());
+                            list.add(online);
+                        }
+                    }
                 }
             }
-            else if (StringUtils.isNotEmpty(userName))
-            {
-                if (StringUtils.equals(userName, user.getUsername()))
-                {
-                    userOnlineList.add(userOnlineService.selectOnlineByUserName(userName, user));
+
+            List<SysUserOnline> userOnlineList = new ArrayList<>();
+            for (Map.Entry<String, List<SysUserOnline>> entry : userOnlineMap.entrySet()) {
+                List<SysUserOnline> sortedList = entry.getValue();
+                sortedList.sort(Comparator.comparing(SysUserOnline::getLoginTime).reversed());
+                if (!sortedList.isEmpty()) {
+                    SysUserOnline lastOnline = sortedList.get(0);
+                    lastOnline.setLoginCount(sortedList.size()); // 设置登录次数
+                    userOnlineList.add(lastOnline);
                 }
             }
-            else
-            {
-                userOnlineList.add(userOnlineService.loginUserToUserOnline(user));
+
+            // 按照登录时间降序排序
+            userOnlineList.sort(Comparator.comparing(SysUserOnline::getLoginTime).reversed());
+
+            long total = userOnlineList.size();
+            int start = (page - 1) * size;
+            int end = Math.min(start + size, (int) total);
+            List<SysUserOnline> pageList = userOnlineList.subList(start, end);
+
+            return ApiResult.success(getDataTable(pageList, page, size, total));
+        } catch (Exception ex) {
+            logger.error("处理/online/list错误", ex);
+            return ApiResult.error("SYS-0001", "内部系统错误", ex.getMessage());
+        }
+    }
+
+    @GetMapping("/history")
+    public ApiResult<TableDataInfo> listOtherLogins(@RequestParam Long userid,
+                                                    @RequestParam(required = false, defaultValue = "1") Integer page,
+                                                    @RequestParam(required = false, defaultValue = "10") Integer size) {
+        try {
+            Collection<String> keys = redisService.keys(CacheConstants.LOGIN_TOKEN_KEY + "*");
+            if (keys == null || keys.isEmpty()) {
+                logger.error("Redis密钥为null或为空");
+                return ApiResult.error("SYS-0000", "Redis密钥为null或为空");
             }
+            List<SysUserOnline> userOnlineList = new ArrayList<>();
+
+            for (String key : keys) {
+                if (redisService.hasKey(key)) {
+                    LoginUser user = redisService.getCacheObject(key);
+                    if (user != null && user.getUserid().equals(userid)) {
+                        SysUserOnline online = userOnlineService.loginUserToUserOnline(user);
+                        if (online != null) {
+                            userOnlineList.add(online);
+                        }
+                    }
+                }
+            }
+
+            // 按照登录时间降序排序
+            userOnlineList.sort(Comparator.comparing(SysUserOnline::getLoginTime).reversed());
+            // 排除最后一条记录,只保留其他记录
+//            if (!userOnlineList.isEmpty()) {
+//                userOnlineList = userOnlineList.subList(1, userOnlineList.size());
+//            }
+
+            long total = userOnlineList.size();
+            int start = (page - 1) * size;
+            int end = Math.min(start + size, (int) total);
+            List<SysUserOnline> pageList = userOnlineList.subList(start, end);
+
+            return ApiResult.success(getDataTable(pageList, page, size, total));
+        } catch (Exception ex) {
+            logger.error("处理/online/listOtherLogins错误", ex);
+            return ApiResult.error("SYS-0001", "内部服务器错误", ex.getMessage());
         }
-        Collections.reverse(userOnlineList);
-        userOnlineList.removeAll(Collections.singleton(null));
-        return ApiResult.success(getDataTable(userOnlineList));
     }
 
     /**
      * 强退用户
      */
-    @RequiresPermissions("monitor:online:forceLogout")
-    @Log(title = "在线用户", businessType = BusinessType.FORCE)
+//    @RequiresPermissions("monitor:online:forceLogout")
     @DeleteMapping("/{tokenId}")
-    public ApiResult forceLogout(@PathVariable String tokenId)
-    {
-        redisService.deleteObject(CacheConstants.LOGIN_TOKEN_KEY + tokenId);
-        return ApiResult.success();
+    public ApiResult forceLogout(@PathVariable String tokenId) {
+        try {
+            if (StringUtils.isBlank(tokenId)) {
+                logger.error("强制注销时Token为空");
+                return ApiResult.error("SYS-0004", "强制注销需要Token");
+            }
+
+            String key = CacheConstants.LOGIN_TOKEN_KEY + tokenId;
+            boolean deleted = redisService.deleteObject(key);
+            if (deleted) {
+                logger.info("tokenId为 {} 的用户已被强制注销.", tokenId);
+                return ApiResult.success();
+            } else {
+                logger.warn("未能找到并删除tokenId为 {} 的用户会话", tokenId);
+                return ApiResult.error("SYS-0002", "未找到会话或已删除会话");
+            }
+        } catch (Exception ex) {
+            logger.error("处理tokenId {} 的forceLogout时出错", tokenId, ex);
+            return ApiResult.error("SYS-0003", "强制注销时出现内部系统错误", ex.getMessage());
+        }
+    }
+
+    @DeleteMapping("/logoutMany/{userid}")
+    public ApiResult forceLogoutMany(@PathVariable Long userid,
+                                     @RequestParam(required = false, defaultValue = "1") Integer page,
+                                     @RequestParam(required = false, defaultValue = "999") Integer size) {
+        try {
+            ApiResult<TableDataInfo> apiResult = listOtherLogins(userid, page, size);
+            if (apiResult.isSuccess() && apiResult.getData() != null) {
+                TableDataInfo tableDataInfo = apiResult.getData();
+                List<SysUserOnline> userOnlineList = (List<SysUserOnline>) tableDataInfo.getRows();
+                List<String> tokenIds = userOnlineList.stream()
+                        .map(SysUserOnline::getTokenId)
+                        .collect(Collectors.toList());
+
+                // 执行强退操作
+                for (String tokenId : tokenIds) {
+                    String key = CacheConstants.LOGIN_TOKEN_KEY + tokenId;
+                    boolean deleted = redisService.deleteObject(key);
+                    if (deleted) {
+                        logger.info("tokenId为 {} 的用户已被强制注销.", tokenId);
+                    } else {
+                        logger.warn("未能找到并删除tokenId为 {} 的用户会话", tokenId);
+                    }
+                }
+                return ApiResult.success("已强制注销所有选中token.");
+            } else {
+                logger.error("调用 listOtherLogins 方法失败,原因:{}", apiResult.getMsg());
+                return ApiResult.error("SYS-0003", "调用历史记录接口失败", apiResult.getMsg());
+            }
+        } catch (Exception ex) {
+            logger.error("处理forceLogoutMany时出错", ex);
+            return ApiResult.error("SYS-0003", "强制注销时出现内部系统错误", ex.getMessage());
+        }
     }
-}
+}

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

@@ -0,0 +1,66 @@
+package com.usky.system.controller.web;
+
+
+import com.usky.common.core.bean.ApiResult;
+import com.usky.common.core.exception.BusinessErrorCode;
+import com.usky.common.log.annotation.Log;
+import com.usky.common.log.enums.BusinessType;
+import com.usky.system.domain.SysTenant;
+import com.usky.system.domain.SysUserTenant;
+import com.usky.system.service.SysUserTenantService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author han
+ * @since 2024-09-11
+ */
+@RestController
+@RequestMapping("/sysUserTenant")
+public class SysUserTenantController extends BaseController {
+
+    @Autowired
+    private SysUserTenantService sysUserTenantService;
+
+    /**
+     * 企业邀请用户
+     */
+    @Log(title = "绑定用户", businessType = BusinessType.INSERT)
+    @PostMapping("/inviteUser")
+    public ApiResult<Void> insertInviteUser(@RequestBody SysUserTenant sysUserTenant)
+    {
+        sysUserTenantService.insertInviteUser(sysUserTenant);
+        return ApiResult.success();
+    }
+
+    /**
+     * 解除用户绑定
+     */
+    @Log(title = "解除用户绑定", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{tenantId}/{userId}")
+    public ApiResult<Void> remove(@PathVariable Integer tenantId,@PathVariable Long userId)
+    {
+        Boolean isDefault = sysUserTenantService.getIdByUser(tenantId,userId);
+        if (isDefault){
+            return ApiResult.error(BusinessErrorCode.BIZ_BUSINESS_ERROR.getCode(), "该用户默认租户不可解绑");
+        }
+        sysUserTenantService.deleteUserTenant(tenantId,userId);
+        return ApiResult.success();
+    }
+
+    /**
+     * 根据用户查询企业下拉框
+     */
+    @GetMapping("/getTenantByUser/{userId}")
+    public ApiResult<List<SysTenant>> getTenantByUser(@PathVariable("userId") Long userId)
+    {
+        return ApiResult.success(sysUserTenantService.getTenantByUser(userId));
+    }
+}
+

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

@@ -79,6 +79,7 @@ public class TokenController {
         SysUser userInfo = sysLoginService.appLogin(form.getUsername(), form.getPassword(), form.getTenantId(), form.getPhone(), form.getVerify());
         LoginUser sysUser = new LoginUser();
         SysUserVO sysUserVO = BeanMapperUtils.map(userInfo, SysUserVO.class);
+        sysUserVO.setTenantId(userInfo.getTenantId());
         sysUser.setSysUser(sysUserVO);
         Set<String> rolePermission = permissionService.getRolePermission(userInfo.getUserId());
         sysUser.setRoles(rolePermission);

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

@@ -1,6 +1,8 @@
 package com.usky.system.controller.web;
 
 import com.usky.common.core.util.StringUtils;
+import com.usky.common.log.annotation.Log;
+import com.usky.common.log.enums.BusinessType;
 import com.usky.common.security.utils.SecurityUtils;
 import com.usky.common.core.bean.ApiResult;
 import com.usky.common.core.bean.CommonPage;
@@ -66,7 +68,7 @@ public class UserConfigController extends BaseController {
      * @param user
      * @return
      */
-//    @Log(title = "租户管理-管理员配置", businessType = BusinessType.UPDATE)
+    @Log(title = "修改租户信息", businessType = BusinessType.UPDATE)
     @Transactional
     @PostMapping("/updateserData")
     public ApiResult<Void> updateserData(@Validated @RequestBody SysUser user) {
@@ -85,7 +87,7 @@ public class UserConfigController extends BaseController {
      * @param userId 用户ID
      * @return
      */
-//    @Log(title = "租户管理-管理员配置", businessType = BusinessType.DELETE)
+    @Log(title = "删除租户", businessType = BusinessType.DELETE)
     @GetMapping("/delUsers")
     public ApiResult<Void> delUsers(@RequestParam Long userId) {
         SysUser user = new SysUser();
@@ -109,7 +111,7 @@ public class UserConfigController extends BaseController {
      * @param UserId      用户ID
      * @return
      */
-//    @Log(title = "租户管理-管理员配置", businessType = BusinessType.UPDATE)
+    @Log(title = "重置租户密码", businessType = BusinessType.UPDATE)
     @PutMapping("/updatePwd")
     public ApiResult updatePwd(String newPassword, Long UserId) {
         SysUser sysUser = userService.selectUserById(UserId);

+ 39 - 0
base-modules/service-system/service-system-biz/src/main/java/com/usky/system/controller/web/page/TableDataInfo.java

@@ -29,6 +29,21 @@ public class TableDataInfo implements Serializable {
      */
     private String msg;
 
+    /**
+     * 当前页码
+     */
+    private int pageNum;
+
+    /**
+     * 每页记录数
+     */
+    private int pageSize;
+
+    /**
+     * 总页数
+     */
+    private int pages;
+
     /**
      * 表格数据对象
      */
@@ -77,4 +92,28 @@ public class TableDataInfo implements Serializable {
     public void setMsg(String msg) {
         this.msg = msg;
     }
+
+    public int getPageNum() {
+        return pageNum;
+    }
+
+    public void setPageNum(int pageNum) {
+        this.pageNum = pageNum;
+    }
+
+    public int getPageSize() {
+        return pageSize;
+    }
+
+    public void setPageSize(int pageSize) {
+        this.pageSize = pageSize;
+    }
+
+    public int getPages() {
+        return pages;
+    }
+
+    public void setPages(int pages) {
+        this.pages = pages;
+    }
 }

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

@@ -51,6 +51,27 @@ public class SysLogininfor extends BaseEntity
      */
     private String createBy;
 
+    /**
+     * 登陆地点
+     */
+    private String loginLocation;
+
+    /**
+     * 浏览器类型
+     */
+    private String browser;
+
+    /**
+     * 操作系统
+     */
+    private String os;
+
+    /**
+     * 部门名称
+     */
+    @TableField(exist = false)
+    private String deptName;
+
     public String getSearchValue() {
         return searchValue;
     }
@@ -168,4 +189,25 @@ public class SysLogininfor extends BaseEntity
     {
         this.createBy = createBy;
     }
+
+    public String getLoginLocation() {return loginLocation;}
+
+    public void setLoginLocation(String loginLocation) {this.loginLocation = loginLocation;}
+
+    public String getBrowser() {return browser;}
+
+    public void setBrowser(String browser) {this.browser = browser;}
+
+    public String getOs() {return os;}
+
+    public void setOs(String os) {this.os = os;}
+    public String getDeptName()
+    {
+        return deptName;
+    }
+
+    public void setDeptName(String deptName)
+    {
+        this.deptName = deptName;
+    }
 }

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

@@ -86,6 +86,18 @@ public class SysOperLog extends BaseEntity
      */
     private String createBy;
 
+    /** 执行开始时间 */
+    private Date startTime;
+
+    /** 执行结束时间 */
+    private Date endTime;
+
+    /** 执行耗时时间 */
+    private Long consumingTime;
+
+    /** 执行耗时时间(单位:毫秒) */
+    private String consumingTimeWithUnit;
+
     public String getSearchValue() {
         return searchValue;
     }
@@ -314,4 +326,20 @@ public class SysOperLog extends BaseEntity
     {
         this.createBy = createBy;
     }
+
+    public Date getStartTime() {return startTime;}
+
+    public void setStartTime(Date startTime) { this.startTime = startTime; }
+
+    public Date getEndTime() { return endTime; }
+
+    public void setEndTime(Date endTime) { this.endTime = endTime; }
+
+    public Long getConsumingTime() { return consumingTime; }
+
+    public void setConsumingTime(Long consumingTime) { this.consumingTime = consumingTime; }
+
+    public String getConsumingTimeWithUnit() { return consumingTimeWithUnit; }
+
+    public void setConsumingTimeWithUnit(String consumingTimeWithUnit) { this.consumingTimeWithUnit = consumingTimeWithUnit; }
 }

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

@@ -46,6 +46,11 @@ public class SysPlatform implements Serializable {
      */
     private String remark;
 
+    /**
+     * 应用图标
+     */
+    private String icon;
+
     /**
      * 创建者
      */

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

@@ -149,4 +149,9 @@ public class SysTenantConfig implements Serializable {
      * 是否开启消息通知: 1、不开启 2、开启
      */
     private Integer messageStatus;
+
+    /**
+     * 中间页显示类型:0 应用列表 1 菜单列表
+     */
+    private Integer middleType;
 }

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

@@ -0,0 +1,37 @@
+package com.usky.system.domain;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+/**
+ * <p>
+ * 租户和应用关联表
+ * </p>
+ *
+ * @author han
+ * @since 2024-08-14
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+public class SysTenantPlatform  implements Serializable {
+    private static final long serialVersionUID=1L;
+
+    /**
+     * 租户ID
+     */
+    private Integer tenantId;
+
+    /**
+     * 应用ID
+     */
+    private Integer platformId;
+
+    /**
+     * 是否为默认应用(默认0; 0:否,1:是)
+     */
+    private Integer isDefault;
+}

+ 69 - 29
base-modules/service-system/service-system-biz/src/main/java/com/usky/system/domain/SysUserOnline.java

@@ -1,15 +1,20 @@
 package com.usky.system.domain;
 
+import java.util.ArrayList;
+import java.util.List;
+
 /**
  * 当前在线会话
  * 
  * @author yq
  */
-public class SysUserOnline
-{
+public class SysUserOnline {
     /** 会话编号 */
     private String tokenId;
 
+    /** 用户ID */
+    private Long userid;
+
     /** 部门名称 */
     private String deptName;
 
@@ -31,68 +36,78 @@ public class SysUserOnline
     /** 登录时间 */
     private Long loginTime;
 
-    public String getTokenId()
-    {
+    /** 最后访问时间 */
+    private Long expireTime;
+
+    /** 登录记录的数量 */
+    private int loginCount;
+
+
+    private SysUserOnline lastOnline;
+    private List<SysUserOnline> previousOnlines;
+
+    public SysUserOnline() {
+        // 初始化默认值
+        this.lastOnline = null;
+    }
+
+    public String getTokenId() {
         return tokenId;
     }
 
-    public void setTokenId(String tokenId)
-    {
+    public void setTokenId(String tokenId) {
         this.tokenId = tokenId;
     }
 
-    public String getDeptName()
-    {
+    public Long getUserid() {
+        return userid;
+    }
+
+    public void setUserid(Long userid) {
+        this.userid = userid;
+    }
+
+    public String getDeptName() {
         return deptName;
     }
 
-    public void setDeptName(String deptName)
-    {
+    public void setDeptName(String deptName) {
         this.deptName = deptName;
     }
 
-    public String getUserName()
-    {
+    public String getUserName() {
         return userName;
     }
 
-    public void setUserName(String userName)
-    {
+    public void setUserName(String userName) {
         this.userName = userName;
     }
 
-    public String getIpaddr()
-    {
+    public String getIpaddr() {
         return ipaddr;
     }
 
-    public void setIpaddr(String ipaddr)
-    {
+    public void setIpaddr(String ipaddr) {
         this.ipaddr = ipaddr;
     }
 
-    public String getLoginLocation()
-    {
+    public String getLoginLocation() {
         return loginLocation;
     }
 
-    public void setLoginLocation(String loginLocation)
-    {
+    public void setLoginLocation(String loginLocation) {
         this.loginLocation = loginLocation;
     }
 
-    public String getBrowser()
-    {
+    public String getBrowser() {
         return browser;
     }
 
-    public void setBrowser(String browser)
-    {
+    public void setBrowser(String browser) {
         this.browser = browser;
     }
 
-    public String getOs()
-    {
+    public String getOs() {
         return os;
     }
 
@@ -110,4 +125,29 @@ public class SysUserOnline
     {
         this.loginTime = loginTime;
     }
-}
+
+    public Long getExpireTime() {
+        return expireTime;
+    }
+
+    public void setExpireTime(Long expireTime) {
+        this.expireTime = expireTime;
+    }
+
+
+    public SysUserOnline getLastOnline() {
+        return lastOnline;
+    }
+
+    public void setLastOnline(SysUserOnline lastOnline) {
+        this.lastOnline = lastOnline;
+    }
+
+    public int getLoginCount() {
+        return loginCount;
+    }
+
+    public void setLoginCount(int loginCount) {
+        this.loginCount = loginCount;
+    }
+}

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

@@ -0,0 +1,39 @@
+package com.usky.system.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * <p>
+ * 
+ * </p>
+ *
+ * @author han
+ * @since 2024-09-11
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+public class SysUserTenant implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 用户ID
+     */
+    private Long userId;
+
+    /**
+     * 租户ID
+     */
+    private Integer tenantId;
+
+    /**
+     * 是否为默认应用(默认0; 0:否,1:是)
+     */
+    private Boolean isDefault;
+
+
+}

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

@@ -0,0 +1,131 @@
+package com.usky.system.domain;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+/**
+ * 读取项目相关配置
+ *
+ * @author yq
+ */
+@Data
+@Component
+@ConfigurationProperties(prefix = "wj")
+public class WjConfig {
+    /** 项目名称 */
+    private String name;
+
+    /** 版本 */
+    private String version;
+
+    /** 版权年份 */
+    private String copyrightYear;
+
+    /** 实例演示开关 */
+    private boolean demoEnabled;
+
+    /** 上传路径 */
+    private static String profile;
+
+    /** 获取地址开关 */
+    private static boolean addressEnabled;
+    /** 验证码开关 */
+    private boolean codeEnabled;
+
+    public String getName()
+    {
+        return name;
+    }
+
+    public void setName(String name)
+    {
+        this.name = name;
+    }
+
+    public String getVersion()
+    {
+        return version;
+    }
+
+    public void setVersion(String version)
+    {
+        this.version = version;
+    }
+
+    public String getCopyrightYear()
+    {
+        return copyrightYear;
+    }
+
+    public void setCopyrightYear(String copyrightYear)
+    {
+        this.copyrightYear = copyrightYear;
+    }
+
+    public boolean isDemoEnabled()
+    {
+        return demoEnabled;
+    }
+
+    public void setDemoEnabled(boolean demoEnabled)
+    {
+        this.demoEnabled = demoEnabled;
+    }
+
+
+    public boolean isCodeEnabled()
+    {
+        return codeEnabled;
+    }
+
+    public void setCodeEnabled(boolean codeEnabled)
+    {
+        this.codeEnabled = codeEnabled;
+    }
+
+    public static String getProfile()
+    {
+        return profile;
+    }
+
+    public void setProfile(String profile)
+    {
+        WjConfig.profile = profile;
+    }
+
+    public static boolean isAddressEnabled()
+    {
+        return addressEnabled;
+    }
+
+    public void setAddressEnabled(boolean addressEnabled)
+    {
+        WjConfig.addressEnabled = addressEnabled;
+    }
+
+    /**
+     * 获取头像上传路径
+     */
+    public static String getAvatarPath()
+    {
+        return getProfile() + "/avatar";
+    }
+
+    /**
+     * 获取下载路径
+     */
+    public static String getDownloadPath()
+    {
+        return getProfile() + "/download/";
+    }
+
+    /**
+     * 获取上传路径
+     */
+    public static String getUploadPath()
+    {
+        return getProfile() + "/upload";
+    }
+}
+

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

@@ -26,6 +26,8 @@ public interface SysDeptMapper extends BaseMapper<SysDept>
 
     public List<SysDept> deptList(SysDept dept);
 
+    public List<SysDept> deptListByTenant(Integer tenantId);
+
     /**
      * 根据角色ID查询部门树信息
      * 

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

@@ -79,8 +79,19 @@ public interface SysMenuMapper extends CrudMapper<SysMenu> {
      */
     public List<SysMenu> selectMenuTreeByUserId(@Param("userId") Long userId);
 
+    /**
+     * 根据用户ID查询菜单
+     *
+     * @param userId 用户ID
+     * @param platformId 应用ID
+     * @return 应用级菜单列表
+     */
+    public List<SysMenu> selectMenuTreeByUserId1(@Param("userId") Long userId,@Param("platformId") Long platformId);
+
     public List<SysMenu> selectMenuTreeByUserIdOne(@Param("tenantId") Integer tenantId);
 
+    public List<SysMenu> selectMenuTreeByUserIdOne1(@Param("tenantId") Integer tenantId,@Param("platformId") Integer platformId);
+
     /**
      * 根据角色ID查询菜单树信息
      *
@@ -143,4 +154,6 @@ public interface SysMenuMapper extends CrudMapper<SysMenu> {
 
     public List<SysMenu> getSysMenuList(String menuType);
 
+    public List<SysMenu> getTenantPlatformMenuList(@Param("tenantId") Integer tenantId,@Param("platformId") Integer platformId);
+
 }

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

@@ -7,6 +7,7 @@ import com.usky.system.domain.SysPlatform;
 import com.usky.system.domain.SysPlatformMenu;
 import com.usky.system.service.vo.SysPlatformVo;
 import org.apache.ibatis.annotations.Param;
+import org.springframework.stereotype.Repository;
 
 import java.util.List;
 
@@ -18,6 +19,7 @@ import java.util.List;
  * @author ya
  * @since 2022-05-18
  */
+@Repository
 public interface SysPlatformMapper extends CrudMapper<SysPlatform> {
 
     List<SysPlatformVo> getPlatformList(@Param("platformName") String platformName,
@@ -40,4 +42,9 @@ public interface SysPlatformMapper extends CrudMapper<SysPlatform> {
 
     List<SysPlatformMenu> getMenuListOne(@Param("platformId") Long platformId,
                                          @Param("menuType")  String menuType);
+
+    List<SysPlatformVo> getRolePlatformList(@Param("tenantId") Integer tenantId,
+                                        @Param("roleId") Integer roleId);
+
+    List<SysPlatformVo> getTenantPlatformList(@Param("tenantId") Integer tenantId);
 }

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

@@ -0,0 +1,27 @@
+package com.usky.system.mapper;
+
+import com.usky.common.mybatis.core.CrudMapper;
+import com.usky.system.domain.SysTenantMenu;
+import com.usky.system.domain.SysTenantPlatform;
+import org.apache.ibatis.annotations.Param;
+import org.springframework.stereotype.Repository;
+
+/**
+ * <p>
+ * 租户和应用关联表 Mapper 接口
+ * </p>
+ *
+ * @author han
+ * @since 2024-8-14
+ */
+@Repository
+public interface SysTenantPlatformMapper extends CrudMapper<SysTenantPlatform> {
+
+    /**
+     * 校验应用是否在用
+     *
+     * @param platformId 用户名称
+     * @return 结果
+     */
+    public int checkPlatformUnique(@Param("platformId") Integer platformId);
+}

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

@@ -143,6 +143,15 @@ public interface SysUserMapper extends CrudMapper<SysUser> {
      */
     public SysUser checkEmailUnique(String email);
 
+    /**
+     * 校验email是否唯一
+     *
+     * @param email 用户邮箱
+     * @param tenantId 租户ID
+     * @return 结果
+     */
+    public int checkEmailUnique1(@Param("email") String email, @Param("tenantId") Integer tenantId);
+
     public int resetUserPwdOne(@Param("userId") Long userId, @Param("password") String password);
 
     public List<SysUser> getUserData(@Param("tenantId") Integer tenantId,
@@ -172,4 +181,10 @@ public interface SysUserMapper extends CrudMapper<SysUser> {
     public void insertMbUser(@Param("userId") Long userId,@Param("cids") String cids,@Param("createBy") String createBy);
 
     public void updateMbUser(@Param("phone") String phone,@Param("openId") String openId,@Param("userId") Long userId,@Param("cids") String cids,@Param("updateBy") String updateBy);
+
+    SysUser selectUserTenantData(@Param("userName") String userName,
+                                 @Param("tenantId") Integer tenantId);
+
+    SysUser selectUserTenantDataOne(@Param("tenantId") Integer tenantId,
+                                    @Param("phone") String phone);
 }

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

@@ -0,0 +1,36 @@
+package com.usky.system.mapper;
+
+import com.usky.system.domain.SysUser;
+import com.usky.system.domain.SysUserTenant;
+import com.usky.common.mybatis.core.CrudMapper;
+import org.apache.ibatis.annotations.Param;
+import org.springframework.stereotype.Repository;
+
+/**
+ * <p>
+ *  Mapper 接口
+ * </p>
+ *
+ * @author han
+ * @since 2024-09-11
+ */
+@Repository
+public interface SysUserTenantMapper extends CrudMapper<SysUserTenant> {
+    /**
+     * 校验用户是否已绑定
+     *
+     * @param userId 用户ID
+     * @param tenantId 租户ID
+     * @return 结果
+     */
+    public int checkUserIdUnique(@Param("tenantId") Integer tenantId, @Param("userId") Long userId);
+
+    /**
+     * 解除用户租户绑定
+     *
+     * @param userId 用户ID
+     * @param tenantId 租户ID
+     * @return 结果
+     */
+    public int deleteUserTenant(@Param("tenantId") Integer tenantId, @Param("userId") Long userId);
+}

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

@@ -26,6 +26,8 @@ public interface ISysDeptService extends IService<SysDept>
 
     public List<SysDept> deptList(SysDept dept);
 
+    public List<SysDept> deptListByTenant(Integer tenantId);
+
     /**
      * 构建前端所需要树结构
      * 

+ 24 - 3
base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/ISysMenuService.java

@@ -5,12 +5,11 @@ import com.usky.common.mybatis.core.CrudService;
 import com.usky.system.domain.SysMenu;
 import com.usky.system.domain.SysMobileMenu;
 import com.usky.system.domain.SysTenantMenu;
-import com.usky.system.service.vo.RouterVo;
-import com.usky.system.service.vo.TreeMobileSelect;
-import com.usky.system.service.vo.TreeSelect;
+import com.usky.system.service.vo.*;
 import org.springframework.web.bind.annotation.RequestBody;
 
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 /**
@@ -66,8 +65,18 @@ public interface ISysMenuService extends CrudService<SysMenu>
      */
     public List<SysMenu> selectMenuTreeByUserId(Long userId);
 
+    /**
+     * 根据用户ID查询菜单树信息
+     *
+     * @param userId 用户ID
+     * @return 菜单列表
+     */
+    public List<SysMenu> selectMenuTreeByUserId1(Long userId,Long platformId);
+
     List<SysMenu> selectMenuTreeByUserIdOne(Integer tenantId);
 
+    List<SysMenu> selectMenuTreeByUserIdOne1(Integer tenantId,Integer platformId);
+
     List<SysTenantMenu> selectTenantMenuList(Integer tenantId);
 
     void updateTenantMenu(SysTenantMenu tenantMenu);
@@ -88,6 +97,12 @@ public interface ISysMenuService extends CrudService<SysMenu>
      */
     public List<RouterVo> buildMenus(List<SysMenu> menus);
 
+    /**
+     * 构建前端路由所需要的菜单(应用级)
+     * @return 路由列表
+     */
+    public List<PlatformRouterVo> buildPlatformMenus();
+
 
     /**
      * 构建前端所需要树结构
@@ -177,4 +192,10 @@ public interface ISysMenuService extends CrudService<SysMenu>
      * @return 结果
      */
     public String checkMenuNameUnique(SysMenu menu);
+
+    /**
+     * 根据角色ID查询应用菜单树信息
+     * @return 选中菜单列表
+     */
+    List<TenantPlatformMenuVo> selectRolePlatformMenu();
 }

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

@@ -4,6 +4,8 @@ import com.usky.common.core.bean.CommonPage;
 import com.usky.common.mybatis.core.CrudService;
 import com.usky.system.domain.SysUser;
 import com.usky.system.model.LoginUser;
+import com.usky.system.service.vo.SysUserNewVO;
+import com.usky.system.service.vo.TenantPlatformMenuVo;
 
 import java.util.List;
 
@@ -21,6 +23,22 @@ public interface ISysUserService extends CrudService<SysUser> {
      */
     public List<SysUser> selectUserList(SysUser user);
 
+    /**
+     * 根据条件分页查询用户列表
+     *
+     * @param user 用户信息
+     * @return 用户信息集合信息
+     */
+    public List<SysUser> selectDUserList(SysUser user);
+
+    /**
+     * 查询用户列表 - new
+     *
+     * @param user 用户信息
+     * @return 用户信息集合信息
+     */
+    List<SysUserNewVO> dUserList(SysUser user);
+
     /**
      * 根据条件分页查询已分配用户角色列表
      *
@@ -106,6 +124,15 @@ public interface ISysUserService extends CrudService<SysUser> {
      */
     public String checkEmailUnique(SysUser user);
 
+    /**
+     * 校验email是否唯一
+     *
+     * @param email 用户邮箱
+     * @param tenantId 租户ID
+     * @return 结果
+     */
+    public String checkEmailUnique1(String email, Integer tenantId);
+
     /**
      * 校验用户是否允许操作
      *
@@ -237,5 +264,10 @@ public interface ISysUserService extends CrudService<SysUser> {
 
     public List<SysUser> userAllList();
 
+    /**
+     * 根据手机号、用户名、邮箱查询用户信息
+     * @return 用户列表
+     */
+    List<SysUser> selectUserOne(String phonenumber,String userName,String email);
 
 }

+ 67 - 60
base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/SysLoginService.java

@@ -8,11 +8,11 @@ import com.usky.common.core.util.*;
 import com.usky.common.redis.core.RedisHelper;
 import com.usky.common.security.utils.SecurityUtils;
 import com.usky.common.core.exception.BusinessException;
-import com.usky.system.RuoYiSystemApplication;
 import com.usky.system.domain.*;
 import com.usky.system.domain.constants.UserConstants;
 import com.usky.system.model.LoginUser;
 import com.usky.system.service.enums.UserStatus;
+import com.usky.system.service.util.AsyncManager;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -47,6 +47,9 @@ public class SysLoginService {
     @Autowired
     private  SysTenantService sysTenantService;
 
+    @Autowired
+    AsyncManager asyncManager;
+
 
     public final String LOGIN_QRCODE_VERIFY ="login_qrcode_verify";
 
@@ -56,21 +59,22 @@ public class SysLoginService {
      * 登录
      */
     public LoginUser login(String username, String password, Integer tenantId) {
+
         // 用户名或密码为空 错误
         if (StringUtils.isAnyBlank(username, password)) {
-            recordLogininfor(tenantId,username, Constants.LOGIN_FAIL, "用户/密码必须填写");
+            asyncManager.insertLog(tenantId,username,Constants.LOGIN_FAIL, "用户/密码必须填写", null);
             throw new BusinessException("用户/密码必须填写");
         }
         // 密码如果不在指定范围内 错误
         if (password.length() < UserConstants.PASSWORD_MIN_LENGTH
                 || password.length() > UserConstants.PASSWORD_MAX_LENGTH) {
-            recordLogininfor(tenantId,username, Constants.LOGIN_FAIL, "用户密码不在指定范围");
+            asyncManager.insertLog(tenantId,username, Constants.LOGIN_FAIL, "用户密码不在指定范围", null);
             throw new BusinessException("用户密码不在指定范围");
         }
         // 用户名不在指定范围内 错误
         if (username.length() < UserConstants.USERNAME_MIN_LENGTH
                 || username.length() > UserConstants.USERNAME_MAX_LENGTH) {
-            recordLogininfor(tenantId,username, Constants.LOGIN_FAIL, "用户名不在指定范围");
+            asyncManager.insertLog(tenantId,username, Constants.LOGIN_FAIL, "用户名不在指定范围", null);
             throw new BusinessException("用户名不在指定范围");
         }
 
@@ -84,17 +88,18 @@ public class SysLoginService {
 
         SysUserVO user = loginUser.getSysUser();
         if (UserStatus.DELETED.getCode().equals(user.getDelFlag())) {
-            recordLogininfor(tenantId,username, Constants.LOGIN_FAIL, "对不起,您的账号已被删除");
+            asyncManager.insertLog(tenantId,username, Constants.LOGIN_FAIL, "对不起,您的账号已被删除", null);
             throw new BusinessException("对不起,您的账号:" + username + " 已被删除");
         }
         if (UserStatus.DISABLE.getCode().equals(user.getStatus())) {
-            recordLogininfor(tenantId,username, Constants.LOGIN_FAIL, "用户已停用,请联系管理员");
+            asyncManager.insertLog(tenantId,username, Constants.LOGIN_FAIL, "用户已停用,请联系管理员", null);
             throw new BusinessException("对不起,您的账号:" + username + " 已停用");
         }
         if (!SecurityUtils.matchesPassword(password, user.getPassword())) {
-            recordLogininfor(tenantId,username, Constants.LOGIN_FAIL, "用户密码错误");
+            asyncManager.insertLog(tenantId,username, Constants.LOGIN_FAIL, "用户密码错误", null);
             throw new BusinessException("用户不存在/密码错误");
         }
+
         //判断租户状态是否停用
         LambdaQueryWrapper<SysTenant> queryWrapper = Wrappers.lambdaQuery();
         queryWrapper.select(SysTenant::getStatus, SysTenant::getDomain)
@@ -104,51 +109,63 @@ public class SysLoginService {
             String status = list.get(0).getStatus();
             String domain = list.get(0).getDomain();
             if(status.equals("1")){
-                recordLogininfor(tenantId,username, Constants.LOGIN_FAIL, "系统已停用,请联系管理员");
+                asyncManager.insertLog(tenantId,username, Constants.LOGIN_FAIL, "系统已停用,请联系管理员", null);
                 throw new BusinessException("对不起,系统已停用,请联系管理员");
             }
         }
 
+        // 获取部门ID
+        LambdaQueryWrapper<SysUser> deptQueryWrapper = Wrappers.lambdaQuery();
+        deptQueryWrapper.select(SysUser::getDeptId)
+                .eq(SysUser::getDelFlag, 0)
+                .eq(SysUser::getTenantId, tenantId)
+                .and(w -> w.eq(SysUser::getUserName, username).or().eq(SysUser::getPhonenumber, username));
+        SysUser sysUser = sysUserService.getOne(deptQueryWrapper);
+        Integer deptId = 0; // 默认值为0,假设0表示没有部门ID
+        if (sysUser != null) {
+            deptId = sysUser.getDeptId().intValue(); // 将Long转换为Integer
+        }
+
         SysPerson sysPerson = sysPersonService.getsysPerson(user.getUserId());
         loginUser.setSysPerson(sysPerson);
-        recordLogininfor(tenantId,username, Constants.LOGIN_SUCCESS, "登录成功");
+        asyncManager.insertLog(tenantId,username, Constants.LOGIN_SUCCESS, "登录成功", deptId);
         return loginUser;
     }
 
 
     public SysUser appLogin(String username, String password, Integer tenantId, String phone, String verify) {
         SysUser loginUser = new SysUser();
+        //查询用户信息
+        loginUser = sysUserService.getAppUserInfo(username, tenantId, null);
         if (!StringUtils.isBlank(username) && !StringUtils.isBlank(password)) {
             // 用户名或密码为空 错误
             if (StringUtils.isAnyBlank(username, password)) {
-                recordLogininfor(tenantId,username, Constants.LOGIN_FAIL, "用户/密码必须填写");
+                asyncManager.insertLog(tenantId,loginUser.getUserName(), Constants.LOGIN_FAIL, "用户/密码必须填写", null);
                 throw new BusinessException("用户/密码必须填写");
             }
 
             // 密码如果不在指定范围内 错误
             if (password.length() < UserConstants.PASSWORD_MIN_LENGTH
                     || password.length() > UserConstants.PASSWORD_MAX_LENGTH) {
-                recordLogininfor(tenantId,username, Constants.LOGIN_FAIL, "用户密码不在指定范围");
+                asyncManager.insertLog(tenantId,loginUser.getUserName(), Constants.LOGIN_FAIL, "用户密码不在指定范围", null);
                 throw new BusinessException("用户密码不在指定范围");
             }
 
             // 用户名不在指定范围内 错误
             if (username.length() < UserConstants.USERNAME_MIN_LENGTH
                     || username.length() > UserConstants.USERNAME_MAX_LENGTH) {
-                recordLogininfor(tenantId,username, Constants.LOGIN_FAIL, "用户名不在指定范围");
+                asyncManager.insertLog(tenantId,loginUser.getUserName(), Constants.LOGIN_FAIL, "用户名不在指定范围", null);
                 throw new BusinessException("用户名不在指定范围");
             }
 
-            //查询用户信息
-            loginUser = sysUserService.getAppUserInfo(username, tenantId, null);
 
             if (Objects.isNull(loginUser)) {
-                recordLogininfor(tenantId,username, Constants.LOGIN_FAIL, "用户不存在");
+                asyncManager.insertLog(tenantId,loginUser.getUserName(), Constants.LOGIN_FAIL, "用户不存在", null);
                 throw new BusinessException("用户不存在");
             }
 
             if (!SecurityUtils.matchesPassword(password, loginUser.getPassword())) {
-                recordLogininfor(tenantId,username, Constants.LOGIN_FAIL, "用户密码错误");
+                asyncManager.insertLog(tenantId,loginUser.getUserName(), Constants.LOGIN_FAIL, "用户密码错误", null);
                 throw new BusinessException("用户不存在/密码错误");
             }
         } else if(!StringUtils.isBlank(phone) && !StringUtils.isBlank(verify)) {
@@ -163,6 +180,17 @@ public class SysLoginService {
                 throw new BusinessException("用户名或手机号不能为空");
             }
             loginUser = sysUserService.getAppUserInfo(null, tenantId, phone);
+            // 获取部门ID
+            LambdaQueryWrapper<SysUser> deptQueryWrapper = Wrappers.lambdaQuery();
+            deptQueryWrapper.select(SysUser::getDeptId)
+                    .eq(SysUser::getDelFlag, 0)
+                    .eq(SysUser::getTenantId, tenantId)
+                    .and(w -> w.eq(SysUser::getUserName, username).or().eq(SysUser::getPhonenumber, username));
+            SysUser sysUser = sysUserService.getOne(deptQueryWrapper);
+            Integer deptId = 0; // 默认值为0,假设0表示没有部门ID
+            if (sysUser != null) {
+                deptId = sysUser.getDeptId().intValue(); // 将Long转换为Integer
+            }
         } else if(!StringUtils.isBlank(username) && !StringUtils.isBlank(verify)) {
             LOGGER.info("二维码验证码登录");
             if (StringUtils.isBlank(username)) {
@@ -174,23 +202,38 @@ public class SysLoginService {
             }
             loginUser = sysUserService.getAppUserInfo(username, tenantId, null);
         }
-
+        // 获取部门ID
+        LambdaQueryWrapper<SysUser> deptQueryWrapper = Wrappers.lambdaQuery();
+        deptQueryWrapper.select(SysUser::getDeptId)
+                .eq(SysUser::getDelFlag, 0)
+                .eq(SysUser::getTenantId, tenantId)
+                .and(w -> w.eq(SysUser::getUserName, username).or().eq(SysUser::getPhonenumber, username));
+        SysUser sysUser = sysUserService.getOne(deptQueryWrapper);
+        Integer deptId = 0; // 默认值为0,假设0表示没有部门ID
+        if (sysUser != null) {
+            deptId = sysUser.getDeptId().intValue(); // 将Long转换为Integer
+        }
         if (UserStatus.DELETED.getCode().equals(loginUser.getDelFlag())) {
-            recordLogininfor(tenantId,username, Constants.LOGIN_FAIL, "对不起,您的账号已被删除");
+            asyncManager.insertLog(tenantId,loginUser.getUserName(), Constants.LOGIN_FAIL, "对不起,您的账号已被删除", null);
             throw new BusinessException("对不起,您的账号:" + username + " 已被删除");
         }
         if (UserStatus.DISABLE.getCode().equals(loginUser.getStatus())) {
-            recordLogininfor(tenantId,username, Constants.LOGIN_FAIL, "用户已停用,请联系管理员");
-            throw new BusinessException("对不起,您的账号:" + username + " 已停用");
+            asyncManager.insertLog(tenantId,loginUser.getUserName(), Constants.LOGIN_FAIL, "用户已停用,请联系管理员", null);
+            throw new BusinessException("对不起,您的账号:" + loginUser.getUserName() + " 已停用");
         }
 
-        recordLogininfor(tenantId,username, Constants.LOGIN_SUCCESS, "登录成功");
+//        Integer deptId = 0; // 默认值为0,假设0表示没有部门ID
+        // 确保在所有登录成功的路径中都获取部门ID
+        if (loginUser != null && loginUser.getDeptId() != null) {
+            deptId = loginUser.getDeptId().intValue();
+        }
+        asyncManager.insertLog(tenantId,loginUser.getUserName(), Constants.LOGIN_SUCCESS, "登录成功", deptId);
         return loginUser;
     }
 
 
     public void logout(Integer tenantId,String loginName) {
-        recordLogininfor(tenantId,loginName, Constants.LOGOUT, "退出成功");
+        asyncManager.insertLog(tenantId,loginName, Constants.LOGOUT, "退出成功", null);
     }
 
     /**
@@ -216,43 +259,7 @@ public class SysLoginService {
         sysUser.setNickName(username);
         sysUser.setPassword(SecurityUtils.encryptPassword(password));
         sysUserService.register(BeanMapperUtils.map(sysUser, SysUser.class));
-        recordLogininfor(SecurityUtils.getTenantId(),username, Constants.REGISTER, "注册成功");
-    }
-
-    /**
-     * 记录登录信息
-     *
-     * @param username 用户名
-     * @param status   状态
-     * @param message  消息内容
-     * @return
-     */
-    public void recordLogininfor(Integer tenantId,String username, String status, String message) {
-        SysLogininforVO logininfor = new SysLogininforVO();
-        logininfor.setUserName(username);
-        logininfor.setIpaddr(IpUtils.getIpAddr(ServletUtils.getRequest()));
-        logininfor.setMsg(message);
-        logininfor.setCreateBy(username);
-
-        LambdaQueryWrapper<SysUser> queryWrapper = Wrappers.lambdaQuery();
-        queryWrapper.select(SysUser::getDeptId)
-                .eq(SysUser::getDelFlag,0)
-                .eq(SysUser::getUserName,username)
-                .eq(SysUser::getTenantId,tenantId);
-        SysUser one = sysUserService.getOne(queryWrapper);
-        if(one != null){
-            logininfor.setDeptId(one.getDeptId().intValue());
-        }
-        logininfor.setTenantId(tenantId);
-
-        // 日志状态
-        if (StringUtils.equalsAny(status, Constants.LOGIN_SUCCESS, Constants.LOGOUT, Constants.REGISTER)) {
-            logininfor.setStatus(Constants.LOGIN_SUCCESS_STATUS);
-        } else if (Constants.LOGIN_FAIL.equals(status)) {
-            logininfor.setStatus(Constants.LOGIN_FAIL_STATUS);
-        }
-        LOGGER.debug(JsonUtils.toJson(logininfor));
-        sysLogininforService.insertLogininfor(BeanMapperUtils.map(logininfor, SysLogininfor.class));
+        asyncManager.insertLog(SecurityUtils.getTenantId(),username, Constants.REGISTER, "注册成功", null);
     }
 
 
@@ -262,7 +269,7 @@ public class SysLoginService {
             String result = String.valueOf(o);
             return result;
         }
-       return null;
+        return null;
     }
 
 

+ 10 - 0
base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/SysPlatformService.java

@@ -30,4 +30,14 @@ public interface SysPlatformService extends CrudService<SysPlatform> {
     void updatePlatformMenu(PlatformMenuVo platformMenuVo);
 
     void updateMobilePlatformMenu(MobilePlatformMenuVO mobilePlatformMenuV0);
+
+    List<SysPlatformVo> getPlatformAllList();
+
+    /**
+     * 通过应用ID删除应用
+     *
+     * @param platformId 应用ID
+     * @return 结果
+     */
+    void deletePlatformById(Integer platformId);
 }

+ 26 - 0
base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/SysTenantPlatformService.java

@@ -0,0 +1,26 @@
+package com.usky.system.service;
+
+import com.usky.common.mybatis.core.CrudService;
+import com.usky.system.domain.SysTenantPlatform;
+import com.usky.system.service.vo.TenantPlatformListVo;
+import com.usky.system.service.vo.TenantPlatformVo;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * <p>
+ * 租户和应用关联表 服务类
+ * </p>
+ *
+ * @author han
+ * @since 2024-08-14
+ */
+public interface SysTenantPlatformService extends CrudService<SysTenantPlatform> {
+
+    void updateTenantPlatform(TenantPlatformVo tenantPlatformVo);
+
+    List<TenantPlatformListVo> getTenantPlatformList(Integer tenantId);
+
+    Map<String, Object> selectTenantPlatform(Integer tenantId);
+}

+ 42 - 0
base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/SysUserTenantService.java

@@ -0,0 +1,42 @@
+package com.usky.system.service;
+
+import com.usky.system.domain.SysTenant;
+import com.usky.system.domain.SysUserTenant;
+import com.usky.common.mybatis.core.CrudService;
+
+import java.util.List;
+
+/**
+ * <p>
+ *  服务类
+ * </p>
+ *
+ * @author han
+ * @since 2024-09-11
+ */
+public interface SysUserTenantService extends CrudService<SysUserTenant> {
+    /**
+     * 企业邀请用户
+     *
+     * @param sysUserTenant
+     */
+    public void insertInviteUser(SysUserTenant sysUserTenant);
+
+    /**
+     * 企业解绑用户
+     *
+     * @param tenantId 租户ID
+     * @param userId 用户ID
+     */
+    public void deleteUserTenant(Integer tenantId,Long userId);
+
+    /**
+     * 根据用户查询企业下拉框
+     */
+    public List<SysTenant> getTenantByUser(Long userId);
+
+    /**
+     * 根据用户查询绑定状态
+     */
+    public Boolean getIdByUser(Integer tenantId,Long userId);
+}

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

@@ -35,9 +35,13 @@ public class MceContentServiceImpl extends AbstractCrudService<MceContentMapper,
         if (sendType.equals(0)){
             String appUrl = "https://fc-mp-85a26092-1305-4bf1-998f-b609512c8f7b.next.bspapp.com/uniPushMessage";
             JsonObject jsonObject = new JsonObject();
+            JsonObject jsonObject1 = new JsonObject();
+            jsonObject1.addProperty("infoType", mceReceiveVO.get("infoType").toString());
+            jsonObject1.addProperty("moduleId", (int)mceReceiveVO.get("id"));
             jsonObject.addProperty("cids", cids);
             jsonObject.addProperty("title", mceReceiveVO.get("infoTitle").toString());
             jsonObject.addProperty("content", mceReceiveVO.get("infoContent").toString());
+            jsonObject.add("payload",jsonObject1);
             String resultString = HttpClientUtils.doPostJson(appUrl,jsonObject.toString());
         }else if (sendType.equals(1)){
             SendWeChatMessageRequestVO sendWeChatMessageRequestVO = new SendWeChatMessageRequestVO();

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

@@ -108,7 +108,7 @@ public class MceReceiveServiceImpl extends AbstractCrudService<MceReceiveMapper,
     }
 
     @Override
-    @DataScope
+//    @DataScope
     public CommonPage<Object> mceManageList(String infoTitle, String infoType, String startTime, String endTime, Integer current, Integer size) {
         List<Object> list = new ArrayList<>();
         IPage<MceContent> page = new Page<>(current, size);
@@ -118,9 +118,8 @@ public class MceReceiveServiceImpl extends AbstractCrudService<MceReceiveMapper,
                 .like(StringUtils.isNotBlank(infoTitle),MceContent::getInfoTitle,infoTitle)
                 .between(StringUtils.isNotBlank(startTime)&&StringUtils.isNotBlank(endTime),MceContent::getCreateTime, startTime,endTime)
                 .eq(StringUtils.isNotBlank(infoType),MceContent::getInfoType, infoType)
-                .apply(DataScopeContextHolder.getDataScopeSql())
-//              .eq(MceContent::getCreateBy,SecurityUtils.getUsername())
-//              .eq(MceContent::getTenantId,SecurityUtils.getTenantId())
+//                .apply(DataScopeContextHolder.getDataScopeSql())
+                .eq(MceContent::getTenantId,SecurityUtils.getTenantId())
                 .orderByDesc(MceContent::getId);
         page = mceContentService.page(page,lambdaQuery1);
 
@@ -244,6 +243,7 @@ public class MceReceiveServiceImpl extends AbstractCrudService<MceReceiveMapper,
         if (!mceReceiveVO.containsKey("infoTypeName")) {
             mceReceiveVO.put("infoTypeName",infoTypeName);
         }
+
         MceContent mceContent = new MceContent();
         mceContent.setInfoTitle(mceReceiveVO.get("infoTitle").toString());
         mceContent.setInfoContent(mceReceiveVO.get("infoContent").toString());
@@ -256,10 +256,22 @@ public class MceReceiveServiceImpl extends AbstractCrudService<MceReceiveMapper,
         mceContentService.save(mceContent);
         Integer contentId = mceContent.getId();
         List<SysUser> list = userMapper.tenantIdUserList(SecurityUtils.getTenantId());
+
         if (CollectionUtils.isNotEmpty(list)) {
             List<Integer> userIds = new ArrayList<>();
             for (int g = 0; g < list.size(); g++) {
                 userIds.add(list.get(g).getUserId().intValue());
+                if (mceReceiveVO.get("userName").equals(list.get(g).getUserName())){
+                    mceContent.setInfoTitle(mceReceiveVO.get("infoTitle").toString());
+                    mceContent.setInfoContent(mceReceiveVO.get("infoContent").toString());
+                    mceContent.setInfoType(mceReceiveVO.get("infoType").toString());
+                    mceContent.setCreateBy(list.get(g).getUserName());
+                    mceContent.setCreateTime(LocalDateTime.now());
+                    mceContent.setDeptId(list.get(g).getDeptId().intValue());
+                    mceContent.setTenantId(list.get(g).getTenantId());
+                    mceContentService.save(mceContent);
+                    contentId = mceContent.getId();
+                }
             }
             List<Integer> userIds1;
             if (mceReceiveVO.containsKey("userIds")) {
@@ -283,10 +295,12 @@ public class MceReceiveServiceImpl extends AbstractCrudService<MceReceiveMapper,
                                 mceReceive1.setIssuerName(mceReceiveVO.get("userName").toString());
                             }
                             mceReceive1.setReceiverName(list.get(i).getUserName());
-                            mceReceive1.setCreateBy(SecurityUtils.getUsername());
+                            mceReceive1.setCreateBy(mceReceiveVO.get("userName").toString());
                             mceReceive1.setCreateTime(LocalDateTime.now());
                             mceReceive1.setTenantId(list.get(i).getTenantId());
-//                mceReceive1.setDeptId(list.get(i).getDeptId().intValue());
+                            if (mceReceiveVO.get("userName").equals(list.get(i).getUserName())){
+                                mceReceive1.setDeptId(list.get(i).getDeptId().intValue());
+                            }
                             this.save(mceReceive1);
                             Integer mceReceiveId = mceReceive1.getId();
                             LambdaQueryWrapper<MceSetting> lambdaQuery = Wrappers.lambdaQuery();

+ 4 - 3
base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/impl/MceSettingServiceImpl.java

@@ -35,13 +35,13 @@ public class MceSettingServiceImpl extends AbstractCrudService<MceSettingMapper,
     public void add(MceSetting mceSetting){
         if (mceSetting.getId().equals(0)){
             if(StringUtils.isBlank(mceSetting.getAppMode())){
-                mceSetting.setAppMode("{\"1\":true,\"2\":true,\"3\":true,\"4\":true}");
+                mceSetting.setAppMode("{\"1\":true,\"2\":true,\"3\":true,\"4\":true,\"5\":true}");
             }
             if(StringUtils.isBlank(mceSetting.getPcMode())){
-                mceSetting.setPcMode("{\"1\":true,\"2\":true,\"3\":true,\"4\":true}");
+                mceSetting.setPcMode("{\"1\":true,\"2\":true,\"3\":true,\"4\":true,\"5\":true}");
             }
             if(StringUtils.isBlank(mceSetting.getWcMode())){
-                mceSetting.setWcMode("{\"1\":true,\"2\":true,\"3\":true,\"4\":true}");
+                mceSetting.setWcMode("{\"1\":true,\"2\":true,\"3\":true,\"4\":true,\"5\":true}");
             }
 
             mceSetting.setCreateBy(SecurityUtils.getUsername());
@@ -70,6 +70,7 @@ public class MceSettingServiceImpl extends AbstractCrudService<MceSettingMapper,
             map1.put("2", true);
             map1.put("3", true);
             map1.put("4", true);
+            map1.put("5", true);
             map.put("appMode",map1);
             map.put("pcMode",map1);
             map.put("wcMode",map1);

+ 12 - 23
base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/impl/SysDeptServiceImpl.java

@@ -69,6 +69,11 @@ public class SysDeptServiceImpl extends AbstractCrudService<SysDeptMapper, SysDe
         return deptMapper.deptList(dept);
     }
 
+    @Override
+    public List<SysDept> deptListByTenant(Integer tenantId) {
+        return deptMapper.deptListByTenant(tenantId);
+    }
+
 
     @Override
     public List<TreeNode> buildDeptUserTreeSelect(List<SysDept> depts, List<SysUser> users) {
@@ -124,6 +129,13 @@ public class SysDeptServiceImpl extends AbstractCrudService<SysDeptMapper, SysDe
         return returnList;
     }
 
+    /**
+     * @description: 递归列表
+     * @author: fu
+     * @date: 2024/8/8 16:00
+     * @param: [list, t]
+     * @return: void
+     **/
     private void recursionFn2(List<SysDept> list, SysDept t) {
         List<SysDept> childList = getChildList(list, t);
         t.setChildren(childList);
@@ -173,29 +185,6 @@ public class SysDeptServiceImpl extends AbstractCrudService<SysDeptMapper, SysDe
         return deptTrees.stream().map(TreeSelect::new).collect(Collectors.toList());
     }
 
-/*    @Override
-    public List<TreeSelect> buildDeptUserTreeSelect(List<SysDept> depts, List<SysUser> users) {
-        List<SysDept> deptTrees = buildDeptTree(depts);
-        List<TreeSelect> treeSelectList = new ArrayList<>();
-        for (SysDept dept : deptTrees) {
-            TreeSelect treeSelect = new TreeSelect();
-            treeSelect.setId(dept.getDeptId());
-            treeSelect.setLabel(dept.getDeptName());
-            List<TreeSelect> children = new ArrayList<>();
-            for (SysUser user : users) {
-                if (user.getDeptId().equals(dept.getDeptId())) {
-                    TreeSelect child = new TreeSelect();
-                    child.setId(user.getUserId());
-                    child.setLabel(user.getNickName());
-                    children.add(child);
-                }
-            }
-            treeSelect.setChildren(children);
-            treeSelectList.add(treeSelect);
-        }
-        return treeSelectList;
-    }*/
-
 
     /**
      * 根据角色ID查询部门树信息

+ 184 - 4
base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/impl/SysMenuServiceImpl.java

@@ -14,10 +14,7 @@ import com.usky.system.mapper.*;
 import com.usky.system.service.ISysMenuService;
 import com.usky.system.service.SysRoleMenuService;
 import com.usky.system.service.SysTenantMenuService;
-import com.usky.system.service.vo.MetaVo;
-import com.usky.system.service.vo.RouterVo;
-import com.usky.system.service.vo.TreeSelect;
-import com.usky.system.service.vo.TreeMobileSelect;
+import com.usky.system.service.vo.*;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
@@ -62,6 +59,9 @@ public class SysMenuServiceImpl extends AbstractCrudService<SysMenuMapper, SysMe
     @Autowired
     private SysUserMapper sysUserMapper;
 
+    @Autowired
+    private SysPlatformMapper sysPlatformMapper;
+
     /**
      * 根据用户查询系统菜单列表
      *
@@ -184,12 +184,38 @@ public class SysMenuServiceImpl extends AbstractCrudService<SysMenuMapper, SysMe
         return getChildPerms(menus, 0);
     }
 
+    /**
+     * 根据用户ID查询菜单
+     *
+     * @param userId 用户名称
+     * @return 菜单列表
+     */
+    @Override
+    public List<SysMenu> selectMenuTreeByUserId1(Long userId,Long platformId)
+    {
+        List<SysMenu> menus = null;
+        if (1L == userId)
+        {
+            menus = menuMapper.selectMenuTreeAll();
+        }
+        else
+        {
+            menus = menuMapper.selectMenuTreeByUserId1(userId,platformId);
+        }
+        return getChildPerms(menus, 0);
+    }
+
 
     public List<SysMenu> selectMenuTreeByUserIdOne(Integer tenantId){
         List<SysMenu> menus = menuMapper.selectMenuTreeByUserIdOne(tenantId);
         return getChildPerms(menus, 0);
     }
 
+    public List<SysMenu> selectMenuTreeByUserIdOne1(Integer tenantId,Integer platformId){
+        List<SysMenu> menus = menuMapper.selectMenuTreeByUserIdOne1(tenantId,platformId);
+        return getChildPerms(menus, 0);
+    }
+
     @Override
     public List<SysTenantMenu> selectTenantMenuList(Integer tenantId){
         List<SysTenantMenu> menus = tenantMenuMapper.selectTenantMenuList(tenantId);
@@ -265,6 +291,142 @@ public class SysMenuServiceImpl extends AbstractCrudService<SysMenuMapper, SysMe
         return routers;
     }
 
+    /**
+     * 构建前端路由所需要的菜单
+     * @return 路由列表
+     */
+    @Override
+    public List<PlatformRouterVo> buildPlatformMenus()
+    {
+        List<PlatformRouterVo> platformRouterVos = new LinkedList<PlatformRouterVo>();
+        if (SecurityUtils.getLoginUser().getSysUser().getUserType().equals("01")){
+            List<SysPlatformVo> sysPlatformVos = sysPlatformMapper.getTenantPlatformList(SecurityUtils.getTenantId());
+            if (CollectionUtils.isNotEmpty(sysPlatformVos)){
+                for (SysPlatformVo platformVo : sysPlatformVos)
+                {
+                    PlatformRouterVo platformRouterVo = new PlatformRouterVo();
+                    platformRouterVo.setPlatformId(platformVo.getId());
+                    platformRouterVo.setPlatformName(platformVo.getPlatformName());
+                    platformRouterVo.setIcon(platformVo.getIcon());
+                    List<SysMenu> menus1 = this.selectMenuTreeByUserIdOne1(SecurityUtils.getTenantId(),
+                            platformVo.getId());
+                    List<RouterVo> routers = new LinkedList<RouterVo>();
+                    for (SysMenu menu : menus1)
+                    {
+                        RouterVo router = new RouterVo();
+                        router.setHidden("1".equals(menu.getVisible()));
+                        router.setName(getRouteName(menu));
+                        router.setPath(getRouterPath(menu));
+                        router.setComponent(getComponent(menu));
+                        router.setMeta(new MetaVo(menu.getMenuName(), menu.getMenuAliasName(), menu.getIcon(), StringUtils.equals("1", menu.getIsCache()), menu.getPath(), menu.getIsFrame(), menu.getIsNew(), menu.getRemark()));
+                        List<SysMenu> cMenus = menu.getChildren();
+                        if (!cMenus.isEmpty() && cMenus.size() > 0 && UserConstants.TYPE_DIR.equals(menu.getMenuType()))
+                        {
+                            router.setAlwaysShow(true);
+                            router.setRedirect("noRedirect");
+                            router.setChildren(buildMenus(cMenus));
+                        }
+                        else if (isMenuFrame(menu))
+                        {
+                            router.setMeta(null);
+                            List<RouterVo> childrenList = new ArrayList<RouterVo>();
+                            RouterVo children = new RouterVo();
+                            children.setPath(menu.getPath());
+                            children.setComponent(menu.getComponent());
+                            children.setName(StringUtils.capitalize(menu.getPath()));
+                            children.setMeta(new MetaVo(menu.getMenuName(), menu.getMenuAliasName(), menu.getIcon(), StringUtils.equals("1", menu.getIsCache()), menu.getPath(), menu.getIsFrame(), menu.getIsNew(), menu.getRemark()));
+                            childrenList.add(children);
+                            router.setChildren(childrenList);
+                        }
+                        else if (menu.getParentId().intValue() == 0 && isInnerLink(menu))
+                        {
+                            router.setMeta(new MetaVo(menu.getMenuName(), menu.getMenuAliasName(), menu.getIcon(), menu.getIsFrame(), menu.getIsNew(), menu.getRemark()));
+                            router.setPath("/inner");
+                            List<RouterVo> childrenList = new ArrayList<RouterVo>();
+                            RouterVo children = new RouterVo();
+                            String routerPath = StringUtils.replaceEach(menu.getPath(), new String[] { Constants.HTTP, Constants.HTTPS }, new String[] { "", "" });
+                            children.setPath(routerPath);
+                            children.setComponent(UserConstants.INNER_LINK);
+                            children.setName(StringUtils.capitalize(routerPath));
+                            children.setMeta(new MetaVo(menu.getMenuName(), menu.getMenuAliasName(), menu.getIcon(), menu.getPath(), menu.getIsFrame(), menu.getIsNew(), menu.getRemark()));
+                            childrenList.add(children);
+                            router.setChildren(childrenList);
+                        }
+                        routers.add(router);
+                    }
+                    platformRouterVo.setRouterVos(routers);
+                    platformRouterVos.add(platformRouterVo);
+                }
+            }
+        }else {
+            LambdaQueryWrapper<SysUserRole> queryWrapper = Wrappers.lambdaQuery();
+            queryWrapper.in(SysUserRole::getUserId,SecurityUtils.getUserId());
+            List<SysUserRole> userRoleList = sysUserRoleMapper.selectList(queryWrapper);
+            if (CollectionUtils.isNotEmpty(userRoleList)){
+                List<SysPlatformVo> sysPlatformVos = sysPlatformMapper.getRolePlatformList(SecurityUtils.getTenantId(),
+                        userRoleList.get(0).getRoleId().intValue());
+                if (CollectionUtils.isNotEmpty(sysPlatformVos)){
+                    for (SysPlatformVo platformVo : sysPlatformVos)
+                    {
+                        PlatformRouterVo platformRouterVo = new PlatformRouterVo();
+                        platformRouterVo.setPlatformId(platformVo.getId());
+                        platformRouterVo.setPlatformName(platformVo.getPlatformName());
+                        platformRouterVo.setIcon(platformVo.getIcon());
+                        List<SysMenu> menus1 = this.selectMenuTreeByUserId1(SecurityUtils.getUserId(),
+                                platformVo.getId().longValue());
+                        List<RouterVo> routers = new LinkedList<RouterVo>();
+                        for (SysMenu menu : menus1)
+                        {
+                            RouterVo router = new RouterVo();
+                            router.setHidden("1".equals(menu.getVisible()));
+                            router.setName(getRouteName(menu));
+                            router.setPath(getRouterPath(menu));
+                            router.setComponent(getComponent(menu));
+                            router.setMeta(new MetaVo(menu.getMenuName(), menu.getMenuAliasName(), menu.getIcon(), StringUtils.equals("1", menu.getIsCache()), menu.getPath(), menu.getIsFrame(), menu.getIsNew(), menu.getRemark()));
+                            List<SysMenu> cMenus = menu.getChildren();
+                            if (!cMenus.isEmpty() && cMenus.size() > 0 && UserConstants.TYPE_DIR.equals(menu.getMenuType()))
+                            {
+                                router.setAlwaysShow(true);
+                                router.setRedirect("noRedirect");
+                                router.setChildren(buildMenus(cMenus));
+                            }
+                            else if (isMenuFrame(menu))
+                            {
+                                router.setMeta(null);
+                                List<RouterVo> childrenList = new ArrayList<RouterVo>();
+                                RouterVo children = new RouterVo();
+                                children.setPath(menu.getPath());
+                                children.setComponent(menu.getComponent());
+                                children.setName(StringUtils.capitalize(menu.getPath()));
+                                children.setMeta(new MetaVo(menu.getMenuName(), menu.getMenuAliasName(), menu.getIcon(), StringUtils.equals("1", menu.getIsCache()), menu.getPath(), menu.getIsFrame(), menu.getIsNew(), menu.getRemark()));
+                                childrenList.add(children);
+                                router.setChildren(childrenList);
+                            }
+                            else if (menu.getParentId().intValue() == 0 && isInnerLink(menu))
+                            {
+                                router.setMeta(new MetaVo(menu.getMenuName(), menu.getMenuAliasName(), menu.getIcon(), menu.getIsFrame(), menu.getIsNew(), menu.getRemark()));
+                                router.setPath("/inner");
+                                List<RouterVo> childrenList = new ArrayList<RouterVo>();
+                                RouterVo children = new RouterVo();
+                                String routerPath = StringUtils.replaceEach(menu.getPath(), new String[] { Constants.HTTP, Constants.HTTPS }, new String[] { "", "" });
+                                children.setPath(routerPath);
+                                children.setComponent(UserConstants.INNER_LINK);
+                                children.setName(StringUtils.capitalize(routerPath));
+                                children.setMeta(new MetaVo(menu.getMenuName(), menu.getMenuAliasName(), menu.getIcon(), menu.getPath(), menu.getIsFrame(), menu.getIsNew(), menu.getRemark()));
+                                childrenList.add(children);
+                                router.setChildren(childrenList);
+                            }
+                            routers.add(router);
+                        }
+                        platformRouterVo.setRouterVos(routers);
+                        platformRouterVos.add(platformRouterVo);
+                    }
+                }
+            }
+        }
+        return platformRouterVos;
+    }
+
     /**
      * 构建前端所需要树结构
      *
@@ -714,4 +876,22 @@ public class SysMenuServiceImpl extends AbstractCrudService<SysMenuMapper, SysMe
     {
         return getChildMobileList(list, t).size() > 0 ? true : false;
     }
+
+    @Override
+    public List<TenantPlatformMenuVo> selectRolePlatformMenu()
+    {
+        List<TenantPlatformMenuVo> list1 = new ArrayList<>();
+        List<SysPlatformVo> list = sysPlatformMapper.getTenantPlatformList(SecurityUtils.getTenantId());
+        if (CollectionUtils.isNotEmpty(list)){
+            for(int i=0;i<list.size();i++){
+                TenantPlatformMenuVo tenantPlatformMenuVo = new TenantPlatformMenuVo();
+                tenantPlatformMenuVo.setId(list.get(i).getId());
+                tenantPlatformMenuVo.setLabel(list.get(i).getPlatformName());
+                List<SysMenu> menus = baseMapper.getTenantPlatformMenuList(SecurityUtils.getTenantId(),list.get(i).getId());
+                tenantPlatformMenuVo.setChildren(this.buildMenuTreeSelect(menus));
+                list1.add(tenantPlatformMenuVo);
+            }
+        }
+        return list1;
+    }
 }

+ 22 - 4
base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/impl/SysPlatformServiceImpl.java

@@ -12,6 +12,7 @@ import com.usky.system.domain.SysPlatformMenu;
 import com.usky.system.domain.SysMobilePlatformMenu;
 import com.usky.system.mapper.SysMenuMapper;
 import com.usky.system.mapper.SysPlatformMapper;
+import com.usky.system.mapper.SysTenantPlatformMapper;
 import com.usky.system.service.SysMobilePlatformMenuService;
 import com.usky.system.service.SysPlatformMenuService;
 import com.usky.system.service.SysPlatformService;
@@ -37,8 +38,6 @@ import java.util.Map;
 @Service
 public class SysPlatformServiceImpl extends AbstractCrudService<SysPlatformMapper, SysPlatform> implements SysPlatformService {
 
-    @Autowired
-    private SysMenuMapper menuMapper;
     @Autowired
     private SysPlatformMenuService sysPlatformMenuService;
     @Autowired
@@ -97,8 +96,9 @@ public class SysPlatformServiceImpl extends AbstractCrudService<SysPlatformMappe
     @Transactional
     public void updatePlatformMenu(PlatformMenuVo platformMenuVo) {
         SysPlatform sysPlatform = new SysPlatform();
+        sysPlatform.setPlatformName(platformMenuVo.getPlatformName());
+        sysPlatform.setIcon(platformMenuVo.getIcon());
         if (platformMenuVo.getPlatformId().intValue() == 0) {
-            sysPlatform.setPlatformName(platformMenuVo.getPlatformName());
             sysPlatform.setCreateBy(SecurityUtils.getUsername());
             sysPlatform.setCreateTime(LocalDateTime.now());
             this.save(sysPlatform);
@@ -106,7 +106,6 @@ public class SysPlatformServiceImpl extends AbstractCrudService<SysPlatformMappe
             platformMenuVo.setPlatformId(fid.longValue());
         }else {
             sysPlatform.setId(platformMenuVo.getPlatformId().intValue());
-            sysPlatform.setPlatformName(platformMenuVo.getPlatformName());
             sysPlatform.setUpdateBy(SecurityUtils.getUsername());
             sysPlatform.setUpdateTime(LocalDateTime.now());
             this.updateById(sysPlatform);
@@ -254,4 +253,23 @@ public class SysPlatformServiceImpl extends AbstractCrudService<SysPlatformMappe
         }
         return arr3;
     }
+
+    @Override
+    public List<SysPlatformVo> getPlatformAllList() {
+        List<SysPlatformVo> list1 = baseMapper.getPlatformList(null, null, null, null, null, null);
+        return list1;
+    }
+
+    /**
+     * 通过应用ID删除应用
+     *
+     * @param platformId 应用ID
+     * @return 结果
+     */
+    @Override
+    @Transactional
+    public void deletePlatformById(Integer platformId) {
+        baseMapper.deleteById(platformId);
+    }
+
 }

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

@@ -0,0 +1,150 @@
+package com.usky.system.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+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.*;
+import com.usky.system.mapper.SysTenantPlatformMapper;
+import com.usky.system.service.ISysMenuService;
+import com.usky.system.service.SysPlatformMenuService;
+import com.usky.system.service.SysPlatformService;
+import com.usky.system.service.SysTenantPlatformService;
+import com.usky.system.service.vo.SysPlatformVo;
+import com.usky.system.service.vo.TenantPlatformListVo;
+import com.usky.system.service.vo.TenantPlatformMenuVo;
+import com.usky.system.service.vo.TenantPlatformVo;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * <p>
+ * 租户和应用关联表 服务实现类
+ * </p>
+ *
+ * @author han
+ * @since 2024-08-14
+ */
+@Service
+public class SysTenantPlatformServiceImpl extends AbstractCrudService<SysTenantPlatformMapper, SysTenantPlatform> implements SysTenantPlatformService {
+
+    @Autowired
+    private SysPlatformService sysPlatformService;
+
+    @Autowired
+    private SysPlatformMenuService sysPlatformMenuService;
+
+    @Autowired
+    private ISysMenuService menuService;
+
+    @Override
+    @Transactional
+    public void updateTenantPlatform(TenantPlatformVo tenantPlatformVo) {
+        Integer[] arr = tenantPlatformVo.getPlatformIds();
+        LambdaQueryWrapper<SysTenantPlatform> queryWrapper = Wrappers.lambdaQuery();
+        if (tenantPlatformVo.getRequestId().equals(0)){
+            queryWrapper.eq(SysTenantPlatform::getTenantId,tenantPlatformVo.getTenantId())
+                    .eq(SysTenantPlatform::getIsDefault,1);
+            this.remove(queryWrapper);
+            LambdaQueryWrapper<SysTenantPlatform> queryWrapper1 = Wrappers.lambdaQuery();
+            queryWrapper1.eq(SysTenantPlatform::getTenantId,tenantPlatformVo.getTenantId())
+                    .eq(SysTenantPlatform::getPlatformId,arr[0]);
+            this.remove(queryWrapper1);
+            SysTenantPlatform sysTenantPlatform = new SysTenantPlatform();
+            sysTenantPlatform.setTenantId(tenantPlatformVo.getTenantId());
+            sysTenantPlatform.setPlatformId(arr[0]);
+            sysTenantPlatform.setIsDefault(1);
+            this.save(sysTenantPlatform);
+        }else {
+            queryWrapper.eq(SysTenantPlatform::getTenantId,tenantPlatformVo.getTenantId())
+                    .ne(SysTenantPlatform::getIsDefault,1);
+            this.remove(queryWrapper);
+            LambdaQueryWrapper<SysTenantPlatform> queryWrapper1 = Wrappers.lambdaQuery();
+            queryWrapper1.eq(SysTenantPlatform::getTenantId,tenantPlatformVo.getTenantId())
+                    .eq(SysTenantPlatform::getIsDefault,1);
+            List<SysTenantPlatform> list = this.list(queryWrapper1);
+            if (list.size()<=0){
+                throw new BusinessException("没有相关关联数据,请联系管理员");
+            }
+            for (int i = 0; i < arr.length; i++){
+                if (!arr[i].equals(list.get(0).getPlatformId())){
+                    SysTenantPlatform sysTenantPlatform1 = new SysTenantPlatform();
+                    sysTenantPlatform1.setPlatformId(arr[i]);
+                    sysTenantPlatform1.setTenantId(tenantPlatformVo.getTenantId());
+                    sysTenantPlatform1.setIsDefault(0);
+                    this.save(sysTenantPlatform1);
+                }
+            }
+        }
+    }
+
+    @Override
+    public List<TenantPlatformListVo> getTenantPlatformList(Integer tenantId) {
+        List<TenantPlatformListVo> list2 = new ArrayList<>();;
+        LambdaQueryWrapper<SysTenantPlatform> queryWrapper1 = Wrappers.lambdaQuery();
+        queryWrapper1.eq(SysTenantPlatform::getTenantId,tenantId);
+        List<SysTenantPlatform> list = this.list(queryWrapper1);
+        List<SysPlatformVo> list1 = sysPlatformService.getPlatformAllList();
+        if(CollectionUtils.isNotEmpty(list1)){
+            for(int j=0;j<list1.size();j++){
+                TenantPlatformListVo tenantPlatformListVo = new TenantPlatformListVo();
+                tenantPlatformListVo.setPlatformName(list1.get(j).getPlatformName());
+                tenantPlatformListVo.setPlatformId(list1.get(j).getId());
+                tenantPlatformListVo.setIcon(list1.get(j).getIcon());
+                if(CollectionUtils.isNotEmpty(list)){
+                    for(int i=0;i<list.size();i++){
+                        if (list1.get(j).getId().equals(list.get(i).getPlatformId())) {
+                            tenantPlatformListVo.setIsDefault(list.get(i).getIsDefault());
+                            tenantPlatformListVo.setIsSelected(1);
+                        }
+                    }
+                }
+                list2.add(tenantPlatformListVo);
+            }
+        }
+        return list2;
+    }
+
+    public Map<String, Object> selectTenantPlatform(Integer tenantId){
+        LambdaQueryWrapper<SysTenantPlatform> queryWrapper = Wrappers.lambdaQuery();
+        queryWrapper.eq(SysTenantPlatform::getTenantId,tenantId);
+        List<SysTenantPlatform> list = this.list(queryWrapper);
+        List<TenantPlatformMenuVo> list1 = new ArrayList<>();
+        Long[] arr = sysPlatformMenuService.selectPlatformMenu(tenantId);
+        Map<String, Object> ajax = new HashMap<>();
+        ajax.put("checkedKeys",arr);
+        if (CollectionUtils.isNotEmpty(list)){
+            List<Integer> platformIds = new ArrayList<>();
+            for(int j=0;j<list.size();j++){
+                platformIds.add(list.get(j).getPlatformId());
+            }
+            LambdaQueryWrapper<SysPlatform> queryWrapper1 = Wrappers.lambdaQuery();
+            queryWrapper1.in(SysPlatform::getId,platformIds);
+            List<SysPlatform> platformList = sysPlatformService.list(queryWrapper1);
+            for(int i=0;i<list.size();i++){
+                TenantPlatformMenuVo tenantPlatformMenuVo = new TenantPlatformMenuVo();
+                tenantPlatformMenuVo.setId(list.get(i).getPlatformId());
+                if (CollectionUtils.isNotEmpty(platformList)){
+                    for(int k=0;k<platformList.size();k++){
+                        if (list.get(i).getPlatformId().equals(platformList.get(k).getId())){
+                            tenantPlatformMenuVo.setLabel(platformList.get(k).getPlatformName());
+                        }
+                    }
+                }
+                List<SysMenu> menus = sysPlatformMenuService.getPlatformMenuList(list.get(i).getPlatformId());
+                tenantPlatformMenuVo.setChildren(menuService.buildMenuTreeSelect(menus));
+                list1.add(tenantPlatformMenuVo);
+            }
+        }
+        ajax.put("menus",list1);
+        return ajax;
+    }
+}

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

@@ -85,9 +85,11 @@ public class SysUserOnlineServiceImpl implements ISysUserOnlineService
         }
         SysUserOnline sysUserOnline = new SysUserOnline();
         sysUserOnline.setTokenId(user.getToken());
+        sysUserOnline.setUserid(user.getUserid());
         sysUserOnline.setUserName(user.getUsername());
         sysUserOnline.setIpaddr(user.getIpaddr());
         sysUserOnline.setLoginTime(user.getLoginTime());
+        sysUserOnline.setExpireTime(user.getExpireTime());
         return sysUserOnline;
     }
 }

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

@@ -1,7 +1,8 @@
 package com.usky.system.service.impl;
 
 
-import com.usky.common.core.constants.Constants;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.usky.common.security.utils.SecurityUtils;
 import com.usky.common.core.bean.CommonPage;
 import com.usky.common.core.exception.BusinessException;
@@ -14,17 +15,18 @@ import com.usky.system.mapper.*;
 import com.usky.system.model.LoginUser;
 import com.usky.system.service.ISysConfigService;
 import com.usky.system.service.ISysUserService;
+import com.usky.system.service.SysUserTenantService;
+import com.usky.system.service.vo.SysUserNewVO;
+import com.usky.system.service.vo.UserPostVo;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.BeanUtils;
+import org.springframework.beans.BeansException;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
-import java.util.Set;
+import java.util.*;
 import java.util.stream.Collectors;
 
 /**
@@ -58,6 +60,9 @@ public class SysUserServiceImpl extends AbstractCrudService<SysUserMapper, SysUs
     @Autowired
     private ISysConfigService iSysConfigService;
 
+    @Autowired
+    private SysUserTenantService sysUserTenantService;
+
 
     /**
      * 根据条件分页查询用户列表
@@ -67,11 +72,56 @@ public class SysUserServiceImpl extends AbstractCrudService<SysUserMapper, SysUs
      */
     @Override
     public List<SysUser> selectUserList(SysUser user) {
+
         user.setTenantId(SecurityUtils.getTenantId());
         user.setUserType("00");
         return userMapper.selectUserList(user);
     }
 
+    /**
+     * 根据条件分页查询用户列表
+     *
+     * @param user 用户信息
+     * @return 用户信息集合信息
+     */
+    @Override
+    public List<SysUser> selectDUserList(SysUser user) {
+        user.setTenantId(SecurityUtils.getTenantId());
+        user.setUserType("00");
+        return userMapper.selectUserList(user);
+    }
+
+    /**
+     * 用户列表-新
+     *
+     * @param user 用户信息
+     * @return 用户信息集合信息
+     */
+    @Override
+    public List<SysUserNewVO> dUserList(SysUser user) {
+        user.setTenantId(SecurityUtils.getTenantId());
+        user.setUserType("00");
+        List<SysUserNewVO> sysUserNewVOS = new ArrayList<>();
+        List<SysUser> sysUsers = userMapper.selectUserList(user);
+        List<Long> userIds = new ArrayList<>();
+        if (!sysUsers.isEmpty()) {
+            for (SysUser sysUser : sysUsers) {
+                SysUserNewVO sysUserNewVO = new SysUserNewVO();
+                try {
+                    BeanUtils.copyProperties(sysUser, sysUserNewVO);
+                } catch (BeansException e) {
+                    throw new BusinessException("dUserList方法,获取用户列表信息异常" + e);
+                }
+                userIds.add(sysUser.getUserId());
+                sysUserNewVOS.add(sysUserNewVO);
+            }
+            Map<Long, String> userIdToPostMap = userPostMapper.getUserPost(userIds).stream()
+                    .collect(Collectors.toMap(UserPostVo::getUserId, UserPostVo::getPostName));
+            sysUserNewVOS.forEach(sysUserNewVO -> sysUserNewVO.setPost(userIdToPostMap.get(sysUserNewVO.getUserId())));
+        }
+        return sysUserNewVOS;
+    }
+
     /**
      * 根据条件分页查询已分配用户角色列表
      *
@@ -204,7 +254,7 @@ public class SysUserServiceImpl extends AbstractCrudService<SysUserMapper, SysUs
     }
 
     @Override
-    public String checkPhoneUnique1(String phone, Integer tenantId){
+    public String checkPhoneUnique1(String phone, Integer tenantId) {
         int count = userMapper.checkPhoneUnique1(phone, tenantId);
         if (count > 0) {
             return UserConstants.NOT_UNIQUE;
@@ -228,6 +278,22 @@ public class SysUserServiceImpl extends AbstractCrudService<SysUserMapper, SysUs
         return UserConstants.UNIQUE;
     }
 
+    /**
+     * 校验email是否唯一
+     *
+     * @param email 用户邮箱
+     * @param tenantId 租户ID
+     * @return
+     */
+    @Override
+    public String checkEmailUnique1(String email, Integer tenantId) {
+        int count = userMapper.checkEmailUnique1(email, tenantId);
+        if (count > 0) {
+            return UserConstants.NOT_UNIQUE;
+        }
+        return UserConstants.UNIQUE;
+    }
+
     /**
      * 校验用户是否允许操作
      *
@@ -251,6 +317,11 @@ public class SysUserServiceImpl extends AbstractCrudService<SysUserMapper, SysUs
     public int insertUser(SysUser user) {
         // 新增用户信息
         int rows = userMapper.insertUser(user);
+        SysUserTenant sysUserTenant = new SysUserTenant();
+        sysUserTenant.setUserId(user.getUserId());
+        sysUserTenant.setIsDefault(true);
+        sysUserTenant.setTenantId(user.getTenantId());
+        sysUserTenantService.save(sysUserTenant);
         // 新增用户岗位关联
         insertUserPost(user);
         // 新增用户与角色管理
@@ -463,16 +534,16 @@ public class SysUserServiceImpl extends AbstractCrudService<SysUserMapper, SysUs
 
     @Override
     @Transactional
-    public int deleteUserByPwd(Long userId,String password) {
+    public int deleteUserByPwd(Long userId, String password) {
         checkUserAllowed(new SysUser(userId));
         SysUser user = this.selectUserById(userId);
-        if (user.getPassword().equals(password)){
+        if (user.getPassword().equals(password)) {
             // 删除用户与角色关联
             userRoleMapper.deleteUserRoleByUserId(userId);
             // 删除用户与岗位表
             userPostMapper.deleteUserPostByUserId(userId);
             return userMapper.deleteUserById(userId);
-        }else {
+        } else {
             throw new BusinessException("密码错误");
         }
     }
@@ -516,26 +587,26 @@ public class SysUserServiceImpl extends AbstractCrudService<SysUserMapper, SysUs
 
     @Override
     public SysUser getAppUserInfo(String username, Integer tenantId, String phone) {
-       SysUser sysUser = new SysUser();
-       if (!StringUtils.isBlank(username)) {
-           sysUser = userMapper.selectUserData(username, tenantId);
-       } else if (!StringUtils.isBlank(phone)) {
-           sysUser = userMapper.selectUserDataOne(tenantId,phone);
-       }
-       if(Objects.isNull(sysUser)){
-           sysUser = userMapper.selectUserDataOne(tenantId,username);
-           if (Objects.isNull(sysUser)){
-               throw new BusinessException("用户信息未注册");
-           }
-       }
-       List<SysRole> sysRoles = roleMapper.selectRolePermissionByUserId(sysUser.getUserId());
-       List<SysRoleVO> collect = sysRoles.stream().map(sysRole -> {
-           SysRoleVO sysRoleVO = new SysRoleVO();
-           BeanUtils.copyProperties(sysRole, sysRoleVO);
-           return sysRoleVO;
-       }).collect(Collectors.toList());
-       sysUser.setRoles(collect);
-       return sysUser;
+        SysUser sysUser = new SysUser();
+        if (!StringUtils.isBlank(username)) {
+            sysUser = userMapper.selectUserTenantData(username, tenantId);
+        } else if (!StringUtils.isBlank(phone)) {
+            sysUser = userMapper.selectUserTenantDataOne(tenantId, phone);
+        }
+        if (Objects.isNull(sysUser)) {
+            sysUser = userMapper.selectUserTenantDataOne(tenantId, username);
+            if (Objects.isNull(sysUser)) {
+                throw new BusinessException("用户信息未注册");
+            }
+        }
+        List<SysRole> sysRoles = roleMapper.selectRolePermissionByUserId(sysUser.getUserId());
+        List<SysRoleVO> collect = sysRoles.stream().map(sysRole -> {
+            SysRoleVO sysRoleVO = new SysRoleVO();
+            BeanUtils.copyProperties(sysRole, sysRoleVO);
+            return sysRoleVO;
+        }).collect(Collectors.toList());
+        sysUser.setRoles(collect);
+        return sysUser;
     }
 
 
@@ -624,4 +695,14 @@ public class SysUserServiceImpl extends AbstractCrudService<SysUserMapper, SysUs
         List<SysUser> list = userMapper.userAllList();
         return list;
     }
+
+    public List<SysUser> selectUserOne(String phonenumber,String userName,String email) {
+        LambdaQueryWrapper<SysUser> queryWrapper = Wrappers.lambdaQuery();
+        queryWrapper.select(SysUser::getUserName,SysUser::getUserId,SysUser::getNickName,SysUser::getPhonenumber,SysUser::getEmail)
+                .eq(StringUtils.isNotBlank(phonenumber),SysUser::getPhonenumber,phonenumber)
+                .eq(StringUtils.isNotBlank(userName),SysUser::getUserName,userName)
+                .eq(StringUtils.isNotBlank(email),SysUser::getEmail,email)
+                .eq(SysUser::getDelFlag,0);
+        return this.list(queryWrapper);
+    }
 }

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

@@ -0,0 +1,96 @@
+package com.usky.system.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.usky.common.core.exception.BusinessException;
+import com.usky.system.RemoteDeptService;
+import com.usky.system.domain.SysTenant;
+import com.usky.system.domain.SysUserTenant;
+import com.usky.system.mapper.SysUserTenantMapper;
+import com.usky.system.service.SysTenantService;
+import com.usky.system.service.SysUserTenantService;
+import com.usky.common.mybatis.core.AbstractCrudService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * <p>
+ *  服务实现类
+ * </p>
+ *
+ * @author han
+ * @since 2024-09-11
+ */
+@Service
+public class SysUserTenantServiceImpl extends AbstractCrudService<SysUserTenantMapper, SysUserTenant> implements SysUserTenantService {
+
+    @Autowired
+    private SysTenantService sysTenantService;
+
+    /**
+     * 企业邀请用户
+     *
+     * @param sysUserTenant
+     */
+    @Override
+    @Transactional
+    public void insertInviteUser(SysUserTenant sysUserTenant) {
+        int userCount = baseMapper.checkUserIdUnique(sysUserTenant.getTenantId(), sysUserTenant.getUserId());
+        if (userCount > 0){
+            throw new BusinessException("用户已绑定,无法重复绑定!");
+        }else {
+            this.save(sysUserTenant);
+        }
+    }
+
+    /**
+     * 企业解绑用户
+     *
+     * @param tenantId 租户ID
+     * @param userId 用户ID
+     */
+    @Override
+    @Transactional
+    public void deleteUserTenant(Integer tenantId,Long userId) {
+        baseMapper.deleteUserTenant(tenantId, userId);
+    }
+
+    /**
+     * 根据用户查询企业下拉框
+     */
+    @Override
+    @Transactional
+    public List<SysTenant> getTenantByUser(Long userId){
+        LambdaQueryWrapper<SysUserTenant> queryWrapper = Wrappers.lambdaQuery();
+        queryWrapper.eq(SysUserTenant::getUserId,userId);
+        List<SysUserTenant> userTenants = this.list(queryWrapper);
+        List<Integer> tenantIdList = new ArrayList<>();
+        List<SysTenant> tenantList = new ArrayList<>();
+        LambdaQueryWrapper<SysTenant> queryWrapper1 = Wrappers.lambdaQuery();
+        if (CollectionUtils.isNotEmpty(userTenants)){
+            for (int i = 0; i < userTenants.size(); i++) {
+                tenantIdList.add(userTenants.get(i).getTenantId());
+            }
+            queryWrapper1.in(SysTenant::getId,tenantIdList)
+                    .eq(SysTenant::getStatus,0);
+            tenantList = sysTenantService.list(queryWrapper1);
+        }
+        return tenantList;
+    }
+
+    @Override
+    @Transactional
+    public Boolean getIdByUser(Integer tenantId,Long userId){
+        LambdaQueryWrapper<SysUserTenant> queryWrapper = Wrappers.lambdaQuery();
+        queryWrapper.eq(SysUserTenant::getUserId,userId)
+                .eq(SysUserTenant::getTenantId,tenantId);
+        List<SysUserTenant> userTenants = this.list(queryWrapper);
+        return userTenants.get(0).getIsDefault();
+    }
+}

+ 115 - 0
base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/util/AddressUtils.java

@@ -0,0 +1,115 @@
+package com.usky.system.service.util;
+
+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 org.json.JSONException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.util.StringUtils;
+import org.json.JSONObject;
+
+
+/*
+ * 获取地址类
+ *
+ * @author xy
+ */
+
+/*
+public class AddressUtils {
+    private static final Logger log = LoggerFactory.getLogger(AddressUtils.class);
+
+    // IP地址查询
+    public static String IP_URL = "http://whois.pconline.com.cn/ip.jsp?ip=";
+
+    // 未知地址
+    public static final String UNKNOWN = "获取地理位置异常";
+
+    // 检查响应是否是503 Service Temporarily Unavailable
+    private static final String SERVICE_UNAVAILABLE_HTML = "503 Service Temporarily Unavailable";
+
+    public static String getRealAddressByIP(String ip) {
+        // 内网不查询
+        if (IpUtils.internalIp(ip)) {
+            return "内网IP";
+        }
+        // 检查地址服务是否启用
+        if (WjConfig.isAddressEnabled()) {
+            try {
+                String url = IP_URL + ip;
+                String rspStr = HttpUtil.get(url);
+                log.info("ip is {}, repStr is {}, url is {}", ip, rspStr, url);
+
+                // 检查响应是否为空或者503错误
+                if (Strings.isNullOrEmpty(rspStr) || rspStr.contains(SERVICE_UNAVAILABLE_HTML)) {
+                    log.error("获取地理位置异常 {}, {}", ip, rspStr);
+                    return UNKNOWN;
+                }
+                // 假设返回的字符串是直接的地理位置信息
+                return rspStr.trim();
+            } catch (Exception e) {
+                log.error("获取地理位置异常 {}", ip, e);
+            }
+        }
+        return UNKNOWN;
+    }
+}
+*/
+
+public class AddressUtils {
+    private static final Logger log = LoggerFactory.getLogger(AddressUtils.class);
+
+    // 腾讯地图API URL
+    public static String IP_URL = "https://apis.map.qq.com/ws/location/v1/ip";
+    public static String API_KEY = "TSIBZ-NZSCU-H5SVQ-GUBLG-G6HFH-7LFSZ";
+
+    // 未知地址
+    public static final String UNKNOWN = "获取地理位置异常";
+
+    public static String getRealAddressByIP(String ip) {
+        // 内网不查询
+        if (IpUtils.internalIp(ip)) {
+            return "内网IP";
+        }
+        // 检查地址服务是否启用
+        if (WjConfig.isAddressEnabled()) {
+            try {
+                // 构建请求URL
+                String url = String.format("%s?ip=%s&key=%s", IP_URL, ip, API_KEY);
+                String rspStr = HttpUtil.get(url); // 使用GET请求发送数据
+                log.info("ip is {}, repStr is {}", ip, rspStr);
+
+                // 检查响应是否为空
+                if (rspStr == null || rspStr.isEmpty()) {
+                    log.error("获取地理位置异常 {}", ip);
+                    return UNKNOWN;
+                }
+
+                // 解析JSON响应
+                JSONObject jsonObject = new JSONObject(rspStr);
+                if (jsonObject.getInt("status") != 0) {
+                    log.error("获取地理位置失败: {}", jsonObject.getString("message"));
+                    return UNKNOWN;
+                }
+
+                // 提取地址信息
+                JSONObject adInfo = jsonObject.getJSONObject("result").getJSONObject("ad_info");
+                String nation = adInfo.getString("nation");
+                String province = adInfo.getString("province");
+                String city = adInfo.getString("city");
+                String district = adInfo.optString("district", "");
+
+                return String.format("%s%s%s%s", nation, province, city, district).trim();
+            } catch (JSONException e) {
+                log.error("JSON 解析异常", e);
+                return UNKNOWN;
+            } catch (Exception e) {
+                log.error("获取地理位置异常 {}", ip, e);
+                return UNKNOWN;
+            }
+        }
+        return UNKNOWN;
+    }
+}

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

@@ -0,0 +1,82 @@
+package com.usky.system.service.util;
+
+
+import com.alibaba.fastjson.JSON;
+import com.ruoyi.common.core.constant.Constants;
+import com.ruoyi.common.core.utils.ServletUtils;
+import com.ruoyi.common.core.utils.StringUtils;
+import com.ruoyi.common.core.utils.ip.IpUtils;
+import com.usky.common.core.util.SpringContextUtils;
+import com.usky.system.domain.SysLogininfor;
+import com.usky.system.service.ISysLogininforService;
+import eu.bitwalker.useragentutils.UserAgent;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * @description: 异步工厂(产生任务用)
+ * @author: XiaoYu
+ * @date: 2024/08/20 13:58
+ */
+public class AsyncFactory
+{
+    private static final Logger sys_user_logger = LoggerFactory.getLogger("sys-user");
+
+    /**
+     * 记录登录信息
+     *
+     * @param username 用户名
+     * @param status 状态
+     * @param message 消息
+     * @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);
+        StringBuilder s = new StringBuilder();
+        s.append(getBlock(ip));
+        s.append(address);
+        s.append(getBlock(username));
+        s.append(getBlock(status));
+        s.append(getBlock(message));
+        // 打印信息到日志
+        sys_user_logger.info(s.toString(), args);
+        // 获取客户端操作系统
+        String os = userAgent.getOperatingSystem().getName();
+        // 获取客户端浏览器
+        String browser = userAgent.getBrowser().getName();
+        // 封装对象
+        SysLogininfor logininfor = new SysLogininfor();
+        logininfor.setUserName(username);
+        logininfor.setIpaddr(ip);
+        logininfor.setLoginLocation(address);
+        logininfor.setBrowser(browser);
+        logininfor.setOs(os);
+        logininfor.setMsg(message);
+        logininfor.setCreateBy(username);
+        logininfor.setTenantId(tenantId);
+        logininfor.setDeptId(deptId);
+        // 日志状态
+        if (StringUtils.equalsAny(status, Constants.LOGIN_SUCCESS, Constants.LOGOUT, Constants.REGISTER)) {
+            logininfor.setStatus(String.valueOf(Constants.LOGIN_SUCCESS_STATUS)); // 使用String.valueOf进行转换
+        } else if (Constants.LOGIN_FAIL.equals(status)) {
+            logininfor.setStatus(String.valueOf(Constants.LOGIN_FAIL_STATUS)); // 使用String.valueOf进行转换
+        }
+        sys_user_logger.info("log is {}", JSON.toJSONString(logininfor));
+        // 插入数据
+        SpringContextUtils.getBean(ISysLogininforService.class).insertLogininfor(logininfor);
+    }
+
+    public static String getBlock(Object msg)
+    {
+        if (msg == null)
+        {
+            msg = "";
+        }
+        return "[" + msg.toString() + "]";
+    }
+}

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

@@ -0,0 +1,62 @@
+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 java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * @description: 异步任务管理器
+ * @author: XiaoYu
+ * @date: 2024/08/20 13:58
+ */
+@Component
+public class AsyncManager {
+
+    private static final Logger logger = LoggerFactory.getLogger(AsyncManager.class);
+
+    private static final ThreadPoolExecutor executorEvent = new ThreadPoolExecutor(
+            20, 30, 0L, TimeUnit.MILLISECONDS,
+            new ArrayBlockingQueue<>(1024),
+            new ThreadPoolExecutor.AbortPolicy()
+    );
+
+    @PreDestroy
+    public void shutdown() {
+        executorEvent.shutdown();
+        try {
+            if (!executorEvent.awaitTermination(60, TimeUnit.SECONDS)) {
+                executorEvent.shutdownNow();
+            }
+        } catch (InterruptedException ex) {
+            executorEvent.shutdownNow();
+            Thread.currentThread().interrupt();
+        }
+    }
+
+    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,无法记录登录信息");
+        }
+    }
+}
+

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

@@ -31,6 +31,11 @@ public class PlatformMenuVo implements Serializable {
      */
     private String platformName;
 
+    /**
+     * 平台名称
+     */
+    private String icon;
+
     /**
      * 菜单ID
      */

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

@@ -0,0 +1,41 @@
+package com.usky.system.service.vo;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import java.util.List;
+
+/**
+ * <p>
+ * 租户和应用关联表
+ * </p>
+ *
+ * @author han
+ * @since 2024-09-02
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+public class PlatformRouterVo {
+    private static final long serialVersionUID=1L;
+
+    /**
+     * 应用ID
+     */
+    private Integer platformId;
+
+    /**
+     * 应用名称
+     */
+    private String platformName;
+
+    /**
+     * 应用图标
+     */
+    private String icon;
+
+    /**
+     * 路由集合
+     */
+    private List<RouterVo> RouterVos;
+}

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

@@ -40,6 +40,10 @@ public class SysLoginExportVO {
     @Excel(name = "用户名称")
     private String userName;
 
+    /** 组织机构 */
+    @Excel(name = "组织机构")
+    private String deptName;
+
     /** 登录状态 0成功 1失败 */
     @Excel(name = "登录状态")
     private String status;
@@ -51,4 +55,16 @@ public class SysLoginExportVO {
     /** 访问时间 */
     @Excel(name = "访问时间")
     private LocalDateTime accessTime;
+
+    /** 登陆地点 */
+    @Excel(name = "登陆地点")
+    private String loginLocation;
+
+    /** 浏览器类型 */
+    @Excel(name = "浏览器类型")
+    private String browser;
+
+    /** 操作系统 */
+    @Excel(name = "操作系统")
+    private String os;
 }

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

@@ -59,4 +59,20 @@ public class SysOperLogExportVO {
     /** 操作时间 */
     @Excel(name = "操作时间")
     private LocalDateTime operTime;
+
+    /** 执行开始时间 */
+    @Excel(name = "执行开始时间")
+    private LocalDateTime startTime;
+
+    /** 执行结束时间 */
+    @Excel(name = "执行结束时间")
+    private LocalDateTime endTime;
+
+    /** 执行耗时时间 */
+    @Excel(name = "执行耗时时间")
+    private Long consumingTime;
+
+    /** 执行耗时时间(单位:毫秒) */
+    @Excel(name = "执行耗时时间(带单位)")
+    private String consumingTimeWithUnit;
 }

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

@@ -46,6 +46,11 @@ public class SysPlatformVo implements Serializable {
      */
     private String remark;
 
+    /**
+     * 应用图标
+     */
+    private String icon;
+
     /**
      * 创建者
      */

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

@@ -0,0 +1,43 @@
+package com.usky.system.service.vo;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import lombok.Data;
+
+/**
+ *
+ * @author fu
+ * @date 2024/8/23
+ */
+@Data
+public class SysUserNewVO {
+    /** 用户ID */
+    private Long userId;
+
+    /** 部门ID */
+    private Long deptId;
+
+    /** 用户账号 */
+    private String userName;
+
+    /** 用户昵称 */
+    private String nickName;
+
+    /** 用户邮箱 */
+    private String email;
+
+    /** 手机号码 */
+    private String phonenumber;
+
+    /** 用户性别 */
+    private String sex;
+
+    /** 用户头像 */
+    private String avatar;
+
+    /** 地址 */
+    private String address;
+
+    /** 岗位 */
+    @TableField(exist = false)
+    private String post;
+}

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

@@ -0,0 +1,47 @@
+package com.usky.system.service.vo;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+/**
+ * <p>
+ * 租户和应用关联表
+ * </p>
+ *
+ * @author han
+ * @since 2024-08-14
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+public class TenantPlatformListVo implements Serializable {
+    private static final long serialVersionUID=1L;
+
+    /**
+     * 应用ID
+     */
+    private Integer platformId;
+
+    /**
+     * 应用名称
+     */
+    private String platformName;
+
+    /**
+     * 是否为选中状态
+     */
+    private Integer isSelected;
+
+    /**
+     * 应用图标
+     */
+    private String icon;
+
+    /**
+     * 是否为默认应用
+     */
+    private Integer isDefault;
+}

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

@@ -0,0 +1,39 @@
+package com.usky.system.service.vo;
+
+import com.usky.system.domain.SysMenu;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * <p>
+ * 租户、应用和菜单关联表
+ * </p>
+ *
+ * @author han
+ * @since 2024-08-16
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+public class TenantPlatformMenuVo implements Serializable {
+    private static final long serialVersionUID=1L;
+
+    /**
+     * 平台ID
+     */
+    private Integer id;
+
+    /**
+     * 平台名称
+     */
+    private String label;
+
+    /**
+     * 菜单列表
+     */
+    private List<TreeSelect> children;
+}

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

@@ -0,0 +1,38 @@
+package com.usky.system.service.vo;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+/**
+ * <p>
+ * 租户和应用关联表
+ * </p>
+ *
+ * @author han
+ * @since 2024-08-14
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+public class TenantPlatformVo implements Serializable {
+
+    private static final long serialVersionUID=1L;
+
+    /**
+     * 请求标识
+     */
+    private Integer requestId;
+
+    /**
+     * 租户ID
+     */
+    private Integer tenantId;
+
+    /**
+     * 应用ID
+     */
+    private Integer[] platformIds;
+}

+ 1 - 25
base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/vo/TreeNode.java

@@ -30,39 +30,15 @@ public class TreeNode implements Serializable {
      */
     private String label;
 
-//    /**
-//     * 用户头像
-//     */
-//    private String avatar;
-//
-//    /**
-//     * 用户职位
-//     */
-//    private String post;
-
     /**
      * 子节点
      */
-    @JsonInclude(JsonInclude.Include.NON_EMPTY)
+    //@JsonInclude(JsonInclude.Include.NON_EMPTY)
     private List<TreeNode> children;
 
     public TreeNode() {
     }
 
-    public TreeNode(Long id, String label, List<TreeNode> children) {
-        this.id = id;
-        this.label = label;
-        this.children = children;
-    }
-
-//    public TreeNode(SysUser user) {
-//        this.id = user.getUserId();
-//        this.label = user.getNickName();
-//        this.avatar = user.getAvatar();
-//        this.post = user.getPost();
-//        this.children = new ArrayList<>();
-//    }
-
     public TreeNode(SysDept dept) {
         this.id = dept.getDeptId();
         this.label = dept.getDeptName();

+ 20 - 5
base-modules/service-system/service-system-biz/src/main/java/com/usky/system/service/vo/UserTreeNode.java

@@ -1,10 +1,10 @@
 package com.usky.system.service.vo;
-import com.usky.system.domain.SysDeptVO;
+import com.fasterxml.jackson.annotation.JsonInclude;
 import com.usky.system.domain.SysUser;
 import lombok.Data;
 
 import java.util.ArrayList;
-import java.util.Date;
+import java.util.List;
 
 /**
  * @description:TODO
@@ -12,7 +12,21 @@ import java.util.Date;
  * @create: 2024-08-01 11:40
  */
 @Data
-public class UserTreeNode extends TreeNode {
+public class UserTreeNode extends TreeNode{
+
+    /**
+     * 节点ID
+     */
+    private Long id;
+
+    /**
+     * 节点名称
+     */
+    private String label;
+
+     /** 子节点 */
+    @JsonInclude(JsonInclude.Include.NON_EMPTY)
+    private List<TreeNode> children;
 
     /** 用户ID */
     private Long userId;
@@ -44,9 +58,9 @@ public class UserTreeNode extends TreeNode {
     /** 岗位 */
     private String post;
 
-
     public UserTreeNode(SysUser user) {
-        super(user.getUserId(), user.getNickName(), new ArrayList<>());
+        this.id = user.getUserId();
+        this.label = user.getNickName();
         this.userId = user.getUserId();
         this.deptId = user.getDeptId();
         this.userName = user.getUserName();
@@ -57,6 +71,7 @@ public class UserTreeNode extends TreeNode {
         this.avatar = user.getAvatar();
         this.address = user.getAddress();
         this.post = user.getPost();
+        this.children = new ArrayList<>();
     }
 }
 

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

@@ -58,6 +58,15 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 		</if>
 		order by d.parent_id, d.order_num
 	</select>
+
+	<select id="deptListByTenant" parameterType="com.usky.system.domain.SysDept" resultMap="SysDeptResult">
+		<include refid="selectDeptVo"/>
+		where d.del_flag = '0'
+		<if test="tenantId != null and tenantId != '' and tenantId != 0">
+			AND tenant_id = #{tenantId}
+		</if>
+		order by d.parent_id, d.order_num
+	</select>
     
     <select id="selectDeptListByRoleId" resultType="Integer">
 		select d.dept_id

+ 35 - 18
base-modules/service-system/service-system-biz/src/main/resources/mapper/system/SysLogininforMapper.xml

@@ -12,8 +12,12 @@
 		<result property="msg"           column="msg"               />
 		<result property="accessTime"    column="access_time"       />
 		<result property="deptId"        column="dept_id"           />
+		<result property="deptName"      column="dept_name"         />
 		<result property="tenantId"      column="tenant_id"         />
 		<result property="createBy"      column="create_by"         />
+		<result property="loginLocation"    column="login_location"       />
+		<result property="browser"    column="browser"       />
+		<result property="os"    column="os"       />
 	</resultMap>
 
 	<insert id="insertLogininfor" parameterType="com.usky.system.domain.SysLogininfor">
@@ -27,6 +31,9 @@
 			<if test="deptId != null"> dept_id, </if>
 			<if test="tenantId != null"> tenant_id, </if>
 			<if test="createBy != null"> create_by, </if>
+			<if test="loginLocation != null"> login_location, </if>
+			<if test="browser != null"> browser, </if>
+			<if test="os != null"> os, </if>
 		</trim>
 		values
 		<trim prefix="(" suffix=")" suffixOverrides=",">
@@ -38,60 +45,70 @@
 			<if test="deptId != null"> #{deptId},</if>
 			<if test="tenantId != null"> #{tenantId},</if>
 			<if test="createBy != null"> #{createBy},</if>
+			<if test="loginLocation != null"> #{loginLocation},</if>
+			<if test="browser != null"> #{browser},</if>
+			<if test="os != null"> #{os},</if>
 		</trim>
 	</insert>
 
 	<select id="selectLogininforList" parameterType="com.usky.system.domain.SysLogininfor" resultMap="SysLogininforResult">
-		select info_id, user_name, ipaddr, status, msg, access_time from sys_logininfor d
+		select d.info_id, d.user_name, d.ipaddr, d.status, d.msg, d.access_time, d.login_location, d.browser, d.os, sd.dept_name
+		from sys_logininfor d
+		left join sys_dept sd on d.dept_id = sd.dept_id
 		<where>
 			<if test="ipaddr != null and ipaddr != ''">
-				AND ipaddr like concat('%', #{ipaddr}, '%')
+				AND d.ipaddr like concat('%', #{ipaddr}, '%')
 			</if>
 			<if test="status != null and status != ''">
-				AND status = #{status}
+				AND d.status = #{status}
 			</if>
 			<if test="userName != null and userName != ''">
-				AND user_name like concat('%', #{userName}, '%')
+				AND d.user_name like concat('%', #{userName}, '%')
 			</if>
 			<if test="params.beginTime != null and params.beginTime != ''"><!-- 开始时间检索 -->
-				and date_format(access_time,'%y%m%d') &gt;= date_format(#{params.beginTime},'%y%m%d')
+				and date_format(d.access_time,'%y%m%d') >= date_format(#{params.beginTime},'%y%m%d')
 			</if>
 			<if test="params.endTime != null and params.endTime != ''"><!-- 结束时间检索 -->
-				and date_format(access_time,'%y%m%d') &lt;= date_format(#{params.endTime},'%y%m%d')
+				and date_format(d.access_time,'%y%m%d') &lt;= date_format(#{params.endTime},'%y%m%d')
 			</if>
 			<if test="1 == 1">
-				and tenant_id = #{tenantId}
+				and d.tenant_id = #{tenantId}
 			</if>
 			<!-- 数据范围过滤 -->
 			${params.dataScope}
 		</where>
-		order by info_id desc
+		order by d.info_id desc
 	</select>
 
 	<select id="selectLogininforListExport" parameterType="com.usky.system.domain.SysLogininfor" resultType="com.usky.system.service.vo.SysLoginExportVO">
-		select info_id, ipaddr, user_name, (case status when '0' then '成功' else '失败' end) as status, msg, access_time from sys_logininfor d
+		select d.info_id, d.ipaddr, d.user_name,
+		(case when d.status = '0' then '成功' else '失败' end) as status,
+		d.msg, d.access_time, d.login_location, d.browser, d.os,
+		sd.dept_name
+		from sys_logininfor d
+		left join sys_dept sd on d.dept_id = sd.dept_id
 		<where>
 			<if test="ipaddr != null and ipaddr != ''">
-				AND ipaddr like concat('%', #{ipaddr}, '%')
+				AND d.ipaddr like concat('%', #{ipaddr}, '%')
 			</if>
 			<if test="status != null and status != ''">
-				AND status = #{status}
+				AND d.status = #{status}
 			</if>
 			<if test="userName != null and userName != ''">
-				AND user_name like concat('%', #{userName}, '%')
+				AND d.user_name like concat('%', #{userName}, '%')
 			</if>
 			<if test="params.beginTime != null and params.beginTime != ''"><!-- 开始时间检索 -->
-				and date_format(access_time,'%y%m%d') &gt;= date_format(#{params.beginTime},'%y%m%d')
+				and date_format(d.access_time,'%y%m%d') >= date_format(#{params.beginTime},'%y%m%d')
 			</if>
 			<if test="params.endTime != null and params.endTime != ''"><!-- 结束时间检索 -->
-				and date_format(access_time,'%y%m%d') &lt;= date_format(#{params.endTime},'%y%m%d')
+				and date_format(d.access_time,'%y%m%d') &lt;= date_format(#{params.endTime},'%y%m%d')
 			</if>
 			<if test="1 == 1">
-				and tenant_id = #{tenantId}
+				and d.tenant_id = #{tenantId}
 			</if>
 			${params.dataScope}
 		</where>
-		order by info_id desc
+		order by d.info_id desc
 	</select>
 
 	<delete id="deleteLogininforByIds" parameterType="Long">
@@ -102,7 +119,7 @@
 	</delete>
 
 	<update id="cleanLogininfor">
-        truncate table sys_logininfor
-    </update>
+	truncate table sys_logininfor
+	</update>
 
 </mapper>

+ 80 - 0
base-modules/service-system/service-system-biz/src/main/resources/mapper/system/SysMenuMapper.xml

@@ -204,6 +204,39 @@
         order by m.parent_id, m.order_num
     </select>
 
+    <select id="selectMenuTreeByUserId1" parameterType="Long" resultMap="SysMenuResult">
+        select distinct m.menu_id,
+                        m.parent_id,
+                        m.menu_name,
+                        rm.menu_alias_name,
+                        m.path,
+                        m.component,
+                        m.visible,
+                        m.status,
+                        ifnull(m.perms, '') as perms,
+                        m.is_frame,
+                        m.is_cache,
+                        m.menu_type,
+                        m.icon,
+                        m.order_num,
+                        m.create_time,
+                        m.remark,
+                        m.isNew
+        from sys_menu m
+                 left join sys_platform_menu pm ON m.menu_id = pm.menu_id
+                 left join sys_role_menu rm on pm.menu_id = rm.menu_id
+                 left join sys_user_role ur on rm.role_id = ur.role_id
+                 left join sys_role ro on ur.role_id = ro.role_id
+                 left join sys_user u on u.user_id = ur.user_id
+                 left join sys_tenant_menu t on u.tenant_id = t.tenant_id
+        where u.user_id = #{userId}
+          and m.menu_type in ('M', 'C')
+          and m.status = 0
+          AND ro.status = 0
+          AND pm.platform_id=#{platformId}
+        order by m.parent_id, m.order_num
+    </select>
+
     <select id="selectMenuTreeByUserIdOne" resultMap="SysMenuResult">
         SELECT
             m.menu_id,
@@ -236,6 +269,39 @@
             m.order_num
     </select>
 
+    <select id="selectMenuTreeByUserIdOne1" resultMap="SysMenuResult">
+        SELECT
+            m.menu_id,
+            m.parent_id,
+            m.menu_name,
+            t.menu_alias_name,
+            m.path,
+            m.component,
+            m.visible,
+            m. STATUS,
+            ifnull(m.perms, '') AS perms,
+            m.is_frame,
+            m.is_cache,
+            m.menu_type,
+            m.icon,
+            m.order_num,
+            m.create_time,
+            m.remark,
+            m.isNew
+        FROM
+            sys_menu m
+                JOIN sys_tenant_menu t on m.menu_id = t.menu_id
+                JOIN sys_platform_menu p on t.menu_id = p.menu_id
+        WHERE
+          m.menu_type IN ('M', 'C')
+          AND m. STATUS = 0
+          AND t.tenant_id=#{tenantId}
+          AND p.platform_id=#{platformId}
+        ORDER BY
+            m.parent_id,
+            m.order_num
+    </select>
+
     <select id="selectMenuListByRoleId" resultType="Integer">
         select m.menu_id
         from sys_menu m
@@ -377,4 +443,18 @@
         order_num
     </select>
 
+    <select id="getTenantPlatformMenuList" resultType="com.usky.system.domain.SysMenu">
+        SELECT
+        	m.*
+        FROM
+        	sys_menu m
+        LEFT JOIN sys_tenant_menu tm ON m.menu_id = tm.menu_id
+        LEFT JOIN sys_platform_menu pm ON tm.menu_id = pm.menu_id
+        WHERE
+        	tm.tenant_id = #{tenantId}
+        AND pm.platform_id = #{platformId}
+        GROUP BY
+        	m.menu_id;
+    </select>
+
 </mapper> 

+ 15 - 3
base-modules/service-system/service-system-biz/src/main/resources/mapper/system/SysOperLogMapper.xml

@@ -24,11 +24,15 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 		<result property="deptId"         column="dept_id"        />
 		<result property="tenantId"       column="tenant_id"      />
 		<result property="createBy"       column="create_by"      />
+		<result property="startTime"     column="start_time"    />
+		<result property="endTime"       column="end_time"      />
+		<result property="consumingTime"   column="consuming_time" />
+		<result property="consumingTimeWithUnit"     column="consuming_time_with_unit"    />
 	</resultMap>
 
 	<sql id="selectOperLogVo">
-        select oper_id, title, business_type, method, request_method, operator_type, oper_name, dept_name, oper_url, oper_ip, oper_location, oper_param, json_result, status, error_msg, oper_time
-        from sys_oper_log d
+		select oper_id, title, business_type, method, request_method, operator_type, oper_name, dept_name, oper_url, oper_ip, oper_location, oper_param, json_result, status, error_msg, oper_time, start_time, end_time, consuming_time, consuming_time_with_unit
+		from sys_oper_log d
     </sql>
     
 	<insert id="insertOperlog" parameterType="com.usky.system.domain.SysOperLog">
@@ -52,6 +56,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 			<if test="deptId != null"> dept_id, </if>
 			<if test="tenantId != null"> tenant_id, </if>
 			<if test="createBy != null"> create_by, </if>
+			<if test="startTime != null"> start_time, </if>
+			<if test="endTime != null"> end_time, </if>
+			<if test="consumingTime != null"> consuming_time, </if>
+			<if test="consumingTimeWithUnit !=null"> consuming_time_with_unit, </if>
 		</trim>
 		values
 		<trim prefix="(" suffix=")" suffixOverrides=",">
@@ -73,6 +81,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 			<if test="deptId != null"> #{deptId},</if>
 			<if test="tenantId != null"> #{tenantId},</if>
 			<if test="createBy != null"> #{createBy},</if>
+			<if test="startTime != null"> #{startTime},</if>
+		    <if test="endTime != null"> #{endTime},</if>
+			<if test="consumingTime != null"> #{consumingTime},</if>
+		    <if test="consumingTimeWithUnit !=null"> #{consumingTimeWithUnit},</if>
 		</trim>
 	</insert>
 	
@@ -113,7 +125,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 	</select>
 
 	<select id="selectOperLogListExport" parameterType="com.usky.system.domain.SysOperLog" resultType="com.usky.system.service.vo.SysOperLogExportVO">
-		SELECT oper_id, oper_ip, oper_name, title, (CASE business_type WHEN '0' THEN '其它' WHEN '1' THEN '新增' WHEN '2' THEN '修改' ELSE '删除' END) AS businessType, request_method, (CASE STATUS WHEN '0' THEN '成功' ELSE '失败' END) AS STATUS, oper_time
+		SELECT oper_id, oper_ip, oper_name, title, (CASE business_type WHEN '0' THEN '其它' WHEN '1' THEN '新增' WHEN '2' THEN '修改' ELSE '删除' END) AS businessType, request_method, (CASE STATUS WHEN '0' THEN '成功' ELSE '失败' END) AS STATUS, oper_time, start_time, end_time, consuming_time, consuming_time_with_unit
 		FROM sys_oper_log d
 		<where>
 			<if test="title != null and title != ''">

+ 28 - 0
base-modules/service-system/service-system-biz/src/main/resources/mapper/system/SysPlatformMapper.xml

@@ -8,6 +8,7 @@
         <result column="platform_name" property="platformName" />
         <result column="status" property="status" />
         <result column="remark" property="remark" />
+        <result column="icon" property="icon" />
         <result column="create_by" property="createBy" />
         <result column="create_time" property="createTime" />
         <result column="update_by" property="updateBy" />
@@ -94,4 +95,31 @@
         </if>
     </select>
 
+    <select id="getRolePlatformList" resultType="com.usky.system.service.vo.SysPlatformVo">
+        SELECT
+        p.*
+        FROM
+        sys_platform p
+        LEFT JOIN sys_tenant_platform tp ON p.id=tp.platform_id
+        LEFT JOIN sys_platform_menu pm ON tp.platform_id=pm.platform_id
+        LEFT JOIN sys_role_menu rm ON pm.menu_id = rm.menu_id
+        WHERE
+        tp.tenant_id = #{tenantId}
+        AND rm.role_id = #{roleId}
+        GROUP BY
+        p.id
+    </select>
+
+    <select id="getTenantPlatformList" resultType="com.usky.system.service.vo.SysPlatformVo">
+        SELECT
+        p.*
+        FROM
+        sys_platform p
+        LEFT JOIN sys_tenant_platform tp ON p.id=tp.platform_id
+        WHERE
+        tp.tenant_id = #{tenantId}
+        GROUP BY
+        p.id
+    </select>
+
 </mapper>

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

@@ -29,6 +29,7 @@
         <result column="cloud_type" property="cloudType"/>
         <result column="cloud_url" property="cloudUrl"/>
         <result column="message_status" property="messageStatus"/>
+        <result column="middle_type" property="middleType"/>
     </resultMap>
     <select id="getTenantConfig" resultType="com.usky.system.service.vo.SysTenantConfigVo">
         SELECT

+ 16 - 0
base-modules/service-system/service-system-biz/src/main/resources/mapper/system/SysTenantPlatformMapper.xml

@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.usky.system.mapper.SysTenantPlatformMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.usky.system.domain.SysTenantPlatform">
+        <id column="tenant_id" property="tenantId" />
+        <result column="platform_id" property="platformId" />
+        <result column="is_default" property="isDefault" />
+    </resultMap>
+
+    <select id="checkPlatformUnique" resultType="int">
+        select count(1) from sys_tenant_platform where platform_id = #{platformId} limit 1
+    </select>
+
+</mapper>

+ 26 - 2
base-modules/service-system/service-system-biz/src/main/resources/mapper/system/SysUserMapper.xml

@@ -61,7 +61,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     </sql>
     
     <select id="selectUserList" parameterType="com.usky.system.domain.SysUser" resultMap="SysUserResult">
-		select u.user_id, u.dept_id, u.nick_name, u.user_name, u.email, u.avatar, u.phonenumber, u.password, u.sex, u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark, d.dept_name, d.leader from sys_user u
+		select u.user_id, u.dept_id, u.nick_name, u.user_name, u.email, u.avatar, u.phonenumber, u.password, u.sex,
+		u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark, d.dept_name, d.leader
+		from sys_user_tenant ut
+		left join sys_user u on ut.user_id = u.user_id
 		left join sys_dept d on u.dept_id = d.dept_id
 		where u.del_flag = '0'
 		<if test="userName != null and userName != ''">
@@ -74,7 +77,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 			AND u.status = #{status}
 		</if>
 		<if test="tenantId != null and tenantId != '' and tenantId !=0">
-			AND u.tenant_id = #{tenantId}
+			AND ut.tenant_id = #{tenantId}
 		</if>
 		<if test="userType != null and userType != ''">
 			AND u.user_type = #{userType}
@@ -180,6 +183,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 	<select id="checkEmailUnique" parameterType="String" resultMap="SysUserResult">
 		select user_id, email from sys_user where email = #{email} and del_flag = '2' limit 1
 	</select>
+
+	<select id="checkEmailUnique1" resultType="int">
+		select count(1) from sys_user where email = #{email} and del_flag != '2'
+		<if test="tenantId != null and tenantId != 0">
+			and tenant_id = #{tenantId}
+		</if>
+		limit 1
+	</select>
 	
 	<insert id="insertUser" parameterType="com.usky.system.domain.SysUser" useGeneratedKeys="true" keyProperty="userId">
  		insert into sys_user(
@@ -365,4 +376,17 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 		</set>
 		where user_id = #{userId}
 	</update>
+
+	<select id="selectUserTenantData" resultMap="SysUserResult">
+        SELECT u.* FROM sys_user_tenant ut
+        JOIN sys_user u ON ut.user_id = u.user_id
+        WHERE u.user_name = #{userName}
+    </select>
+
+	<select id="selectUserTenantDataOne" resultMap="SysUserResult">
+        SELECT u.* FROM sys_user_tenant ut
+        JOIN sys_user u ON ut.user_id = u.user_id
+        WHERE ut.tenant_id = #{tenantId} AND
+        u.phonenumber = #{phone}
+    </select>
 </mapper> 

+ 19 - 0
base-modules/service-system/service-system-biz/src/main/resources/mapper/system/SysUserTenantMapper.xml

@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.usky.system.mapper.SysUserTenantMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.usky.system.domain.SysUserTenant">
+        <id column="user_id" property="userId" />
+        <result column="tenant_id" property="tenantId" />
+        <result column="is_default" property="isDefault" />
+    </resultMap>
+
+    <select id="checkUserIdUnique" resultType="int">
+        select count(1) from sys_user_tenant where user_id = #{userId} and tenant_id = #{tenantId} limit 1
+    </select>
+
+    <delete id="deleteUserTenant">
+		delete from sys_user_tenant where user_id = #{userId} and tenant_id = #{tenantId}
+ 	</delete>
+</mapper>

+ 4 - 0
usky-common/usky-common-core/src/main/java/com/usky/common/core/bean/ApiResult.java

@@ -62,6 +62,10 @@ public class ApiResult<T> implements Serializable {
         return new ApiResult<>(null);
     }
 
+    public static <T> ApiResult<T> error(String message) {
+        return new ApiResult<>("9999", message);
+    }
+
     public static <T> ApiResult<T> error(String code, String message) {
         return new ApiResult<>(code, message);
     }

+ 58 - 75
usky-common/usky-common-log/src/main/java/com/usky/common/log/aspect/LogAspect.java

@@ -1,8 +1,10 @@
 package com.usky.common.log.aspect;//package com.ruoyi.common.log.aspect;
 
 import java.util.Collection;
+import java.util.Date;
 import java.util.Map;
 import java.util.Objects;
+import java.util.concurrent.TimeUnit;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
@@ -16,9 +18,8 @@ import com.usky.common.log.service.AsyncLogService;
 import com.usky.common.security.utils.SecurityUtils;
 import com.usky.system.domain.SysOperLogVO;
 import org.aspectj.lang.JoinPoint;
-import org.aspectj.lang.annotation.AfterReturning;
-import org.aspectj.lang.annotation.AfterThrowing;
-import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.*;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -34,56 +35,51 @@ import org.springframework.web.multipart.MultipartFile;
  */
 @Aspect
 @Component
-public class LogAspect
-{
+public class LogAspect {
     private static final Logger log = LoggerFactory.getLogger(LogAspect.class);
 
     @Autowired
     private AsyncLogService asyncLogService;
 
-    /**
-     * 处理完请求后执行
-     *
-     * @param joinPoint 切点
-     */
-    @AfterReturning(pointcut = "@annotation(controllerLog)", returning = "jsonResult")
-    public void doAfterReturning(JoinPoint joinPoint, Log controllerLog, Object jsonResult)
-    {
-        handleLog(joinPoint, controllerLog, null, jsonResult);
+    // 定义切入点,使用@annotation指示器
+    @Pointcut("@annotation(com.usky.common.log.annotation.Log)")
+    public void logPointcut() {
     }
 
-    /**
-     * 拦截异常操作
-     *
-     * @param joinPoint 切点
-     * @param e 异常
-     */
-    @AfterThrowing(value = "@annotation(controllerLog)", throwing = "e")
-    public void doAfterThrowing(JoinPoint joinPoint, Log controllerLog, Exception e)
-    {
-        handleLog(joinPoint, controllerLog, e, null);
+    // 环绕通知,引用切入点并传递注解实例
+    @Around("logPointcut() && @annotation(controllerLog)")
+    public Object aroundLog(ProceedingJoinPoint joinPoint, Log controllerLog) throws Throwable {
+        Date startTime = new Date();
+        Object result = null;
+        Exception exception = null;
+        try {
+            result = joinPoint.proceed();
+        } catch (Exception e) {
+            exception = e;
+            throw e;
+        } finally {
+            Date endTime = new Date();
+            long consumingTime = TimeUnit.MILLISECONDS.convert(endTime.getTime() - startTime.getTime(), TimeUnit.MILLISECONDS);
+            handleLog(joinPoint, controllerLog, exception, result, startTime, endTime, consumingTime);
+        }
+        return result;
     }
 
-    protected void handleLog(final JoinPoint joinPoint, Log controllerLog, final Exception e, Object jsonResult)
-    {
-        try
-        {
+    protected void handleLog(final JoinPoint joinPoint, Log controllerLog, final Exception e, Object jsonResult, Date startTime, Date endTime, long consumingTime) {
+        try {
             // *========数据库日志=========*//
             SysOperLogVO operLog = new SysOperLogVO();
-            operLog.setStatus(BusinessStatus.SUCCESS.ordinal());
+            operLog.setStatus(e == null ? BusinessStatus.SUCCESS.ordinal() : BusinessStatus.FAIL.ordinal());
             // 请求的地址
             String ip = IpUtils.getIpAddr(ServletUtils.getRequest());
             operLog.setOperIp(ip);
             operLog.setOperUrl(ServletUtils.getRequest().getRequestURI());
             String username = SecurityUtils.getUsername();
-            if (StringUtils.isNotBlank(username))
-            {
+            if (StringUtils.isNotBlank(username)) {
                 operLog.setOperName(username);
             }
 
-            if (e != null)
-            {
-                operLog.setStatus(BusinessStatus.FAIL.ordinal());
+            if (e != null) {
                 operLog.setErrorMsg(StringUtils.substring(e.getMessage(), 0, 2000));
             }
             // 设置方法名称
@@ -94,11 +90,18 @@ public class LogAspect
             operLog.setRequestMethod(ServletUtils.getRequest().getMethod());
             // 处理设置注解上的参数
             getControllerMethodDescription(joinPoint, controllerLog, operLog, jsonResult);
+            // 记录开始时间、结束时间与耗时
+            operLog.setStartTime(startTime);
+            operLog.setEndTime(endTime);
+
+            // 将耗时转换为带有单位"ms"的字符串
+            String consumingTimeWithUnit = consumingTime + "ms";
+            operLog.setConsumingTime(consumingTime); // 存储耗时
+            operLog.setConsumingTimeWithUnit(consumingTimeWithUnit); // 存储带有单位的字符串
+
             // 保存数据库
             asyncLogService.saveSysLog(operLog);
-        }
-        catch (Exception exp)
-        {
+        } catch (Exception exp) {
             // 记录本地异常日志
             log.error("==前置通知异常==");
             log.error("异常信息:{}", exp.getMessage());
@@ -113,8 +116,7 @@ public class LogAspect
      * @param operLog 操作日志
      * @throws Exception
      */
-    public void getControllerMethodDescription(JoinPoint joinPoint, Log log, SysOperLogVO operLog, Object jsonResult) throws Exception
-    {
+    public void getControllerMethodDescription(JoinPoint joinPoint, Log log, SysOperLogVO operLog, Object jsonResult) throws Exception {
         // 设置action动作
         operLog.setBusinessType(log.businessType().ordinal());
         // 设置标题
@@ -122,14 +124,12 @@ public class LogAspect
         // 设置操作人类别
         operLog.setOperatorType(log.operatorType().ordinal());
         // 是否需要保存request,参数和值
-        if (log.isSaveRequestData())
-        {
+        if (log.isSaveRequestData()) {
             // 获取参数的信息,传入到数据库中。
             setRequestValue(joinPoint, operLog);
         }
         // 是否需要保存response,参数和值
-        if (log.isSaveResponseData() && Objects.nonNull(jsonResult))
-        {
+        if (log.isSaveResponseData() && Objects.nonNull(jsonResult)) {
             operLog.setJsonResult(StringUtils.substring(JSON.toJSONString(jsonResult), 0, 2000));
         }
     }
@@ -140,11 +140,9 @@ public class LogAspect
      * @param operLog 操作日志
      * @throws Exception 异常
      */
-    private void setRequestValue(JoinPoint joinPoint, SysOperLogVO operLog) throws Exception
-    {
+    private void setRequestValue(JoinPoint joinPoint, SysOperLogVO operLog) throws Exception {
         String requestMethod = operLog.getRequestMethod();
-        if (HttpMethod.PUT.name().equals(requestMethod) || HttpMethod.POST.name().equals(requestMethod))
-        {
+        if (HttpMethod.PUT.name().equals(requestMethod) || HttpMethod.POST.name().equals(requestMethod)) {
             String params = argsArrayToString(joinPoint.getArgs());
             operLog.setOperParam(StringUtils.substring(params, 0, 2000));
         }
@@ -153,22 +151,15 @@ public class LogAspect
     /**
      * 参数拼装
      */
-    private String argsArrayToString(Object[] paramsArray)
-    {
+    private String argsArrayToString(Object[] paramsArray) {
         String params = "";
-        if (paramsArray != null && paramsArray.length > 0)
-        {
-            for (Object o : paramsArray)
-            {
-                if (Objects.nonNull(o) && !isFilterObject(o))
-                {
-                    try
-                    {
+        if (paramsArray != null && paramsArray.length > 0) {
+            for (Object o : paramsArray) {
+                if (Objects.nonNull(o) && !isFilterObject(o)) {
+                    try {
                         Object jsonObj = JSON.toJSON(o);
                         params += jsonObj.toString() + " ";
-                    }
-                    catch (Exception e)
-                    {
+                    } catch (Exception e) {
                     }
                 }
             }
@@ -183,26 +174,18 @@ public class LogAspect
      * @return 如果是需要过滤的对象,则返回true;否则返回false。
      */
     @SuppressWarnings("rawtypes")
-    public boolean isFilterObject(final Object o)
-    {
+    public boolean isFilterObject(final Object o) {
         Class<?> clazz = o.getClass();
-        if (clazz.isArray())
-        {
+        if (clazz.isArray()) {
             return clazz.getComponentType().isAssignableFrom(MultipartFile.class);
-        }
-        else if (Collection.class.isAssignableFrom(clazz))
-        {
+        } else if (Collection.class.isAssignableFrom(clazz)) {
             Collection collection = (Collection) o;
-            for (Object value : collection)
-            {
+            for (Object value : collection) {
                 return value instanceof MultipartFile;
             }
-        }
-        else if (Map.class.isAssignableFrom(clazz))
-        {
+        } else if (Map.class.isAssignableFrom(clazz)) {
             Map map = (Map) o;
-            for (Object value : map.entrySet())
-            {
+            for (Object value : map.entrySet()) {
                 Map.Entry entry = (Map.Entry) value;
                 return entry.getValue() instanceof MultipartFile;
             }
@@ -210,4 +193,4 @@ public class LogAspect
         return o instanceof MultipartFile || o instanceof HttpServletRequest || o instanceof HttpServletResponse
                 || o instanceof BindingResult;
     }
-}
+}

+ 6 - 0
usky-common/usky-common-log/src/main/java/com/usky/common/log/enums/BusinessType.java

@@ -56,4 +56,10 @@ public enum BusinessType
      * 清空数据
      */
     CLEAN,
+
+    /**
+     * 查询
+     */
+    SELECT,
+
 }

+ 3 - 1
usky-common/usky-common-log/src/main/java/com/usky/common/log/service/AsyncLogService.java

@@ -3,6 +3,7 @@ package com.usky.common.log.service;//package com.ruoyi.common.log.service;
 import com.usky.system.RemoteLogService;
 import com.usky.system.domain.SysOperLogVO;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
 
@@ -14,6 +15,7 @@ import org.springframework.stereotype.Service;
 @Service
 public class AsyncLogService
 {
+    @Qualifier("com.usky.system.RemoteLogService")
     @Autowired
     private RemoteLogService remoteLogService;
 
@@ -23,6 +25,6 @@ public class AsyncLogService
     @Async
     public void saveSysLog(SysOperLogVO sysOperLog)
     {
-        remoteLogService.saveLog(sysOperLog);
+        this.remoteLogService.saveLog(sysOperLog);
     }
 }

+ 17 - 4
usky-common/usky-common-security/src/main/java/com/usky/common/security/auth/AuthLogic.java

@@ -1,5 +1,6 @@
 package com.usky.common.security.auth;
 
+import com.usky.common.core.bean.ApiResult;
 import com.usky.common.core.util.SpringContextUtils;
 import com.usky.common.security.annotation.Logical;
 import com.usky.common.security.annotation.RequiresLogin;
@@ -13,9 +14,11 @@ import com.usky.common.security.utils.SecurityUtils;
 import com.usky.system.model.LoginUser;
 import org.springframework.util.PatternMatchUtils;
 import org.springframework.util.StringUtils;
+import org.springframework.web.bind.annotation.ExceptionHandler;
 
 import java.util.Collection;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Set;
 
 /**
@@ -109,14 +112,20 @@ public class AuthLogic
      * @param permission 权限字符串
      * @return 用户是否具备某权限
      */
-    public boolean hasPermi(String permission)
-    {
-        return hasPermi(getPermiList(), permission);
+    public boolean hasPermi(List<String> permissions, String permission) {
+        if (permissions == null || permission == null) {
+            return false;
+        }
+        return permissions.stream().anyMatch(p -> p.equals(permission));
+    }
+    @ExceptionHandler(NotPermissionException.class)
+    public ApiResult<Void> handleNotPermissionException(NotPermissionException ex) {
+        return ApiResult.error("您没有权限执行这个操作");
     }
 
     /**
      * 验证用户是否具备某权限, 如果验证未通过,则抛出异常: NotPermissionException
-     * 
+     *
      * @param permission 权限字符串
      * @return 用户是否具备某权限
      */
@@ -369,4 +378,8 @@ public class AuthLogic
         return roles.stream().filter(StringUtils::hasText)
                 .anyMatch(x -> SUPER_ADMIN.contains(x) || PatternMatchUtils.simpleMatch(x, role));
     }
+
+    public boolean hasPermi(String permission) {
+        return hasPermi(getPermiList(), permission);
+    }
 }

+ 2 - 2
usky-common/usky-common-security/src/main/java/com/usky/common/security/auth/AuthUtil.java

@@ -26,8 +26,8 @@ public class AuthUtil
 
     /**
      * 会话注销,根据指定Token
-     * 
-     * @param tokenValue 指定token
+     *
+     * @param token 指定token
      */
     public static void logoutByToken(String token,String openId)
     {