Browse Source

init program

杨思远 2 months ago
parent
commit
53a85f95e5
100 changed files with 3125 additions and 1751 deletions
  1. 102 0
      README.md
  2. 86 0
      bin/ry.sh
  3. 31 10
      pom.xml
  4. 41 0
      src/main/java/com/zhiyun/common/annotation/Log.java
  5. 24 0
      src/main/java/com/zhiyun/common/annotation/RepeatSubmit.java
  6. 18 0
      src/main/java/com/zhiyun/common/enums/BusinessStatus.java
  7. 53 0
      src/main/java/com/zhiyun/common/enums/BusinessType.java
  8. 0 25
      src/main/java/com/zhiyun/common/enums/DeviceTypeEnum.java
  9. 0 18
      src/main/java/com/zhiyun/common/enums/MenuSysType.java
  10. 23 0
      src/main/java/com/zhiyun/common/enums/OperatorType.java
  11. 40 0
      src/main/java/com/zhiyun/common/filter/RepeatableFilter.java
  12. 68 0
      src/main/java/com/zhiyun/common/filter/RepeatedlyRequestWrapper.java
  13. 19 8
      src/main/java/com/zhiyun/common/model/BaseBody.java
  14. 1 2
      src/main/java/com/zhiyun/common/model/TableResult.java
  15. 113 0
      src/main/java/com/zhiyun/common/utils/Arith.java
  16. 0 3
      src/main/java/com/zhiyun/common/utils/DatePatternUtil.java
  17. 119 0
      src/main/java/com/zhiyun/common/utils/EasyExcelDashboardUtils.java
  18. 0 76
      src/main/java/com/zhiyun/common/utils/HttpClientUtil.java
  19. 0 72
      src/main/java/com/zhiyun/common/utils/HttpUtil.java
  20. 0 151
      src/main/java/com/zhiyun/common/utils/RabbitMQApi.java
  21. 0 41
      src/main/java/com/zhiyun/common/utils/RandomCode.java
  22. 1 1
      src/main/java/com/zhiyun/common/utils/SecurityUtils.java
  23. 0 1
      src/main/java/com/zhiyun/common/utils/ServletUtils.java
  24. 30 0
      src/main/java/com/zhiyun/common/utils/file/ExcelDashboardUtil.java
  25. 1 1
      src/main/java/com/zhiyun/common/utils/file/ImageUtils.java
  26. 1 1
      src/main/java/com/zhiyun/common/utils/file/MimeTypeUtils.java
  27. 44 0
      src/main/java/com/zhiyun/common/utils/http/HttpHelper.java
  28. 1 1
      src/main/java/com/zhiyun/common/utils/ip/AddressUtils.java
  29. 107 0
      src/main/java/com/zhiyun/framework/RoleDataScope.java
  30. 0 36
      src/main/java/com/zhiyun/framework/UserDataScope.java
  31. 195 0
      src/main/java/com/zhiyun/framework/aspectj/LogAspect.java
  32. 27 0
      src/main/java/com/zhiyun/framework/config/FilterConfig.java
  33. 13 0
      src/main/java/com/zhiyun/framework/config/ResourcesConfig.java
  34. 1 1
      src/main/java/com/zhiyun/framework/config/captcha/CaptchaConfig.java
  35. 29 0
      src/main/java/com/zhiyun/framework/config/mqtt/MqttCallbackHandler.java
  36. 3 3
      src/main/java/com/zhiyun/framework/config/mqtt/MqttConfig.java
  37. 0 68
      src/main/java/com/zhiyun/framework/config/mqtt/MqttConstant.java
  38. 10 6
      src/main/java/com/zhiyun/framework/config/mqtt/MqttConsumerCfg.java
  39. 2 2
      src/main/java/com/zhiyun/framework/config/mqtt/MqttGateway.java
  40. 2 2
      src/main/java/com/zhiyun/framework/config/mqtt/MqttProducerCfg.java
  41. 43 0
      src/main/java/com/zhiyun/framework/interceptor/RepeatSubmitInterceptor.java
  42. 98 0
      src/main/java/com/zhiyun/framework/interceptor/impl/SameUrlDataInterceptor.java
  43. 54 0
      src/main/java/com/zhiyun/framework/manager/AsyncManager.java
  44. 34 0
      src/main/java/com/zhiyun/framework/manager/ShutdownManager.java
  45. 91 0
      src/main/java/com/zhiyun/framework/manager/factory/AsyncFactory.java
  46. 24 0
      src/main/java/com/zhiyun/framework/security/context/PermissionContextHolder.java
  47. 5 0
      src/main/java/com/zhiyun/framework/security/filter/JwtAuthenticationTokenFilter.java
  48. 6 0
      src/main/java/com/zhiyun/framework/security/handle/ZyLogoutSuccessHandler.java
  49. 108 4
      src/main/java/com/zhiyun/framework/web/PermissionService.java
  50. 37 16
      src/main/java/com/zhiyun/framework/web/SysPermissionService.java
  51. 35 3
      src/main/java/com/zhiyun/framework/web/UserDetailsServiceImpl.java
  52. 1 1
      src/main/java/com/zhiyun/project/common/BaseController.java
  53. 2 5
      src/main/java/com/zhiyun/project/common/CaptchaController.java
  54. 27 0
      src/main/java/com/zhiyun/project/item/domain/dto/Perm.java
  55. 11 9
      src/main/java/com/zhiyun/project/monitor/controller/CacheController.java
  56. 25 0
      src/main/java/com/zhiyun/project/monitor/controller/ServerController.java
  57. 61 0
      src/main/java/com/zhiyun/project/monitor/controller/SysLoginInfoController.java
  58. 48 0
      src/main/java/com/zhiyun/project/monitor/controller/SysOperlogController.java
  59. 75 0
      src/main/java/com/zhiyun/project/monitor/controller/SysUserOnlineController.java
  60. 211 0
      src/main/java/com/zhiyun/project/monitor/domain/Server.java
  61. 58 0
      src/main/java/com/zhiyun/project/monitor/domain/SysLoginInfo.java
  62. 86 0
      src/main/java/com/zhiyun/project/monitor/domain/SysOperLog.java
  63. 51 0
      src/main/java/com/zhiyun/project/monitor/domain/SysUserOnline.java
  64. 88 0
      src/main/java/com/zhiyun/project/monitor/domain/server/Cpu.java
  65. 115 0
      src/main/java/com/zhiyun/project/monitor/domain/server/Jvm.java
  66. 54 0
      src/main/java/com/zhiyun/project/monitor/domain/server/Mem.java
  67. 73 0
      src/main/java/com/zhiyun/project/monitor/domain/server/Sys.java
  68. 99 0
      src/main/java/com/zhiyun/project/monitor/domain/server/SysFile.java
  69. 28 0
      src/main/java/com/zhiyun/project/monitor/mapper/SysLoginInfoMapper.java
  70. 26 0
      src/main/java/com/zhiyun/project/monitor/mapper/SysOperLogMapper.java
  71. 26 0
      src/main/java/com/zhiyun/project/monitor/service/ISysLoginInfoService.java
  72. 26 0
      src/main/java/com/zhiyun/project/monitor/service/ISysOperLogService.java
  73. 47 0
      src/main/java/com/zhiyun/project/monitor/service/ISysUserOnlineService.java
  74. 31 0
      src/main/java/com/zhiyun/project/monitor/service/impl/SysLoginInfoServiceImpl.java
  75. 30 0
      src/main/java/com/zhiyun/project/monitor/service/impl/SysOperLogServiceImpl.java
  76. 86 0
      src/main/java/com/zhiyun/project/monitor/service/impl/SysUserOnlineServiceImpl.java
  77. 0 33
      src/main/java/com/zhiyun/project/project/controller/CommandController.java
  78. 0 69
      src/main/java/com/zhiyun/project/project/controller/CompanyController.java
  79. 0 90
      src/main/java/com/zhiyun/project/project/controller/DeviceController.java
  80. 0 47
      src/main/java/com/zhiyun/project/project/controller/HomeController.java
  81. 0 45
      src/main/java/com/zhiyun/project/project/controller/LogController.java
  82. 0 28
      src/main/java/com/zhiyun/project/project/controller/MQTTController.java
  83. 0 92
      src/main/java/com/zhiyun/project/project/controller/ProjectController.java
  84. 0 18
      src/main/java/com/zhiyun/project/project/domain/body/DeviceBody.java
  85. 0 10
      src/main/java/com/zhiyun/project/project/domain/body/LogBody.java
  86. 0 27
      src/main/java/com/zhiyun/project/project/domain/body/MqttBody.java
  87. 0 18
      src/main/java/com/zhiyun/project/project/domain/body/ProjectBody.java
  88. 0 114
      src/main/java/com/zhiyun/project/project/domain/dto/MqttDTO.java
  89. 0 29
      src/main/java/com/zhiyun/project/project/domain/dto/Perm.java
  90. 0 47
      src/main/java/com/zhiyun/project/project/domain/entity/Command.java
  91. 0 39
      src/main/java/com/zhiyun/project/project/domain/entity/Company.java
  92. 0 70
      src/main/java/com/zhiyun/project/project/domain/entity/Device.java
  93. 0 76
      src/main/java/com/zhiyun/project/project/domain/entity/DeviceState.java
  94. 0 80
      src/main/java/com/zhiyun/project/project/domain/entity/MqttLog.java
  95. 0 48
      src/main/java/com/zhiyun/project/project/domain/entity/Project.java
  96. 0 91
      src/main/java/com/zhiyun/project/project/domain/vo/DeviceVo.java
  97. 0 21
      src/main/java/com/zhiyun/project/project/domain/vo/SelectOptionsVo.java
  98. 0 13
      src/main/java/com/zhiyun/project/project/mapper/CommandMapper.java
  99. 0 19
      src/main/java/com/zhiyun/project/project/mapper/CompanyMapper.java
  100. 0 60
      src/main/java/com/zhiyun/project/project/mapper/DeviceMapper.java

File diff suppressed because it is too large
+ 102 - 0
README.md


+ 86 - 0
bin/ry.sh

@@ -0,0 +1,86 @@
+#!/bin/sh
+# ./ry.sh start 启动 stop 停止 restart 重启 status 状态
+AppName=target/ruoyi.jar
+
+# JVM参数
+JVM_OPTS="-Dname=$AppName  -Duser.timezone=Asia/Shanghai -Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError -XX:+PrintGCDateStamps  -XX:+PrintGCDetails -XX:NewRatio=1 -XX:SurvivorRatio=30 -XX:+UseParallelGC -XX:+UseParallelOldGC"
+APP_HOME=`pwd`
+LOG_PATH=$APP_HOME/logs/$AppName.log
+
+if [ "$1" = "" ];
+then
+    echo -e "\033[0;31m 未输入操作名 \033[0m  \033[0;34m {start|stop|restart|status} \033[0m"
+    exit 1
+fi
+
+if [ "$AppName" = "" ];
+then
+    echo -e "\033[0;31m 未输入应用名 \033[0m"
+    exit 1
+fi
+
+function start()
+{
+    PID=`ps -ef |grep java|grep $AppName|grep -v grep|awk '{print $2}'`
+
+	if [ x"$PID" != x"" ]; then
+	    echo "$AppName is running..."
+	else
+		nohup java $JVM_OPTS -jar $AppName > /dev/null 2>&1 &
+		echo "Start $AppName success..."
+	fi
+}
+
+function stop()
+{
+    echo "Stop $AppName"
+
+	PID=""
+	query(){
+		PID=`ps -ef |grep java|grep $AppName|grep -v grep|awk '{print $2}'`
+	}
+
+	query
+	if [ x"$PID" != x"" ]; then
+		kill -TERM $PID
+		echo "$AppName (pid:$PID) exiting..."
+		while [ x"$PID" != x"" ]
+		do
+			sleep 1
+			query
+		done
+		echo "$AppName exited."
+	else
+		echo "$AppName already stopped."
+	fi
+}
+
+function restart()
+{
+    stop
+    sleep 2
+    start
+}
+
+function status()
+{
+    PID=`ps -ef |grep java|grep $AppName|grep -v grep|wc -l`
+    if [ $PID != 0 ];then
+        echo "$AppName is running..."
+    else
+        echo "$AppName is not running..."
+    fi
+}
+
+case $1 in
+    start)
+    start;;
+    stop)
+    stop;;
+    restart)
+    restart;;
+    status)
+    status;;
+    *)
+
+esac

+ 31 - 10
pom.xml

@@ -45,6 +45,12 @@
             <artifactId>spring-boot-starter</artifactId>
         </dependency>
 
+        <!-- SpringBoot 前后端一体化打包 -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-thymeleaf</artifactId>
+        </dependency>
+
         <!-- SpringBoot 测试 -->
         <dependency>
             <groupId>org.springframework.boot</groupId>
@@ -112,6 +118,31 @@
             <artifactId>mysql-connector-java</artifactId>
         </dependency>
 
+        <!--MQTT-->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-integration</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.integration</groupId>
+            <artifactId>spring-integration-stream</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.integration</groupId>
+            <artifactId>spring-integration-mqtt</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>com.microsoft.sqlserver</groupId>
+            <artifactId>sqljdbc4</artifactId>
+            <version>4.0</version>
+        </dependency>
+
+        <dependency>
+            <groupId>cn.easyproject</groupId>
+            <artifactId>orai18n</artifactId>
+            <version>12.1.0.2.0</version>
+        </dependency>
 
         <!-- Token生成与解析-->
         <dependency>
@@ -252,16 +283,6 @@
             <version>0.10.4</version>
         </dependency>
 
-        <dependency>
-            <groupId>org.apache.httpcomponents</groupId>
-            <artifactId>httpclient</artifactId>
-        </dependency>
-
-        <!-- mqtt -->
-        <dependency>
-            <groupId>org.springframework.integration</groupId>
-            <artifactId>spring-integration-mqtt</artifactId>
-        </dependency>
     </dependencies>
 
     <repositories>

+ 41 - 0
src/main/java/com/zhiyun/common/annotation/Log.java

@@ -0,0 +1,41 @@
+package com.zhiyun.common.annotation;
+
+import com.zhiyun.common.enums.BusinessType;
+import com.zhiyun.common.enums.OperatorType;
+
+import java.lang.annotation.*;
+
+/**
+ * 自定义操作日志记录注解
+ *
+ * @author ruoyi
+ */
+@Target({ElementType.PARAMETER, ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface Log {
+    /**
+     * 模块
+     */
+    String title() default "";
+
+    /**
+     * 功能
+     */
+    BusinessType businessType() default BusinessType.OTHER;
+
+    /**
+     * 操作人类别
+     */
+    OperatorType operatorType() default OperatorType.MANAGE;
+
+    /**
+     * 是否保存请求的参数
+     */
+    boolean isSaveRequestData() default true;
+
+    /**
+     * 是否保存响应的参数
+     */
+    boolean isSaveResponseData() default true;
+}

+ 24 - 0
src/main/java/com/zhiyun/common/annotation/RepeatSubmit.java

@@ -0,0 +1,24 @@
+package com.zhiyun.common.annotation;
+
+import java.lang.annotation.*;
+
+/**
+ * 自定义注解防止表单重复提交
+ *
+ * @author ruoyi
+ */
+@Inherited
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface RepeatSubmit {
+    /**
+     * 间隔时间(ms),小于此时间视为重复提交
+     */
+    int interval() default 5000;
+
+    /**
+     * 提示消息
+     */
+    String message() default "不允许重复提交,请稍候再试";
+}

+ 18 - 0
src/main/java/com/zhiyun/common/enums/BusinessStatus.java

@@ -0,0 +1,18 @@
+package com.zhiyun.common.enums;
+
+/**
+ * 操作状态
+ *
+ * @author ruoyi
+ */
+public enum BusinessStatus {
+    /**
+     * 成功
+     */
+    SUCCESS,
+
+    /**
+     * 失败
+     */
+    FAIL,
+}

+ 53 - 0
src/main/java/com/zhiyun/common/enums/BusinessType.java

@@ -0,0 +1,53 @@
+package com.zhiyun.common.enums;
+
+/**
+ * 业务操作类型
+ *
+ * @author ruoyi
+ */
+public enum BusinessType {
+    /**
+     * 其它
+     */
+    OTHER,
+
+    /**
+     * 新增
+     */
+    INSERT,
+
+    /**
+     * 修改
+     */
+    UPDATE,
+
+    /**
+     * 删除
+     */
+    DELETE,
+
+    /**
+     * 授权
+     */
+    GRANT,
+
+    /**
+     * 导出
+     */
+    EXPORT,
+
+    /**
+     * 导入
+     */
+    IMPORT,
+
+    /**
+     * 强退
+     */
+    FORCE,
+
+    /**
+     * 清空数据
+     */
+    CLEAN,
+}

+ 0 - 25
src/main/java/com/zhiyun/common/enums/DeviceTypeEnum.java

@@ -1,25 +0,0 @@
-package com.zhiyun.common.enums;
-
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-
-/**
- * 业务操作类型
- *
- * @author ruoyi
- */
-@Getter
-@AllArgsConstructor
-public enum DeviceTypeEnum {
-    /**
-     * 其它
-     */
-    GNSS("L1_GP"),
-    RAIN("L3_YL"),
-    WATER("L4_NW"),
-    DEEP("L1_NB"),
-    TRACK("L1_LF");
-
-    private final String type;
-
-}

+ 0 - 18
src/main/java/com/zhiyun/common/enums/MenuSysType.java

@@ -1,18 +0,0 @@
-package com.zhiyun.common.enums;
-
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-
-/**
- * @author yxk
- * @since 2024/9/23 14:11
- */
-@Getter
-@AllArgsConstructor
-public enum MenuSysType {
-    ADMIN("admin"),
-    COMMON("comn"),
-    PROJECT("pjt");
-    private final String value;
-
-}

+ 23 - 0
src/main/java/com/zhiyun/common/enums/OperatorType.java

@@ -0,0 +1,23 @@
+package com.zhiyun.common.enums;
+
+/**
+ * 操作人类别
+ *
+ * @author ruoyi
+ */
+public enum OperatorType {
+    /**
+     * 其它
+     */
+    OTHER,
+
+    /**
+     * 后台用户
+     */
+    MANAGE,
+
+    /**
+     * 手机端用户
+     */
+    MOBILE
+}

+ 40 - 0
src/main/java/com/zhiyun/common/filter/RepeatableFilter.java

@@ -0,0 +1,40 @@
+package com.zhiyun.common.filter;
+
+import com.zhiyun.common.utils.StringUtils;
+import org.springframework.http.MediaType;
+
+import javax.servlet.*;
+import javax.servlet.http.HttpServletRequest;
+import java.io.IOException;
+
+/**
+ * Repeatable 过滤器
+ *
+ * @author ruoyi
+ */
+public class RepeatableFilter implements Filter {
+    @Override
+    public void init(FilterConfig filterConfig) {
+
+    }
+
+    @Override
+    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
+            throws IOException, ServletException {
+        ServletRequest requestWrapper = null;
+        if (request instanceof HttpServletRequest
+                && StringUtils.startsWithIgnoreCase(request.getContentType(), MediaType.APPLICATION_JSON_VALUE)) {
+            requestWrapper = new RepeatedlyRequestWrapper((HttpServletRequest) request, response);
+        }
+        if (null == requestWrapper) {
+            chain.doFilter(request, response);
+        } else {
+            chain.doFilter(requestWrapper, response);
+        }
+    }
+
+    @Override
+    public void destroy() {
+
+    }
+}

+ 68 - 0
src/main/java/com/zhiyun/common/filter/RepeatedlyRequestWrapper.java

@@ -0,0 +1,68 @@
+package com.zhiyun.common.filter;
+
+import com.zhiyun.common.constant.Constants;
+import com.zhiyun.common.utils.http.HttpHelper;
+
+import javax.servlet.ReadListener;
+import javax.servlet.ServletInputStream;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+
+/**
+ * 构建可重复读取inputStream的request
+ *
+ * @author ruoyi
+ */
+public class RepeatedlyRequestWrapper extends HttpServletRequestWrapper {
+    private final byte[] body;
+
+    public RepeatedlyRequestWrapper(HttpServletRequest request, ServletResponse response) throws IOException {
+        super(request);
+        request.setCharacterEncoding(Constants.UTF8);
+        response.setCharacterEncoding(Constants.UTF8);
+
+        body = HttpHelper.getBodyString(request).getBytes(StandardCharsets.UTF_8);
+    }
+
+    @Override
+    public BufferedReader getReader() throws IOException {
+        return new BufferedReader(new InputStreamReader(getInputStream()));
+    }
+
+    @Override
+    public ServletInputStream getInputStream() {
+        final ByteArrayInputStream bais = new ByteArrayInputStream(body);
+        return new ServletInputStream() {
+            @Override
+            public int read() {
+                return bais.read();
+            }
+
+            @Override
+            public int available() {
+                return body.length;
+            }
+
+            @Override
+            public boolean isFinished() {
+                return false;
+            }
+
+            @Override
+            public boolean isReady() {
+                return false;
+            }
+
+            @Override
+            public void setReadListener(ReadListener readListener) {
+
+            }
+        };
+    }
+}

+ 19 - 8
src/main/java/com/zhiyun/common/model/BaseBody.java

@@ -3,8 +3,10 @@ package com.zhiyun.common.model;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.zhiyun.common.utils.StringUtils;
 import com.zhiyun.common.utils.sql.SqlUtil;
+import com.zhiyun.framework.RoleDataScope;
 import lombok.Data;
 
+import java.util.Map;
 
 /**
  * 分页数据
@@ -19,15 +21,20 @@ public class BaseBody {
      */
     private Long userId;
 
+    /**
+     * 数据权限
+     */
+    private Map<String, String> dataScope;
+
     /**
      * 当前记录起始索引
      */
-    private Integer pageNum = 1;
+    private Integer pageNum;
 
     /**
      * 每页显示记录数
      */
-    private Integer pageSize = 10;
+    private Integer pageSize;
 
     /**
      * 排序列
@@ -56,17 +63,21 @@ public class BaseBody {
         }
     }
 
+    /**
+     * 获取SQL中用户过滤条件
+     * 如果是管理员,则返回空,配合<if test></if> 标签
+     */
+    public Long getPremUserId() {
+        if (RoleDataScope.isAdmin(userId)) {
+            return null;
+        }
+        return userId;
+    }
 
     public <T> Page<T> getPage() {
         return new Page<>(pageNum, pageSize);
     }
 
-    public <T> Page<T> getPageNoOptimize() {
-        Page<T> result = new Page<T>(pageNum, pageSize);
-        result.setOptimizeCountSql(false);
-        return result;
-    }
-
     public <T> Page<T> getNotPage() {
         return new Page<>(0, -1);
     }

+ 1 - 2
src/main/java/com/zhiyun/common/model/TableResult.java

@@ -1,6 +1,5 @@
 package com.zhiyun.common.model;
 
-import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import lombok.Data;
 import lombok.NoArgsConstructor;
@@ -48,7 +47,7 @@ public class TableResult implements Serializable {
         this.total = total;
     }
 
-    public static TableResult getTableResult(IPage<?> page) {
+    public static TableResult getTableResult(Page<?> page) {
         return new TableResult(page.getRecords(), page.getTotal());
     }
 

+ 113 - 0
src/main/java/com/zhiyun/common/utils/Arith.java

@@ -0,0 +1,113 @@
+package com.zhiyun.common.utils;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+
+/**
+ * 精确的浮点数运算
+ *
+ * @author ruoyi
+ */
+public class Arith {
+
+    /**
+     * 默认除法运算精度
+     */
+    private static final int DEF_DIV_SCALE = 10;
+
+    /**
+     * 这个类不能实例化
+     */
+    private Arith() {
+    }
+
+    /**
+     * 提供精确的加法运算。
+     *
+     * @param v1 被加数
+     * @param v2 加数
+     * @return 两个参数的和
+     */
+    public static double add(double v1, double v2) {
+        BigDecimal b1 = new BigDecimal(Double.toString(v1));
+        BigDecimal b2 = new BigDecimal(Double.toString(v2));
+        return b1.add(b2).doubleValue();
+    }
+
+    /**
+     * 提供精确的减法运算。
+     *
+     * @param v1 被减数
+     * @param v2 减数
+     * @return 两个参数的差
+     */
+    public static double sub(double v1, double v2) {
+        BigDecimal b1 = new BigDecimal(Double.toString(v1));
+        BigDecimal b2 = new BigDecimal(Double.toString(v2));
+        return b1.subtract(b2).doubleValue();
+    }
+
+    /**
+     * 提供精确的乘法运算。
+     *
+     * @param v1 被乘数
+     * @param v2 乘数
+     * @return 两个参数的积
+     */
+    public static double mul(double v1, double v2) {
+        BigDecimal b1 = new BigDecimal(Double.toString(v1));
+        BigDecimal b2 = new BigDecimal(Double.toString(v2));
+        return b1.multiply(b2).doubleValue();
+    }
+
+    /**
+     * 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到
+     * 小数点以后10位,以后的数字四舍五入。
+     *
+     * @param v1 被除数
+     * @param v2 除数
+     * @return 两个参数的商
+     */
+    public static double div(double v1, double v2) {
+        return div(v1, v2, DEF_DIV_SCALE);
+    }
+
+    /**
+     * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指
+     * 定精度,以后的数字四舍五入。
+     *
+     * @param v1    被除数
+     * @param v2    除数
+     * @param scale 表示表示需要精确到小数点以后几位。
+     * @return 两个参数的商
+     */
+    public static double div(double v1, double v2, int scale) {
+        if (scale < 0) {
+            throw new IllegalArgumentException(
+                    "The scale must be a positive integer or zero");
+        }
+        BigDecimal b1 = new BigDecimal(Double.toString(v1));
+        BigDecimal b2 = new BigDecimal(Double.toString(v2));
+        if (b1.compareTo(BigDecimal.ZERO) == 0) {
+            return BigDecimal.ZERO.doubleValue();
+        }
+        return b1.divide(b2, scale, RoundingMode.HALF_UP).doubleValue();
+    }
+
+    /**
+     * 提供精确的小数位四舍五入处理。
+     *
+     * @param v     需要四舍五入的数字
+     * @param scale 小数点后保留几位
+     * @return 四舍五入后的结果
+     */
+    public static double round(double v, int scale) {
+        if (scale < 0) {
+            throw new IllegalArgumentException(
+                    "The scale must be a positive integer or zero");
+        }
+        BigDecimal b = new BigDecimal(Double.toString(v));
+        BigDecimal one = BigDecimal.ONE;
+        return b.divide(one, scale, RoundingMode.HALF_UP).doubleValue();
+    }
+}

+ 0 - 3
src/main/java/com/zhiyun/common/utils/DatePatternUtil.java

@@ -22,9 +22,6 @@ public class DatePatternUtil {
     public static final String NORM_DATETIME_PATTERN = "yyyy-MM-dd HH:mm:ss";
     public static final DateTimeFormatter NORM_DATETIME_FORMATTER = DateTimeFormatter.ofPattern(NORM_DATETIME_PATTERN);
 
-    public static final String NORM_DATETIME_PATTERN_2 = "yyyy-M-dd HH:mm:ss";
-    public static final DateTimeFormatter NORM_DATETIME_FORMATTER_2 = DateTimeFormatter.ofPattern(NORM_DATETIME_PATTERN_2);
-
     public static final String NORM_DATETIME_MINUTE_PATTERN = "yyyy-MM-dd HH:mm";
     public static final DateTimeFormatter NORM_DATETIME_MINUTE_FORMATTER = DateTimeFormatter.ofPattern(NORM_DATETIME_MINUTE_PATTERN);
 

+ 119 - 0
src/main/java/com/zhiyun/common/utils/EasyExcelDashboardUtils.java

@@ -0,0 +1,119 @@
+package com.zhiyun.common.utils;
+
+import com.alibaba.excel.EasyExcel;
+import com.alibaba.excel.ExcelWriter;
+import com.alibaba.excel.metadata.Head;
+import com.alibaba.excel.metadata.data.WriteCellData;
+import com.alibaba.excel.write.metadata.WriteSheet;
+import com.alibaba.excel.write.metadata.WriteTable;
+import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
+import com.alibaba.excel.write.metadata.style.WriteCellStyle;
+import com.alibaba.excel.write.metadata.style.WriteFont;
+import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
+import com.alibaba.excel.write.style.column.AbstractColumnWidthStyleStrategy;
+import com.alibaba.excel.write.style.column.SimpleColumnWidthStyleStrategy;
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.poi.ss.usermodel.*;
+
+import javax.servlet.http.HttpServletResponse;
+import java.net.URLEncoder;
+import java.util.List;
+
+/**
+ * @author yxk
+ * @since 2024/4/3 22:39
+ */
+@Slf4j
+public class EasyExcelDashboardUtils {
+
+
+    public static AbstractColumnWidthStyleStrategy getColumnWidthStrategy(int size) {
+        return new AbstractColumnWidthStyleStrategy() {
+            @Override
+            protected void setColumnWidth(WriteSheetHolder writeSheetHolder, List<WriteCellData<?>> cellDataList, Cell cell, Head head, Integer integer, Boolean isHead) {
+                boolean needSetWidth = isHead || !CollectionUtils.isEmpty(cellDataList);
+                if (needSetWidth) {
+                    Sheet sheet = writeSheetHolder.getSheet();
+                    for (int i = 0; i < size; i++) {
+                        sheet.setColumnWidth(i + 2, 3000);
+                    }
+                }
+            }
+        };
+    }
+
+
+    /**
+     * 导出Excel
+     */
+    public static void export(String fileName, List<List<String>> head, List<List<Object>> content, HttpServletResponse response) {
+        try {
+            fileName = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20");
+            response.setCharacterEncoding("utf-8");
+            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
+            ExcelWriter writer = EasyExcel.write(response.getOutputStream()).registerWriteHandler(new SimpleColumnWidthStyleStrategy(15)).registerWriteHandler(EasyExcelDashboardUtils.getCellStyleStrategy()).build();
+            // 动态添加表头,适用一些表头动态变化的场景
+            WriteSheet sheet = new WriteSheet();
+            sheet.setSheetName("数据");
+            // 创建一个表格,用于 Sheet 中使用
+            WriteTable table = new WriteTable();
+            table.setHead(head);
+            // 写数据
+            writer.write(content, sheet, table);
+            writer.finish();
+        } catch (Exception e) {
+            log.error("导出{}异常:", fileName, e);
+        }
+
+    }
+
+    /**
+     * 样式策略
+     */
+    public static HorizontalCellStyleStrategy getCellStyleStrategy() {
+        return new HorizontalCellStyleStrategy(headStyle(), contentStyle());
+    }
+
+    /**
+     * 标题样式
+     */
+    private static WriteCellStyle headStyle() {
+        // 头的策略
+        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
+        //字体
+        WriteFont writeFont = new WriteFont();
+        // 加粗
+        writeFont.setBold(false);
+        //字体
+        writeFont.setFontName("黑体");
+        headWriteCellStyle.setWriteFont(writeFont);
+        // 背景色
+        headWriteCellStyle.setFillForegroundColor(IndexedColors.WHITE1.getIndex());
+        return headWriteCellStyle;
+    }
+
+    /**
+     * 内容样式
+     */
+    private static WriteCellStyle contentStyle() {
+        // 内容的策略
+        WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
+        // 字体策略
+        WriteFont writeFont = new WriteFont();
+        writeFont.setFontName("黑体");
+        writeFont.setFontHeightInPoints((short) 12);
+        contentWriteCellStyle.setWriteFont(writeFont);
+        //导出数据垂直居中
+        contentWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
+        //导出数据水平居中
+        contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
+        //边框
+        contentWriteCellStyle.setBorderLeft(BorderStyle.THIN);
+        contentWriteCellStyle.setBorderTop(BorderStyle.THIN);
+        contentWriteCellStyle.setBorderRight(BorderStyle.THIN);
+        contentWriteCellStyle.setBorderBottom(BorderStyle.THIN);
+        return contentWriteCellStyle;
+    }
+
+}

+ 0 - 76
src/main/java/com/zhiyun/common/utils/HttpClientUtil.java

@@ -1,76 +0,0 @@
-package com.zhiyun.common.utils;
-
-import com.alibaba.fastjson2.JSON;
-import org.apache.http.HttpEntity;
-import org.apache.http.client.entity.UrlEncodedFormEntity;
-import org.apache.http.client.methods.CloseableHttpResponse;
-import org.apache.http.client.methods.HttpPost;
-import org.apache.http.entity.ContentType;
-import org.apache.http.entity.StringEntity;
-import org.apache.http.impl.client.CloseableHttpClient;
-import org.apache.http.impl.client.HttpClients;
-import org.apache.http.message.BasicNameValuePair;
-import org.apache.http.util.EntityUtils;
-
-import java.io.IOException;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
-
-/**
- * @author yxk
- * @since 2024/10/31 9:57
- */
-public class HttpClientUtil {
-    /**
-     * http post 请求
-     */
-    public static String doPost(String url, Map<String, Object> params, Map<String, String> headers) {
-        String result = null;
-        CloseableHttpClient httpClient = HttpClients.createDefault();
-        CloseableHttpResponse response = null;
-        try {
-            //2. 创建post请求
-            HttpPost httpPost = new HttpPost(url);
-
-            //4.设置请求头
-            for (String head : headers.keySet()) {
-                httpPost.addHeader(head, headers.get(head));
-            }
-            //3.请求参数
-            if (headers.containsKey("Content-type") && headers.get("Content-type").equals("application/json")) {
-                httpPost.setEntity(new StringEntity(JSON.toJSONString(params), ContentType.APPLICATION_JSON));
-            } else {
-                List<BasicNameValuePair> paramsList = params.keySet().stream().map(key -> new BasicNameValuePair(key, params.get(key).toString())).collect(Collectors.toList());
-                httpPost.setEntity(new UrlEncodedFormEntity(paramsList, "UTF-8"));
-            }
-            response = httpClient.execute(httpPost);
-            //7. 转换成实体类
-            HttpEntity entity = response.getEntity();
-            if (null != entity) {
-                result = EntityUtils.toString(entity, "UTF-8");
-            }
-            EntityUtils.consume(entity);
-        } catch (Exception e) {
-            e.printStackTrace();
-        } finally {
-            //8. 关闭所有资源连接
-            if (null != response) {
-                try {
-                    response.close();
-                } catch (IOException e) {
-                    e.printStackTrace();
-                }
-            }
-            if (null != httpClient) {
-                try {
-                    httpClient.close();
-                } catch (IOException e) {
-                    e.printStackTrace();
-                }
-            }
-        }
-        return result;
-    }
-
-}

+ 0 - 72
src/main/java/com/zhiyun/common/utils/HttpUtil.java

@@ -1,72 +0,0 @@
-package com.zhiyun.common.utils;
-
-import org.springframework.http.*;
-import org.springframework.util.MultiValueMap;
-import org.springframework.web.client.RestTemplate;
-
-import java.net.URI;
-import java.util.Map;
-
-/**
- * Http 工具类
- *
- * @author chenyi
- * date create on 2019/4/21
- */
-public class HttpUtil {
-
-    private static final RestTemplate restTemplate = new RestTemplate();
-
-    /**
-     * 发送 PUT 请求
-     *
-     * @param url 请求地址
-     */
-    public static String putForJSONEntity(String url, HttpHeaders header, String json) {
-        header.setContentType(MediaType.APPLICATION_JSON);
-        HttpEntity<String> httpEntity = new HttpEntity<>(json, header);
-        return restTemplate.exchange(URI.create(url), HttpMethod.PUT, httpEntity, String.class).getBody();
-    }
-
-    /**
-     * 发送 Get 请求
-     *
-     * @param url 请求地址
-     */
-    public static String getForEntity(String url, HttpHeaders header, Object... uriVariables) {
-        HttpEntity<String> httpEntity = new HttpEntity<>(header);
-        ResponseEntity<String> result = restTemplate.exchange(url, HttpMethod.GET, httpEntity, String.class, uriVariables);
-        return result.getBody();
-    }
-
-    /**
-     * 发送 Get 请求
-     *
-     * @param url          请求地址
-     * @param uriVariables 请求参数
-     */
-    public static String getForEntity(String url, Object... uriVariables) {
-        ResponseEntity<String> result = restTemplate.getForEntity(url, String.class, uriVariables);
-        return result.getBody();
-    }
-
-    /**
-     * 发送 POST 请求
-     * JSON 格式请求信息
-     *
-     * @param url    地址
-     * @param params 参数
-     */
-    public static String post(String url, Map<String, String> header, MultiValueMap<String, String> params) {
-        HttpHeaders headers = new HttpHeaders();
-        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
-        //设置请求头信息
-        if (header != null && !header.isEmpty()) {
-            for (Map.Entry<String, String> entry : header.entrySet()) {
-                headers.add(entry.getKey(), entry.getValue());
-            }
-        }
-        HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(params, headers);
-        return restTemplate.postForEntity(url, request, String.class).getBody();
-    }
-}

+ 0 - 151
src/main/java/com/zhiyun/common/utils/RabbitMQApi.java

@@ -1,151 +0,0 @@
-package com.zhiyun.common.utils;
-
-import com.alibaba.fastjson2.JSON;
-import com.alibaba.fastjson2.JSONArray;
-import com.alibaba.fastjson2.JSONObject;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.http.HttpHeaders;
-
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-
-/**
- * RabbitMQ HTTP API接口请求
- *
- * @author yang xiao kun
- * create on 2021/5/14
- */
-@Slf4j
-public class RabbitMQApi {
-    private final static String authorization = "Basic bHEyMDE5OkxpUXVhblJhYmJpdA==";
-
-    /**
-     * 向 MQTT 服务器申请用户,供设备进行登录
-     * <p>
-     * 因为存在先后问题,需要先注册用户,在开通虚拟机权限,
-     * 所以逻辑为
-     * 发送注册用户请求
-     * 尝试申请权限
-     * 如果失败,则间隔一秒再次请求
-     * 如果申请次数超过3次,则尝试重新注册
-     * 重新注册后再次尝试申请
-     * 如果申请五次都失败,则结束方法,记录日志
-     *
-     * @param username 设备登录ID
-     * @param password 设备登录密码
-     */
-    public static void register(String username, String password) {
-        addRabbitMqUser(username, password);
-        int count = 0;
-        while (!setPermission(username)) {
-            try {
-                Thread.sleep(1000);
-                if (count == 2) {
-                    addRabbitMqUser(username, password);
-                }
-                if (count > 4) {
-                    break;
-                }
-                count++;
-            } catch (InterruptedException e) {
-                log.error("向 MQTT 服务器申请用户失败", e);
-                break;
-            }
-        }
-    }
-
-    /**
-     * 注册 RabbitMQ 用户
-     *
-     * @param username 用户名
-     * @param password 用户密码
-     */
-    private static void addRabbitMqUser(String username, String password) {
-        String url = "http://view.ailishi.org:15672/api/users/" + username;
-        //请求头
-        HttpHeaders headers = new HttpHeaders();
-        headers.add("authorization", authorization);
-        //请求参数
-        Map<String, String> params = new HashMap<>();
-        params.put("username", username);
-        params.put("password", password);
-        params.put("tags", "");
-        HttpUtil.putForJSONEntity(url, headers, JSON.toJSONString(params));
-    }
-
-    /**
-     * 申请虚拟机权限
-     *
-     * @param clientId 用户ID
-     */
-    private static boolean setPermission(String clientId) {
-        String url = "http://view.ailishi.org:15672/api/permissions/%2F/" + clientId;
-        //请求头
-        HttpHeaders headers = new HttpHeaders();
-        headers.add("authorization", authorization);
-        //请求参数
-        Map<String, String> params = new HashMap<>();
-        params.put("username", clientId);
-        params.put("vhost", "/");
-        params.put("configure", ".*");
-        params.put("write", ".*");
-        params.put("read", ".*");
-        try {
-            HttpUtil.putForJSONEntity(url, headers, JSON.toJSONString(params));
-        } catch (Exception e) {
-            return false;
-        }
-        return true;
-    }
-
-    /**
-     * 查询MQTT服务器链接状态
-     */
-    public static List<String> connections() {
-        String url = "http://view.ailishi.org:15672/api/connections";
-        List<String> result = new LinkedList<>();
-        HttpHeaders headers = new HttpHeaders();
-        headers.add("authorization", authorization);
-        try {
-            String response = HttpUtil.getForEntity(url, headers);
-            //返回结果不为空
-            if (!response.equals("")) {
-                JSONArray jsonArray = JSON.parseArray(response);
-                for (int i = 0; i < jsonArray.size(); i++) {
-                    JSONObject jsonObject = jsonArray.getJSONObject(i);
-                    result.add(jsonObject.getString("user"));
-                }
-            }
-        } catch (Exception e) {
-            log.error("查询MQTT服务器Connections错误", e);
-        }
-        return result;
-    }
-
-    /**
-     * 查询MQTT服务器注册的用户
-     */
-    public static List<String> users() {
-        String url = "http://view.ailishi.org:15672/api/users";
-        List<String> result = new LinkedList<>();
-        HttpHeaders headers = new HttpHeaders();
-        headers.add("authorization", authorization);
-        try {
-            String response = HttpUtil.getForEntity(url, headers);
-            //返回结果不为空
-            if (!response.equals("")) {
-                JSONArray jsonArray = JSON.parseArray(response);
-                for (int i = 0; i < jsonArray.size(); i++) {
-                    JSONObject jsonObject = jsonArray.getJSONObject(i);
-                    result.add(jsonObject.getString("name"));
-                }
-            }
-        } catch (Exception e) {
-            log.error("查询MQTT服务器users错误", e);
-        }
-        return result;
-    }
-
-}

+ 0 - 41
src/main/java/com/zhiyun/common/utils/RandomCode.java

@@ -1,41 +0,0 @@
-package com.zhiyun.common.utils;
-
-import java.util.UUID;
-
-/**
- * 生成随机码
- *
- * @author yang xiao kun
- * create on 2021/1/15
- */
-public class RandomCode {
-
-    private static final String[] codeChars = {
-            "0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
-            "a", "b", "c", "d", "e", "f", "g", "h", "i", "j",
-            "k", "l", "m", "n", "o", "p", "q", "r", "s", "t",
-            "u", "v", "w", "x", "y", "z", "A", "B", "C", "D",
-            "E", "F", "G", "H", "I", "J", "K", "L", "M", "N",
-            "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X",
-            "Y", "Z"};
-
-    /**
-     * 生成短八位UUID随机码
-     */
-    public static String UUID_8() {
-        StringBuilder stringBuilder = new StringBuilder();
-        String uuid = UUID.randomUUID().toString().replace("-", "");
-        for (int i = 0; i < 8; i++) {
-            stringBuilder.append(codeChars[Integer.parseInt(uuid.substring(i * 4, i * 4 + 4), 16) % 0x3E]);
-        }
-        return stringBuilder.toString();
-    }
-
-    /**
-     * 随机生成UUID
-     * 小写,去掉 '-'
-     */
-    public static String UUID() {
-        return UUID.randomUUID().toString().replace("-", "");
-    }
-}

+ 1 - 1
src/main/java/com/zhiyun/common/utils/SecurityUtils.java

@@ -16,7 +16,7 @@ public class SecurityUtils {
     /**
      * 用户ID
      **/
-    public static Integer getUserId() {
+    public static Long getUserId() {
         try {
             return getLoginUser().getUserId();
         } catch (Exception e) {

+ 0 - 1
src/main/java/com/zhiyun/common/utils/ServletUtils.java

@@ -9,7 +9,6 @@ import org.springframework.web.context.request.ServletRequestAttributes;
 import javax.servlet.ServletRequest;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
-import javax.servlet.http.HttpSession;
 import java.io.IOException;
 import java.io.UnsupportedEncodingException;
 import java.net.URLDecoder;

+ 30 - 0
src/main/java/com/zhiyun/common/utils/file/ExcelDashboardUtil.java

@@ -0,0 +1,30 @@
+package com.zhiyun.common.utils.file;
+
+import com.zhiyun.framework.config.ZySystemConfig;
+
+import java.io.File;
+import java.util.UUID;
+
+public class ExcelDashboardUtil {
+    /**
+     * 获取下载路径
+     *
+     * @param filename 文件名称
+     */
+    public static String getAbsoluteFile(String filename) {
+        String downloadPath = ZySystemConfig.getDownloadPath() + filename;
+        File desc = new File(downloadPath);
+        if (!desc.getParentFile().exists()) {
+            desc.getParentFile().mkdirs();
+        }
+        return downloadPath;
+    }
+
+    /**
+     * 编码文件名
+     */
+    public static String encodingFilename(String filename) {
+        filename = UUID.randomUUID() + "_" + filename + ".xlsx";
+        return filename;
+    }
+}

+ 1 - 1
src/main/java/com/zhiyun/common/utils/file/ImageUtils.java

@@ -1,8 +1,8 @@
 package com.zhiyun.common.utils.file;
 
-import com.zhiyun.framework.config.ZySystemConfig;
 import com.zhiyun.common.constant.Constants;
 import com.zhiyun.common.utils.StringUtils;
+import com.zhiyun.framework.config.ZySystemConfig;
 import org.apache.poi.util.IOUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;

+ 1 - 1
src/main/java/com/zhiyun/common/utils/file/MimeTypeUtils.java

@@ -27,7 +27,7 @@ public class MimeTypeUtils {
 
     public static final String[] DEFAULT_ALLOWED_EXTENSION = {
             // 图片
-            "bmp", "gif", "jpg", "jpeg", "png","webp",
+            "bmp", "gif", "jpg", "jpeg", "png", "webp",
             // word excel powerpoint
             "doc", "docx", "xls", "xlsx", "ppt", "pptx", "html", "htm", "txt",
             // 压缩文件

+ 44 - 0
src/main/java/com/zhiyun/common/utils/http/HttpHelper.java

@@ -0,0 +1,44 @@
+package com.zhiyun.common.utils.http;
+
+import org.apache.commons.lang3.exception.ExceptionUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.servlet.ServletRequest;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+
+/**
+ * 通用http工具封装
+ *
+ * @author ruoyi
+ */
+public class HttpHelper {
+    private static final Logger LOGGER = LoggerFactory.getLogger(HttpHelper.class);
+
+    public static String getBodyString(ServletRequest request) {
+        StringBuilder sb = new StringBuilder();
+        BufferedReader reader = null;
+        try (InputStream inputStream = request.getInputStream()) {
+            reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
+            String line = "";
+            while ((line = reader.readLine()) != null) {
+                sb.append(line);
+            }
+        } catch (IOException e) {
+            LOGGER.warn("getBodyString出现问题!");
+        } finally {
+            if (reader != null) {
+                try {
+                    reader.close();
+                } catch (IOException e) {
+                    LOGGER.error(ExceptionUtils.getMessage(e));
+                }
+            }
+        }
+        return sb.toString();
+    }
+}

+ 1 - 1
src/main/java/com/zhiyun/common/utils/ip/AddressUtils.java

@@ -2,10 +2,10 @@ package com.zhiyun.common.utils.ip;
 
 import com.alibaba.fastjson2.JSON;
 import com.alibaba.fastjson2.JSONObject;
-import com.zhiyun.framework.config.ZySystemConfig;
 import com.zhiyun.common.constant.Constants;
 import com.zhiyun.common.utils.StringUtils;
 import com.zhiyun.common.utils.http.HttpUtils;
+import com.zhiyun.framework.config.ZySystemConfig;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 

+ 107 - 0
src/main/java/com/zhiyun/framework/RoleDataScope.java

@@ -0,0 +1,107 @@
+package com.zhiyun.framework;
+
+import com.zhiyun.common.exception.UserException;
+import com.zhiyun.common.utils.SecurityUtils;
+import com.zhiyun.common.utils.StringUtils;
+import com.zhiyun.project.item.domain.dto.Perm;
+import com.zhiyun.project.system.domain.dto.LoginUser;
+import com.zhiyun.project.system.domain.entity.SysRole;
+
+/**
+ * 数据过滤处理
+ *
+ * @author ruoyi
+ */
+public class RoleDataScope {
+    /**
+     * 全部数据权限
+     */
+    private static final String DATA_SCOPE_ALL = "1";
+
+    /**
+     * 自定数据权限
+     */
+    private static final String DATA_SCOPE_CUSTOM = "2";
+
+    /**
+     * 部门数据权限
+     */
+    private static final String DATA_SCOPE_DEPT = "3";
+
+    /**
+     * 部门及以下数据权限
+     */
+    private static final String DATA_SCOPE_DEPT_AND_CHILD = "4";
+
+    public static Perm getDataScopePerm() {
+        Perm perm = new Perm();
+        LoginUser user = SecurityUtils.getLoginUser();
+        if (user == null) {
+            throw new UserException("获取当前登录用户信息失败");
+        }
+        // 如果是超级管理员,则不过滤数据
+        if (isAdmin(user.getUserId()) || user.getUserId() <= 100) return perm;
+
+        StringBuilder deptStr = new StringBuilder();
+        StringBuilder itemStr = new StringBuilder();
+        StringBuilder surveyStr = new StringBuilder();
+
+        for (SysRole role : user.getRoles()) {
+            //角色的数据权限
+            String dataScope = role.getDataScope();
+
+            //角色拥有全部数据权限
+            if (DATA_SCOPE_ALL.equals(dataScope)) {
+                return new Perm();
+            }
+            //角色拥有自定义权限
+            else if (DATA_SCOPE_CUSTOM.equals(dataScope)) {
+                deptStr.append(StringUtils.format("SELECT dept_id FROM sys_role_dept WHERE role_id = {} UNION ", role.getRoleId()));
+                itemStr.append(StringUtils.format("SELECT mine_id FROM sys_dept_mine WHERE dept_id IN (SELECT dept_id FROM sys_role_dept WHERE role_id = {}) UNION ", role.getRoleId()));
+                surveyStr.append(StringUtils.format("SELECT areagroup FROM survey_area WHERE mine_id IN (SELECT mine_id FROM sys_dept_mine WHERE dept_id IN (SELECT dept_id FROM sys_role_dept WHERE role_id = {})) UNION ", role.getRoleId()));
+            }
+
+            //部门权限
+            else if (DATA_SCOPE_DEPT.equals(dataScope)) {
+                deptStr.append(StringUtils.format("SELECT {} FROM DUAL UNION ", user.getDeptId()));
+                itemStr.append(StringUtils.format("SELECT mine_id FROM sys_dept_mine WHERE dept_id = {} UNION ", user.getDeptId()));
+                surveyStr.append(StringUtils.format("SELECT areagroup FROM survey_area WHERE mine_id IN (SELECT mine_id FROM sys_dept_mine WHERE dept_id = {}) UNION ", user.getDeptId()));
+            }
+
+            //部门及其子部门权限
+            else if (DATA_SCOPE_DEPT_AND_CHILD.equals(dataScope)) {
+                deptStr.append(StringUtils.format("SELECT dept_id FROM sys_dept WHERE dept_id = {} or find_in_set({},ancestors) UNION ", user.getDeptId(), user.getDeptId()));
+                itemStr.append(StringUtils.format("SELECT mine_id FROM sys_dept_mine WHERE dept_id IN (SELECT dept_id FROM sys_dept WHERE dept_id = {} or find_in_set({},ancestors)) UNION ", user.getDeptId(), user.getDeptId()));
+                surveyStr.append(StringUtils.format("SELECT areagroup FROM survey_area WHERE mine_id IN (SELECT mine_id FROM sys_dept_mine WHERE dept_id IN (SELECT dept_id FROM sys_dept WHERE dept_id = {} or find_in_set({},ancestors))) UNION ", user.getDeptId(), user.getDeptId()));
+            }
+        }
+        //部门
+        String deptScope = deptStr.toString();
+        if (StringUtils.isNotBlank(deptScope)) {
+            perm.setDept(deptScope.substring(0, deptScope.length() - 7));
+        }
+
+        //部门
+        String itemScope = itemStr.toString();
+        if (StringUtils.isNotBlank(deptScope)) {
+            perm.setItem(itemScope.substring(0, itemScope.length() - 7));
+        }
+
+        //测区
+        String surveyScope = surveyStr.toString();
+        if (StringUtils.isNotBlank(surveyScope)) {
+            perm.setSurvey(surveyScope.substring(0, surveyScope.length() - 7));
+        }
+
+        return perm;
+    }
+
+
+    public static boolean isAdmin(Long userId) {
+        return userId != null && userId == 1;
+    }
+
+    public static boolean isAdminRole(Long roleId) {
+        return roleId != null && roleId == 1;
+    }
+}

+ 0 - 36
src/main/java/com/zhiyun/framework/UserDataScope.java

@@ -1,36 +0,0 @@
-package com.zhiyun.framework;
-
-import com.zhiyun.common.exception.UserException;
-import com.zhiyun.common.utils.SecurityUtils;
-import com.zhiyun.common.utils.StringUtils;
-import com.zhiyun.project.project.domain.dto.Perm;
-import com.zhiyun.project.system.domain.dto.LoginUser;
-
-/**
- * 数据过滤处理
- *
- * @author ruoyi
- */
-public class UserDataScope {
-
-    public static Perm getDataScopePerm() {
-        Perm perm = new Perm();
-        LoginUser user = SecurityUtils.getLoginUser();
-        if (user == null) {
-            throw new UserException("获取当前登录用户信息失败");
-        }
-        if (user.getUserId() <= 100) {
-            perm.setProject("SELECT pjtid FROM project");
-        } else {
-            perm.setProject(StringUtils.format("SELECT pjtid FROM project WHERE cpyid = {}", user.getCpyid()));
-        }
-        perm.setUserId(user.getUserId());
-        return perm;
-    }
-
-
-    public static boolean isAdmin(Integer userId) {
-        return userId != null && userId <= 100;
-    }
-
-}

+ 195 - 0
src/main/java/com/zhiyun/framework/aspectj/LogAspect.java

@@ -0,0 +1,195 @@
+package com.zhiyun.framework.aspectj;
+
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.filter.SimplePropertyPreFilter;
+import com.google.common.collect.Lists;
+import com.zhiyun.common.annotation.Log;
+import com.zhiyun.common.enums.BusinessStatus;
+import com.zhiyun.common.enums.HttpMethod;
+import com.zhiyun.common.utils.SecurityUtils;
+import com.zhiyun.common.utils.ServletUtils;
+import com.zhiyun.common.utils.StringUtils;
+import com.zhiyun.common.utils.ip.IpUtils;
+import com.zhiyun.framework.manager.AsyncManager;
+import com.zhiyun.framework.manager.factory.AsyncFactory;
+import com.zhiyun.project.monitor.domain.SysOperLog;
+import com.zhiyun.project.system.domain.dto.LoginUser;
+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.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+import org.springframework.validation.BindingResult;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 操作日志记录处理
+ *
+ * @author ruoyi
+ */
+@Aspect
+@Component
+public class LogAspect {
+    private static final Logger log = LoggerFactory.getLogger(LogAspect.class);
+
+    /**
+     * 排除敏感属性字段
+     */
+    public static final List<String> EXCLUDE_PROPERTIES = Lists.newArrayList("password", "oldPassword", "newPassword", "confirmPassword");
+
+    /**
+     * 处理完请求后执行
+     *
+     * @param joinPoint 切点
+     */
+    @AfterReturning(pointcut = "@annotation(controllerLog)", returning = "jsonResult")
+    public void doAfterReturning(JoinPoint joinPoint, Log controllerLog, Object jsonResult) {
+        handleLog(joinPoint, controllerLog, null, jsonResult);
+    }
+
+    /**
+     * 拦截异常操作
+     *
+     * @param joinPoint 切点
+     * @param e         异常
+     */
+    @AfterThrowing(value = "@annotation(controllerLog)", throwing = "e")
+    public void doAfterThrowing(JoinPoint joinPoint, Log controllerLog, Exception e) {
+        handleLog(joinPoint, controllerLog, e, null);
+    }
+
+    protected void handleLog(final JoinPoint joinPoint, Log controllerLog, final Exception e, Object jsonResult) {
+        try {
+            // 获取当前的用户
+            LoginUser loginUser = SecurityUtils.getLoginUser();
+
+            // *========数据库日志=========*//
+            SysOperLog operLog = new SysOperLog();
+            operLog.setStatus(BusinessStatus.SUCCESS.ordinal());
+            // 请求的地址
+            operLog.setOperIp(IpUtils.getIpAddress(ServletUtils.getRequest()));
+            operLog.setOperUrl(StringUtils.substring(ServletUtils.getRequest().getRequestURI(), 0, 255));
+            if (loginUser != null) {
+                operLog.setOperName(loginUser.getUsername());
+            }
+
+            if (e != null) {
+                operLog.setStatus(BusinessStatus.FAIL.ordinal());
+                operLog.setErrorMsg(StringUtils.substring(e.getMessage(), 0, 2000));
+            }
+            // 设置方法名称
+            String className = joinPoint.getTarget().getClass().getName();
+            String methodName = joinPoint.getSignature().getName();
+            operLog.setMethod(className + "." + methodName + "()");
+            // 设置请求方式
+            operLog.setRequestMethod(ServletUtils.getRequest().getMethod());
+            // 处理设置注解上的参数
+            getControllerMethodDescription(joinPoint, controllerLog, operLog, jsonResult);
+            // 保存数据库
+            AsyncManager.me().execute(AsyncFactory.recordOperateInfo(operLog));
+        } catch (Exception exp) {
+            // 记录本地异常日志
+            log.error("异常信息:{}", exp.getMessage());
+            exp.printStackTrace();
+        }
+    }
+
+    /**
+     * 获取注解中对方法的描述信息 用于Controller层注解
+     *
+     * @param log     日志
+     * @param operLog 操作日志
+     */
+    public void getControllerMethodDescription(JoinPoint joinPoint, Log log, SysOperLog operLog, Object jsonResult) {
+        // 设置action动作
+        operLog.setBusinessType(log.businessType().ordinal());
+        // 设置标题
+        operLog.setTitle(log.title());
+        // 设置操作人类别
+        operLog.setOperatorType(log.operatorType().ordinal());
+        // 是否需要保存request,参数和值
+        if (log.isSaveRequestData()) {
+            // 获取参数的信息,传入到数据库中。
+            setRequestValue(joinPoint, operLog);
+        }
+        // 是否需要保存response,参数和值
+        if (log.isSaveResponseData() && StringUtils.isNotNull(jsonResult)) {
+            operLog.setJsonResult(StringUtils.substring(JSON.toJSONString(jsonResult), 0, 2000));
+        }
+    }
+
+    /**
+     * 获取请求的参数,放到log中
+     *
+     * @param operLog 操作日志
+     */
+    private void setRequestValue(JoinPoint joinPoint, SysOperLog operLog) {
+        String requestMethod = operLog.getRequestMethod();
+        if (HttpMethod.PUT.name().equals(requestMethod) || HttpMethod.POST.name().equals(requestMethod)) {
+            String params = argsArrayToString(joinPoint.getArgs());
+            operLog.setOperParam(StringUtils.substring(params, 0, 2000));
+        } else {
+            Map<?, ?> paramsMap = ServletUtils.getParamMap(ServletUtils.getRequest());
+            operLog.setOperParam(StringUtils.substring(JSON.toJSONString(paramsMap, excludePropertyPreFilter()), 0, 2000));
+        }
+    }
+
+    /**
+     * 参数拼装
+     */
+    private String argsArrayToString(Object[] paramsArray) {
+        StringBuilder params = new StringBuilder();
+        if (paramsArray != null && paramsArray.length > 0) {
+            for (Object o : paramsArray) {
+                if (StringUtils.isNotNull(o) && !isFilterObject(o)) {
+                    String jsonObj = JSON.toJSONString(o, excludePropertyPreFilter());
+                    params.append(jsonObj).append(" ");
+                }
+            }
+        }
+        return params.toString().trim();
+    }
+
+    /**
+     * 忽略敏感属性
+     */
+    public SimplePropertyPreFilter excludePropertyPreFilter() {
+        SimplePropertyPreFilter filter = new SimplePropertyPreFilter();
+        filter.getExcludes().addAll(EXCLUDE_PROPERTIES);
+        return filter;
+    }
+
+    /**
+     * 判断是否需要过滤的对象。
+     *
+     * @param o 对象信息。
+     * @return 如果是需要过滤的对象,则返回true;否则返回false。
+     */
+    @SuppressWarnings("rawtypes")
+    public boolean isFilterObject(final Object o) {
+        Class<?> clazz = o.getClass();
+        if (clazz.isArray()) {
+            return clazz.getComponentType().isAssignableFrom(MultipartFile.class);
+        } else if (Collection.class.isAssignableFrom(clazz)) {
+            Collection collection = (Collection) o;
+            for (Object value : collection) {
+                return value instanceof MultipartFile;
+            }
+        } else if (Map.class.isAssignableFrom(clazz)) {
+            Map map = (Map) o;
+            for (Object value : map.entrySet()) {
+                Map.Entry entry = (Map.Entry) value;
+                return entry.getValue() instanceof MultipartFile;
+            }
+        }
+        return o instanceof MultipartFile || o instanceof HttpServletRequest || o instanceof HttpServletResponse || o instanceof BindingResult;
+    }
+}

+ 27 - 0
src/main/java/com/zhiyun/framework/config/FilterConfig.java

@@ -0,0 +1,27 @@
+package com.zhiyun.framework.config;
+
+import com.zhiyun.common.filter.RepeatableFilter;
+import org.springframework.boot.web.servlet.FilterRegistrationBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * Filter配置
+ *
+ * @author ruoyi
+ */
+@Configuration
+public class FilterConfig {
+
+    @SuppressWarnings({"rawtypes", "unchecked"})
+    @Bean
+    public FilterRegistrationBean someFilterRegistration() {
+        FilterRegistrationBean registration = new FilterRegistrationBean();
+        registration.setFilter(new RepeatableFilter());
+        registration.addUrlPatterns("/*");
+        registration.setName("repeatableFilter");
+        registration.setOrder(FilterRegistrationBean.LOWEST_PRECEDENCE);
+        return registration;
+    }
+
+}

+ 13 - 0
src/main/java/com/zhiyun/framework/config/ResourcesConfig.java

@@ -1,11 +1,14 @@
 package com.zhiyun.framework.config;
 
 import com.zhiyun.common.constant.Constants;
+import com.zhiyun.framework.interceptor.RepeatSubmitInterceptor;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.web.cors.CorsConfiguration;
 import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
 import org.springframework.web.filter.CorsFilter;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
 import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
 import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
 
@@ -16,6 +19,8 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
  */
 @Configuration
 public class ResourcesConfig implements WebMvcConfigurer {
+    @Autowired
+    private RepeatSubmitInterceptor repeatSubmitInterceptor;
 
     @Override
     public void addResourceHandlers(ResourceHandlerRegistry registry) {
@@ -24,6 +29,14 @@ public class ResourcesConfig implements WebMvcConfigurer {
                 .addResourceLocations("file:" + ZySystemConfig.getProfile() + "/");
     }
 
+    /**
+     * 自定义拦截规则
+     */
+    @Override
+    public void addInterceptors(InterceptorRegistry registry) {
+        registry.addInterceptor(repeatSubmitInterceptor).addPathPatterns("/**");
+    }
+
     /**
      * 跨域配置
      */

+ 1 - 1
src/main/java/com/zhiyun/framework/config/captcha/CaptchaConfig.java

@@ -68,7 +68,7 @@ public class CaptchaConfig {
         // 验证码文本字符长度 默认为5
         properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, "6");
         // 验证码文本字体样式 默认为new Font("Arial", 1, fontSize), new Font("Courier", 1, fontSize)
-        properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_NAMES, "Arial,Courier");
+//        properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_NAMES, "Arial,Courier");
         // 验证码噪点颜色 默认为Color.BLACK
         //properties.setProperty(KAPTCHA_NOISE_COLOR, "white");
         // 干扰实现类

+ 29 - 0
src/main/java/com/zhiyun/framework/config/mqtt/MqttCallbackHandler.java

@@ -0,0 +1,29 @@
+package com.zhiyun.framework.config.mqtt;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+
+/**
+ * MQTT 消息返回处理类
+ *
+ * @author yang xiao kun
+ * create on 2021/1/19
+ */
+@Slf4j
+@Component
+public class MqttCallbackHandler {
+
+    /**
+     * 处理消息
+     *
+     * @param topic   主题
+     * @param payload 消息内容
+     */
+    public void handle(String topic, String payload) {
+
+    }
+
+
+}

+ 3 - 3
src/main/java/com/zhiyun/framework/config/mqtt/MqttConfig.java

@@ -15,9 +15,9 @@ import org.springframework.integration.mqtt.core.MqttPahoClientFactory;
 @Configuration
 public class MqttConfig {
 
-    private static final String username = "lq2019";
-    private static final String password = "LiQuanRabbit";
-    private static final String address = "tcp://view.ailishi.org:1883";
+    private static final String username = "user";
+    private static final String password = "user@2024";
+    private static final String address = "tcp://192.168.1.100:1883";
 
     /**
      * MQTT连接器配置选项

+ 0 - 68
src/main/java/com/zhiyun/framework/config/mqtt/MqttConstant.java

@@ -1,68 +0,0 @@
-package com.zhiyun.framework.config.mqtt;
-
-/**
- * 常量数据
- *
- * @author yang xiao kun
- * create on 2021/2/2
- */
-public class MqttConstant {
-    /**
-     * 前缀
-     */
-    public static class PREF {
-        // rabbit MQ 用户名前缀
-        public static final String RABBIT_MQ_USERNAME = "IMEI";
-
-    }
-
-    /**
-     * MQTT 协议报文 中 M值
-     */
-    public static class M {
-        //设备发送注册请求
-        public static final String REGISTER = "10";
-        //服务器响应设备注册请求
-        public static final String HANDLE_REGISTER = "11";
-        //普适型 - 设备心跳包
-        public static final String UBI_HEARTBEAT = "21";
-
-    }
-
-    /**
-     * 主题前缀
-     * SERVER为服务器订阅主题  用来接收设备发来消息
-     * CLIENT为设备订阅主题    用来发送消息给设备
-     */
-    public static class TOPIC {
-        // 设备注册时device -> server主题,仅设备注册使用
-        public static final String REGISTER_SERVER = "$regdtx2";
-        // 设备注册时server -> device主题,仅设备注册使用
-        public static final String REGISTER_CLIENT = "$regdrx2";
-        // device -> server 通讯主题
-        public static final String DEVICE_SERVER = "$dtx2/#";
-        // 设备设置指令主题
-        public static final String DEVICE_SERVER_NEW = "/device/+/DTU/+";
-
-    }
-
-    /**
-     * 通过订阅的主题裁剪出openNum
-     *
-     * @param topic 主题
-     */
-    public static String splitOpenNum(String topic) {
-        String[] result = topic.split(PREF.RABBIT_MQ_USERNAME);
-        return result.length > 1 ? result[1] : null;
-    }
-
-    /**
-     * 通过订阅的主题裁剪出openNum
-     *
-     * @param topic 主题
-     */
-    public static String splitDevicenameNew(String topic) {
-        String[] result = topic.split("/");
-        return result.length > 2 ? result[2] : null;
-    }
-}

+ 10 - 6
src/main/java/com/zhiyun/framework/config/mqtt/MqttConsumerCfg.java

@@ -1,7 +1,6 @@
 package com.zhiyun.framework.config.mqtt;
 
-import com.zhiyun.common.utils.RandomCode;
-import com.zhiyun.project.project.mqtt.handler.MqttCallbackHandler;
+import com.zhiyun.common.utils.uuid.UUID;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
@@ -32,7 +31,8 @@ public class MqttConsumerCfg {
     private MqttPahoClientFactory mqttClientFactory;
 
     //默认监听主题
-    private final String[] defaultTopic = new String[]{MqttConstant.TOPIC.DEVICE_SERVER_NEW};
+    private final String[] defaultTopic = new String[]{"dts/gnss/#","dts/setzfq/#", "status/#"};
+    //"dts/setzfq/#", "status/#",
 
     /**
      * MQTT 消息订阅绑定(消费者)
@@ -41,13 +41,17 @@ public class MqttConsumerCfg {
     @Bean
     public MessageProducer inbound() {
         // 初始化入站通道适配器,使用的是Eclipse Paho MQTT客户端库
-        MqttPahoMessageDrivenChannelAdapter adapter =
-                new MqttPahoMessageDrivenChannelAdapter(RandomCode.UUID_8() + "consumer", mqttClientFactory, defaultTopic);
+        MqttPahoMessageDrivenChannelAdapter adapter = new MqttPahoMessageDrivenChannelAdapter(UUID.randomUUID() + "_Consumer", mqttClientFactory, defaultTopic);
         // 设置连接超时时长 毫秒
         adapter.setCompletionTimeout(5000);
         // 配置默认Paho消息转换器(qos=0, retain=false, charset=UTF-8)
         adapter.setConverter(new DefaultPahoMessageConverter());
-        // 设置服务质量 0 最多一次,数据可能丢失; 1 至少一次,数据可能重复; 2 只有一次,有且只有一次;最耗性能;
+        /*
+            设置服务质量
+            0 最多一次,数据可能丢失;
+            1 至少一次,数据可能重复;
+            2 只有一次,有且只有一次;最耗性能;
+         */
         adapter.setQos(0);
         // 设置订阅通道
         adapter.setOutputChannel(mqttInboundChannel());

+ 2 - 2
src/main/java/com/zhiyun/framework/config/mqtt/MqttGateway.java

@@ -3,12 +3,12 @@ package com.zhiyun.framework.config.mqtt;
 import org.springframework.integration.annotation.MessagingGateway;
 import org.springframework.integration.mqtt.support.MqttHeaders;
 import org.springframework.messaging.handler.annotation.Header;
-import org.springframework.stereotype.Component;
+import org.springframework.stereotype.Service;
 
 /**
  * 消息推送接口
  */
-@Component
+@Service
 @MessagingGateway(defaultRequestChannel = "mqttOutboundChannel")
 public interface MqttGateway {
     /**

+ 2 - 2
src/main/java/com/zhiyun/framework/config/mqtt/MqttProducerCfg.java

@@ -1,6 +1,6 @@
 package com.zhiyun.framework.config.mqtt;
 
-import com.zhiyun.common.utils.RandomCode;
+import com.zhiyun.common.utils.uuid.UUID;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
@@ -37,7 +37,7 @@ public class MqttProducerCfg {
     @Bean
     @ServiceActivator(inputChannel = "mqttOutboundChannel")
     public MessageHandler mqttOutbound() {
-        MqttPahoMessageHandler messageHandler = new MqttPahoMessageHandler(RandomCode.UUID_8() + "_product", mqttClientFactory);
+        MqttPahoMessageHandler messageHandler = new MqttPahoMessageHandler(UUID.randomUUID() + "_Producer", mqttClientFactory);
         // 设置异步发送,默认是false(发送时阻塞)
         messageHandler.setAsync(true);
         // 设置默认的服务质量

+ 43 - 0
src/main/java/com/zhiyun/framework/interceptor/RepeatSubmitInterceptor.java

@@ -0,0 +1,43 @@
+package com.zhiyun.framework.interceptor;
+
+import com.alibaba.fastjson2.JSON;
+import com.zhiyun.common.annotation.RepeatSubmit;
+import com.zhiyun.common.model.ApiResult;
+import com.zhiyun.common.utils.ServletUtils;
+import org.springframework.stereotype.Component;
+import org.springframework.web.method.HandlerMethod;
+import org.springframework.web.servlet.HandlerInterceptor;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.lang.reflect.Method;
+
+/**
+ * 防止重复提交拦截器
+ *
+ * @author ruoyi
+ */
+@Component
+public abstract class RepeatSubmitInterceptor implements HandlerInterceptor {
+    @Override
+    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
+        if (handler instanceof HandlerMethod) {
+            HandlerMethod handlerMethod = (HandlerMethod) handler;
+            Method method = handlerMethod.getMethod();
+            RepeatSubmit annotation = method.getAnnotation(RepeatSubmit.class);
+            if (annotation != null) {
+                if (this.isRepeatSubmit(request, annotation)) {
+                    ApiResult apiResult = ApiResult.error(annotation.message());
+                    ServletUtils.renderString(response, JSON.toJSONString(apiResult));
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    /**
+     * 验证是否重复提交由子类实现具体的防重复提交的规则
+     */
+    public abstract boolean isRepeatSubmit(HttpServletRequest request, RepeatSubmit annotation);
+}

+ 98 - 0
src/main/java/com/zhiyun/framework/interceptor/impl/SameUrlDataInterceptor.java

@@ -0,0 +1,98 @@
+package com.zhiyun.framework.interceptor.impl;
+
+import com.alibaba.fastjson2.JSON;
+import com.zhiyun.common.annotation.RepeatSubmit;
+import com.zhiyun.common.constant.CacheConstants;
+import com.zhiyun.common.core.redis.RedisCache;
+import com.zhiyun.common.filter.RepeatedlyRequestWrapper;
+import com.zhiyun.common.utils.StringUtils;
+import com.zhiyun.common.utils.http.HttpHelper;
+import com.zhiyun.framework.interceptor.RepeatSubmitInterceptor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * 判断请求url和数据是否和上一次相同,
+ * 如果和上次相同,则是重复提交表单。 有效时间为10秒内。
+ *
+ * @author ruoyi
+ */
+@Component
+public class SameUrlDataInterceptor extends RepeatSubmitInterceptor {
+    public final String REPEAT_PARAMS = "repeatParams";
+
+    public final String REPEAT_TIME = "repeatTime";
+
+    // 令牌自定义标识
+    @Value("${token.header}")
+    private String header;
+
+    @Autowired
+    private RedisCache redisCache;
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public boolean isRepeatSubmit(HttpServletRequest request, RepeatSubmit annotation) {
+        String nowParams = "";
+        if (request instanceof RepeatedlyRequestWrapper) {
+            RepeatedlyRequestWrapper repeatedlyRequest = (RepeatedlyRequestWrapper) request;
+            nowParams = HttpHelper.getBodyString(repeatedlyRequest);
+        }
+
+        // body参数为空,获取Parameter的数据
+        if (StringUtils.isEmpty(nowParams)) {
+            nowParams = JSON.toJSONString(request.getParameterMap());
+        }
+        Map<String, Object> nowDataMap = new HashMap<>();
+        nowDataMap.put(REPEAT_PARAMS, nowParams);
+        nowDataMap.put(REPEAT_TIME, System.currentTimeMillis());
+
+        // 请求地址(作为存放cache的key值)
+        String url = request.getRequestURI();
+
+        // 唯一值(没有消息头则使用请求地址)
+        String submitKey = StringUtils.trimToEmpty(request.getHeader(header));
+
+        // 唯一标识(指定key + url + 消息头)
+        String cacheRepeatKey = CacheConstants.REPEAT_SUBMIT_KEY + url + submitKey;
+
+        Object sessionObj = redisCache.getCacheObject(cacheRepeatKey);
+        if (sessionObj != null) {
+            Map<String, Object> sessionMap = (Map<String, Object>) sessionObj;
+            if (sessionMap.containsKey(url)) {
+                Map<String, Object> preDataMap = (Map<String, Object>) sessionMap.get(url);
+                if (compareParams(nowDataMap, preDataMap) && compareTime(nowDataMap, preDataMap, annotation.interval())) {
+                    return true;
+                }
+            }
+        }
+        Map<String, Object> cacheMap = new HashMap<>();
+        cacheMap.put(url, nowDataMap);
+        redisCache.setCacheObject(cacheRepeatKey, cacheMap, annotation.interval(), TimeUnit.MILLISECONDS);
+        return false;
+    }
+
+    /**
+     * 判断参数是否相同
+     */
+    private boolean compareParams(Map<String, Object> nowMap, Map<String, Object> preMap) {
+        String nowParams = (String) nowMap.get(REPEAT_PARAMS);
+        String preParams = (String) preMap.get(REPEAT_PARAMS);
+        return nowParams.equals(preParams);
+    }
+
+    /**
+     * 判断两次间隔时间
+     */
+    private boolean compareTime(Map<String, Object> nowMap, Map<String, Object> preMap, int interval) {
+        long time1 = (Long) nowMap.get(REPEAT_TIME);
+        long time2 = (Long) preMap.get(REPEAT_TIME);
+        return (time1 - time2) < interval;
+    }
+}

+ 54 - 0
src/main/java/com/zhiyun/framework/manager/AsyncManager.java

@@ -0,0 +1,54 @@
+package com.zhiyun.framework.manager;
+
+
+import com.zhiyun.common.utils.Threads;
+import com.zhiyun.common.utils.spring.SpringUtils;
+
+import java.util.TimerTask;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * 异步任务管理器
+ *
+ * @author ruoyi
+ */
+public class AsyncManager {
+    /**
+     * 操作延迟10毫秒
+     */
+    private static final int OPERATE_DELAY_TIME = 10;
+
+    /**
+     * 异步操作任务调度线程池
+     */
+    private final ScheduledExecutorService executor = SpringUtils.getBean("scheduledExecutorService");
+
+    /**
+     * 单例模式
+     */
+    private AsyncManager() {
+    }
+
+    private static final AsyncManager me = new AsyncManager();
+
+    public static AsyncManager me() {
+        return me;
+    }
+
+    /**
+     * 执行任务
+     *
+     * @param task 任务
+     */
+    public void execute(TimerTask task) {
+        executor.schedule(task, OPERATE_DELAY_TIME, TimeUnit.MILLISECONDS);
+    }
+
+    /**
+     * 停止任务线程池
+     */
+    public void shutdown() {
+        Threads.shutdownAndAwaitTermination(executor);
+    }
+}

+ 34 - 0
src/main/java/com/zhiyun/framework/manager/ShutdownManager.java

@@ -0,0 +1,34 @@
+package com.zhiyun.framework.manager;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.PreDestroy;
+
+/**
+ * 确保应用退出时能关闭后台线程
+ *
+ * @author ruoyi
+ */
+@Component
+public class ShutdownManager {
+    private static final Logger logger = LoggerFactory.getLogger("sys-user");
+
+    @PreDestroy
+    public void destroy() {
+        shutdownAsyncManager();
+    }
+
+    /**
+     * 停止异步执行任务
+     */
+    private void shutdownAsyncManager() {
+        try {
+            logger.info("====关闭后台任务任务线程池====");
+            AsyncManager.me().shutdown();
+        } catch (Exception e) {
+            logger.error(e.getMessage(), e);
+        }
+    }
+}

+ 91 - 0
src/main/java/com/zhiyun/framework/manager/factory/AsyncFactory.java

@@ -0,0 +1,91 @@
+package com.zhiyun.framework.manager.factory;
+
+import com.google.common.collect.Sets;
+import com.zhiyun.common.constant.Constants;
+import com.zhiyun.common.utils.ServletUtils;
+import com.zhiyun.common.utils.ip.AddressUtils;
+import com.zhiyun.common.utils.ip.IpUtils;
+import com.zhiyun.common.utils.spring.SpringUtils;
+import com.zhiyun.project.monitor.domain.SysLoginInfo;
+import com.zhiyun.project.monitor.domain.SysOperLog;
+import com.zhiyun.project.monitor.service.ISysLoginInfoService;
+import com.zhiyun.project.monitor.service.ISysOperLogService;
+import eu.bitwalker.useragentutils.UserAgent;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Set;
+import java.util.TimerTask;
+
+/**
+ * 异步工厂(产生任务用)
+ *
+ * @author ruoyi
+ */
+public class AsyncFactory {
+
+    private static final Logger sys_user_logger = LoggerFactory.getLogger("sys-user");
+
+    private static final Set<String> SUCCESS_SET = Sets.newHashSet(Constants.LOGIN_SUCCESS, Constants.LOGOUT, Constants.REGISTER);
+
+    /**
+     * 记录登录信息
+     *
+     * @param username 用户名
+     * @param status   状态
+     * @param message  消息
+     * @param args     列表
+     * @return 任务task
+     */
+    public static TimerTask recordLoginInfo(final String username, final String status, final String message, final Object... args) {
+        final UserAgent userAgent = UserAgent.parseUserAgentString(ServletUtils.getRequest().getHeader("User-Agent"));
+        final String ip = IpUtils.getIpAddress(ServletUtils.getRequest());
+        return new TimerTask() {
+            @Override
+            public void run() {
+                String address = AddressUtils.getRealAddressByIP(ip);
+                String s = getBlock(ip) + address + getBlock(username) + getBlock(status) + getBlock(message);
+                // 打印信息到日志
+                sys_user_logger.info(s, args);
+                // 封装对象
+                SysLoginInfo loginInfo = new SysLoginInfo();
+                loginInfo.setUserName(username);
+                loginInfo.setIpaddr(ip);
+                loginInfo.setLoginLocation(address);
+                // 获取客户端浏览器
+                loginInfo.setBrowser(userAgent.getBrowser().getName());
+                // 获取客户端操作系统
+                loginInfo.setOs(userAgent.getOperatingSystem().getName());
+                loginInfo.setMsg(message);
+                // 日志状态
+                loginInfo.setStatus(SUCCESS_SET.contains(status) ? Constants.SUCCESS : Constants.FAIL);
+                // 插入数据
+                SpringUtils.getBean(ISysLoginInfoService.class).save(loginInfo);
+            }
+        };
+    }
+
+    /**
+     * 操作日志记录
+     *
+     * @param operLog 操作日志信息
+     * @return 任务task
+     */
+    public static TimerTask recordOperateInfo(final SysOperLog operLog) {
+        return new TimerTask() {
+            @Override
+            public void run() {
+                // 远程查询操作地点
+                operLog.setOperLocation(AddressUtils.getRealAddressByIP(operLog.getOperIp()));
+                SpringUtils.getBean(ISysOperLogService.class).save(operLog);
+            }
+        };
+    }
+
+    private static String getBlock(Object msg) {
+        if (msg == null) {
+            msg = "";
+        }
+        return "[" + msg + "]";
+    }
+}

+ 24 - 0
src/main/java/com/zhiyun/framework/security/context/PermissionContextHolder.java

@@ -0,0 +1,24 @@
+package com.zhiyun.framework.security.context;
+
+import com.zhiyun.common.core.text.Convert;
+import org.springframework.web.context.request.RequestAttributes;
+import org.springframework.web.context.request.RequestContextHolder;
+
+/**
+ * 权限信息
+ *
+ * @author ruoyi
+ */
+public class PermissionContextHolder {
+    private static final String PERMISSION_CONTEXT_ATTRIBUTES = "PERMISSION_CONTEXT";
+
+    public static void setContext(String permission) {
+        RequestContextHolder.currentRequestAttributes().setAttribute(PERMISSION_CONTEXT_ATTRIBUTES, permission,
+                RequestAttributes.SCOPE_REQUEST);
+    }
+
+    public static String getContext() {
+        return Convert.toStr(RequestContextHolder.currentRequestAttributes().getAttribute(PERMISSION_CONTEXT_ATTRIBUTES,
+                RequestAttributes.SCOPE_REQUEST));
+    }
+}

+ 5 - 0
src/main/java/com/zhiyun/framework/security/filter/JwtAuthenticationTokenFilter.java

@@ -29,6 +29,11 @@ public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
     @Override
     protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
         LoginUser loginUser = tokenService.getLoginUser(request);
+        try {
+            Integer item = Integer.parseInt(request.getHeader("item"));
+            loginUser.setItem(item);
+        } catch (Exception ignored) {
+        }
         if (loginUser != null && SecurityUtils.getAuthentication() == null) {
             //校验token是否过期
             tokenService.verifyToken(loginUser);

+ 6 - 0
src/main/java/com/zhiyun/framework/security/handle/ZyLogoutSuccessHandler.java

@@ -1,9 +1,12 @@
 package com.zhiyun.framework.security.handle;
 
 import com.alibaba.fastjson2.JSON;
+import com.zhiyun.common.constant.Constants;
 import com.zhiyun.common.model.ApiResult;
 import com.zhiyun.common.utils.ServletUtils;
 import com.zhiyun.common.utils.StringUtils;
+import com.zhiyun.framework.manager.AsyncManager;
+import com.zhiyun.framework.manager.factory.AsyncFactory;
 import com.zhiyun.framework.web.TokenService;
 import com.zhiyun.project.system.domain.dto.LoginUser;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -31,8 +34,11 @@ public class ZyLogoutSuccessHandler implements LogoutSuccessHandler {
     public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
         LoginUser loginUser = tokenService.getLoginUser(request);
         if (StringUtils.isNotNull(loginUser)) {
+            String userName = loginUser.getUsername();
             // 删除用户缓存记录
             tokenService.delLoginUser(loginUser.getToken());
+            // 记录用户退出日志
+            AsyncManager.me().execute(AsyncFactory.recordLoginInfo(userName, Constants.LOGOUT, "退出成功"));
         }
         ServletUtils.renderString(response, JSON.toJSONString(ApiResult.success("退出成功")));
     }

+ 108 - 4
src/main/java/com/zhiyun/framework/web/PermissionService.java

@@ -1,9 +1,14 @@
 package com.zhiyun.framework.web;
 
 import com.zhiyun.common.utils.SecurityUtils;
-import com.zhiyun.framework.UserDataScope;
+import com.zhiyun.common.utils.StringUtils;
+import com.zhiyun.framework.security.context.PermissionContextHolder;
 import com.zhiyun.project.system.domain.dto.LoginUser;
+import com.zhiyun.project.system.domain.entity.SysRole;
 import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+
+import java.util.Set;
 
 /**
  * RuoYi首创 自定义权限实现,ss取自SpringSecurity首字母
@@ -12,16 +17,115 @@ import org.springframework.stereotype.Service;
  */
 @Service("ss")
 public class PermissionService {
+    /**
+     * 所有权限标识
+     */
+    private static final String ALL_PERMISSION = "*:*:*";
+
+    /**
+     * 管理员角色权限标识
+     */
+    private static final String SUPER_ADMIN = "admin";
+
+    private static final String ROLE_DELIMETER = ",";
+
+    private static final String PERMISSION_DELIMETER = ",";
+
+    /**
+     * 验证用户是否具备某权限
+     *
+     * @param permission 权限字符串
+     * @return 用户是否具备某权限
+     */
+    public boolean hasPermi(String permission) {
+        if (StringUtils.isEmpty(permission)) {
+            return false;
+        }
+        LoginUser loginUser = SecurityUtils.getLoginUser();
+        if (loginUser == null || CollectionUtils.isEmpty(loginUser.getMenuPermissions())) {
+            return false;
+        }
+        PermissionContextHolder.setContext(permission);
+        return hasPermissions(loginUser.getMenuPermissions(), permission);
+    }
+
+    /**
+     * 验证用户是否具有以下任意一个权限
+     *
+     * @param permissions 以 PERMISSION_NAMES_DELIMETER 为分隔符的权限列表
+     * @return 用户是否具有以下任意一个权限
+     */
+    public boolean hasAnyPermi(String permissions) {
+        if (StringUtils.isEmpty(permissions)) {
+            return false;
+        }
+        LoginUser loginUser = SecurityUtils.getLoginUser();
+        if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getMenuPermissions())) {
+            return false;
+        }
+        PermissionContextHolder.setContext(permissions);
+        Set<String> authorities = loginUser.getMenuPermissions();
+        for (String permission : permissions.split(PERMISSION_DELIMETER)) {
+            if (permission != null && hasPermissions(authorities, permission)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * 判断是否包含权限
+     *
+     * @param permissions 权限列表
+     * @param permission  权限字符串
+     * @return 用户是否具备某权限
+     */
+    private boolean hasPermissions(Set<String> permissions, String permission) {
+        return permissions.contains(ALL_PERMISSION) || permissions.contains(StringUtils.trim(permission));
+    }
 
     /**
      * 判断用户是否拥有某个角色
+     *
+     * @param role 角色字符串
+     * @return 用户是否具备某角色
      */
-    public boolean checkAdmin() {
+    public boolean hasRole(String role) {
+        if (StringUtils.isEmpty(role)) {
+            return false;
+        }
         LoginUser loginUser = SecurityUtils.getLoginUser();
-        if (loginUser == null) {
+        if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getRoles())) {
             return false;
         }
-        return UserDataScope.isAdmin(loginUser.getUserId());
+        for (SysRole sysRole : loginUser.getRoles()) {
+            String roleKey = sysRole.getRoleKey();
+            if (SUPER_ADMIN.equals(roleKey) || roleKey.equals(StringUtils.trim(role))) {
+                return true;
+            }
+        }
+        return false;
     }
 
+    /**
+     * 验证用户是否具有以下任意一个角色
+     *
+     * @param roles 以 ROLE_NAMES_DELIMETER 为分隔符的角色列表
+     * @return 用户是否具有以下任意一个角色
+     */
+    public boolean hasAnyRoles(String roles) {
+        if (StringUtils.isEmpty(roles)) {
+            return false;
+        }
+        LoginUser loginUser = SecurityUtils.getLoginUser();
+        if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getRoles())) {
+            return false;
+        }
+        for (String role : roles.split(ROLE_DELIMETER)) {
+            if (hasRole(role)) {
+                return true;
+            }
+        }
+        return false;
+    }
 }

+ 37 - 16
src/main/java/com/zhiyun/framework/web/SysPermissionService.java

@@ -1,16 +1,14 @@
-
 package com.zhiyun.framework.web;
 
-import com.google.common.collect.Lists;
-import com.zhiyun.common.exception.UserException;
-import com.zhiyun.common.utils.SecurityUtils;
-import com.zhiyun.project.project.mapper.DeviceMapper;
-import com.zhiyun.project.system.domain.dto.LoginUser;
+import com.zhiyun.framework.RoleDataScope;
+import com.zhiyun.project.system.service.ISysMenuService;
+import com.zhiyun.project.system.service.ISysRoleService;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
-import java.util.List;
+import java.util.HashSet;
+import java.util.Set;
 
 /**
  * 用户权限处理
@@ -22,21 +20,44 @@ import java.util.List;
 public class SysPermissionService {
 
     @Autowired
-    private DeviceMapper deviceMapper;
+    private ISysRoleService roleService;
+    @Autowired
+    private ISysMenuService menuService;
 
     /**
-     * 检查用户设备数据权限
+     * 获取角色数据权限
      */
-    public void checkUserDevicePerm(String devicename) {
-        checkUserDevicePerm(Lists.newArrayList(devicename));
+    public Set<String> getRolePermission(Long userId) {
+        Set<String> roles = new HashSet<>();
+        // 管理员拥有所有权限
+        if (RoleDataScope.isAdmin(userId)) {
+            roles.add("admin");
+        } else {
+            roles.addAll(roleService.selectRolePermissionByUserId(userId));
+        }
+        return roles;
     }
 
-    public void checkUserDevicePerm(List<String> devicenameList) {
-        LoginUser loginUser = SecurityUtils.getLoginUser();
-        if (deviceMapper.checkUserPrem(devicenameList, loginUser.getCpyid()) < devicenameList.size()) {
-            log.error("用户{}无设备{}权限", loginUser.getUsername(), devicenameList);
-            throw new UserException("无设备权限");
+    /**
+     * 获取菜单数据权限
+     */
+    public Set<String> getMenuPermissionByUserId(Long userId) {
+        Set<String> perms = new HashSet<>();
+        // 管理员拥有所有权限
+        if (RoleDataScope.isAdmin(userId)) {
+            perms.add("*:*:*");
+        } else {
+            perms.addAll(menuService.selectMenuPermsByUserId(userId));
         }
+        return perms;
     }
 
+    /**
+     * 获取菜单数据权限
+     */
+    public Set<String> getMenuPermissionByRoleId(Long roleId) {
+        return menuService.selectMenuPermsByRoleId(roleId);
+    }
+
+
 }

+ 35 - 3
src/main/java/com/zhiyun/framework/web/UserDetailsServiceImpl.java

@@ -4,7 +4,11 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.zhiyun.common.enums.UserStatus;
 import com.zhiyun.common.exception.UserException;
 import com.zhiyun.project.system.domain.dto.LoginUser;
+import com.zhiyun.project.system.domain.entity.SysDept;
+import com.zhiyun.project.system.domain.entity.SysRole;
 import com.zhiyun.project.system.domain.entity.SysUser;
+import com.zhiyun.project.system.service.ISysDeptService;
+import com.zhiyun.project.system.service.ISysRoleService;
 import com.zhiyun.project.system.service.ISysUserService;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -13,6 +17,8 @@ import org.springframework.security.core.userdetails.UserDetailsService;
 import org.springframework.security.core.userdetails.UsernameNotFoundException;
 import org.springframework.stereotype.Service;
 
+import java.util.List;
+
 /**
  * 用户验证处理
  *
@@ -24,18 +30,44 @@ public class UserDetailsServiceImpl implements UserDetailsService {
 
     @Autowired
     private ISysUserService userService;
+    @Autowired
+    private ISysDeptService deptService;
+    @Autowired
+    private ISysRoleService roleService;
+    @Autowired
+    private SysPermissionService permissionService;
 
     @Override
     public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
         SysUser user = userService.getOne(new QueryWrapper<SysUser>().eq("user_name", username));
         if (user == null) {
-            log.error("登录用户:{} 不存在.", username);
+            log.info("登录用户:{} 不存在.", username);
             throw new UserException("登录用户:" + username + " 不存在");
         } else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) {
-            log.error("登录用户:{} 已被停用.", username);
+            log.info("登录用户:{} 已被停用.", username);
             throw new UserException("对不起,您的账号:" + username + " 已停用");
         }
-        return new LoginUser(user);
+        return createLoginUser(user);
     }
 
+    private UserDetails createLoginUser(SysUser user) {
+        LoginUser loginUser = new LoginUser();
+        loginUser.setUserId(user.getUserId());
+        loginUser.setDeptId(user.getDeptId());
+        loginUser.setUser(user);
+        //角色
+        List<SysRole> roles = roleService.selectRolesByUserId(user.getUserId());
+        //角色的菜单权限
+        roles.forEach(item -> item.setMenuPermission(permissionService.getMenuPermissionByRoleId(item.getRoleId())));
+        loginUser.setRoles(roles);
+        //设置用户的菜单权限
+        loginUser.setMenuPermissions(permissionService.getMenuPermissionByUserId(user.getUserId()));
+        //部门
+        SysDept dept = deptService.getById(user.getDeptId());
+        loginUser.setDept(dept);
+        loginUser.setMineId(dept.getMineId());
+        return loginUser;
+    }
+
+
 }

+ 1 - 1
src/main/java/com/zhiyun/project/common/BaseController.java

@@ -55,7 +55,7 @@ public class BaseController {
     /**
      * 获取登录用户id
      */
-    public Integer getUserId() {
+    public Long getUserId() {
         return getLoginUser().getUserId();
     }
 

+ 2 - 5
src/main/java/com/zhiyun/project/common/CaptchaController.java

@@ -49,8 +49,8 @@ public class CaptchaController {
         String uuid = IdUtils.simpleUUID();
         String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + uuid;
 
-        String capStr, code;
-        BufferedImage image;
+        String capStr, code = null;
+        BufferedImage image = null;
 
         // 生成验证码
         String captchaType = ZySystemConfig.getCaptchaType();
@@ -62,9 +62,6 @@ public class CaptchaController {
         } else if ("char".equals(captchaType)) {
             capStr = code = captchaProducer.createText();
             image = captchaProducer.createImage(capStr);
-        } else {
-            capStr = code = captchaProducer.createText();
-            image = captchaProducer.createImage(capStr);
         }
         redisCache.setCacheObject(verifyKey, code, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES);
         // 转换流信息写出

+ 27 - 0
src/main/java/com/zhiyun/project/item/domain/dto/Perm.java

@@ -0,0 +1,27 @@
+package com.zhiyun.project.item.domain.dto;
+
+import lombok.Data;
+
+/**
+ * 数据权限
+ *
+ * @author yang xiao kun
+ * create on 2023/11/15
+ */
+@Data
+public class Perm {
+    /**
+     * 部门权限过滤SQL
+     */
+    private String dept = null;
+
+    /**
+     * 用户权限过滤SQL
+     */
+    private String item = null;
+
+    /**
+     * 测区权限过滤SQL
+     */
+    private String survey = null;
+}

+ 11 - 9
src/main/java/com/zhiyun/project/monitor/controller/CacheController.java

@@ -37,7 +37,7 @@ public class CacheController {
         caches.add(new SysCache(CacheConstants.PWD_ERR_CNT_KEY, "密码错误次数"));
     }
 
-    @PreAuthorize("@ss.checkAdmin()")
+    @PreAuthorize("@ss.hasPermi('monitor:cache:list')")
     @GetMapping()
     public ApiResult getInfo() throws Exception {
         Properties info = (Properties) redisTemplate.execute((RedisCallback<Object>) RedisServerCommands::info);
@@ -62,20 +62,20 @@ public class CacheController {
         return ApiResult.success(result);
     }
 
-    @PreAuthorize("@ss.checkAdmin()")
+    @PreAuthorize("@ss.hasPermi('monitor:cache:list')")
     @GetMapping("/getNames")
     public ApiResult cache() {
         return ApiResult.success(caches);
     }
 
-    @PreAuthorize("@ss.checkAdmin()")
+    @PreAuthorize("@ss.hasPermi('monitor:cache:list')")
     @GetMapping("/getKeys/{cacheName}")
     public ApiResult getCacheKeys(@PathVariable String cacheName) {
         Set<String> cacheKeys = redisTemplate.keys(cacheName + "*");
         return ApiResult.success(cacheKeys);
     }
 
-    @PreAuthorize("@ss.checkAdmin()")
+    @PreAuthorize("@ss.hasPermi('monitor:cache:list')")
     @GetMapping("/getValue/{cacheName}/{cacheKey}")
     public ApiResult getCacheValue(@PathVariable String cacheName, @PathVariable String cacheKey) {
         String cacheValue = redisTemplate.opsForValue().get(cacheKey);
@@ -83,26 +83,28 @@ public class CacheController {
         return ApiResult.success(sysCache);
     }
 
-    @PreAuthorize("@ss.checkAdmin()")
+    @PreAuthorize("@ss.hasPermi('monitor:cache:list')")
     @DeleteMapping("/clearCacheName/{cacheName}")
     public ApiResult clearCacheName(@PathVariable String cacheName) {
         Collection<String> cacheKeys = redisTemplate.keys(cacheName + "*");
-        if (cacheKeys != null) redisTemplate.delete(cacheKeys);
+        if (cacheKeys != null)
+            redisTemplate.delete(cacheKeys);
         return ApiResult.success();
     }
 
-    @PreAuthorize("@ss.checkAdmin()")
+    @PreAuthorize("@ss.hasPermi('monitor:cache:list')")
     @DeleteMapping("/clearCacheKey/{cacheKey}")
     public ApiResult clearCacheKey(@PathVariable String cacheKey) {
         redisTemplate.delete(cacheKey);
         return ApiResult.success();
     }
 
-    @PreAuthorize("@ss.checkAdmin()")
+    @PreAuthorize("@ss.hasPermi('monitor:cache:list')")
     @DeleteMapping("/clearCacheAll")
     public ApiResult clearCacheAll() {
         Collection<String> cacheKeys = redisTemplate.keys("*");
-        if (cacheKeys != null) redisTemplate.delete(cacheKeys);
+        if (cacheKeys != null)
+            redisTemplate.delete(cacheKeys);
         return ApiResult.success();
     }
 }

+ 25 - 0
src/main/java/com/zhiyun/project/monitor/controller/ServerController.java

@@ -0,0 +1,25 @@
+package com.zhiyun.project.monitor.controller;
+
+import com.zhiyun.common.model.ApiResult;
+import com.zhiyun.project.monitor.domain.Server;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * 服务器监控
+ *
+ * @author ruoyi
+ */
+@RestController
+@RequestMapping("/monitor/server")
+public class ServerController {
+    @PreAuthorize("@ss.hasPermi('monitor:server:list')")
+    @GetMapping()
+    public ApiResult getInfo() throws Exception {
+        Server server = new Server();
+        server.copyTo();
+        return ApiResult.success(server);
+    }
+}

+ 61 - 0
src/main/java/com/zhiyun/project/monitor/controller/SysLoginInfoController.java

@@ -0,0 +1,61 @@
+package com.zhiyun.project.monitor.controller;
+
+import com.zhiyun.common.annotation.Log;
+import com.zhiyun.common.constant.CacheConstants;
+import com.zhiyun.common.core.redis.RedisCache;
+import com.zhiyun.common.enums.BusinessType;
+import com.zhiyun.common.model.ApiResult;
+import com.zhiyun.common.model.TableResult;
+import com.zhiyun.project.common.BaseController;
+import com.zhiyun.project.monitor.domain.body.LoginInfoBody;
+import com.zhiyun.project.monitor.service.ISysLoginInfoService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.Arrays;
+import java.util.stream.Collectors;
+
+/**
+ * 系统访问记录
+ *
+ * @author ruoyi
+ */
+@RestController
+@RequestMapping("/monitor/logininfor")
+public class SysLoginInfoController extends BaseController {
+
+    @Autowired
+    private ISysLoginInfoService loginInfoService;
+    @Autowired
+    private RedisCache redisCache;
+
+    @PreAuthorize("@ss.hasPermi('monitor:logininfor:list')")
+    @GetMapping("/list")
+    public TableResult list(LoginInfoBody body) {
+        return TableResult.getTableResult(loginInfoService.pageLoginInfo(body));
+    }
+
+    @PreAuthorize("@ss.hasPermi('monitor:logininfor:remove')")
+    @Log(title = "登录日志", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{infoIds}")
+    public ApiResult remove(@PathVariable Long[] infoIds) {
+        return toApiResult(loginInfoService.removeBatchByIds(Arrays.stream(infoIds).collect(Collectors.toSet())));
+    }
+
+    @PreAuthorize("@ss.hasPermi('monitor:logininfor:remove')")
+    @Log(title = "登录日志", businessType = BusinessType.CLEAN)
+    @DeleteMapping("/clean")
+    public ApiResult clean() {
+        loginInfoService.cleanLoginInfo();
+        return ApiResult.success();
+    }
+
+    @PreAuthorize("@ss.hasPermi('monitor:logininfor:unlock')")
+    @Log(title = "账户解锁", businessType = BusinessType.OTHER)
+    @GetMapping("/unlock/{userName}")
+    public ApiResult unlock(@PathVariable("userName") String userName) {
+        redisCache.deleteObject(CacheConstants.PWD_ERR_CNT_KEY + userName);
+        return ApiResult.success();
+    }
+}

+ 48 - 0
src/main/java/com/zhiyun/project/monitor/controller/SysOperlogController.java

@@ -0,0 +1,48 @@
+package com.zhiyun.project.monitor.controller;
+
+import com.zhiyun.common.annotation.Log;
+import com.zhiyun.common.enums.BusinessType;
+import com.zhiyun.common.model.ApiResult;
+import com.zhiyun.common.model.TableResult;
+import com.zhiyun.project.common.BaseController;
+import com.zhiyun.project.monitor.domain.body.OperLogBody;
+import com.zhiyun.project.monitor.service.ISysOperLogService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.Arrays;
+import java.util.stream.Collectors;
+
+/**
+ * 操作日志记录
+ *
+ * @author ruoyi
+ */
+@RestController
+@RequestMapping("/monitor/operlog")
+public class SysOperlogController extends BaseController {
+    @Autowired
+    private ISysOperLogService operLogService;
+
+    @PreAuthorize("@ss.hasPermi('monitor:operlog:list')")
+    @GetMapping("/list")
+    public TableResult list(OperLogBody body) {
+        return TableResult.getTableResult(operLogService.selectOperLogPage(body));
+    }
+
+    @Log(title = "操作日志", businessType = BusinessType.DELETE)
+    @PreAuthorize("@ss.hasPermi('monitor:operlog:remove')")
+    @DeleteMapping("/{operIds}")
+    public ApiResult remove(@PathVariable Long[] operIds) {
+        return toApiResult(operLogService.removeBatchByIds(Arrays.stream(operIds).collect(Collectors.toSet())));
+    }
+
+    @Log(title = "操作日志", businessType = BusinessType.CLEAN)
+    @PreAuthorize("@ss.hasPermi('monitor:operlog:remove')")
+    @DeleteMapping("/clean")
+    public ApiResult clean() {
+        operLogService.cleanOperLog();
+        return ApiResult.success();
+    }
+}

+ 75 - 0
src/main/java/com/zhiyun/project/monitor/controller/SysUserOnlineController.java

@@ -0,0 +1,75 @@
+package com.zhiyun.project.monitor.controller;
+
+import com.zhiyun.common.annotation.Log;
+import com.zhiyun.common.constant.CacheConstants;
+import com.zhiyun.common.core.redis.RedisCache;
+import com.zhiyun.common.enums.BusinessType;
+import com.zhiyun.common.model.ApiResult;
+import com.zhiyun.common.model.TableResult;
+import com.zhiyun.common.utils.StringUtils;
+import com.zhiyun.project.common.BaseController;
+import com.zhiyun.project.monitor.domain.SysUserOnline;
+import com.zhiyun.project.monitor.service.ISysUserOnlineService;
+import com.zhiyun.project.system.domain.dto.LoginUser;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * 在线用户监控
+ *
+ * @author ruoyi
+ */
+@RestController
+@RequestMapping("/monitor/online")
+public class SysUserOnlineController extends BaseController {
+    @Autowired
+    private ISysUserOnlineService userOnlineService;
+
+    @Autowired
+    private RedisCache redisCache;
+
+    @PreAuthorize("@ss.hasPermi('monitor:online:list')")
+    @GetMapping("/list")
+    public TableResult list(String ipaddr, String userName) {
+        Collection<String> keys = redisCache.keys(CacheConstants.LOGIN_TOKEN_KEY + "*");
+        List<SysUserOnline> userOnlineList = new ArrayList<>();
+        for (String key : keys) {
+            LoginUser user = redisCache.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));
+                }
+            } else if (StringUtils.isNotEmpty(ipaddr)) {
+                if (StringUtils.equals(ipaddr, user.getIpaddr())) {
+                    userOnlineList.add(userOnlineService.selectOnlineByIpaddr(ipaddr, user));
+                }
+            } else if (StringUtils.isNotEmpty(userName) && StringUtils.isNotNull(user.getUser())) {
+                if (StringUtils.equals(userName, user.getUsername())) {
+                    userOnlineList.add(userOnlineService.selectOnlineByUserName(userName, user));
+                }
+            } else {
+                userOnlineList.add(userOnlineService.loginUserToUserOnline(user));
+            }
+        }
+        Collections.reverse(userOnlineList);
+        userOnlineList.removeAll(Collections.singleton(null));
+        return TableResult.getTableResult(userOnlineList);
+    }
+
+    /**
+     * 强退用户
+     */
+    @PreAuthorize("@ss.hasPermi('monitor:online:forceLogout')")
+    @Log(title = "在线用户", businessType = BusinessType.FORCE)
+    @DeleteMapping("/{tokenId}")
+    public ApiResult forceLogout(@PathVariable String tokenId) {
+        redisCache.deleteObject(CacheConstants.LOGIN_TOKEN_KEY + tokenId);
+        return ApiResult.success();
+    }
+}

+ 211 - 0
src/main/java/com/zhiyun/project/monitor/domain/Server.java

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

+ 58 - 0
src/main/java/com/zhiyun/project/monitor/domain/SysLoginInfo.java

@@ -0,0 +1,58 @@
+package com.zhiyun.project.monitor.domain;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.zhiyun.common.annotation.Excel;
+import com.zhiyun.common.annotation.Excel.ColumnType;
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * 系统访问记录表 sys_logininfor
+ *
+ * @author ruoyi
+ */
+@Data
+public class SysLoginInfo {
+    private static final long serialVersionUID = 1L;
+
+    @TableId("info_id")
+    @Excel(name = "序号", cellType = ColumnType.NUMERIC)
+    private Long infoId;
+
+    @TableField("user_name")
+    @Excel(name = "用户账号")
+    private String userName;
+
+    @TableField("status")
+    @Excel(name = "登录状态", readConverterExp = "0=成功,1=失败")
+    private String status;
+
+    @TableField("ipaddr")
+    @Excel(name = "登录地址")
+    private String ipaddr;
+
+    @TableField("login_location")
+    @Excel(name = "登录地点")
+    private String loginLocation;
+
+    @TableField("browser")
+    @Excel(name = "浏览器")
+    private String browser;
+
+    @TableField("os")
+    @Excel(name = "操作系统")
+    private String os;
+
+    @TableField("msg")
+    @Excel(name = "提示消息")
+    private String msg;
+
+    @TableField("login_time")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @Excel(name = "访问时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
+    private Date loginTime;
+
+}

+ 86 - 0
src/main/java/com/zhiyun/project/monitor/domain/SysOperLog.java

@@ -0,0 +1,86 @@
+package com.zhiyun.project.monitor.domain;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.zhiyun.common.annotation.Excel;
+import com.zhiyun.common.annotation.Excel.ColumnType;
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * 操作日志记录表 oper_log
+ *
+ * @author ruoyi
+ */
+@Data
+public class SysOperLog {
+    private static final long serialVersionUID = 1L;
+
+    @Excel(name = "操作序号", cellType = ColumnType.NUMERIC)
+    @TableId("oper_id")
+    private Long operId;
+
+    @Excel(name = "操作模块")
+    @TableField("title")
+    private String title;
+
+    @Excel(name = "业务类型", readConverterExp = "0=其它,1=新增,2=修改,3=删除,4=授权,5=导出,6=导入,7=强退,8=生成代码,9=清空数据")
+    @TableField("business_type")
+    private Integer businessType;
+
+    @Excel(name = "请求方法")
+    @TableField("method")
+    private String method;
+
+    @Excel(name = "请求方式")
+    @TableField("request_method")
+    private String requestMethod;
+
+    @Excel(name = "操作类别", readConverterExp = "0=其它,1=后台用户,2=手机端用户")
+    @TableField("operator_type")
+    private Integer operatorType;
+
+    @Excel(name = "操作人员")
+    @TableField("oper_name")
+    private String operName;
+
+    @Excel(name = "部门名称")
+    @TableField("dept_name")
+    private String deptName;
+
+    @Excel(name = "请求地址")
+    @TableField("oper_url")
+    private String operUrl;
+
+    @Excel(name = "操作地址")
+    @TableField("oper_ip")
+    private String operIp;
+
+    @Excel(name = "操作地点")
+    @TableField("oper_location")
+    private String operLocation;
+
+    @Excel(name = "请求参数")
+    @TableField("oper_param")
+    private String operParam;
+
+    @Excel(name = "返回参数")
+    @TableField("json_result")
+    private String jsonResult;
+
+    @Excel(name = "状态", readConverterExp = "0=正常,1=异常")
+    @TableField("status")
+    private Integer status;
+
+    @Excel(name = "错误消息")
+    @TableField("error_msg")
+    private String errorMsg;
+
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @Excel(name = "操作时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
+    @TableField("oper_time")
+    private Date operTime;
+
+}

+ 51 - 0
src/main/java/com/zhiyun/project/monitor/domain/SysUserOnline.java

@@ -0,0 +1,51 @@
+package com.zhiyun.project.monitor.domain;
+
+import lombok.Data;
+
+/**
+ * 当前在线会话
+ *
+ * @author ruoyi
+ */
+@Data
+public class SysUserOnline {
+    /**
+     * 会话编号
+     */
+    private String tokenId;
+
+    /**
+     * 部门名称
+     */
+    private String deptName;
+
+    /**
+     * 用户名称
+     */
+    private String userName;
+
+    /**
+     * 登录IP地址
+     */
+    private String ipaddr;
+
+    /**
+     * 登录地址
+     */
+    private String loginLocation;
+
+    /**
+     * 浏览器类型
+     */
+    private String browser;
+
+    /**
+     * 操作系统
+     */
+    private String os;
+
+    /**
+     * 登录时间
+     */
+    private Long loginTime;
+}

+ 88 - 0
src/main/java/com/zhiyun/project/monitor/domain/server/Cpu.java

@@ -0,0 +1,88 @@
+package com.zhiyun.project.monitor.domain.server;
+
+import com.zhiyun.common.utils.Arith;
+
+/**
+ * CPU相关信息
+ *
+ * @author ruoyi
+ */
+public class Cpu {
+    /**
+     * 核心数
+     */
+    private int cpuNum;
+
+    /**
+     * CPU总的使用率
+     */
+    private double total;
+
+    /**
+     * CPU系统使用率
+     */
+    private double sys;
+
+    /**
+     * CPU用户使用率
+     */
+    private double used;
+
+    /**
+     * CPU当前等待率
+     */
+    private double wait;
+
+    /**
+     * CPU当前空闲率
+     */
+    private double free;
+
+    public int getCpuNum() {
+        return cpuNum;
+    }
+
+    public void setCpuNum(int cpuNum) {
+        this.cpuNum = cpuNum;
+    }
+
+    public double getTotal() {
+        return Arith.round(Arith.mul(total, 100), 2);
+    }
+
+    public void setTotal(double total) {
+        this.total = total;
+    }
+
+    public double getSys() {
+        return Arith.round(Arith.mul(sys / total, 100), 2);
+    }
+
+    public void setSys(double sys) {
+        this.sys = sys;
+    }
+
+    public double getUsed() {
+        return Arith.round(Arith.mul(used / total, 100), 2);
+    }
+
+    public void setUsed(double used) {
+        this.used = used;
+    }
+
+    public double getWait() {
+        return Arith.round(Arith.mul(wait / total, 100), 2);
+    }
+
+    public void setWait(double wait) {
+        this.wait = wait;
+    }
+
+    public double getFree() {
+        return Arith.round(Arith.mul(free / total, 100), 2);
+    }
+
+    public void setFree(double free) {
+        this.free = free;
+    }
+}

+ 115 - 0
src/main/java/com/zhiyun/project/monitor/domain/server/Jvm.java

@@ -0,0 +1,115 @@
+package com.zhiyun.project.monitor.domain.server;
+
+
+import com.zhiyun.common.utils.Arith;
+import com.zhiyun.common.utils.DateUtils;
+
+import java.lang.management.ManagementFactory;
+
+/**
+ * JVM相关信息
+ *
+ * @author ruoyi
+ */
+public class Jvm {
+    /**
+     * 当前JVM占用的内存总数(M)
+     */
+    private double total;
+
+    /**
+     * JVM最大可用内存总数(M)
+     */
+    private double max;
+
+    /**
+     * JVM空闲内存(M)
+     */
+    private double free;
+
+    /**
+     * JDK版本
+     */
+    private String version;
+
+    /**
+     * JDK路径
+     */
+    private String home;
+
+    public double getTotal() {
+        return Arith.div(total, (1024 * 1024), 2);
+    }
+
+    public void setTotal(double total) {
+        this.total = total;
+    }
+
+    public double getMax() {
+        return Arith.div(max, (1024 * 1024), 2);
+    }
+
+    public void setMax(double max) {
+        this.max = max;
+    }
+
+    public double getFree() {
+        return Arith.div(free, (1024 * 1024), 2);
+    }
+
+    public void setFree(double free) {
+        this.free = free;
+    }
+
+    public double getUsed() {
+        return Arith.div(total - free, (1024 * 1024), 2);
+    }
+
+    public double getUsage() {
+        return Arith.mul(Arith.div(total - free, total, 4), 100);
+    }
+
+    /**
+     * 获取JDK名称
+     */
+    public String getName() {
+        return ManagementFactory.getRuntimeMXBean().getVmName();
+    }
+
+    public String getVersion() {
+        return version;
+    }
+
+    public void setVersion(String version) {
+        this.version = version;
+    }
+
+    public String getHome() {
+        return home;
+    }
+
+    public void setHome(String home) {
+        this.home = home;
+    }
+
+    /**
+     * JDK启动时间
+     */
+    public String getStartTime() {
+        return DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, DateUtils.getServerStartDate());
+    }
+
+    /**
+     * JDK运行时间
+     */
+    public String getRunTime() {
+        return DateUtils.getDatePoor(DateUtils.getNowDate(), DateUtils.getServerStartDate());
+    }
+
+    /**
+     * 运行参数
+     */
+    public String getInputArgs() {
+        return ManagementFactory.getRuntimeMXBean().getInputArguments().toString();
+    }
+}

+ 54 - 0
src/main/java/com/zhiyun/project/monitor/domain/server/Mem.java

@@ -0,0 +1,54 @@
+package com.zhiyun.project.monitor.domain.server;
+
+
+import com.zhiyun.common.utils.Arith;
+
+/**
+ * 內存相关信息
+ *
+ * @author ruoyi
+ */
+public class Mem {
+    /**
+     * 内存总量
+     */
+    private double total;
+
+    /**
+     * 已用内存
+     */
+    private double used;
+
+    /**
+     * 剩余内存
+     */
+    private double free;
+
+    public double getTotal() {
+        return Arith.div(total, (1024 * 1024 * 1024), 2);
+    }
+
+    public void setTotal(long total) {
+        this.total = total;
+    }
+
+    public double getUsed() {
+        return Arith.div(used, (1024 * 1024 * 1024), 2);
+    }
+
+    public void setUsed(long used) {
+        this.used = used;
+    }
+
+    public double getFree() {
+        return Arith.div(free, (1024 * 1024 * 1024), 2);
+    }
+
+    public void setFree(long free) {
+        this.free = free;
+    }
+
+    public double getUsage() {
+        return Arith.mul(Arith.div(used, total, 4), 100);
+    }
+}

+ 73 - 0
src/main/java/com/zhiyun/project/monitor/domain/server/Sys.java

@@ -0,0 +1,73 @@
+package com.zhiyun.project.monitor.domain.server;
+
+/**
+ * 系统相关信息
+ *
+ * @author ruoyi
+ */
+public class Sys {
+    /**
+     * 服务器名称
+     */
+    private String computerName;
+
+    /**
+     * 服务器Ip
+     */
+    private String computerIp;
+
+    /**
+     * 项目路径
+     */
+    private String userDir;
+
+    /**
+     * 操作系统
+     */
+    private String osName;
+
+    /**
+     * 系统架构
+     */
+    private String osArch;
+
+    public String getComputerName() {
+        return computerName;
+    }
+
+    public void setComputerName(String computerName) {
+        this.computerName = computerName;
+    }
+
+    public String getComputerIp() {
+        return computerIp;
+    }
+
+    public void setComputerIp(String computerIp) {
+        this.computerIp = computerIp;
+    }
+
+    public String getUserDir() {
+        return userDir;
+    }
+
+    public void setUserDir(String userDir) {
+        this.userDir = userDir;
+    }
+
+    public String getOsName() {
+        return osName;
+    }
+
+    public void setOsName(String osName) {
+        this.osName = osName;
+    }
+
+    public String getOsArch() {
+        return osArch;
+    }
+
+    public void setOsArch(String osArch) {
+        this.osArch = osArch;
+    }
+}

+ 99 - 0
src/main/java/com/zhiyun/project/monitor/domain/server/SysFile.java

@@ -0,0 +1,99 @@
+package com.zhiyun.project.monitor.domain.server;
+
+/**
+ * 系统文件相关信息
+ *
+ * @author ruoyi
+ */
+public class SysFile {
+    /**
+     * 盘符路径
+     */
+    private String dirName;
+
+    /**
+     * 盘符类型
+     */
+    private String sysTypeName;
+
+    /**
+     * 文件类型
+     */
+    private String typeName;
+
+    /**
+     * 总大小
+     */
+    private String total;
+
+    /**
+     * 剩余大小
+     */
+    private String free;
+
+    /**
+     * 已经使用量
+     */
+    private String used;
+
+    /**
+     * 资源的使用率
+     */
+    private double usage;
+
+    public String getDirName() {
+        return dirName;
+    }
+
+    public void setDirName(String dirName) {
+        this.dirName = dirName;
+    }
+
+    public String getSysTypeName() {
+        return sysTypeName;
+    }
+
+    public void setSysTypeName(String sysTypeName) {
+        this.sysTypeName = sysTypeName;
+    }
+
+    public String getTypeName() {
+        return typeName;
+    }
+
+    public void setTypeName(String typeName) {
+        this.typeName = typeName;
+    }
+
+    public String getTotal() {
+        return total;
+    }
+
+    public void setTotal(String total) {
+        this.total = total;
+    }
+
+    public String getFree() {
+        return free;
+    }
+
+    public void setFree(String free) {
+        this.free = free;
+    }
+
+    public String getUsed() {
+        return used;
+    }
+
+    public void setUsed(String used) {
+        this.used = used;
+    }
+
+    public double getUsage() {
+        return usage;
+    }
+
+    public void setUsage(double usage) {
+        this.usage = usage;
+    }
+}

+ 28 - 0
src/main/java/com/zhiyun/project/monitor/mapper/SysLoginInfoMapper.java

@@ -0,0 +1,28 @@
+package com.zhiyun.project.monitor.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.zhiyun.project.monitor.domain.SysLoginInfo;
+import com.zhiyun.project.monitor.domain.body.LoginInfoBody;
+import org.apache.ibatis.annotations.Param;
+
+/**
+ * 系统访问日志情况信息 数据层
+ *
+ * @author ruoyi
+ */
+public interface SysLoginInfoMapper extends BaseMapper<SysLoginInfo> {
+
+    /**
+     * 查询系统登录日志集合
+     *
+     * @param param 访问日志对象
+     */
+    Page<SysLoginInfo> listLoginInfo(Page<SysLoginInfo> page, @Param("param") LoginInfoBody param);
+
+
+    /**
+     * 清空系统登录日志
+     */
+    int cleanLoginInfo();
+}

+ 26 - 0
src/main/java/com/zhiyun/project/monitor/mapper/SysOperLogMapper.java

@@ -0,0 +1,26 @@
+package com.zhiyun.project.monitor.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.zhiyun.project.monitor.domain.SysOperLog;
+import com.zhiyun.project.monitor.domain.body.OperLogBody;
+import org.apache.ibatis.annotations.Param;
+
+/**
+ * 操作日志 数据层
+ *
+ * @author ruoyi
+ */
+public interface SysOperLogMapper extends BaseMapper<SysOperLog> {
+    /**
+     * 查询系统操作日志集合
+     *
+     * @param operLog 操作日志对象
+     */
+    Page<SysOperLog> selectOperLogList(Page<SysOperLog> page, @Param("param") OperLogBody operLog);
+
+    /**
+     * 清空操作日志
+     */
+    void cleanOperLog();
+}

+ 26 - 0
src/main/java/com/zhiyun/project/monitor/service/ISysLoginInfoService.java

@@ -0,0 +1,26 @@
+package com.zhiyun.project.monitor.service;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.zhiyun.project.monitor.domain.SysLoginInfo;
+import com.zhiyun.project.monitor.domain.body.LoginInfoBody;
+
+/**
+ * 系统访问日志情况信息 服务层
+ *
+ * @author ruoyi
+ */
+public interface ISysLoginInfoService extends IService<SysLoginInfo> {
+
+    /**
+     * 查询系统登录日志集合
+     *
+     * @param body 访问日志对象
+     */
+    Page<SysLoginInfo> pageLoginInfo(LoginInfoBody body);
+
+    /**
+     * 清空系统登录日志
+     */
+    void cleanLoginInfo();
+}

+ 26 - 0
src/main/java/com/zhiyun/project/monitor/service/ISysOperLogService.java

@@ -0,0 +1,26 @@
+package com.zhiyun.project.monitor.service;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.zhiyun.project.monitor.domain.SysOperLog;
+import com.zhiyun.project.monitor.domain.body.OperLogBody;
+
+/**
+ * 操作日志 服务层
+ *
+ * @author ruoyi
+ */
+public interface ISysOperLogService extends IService<SysOperLog> {
+
+    /**
+     * 查询系统操作日志集合
+     *
+     * @param body 操作日志对象
+     */
+    Page<SysOperLog> selectOperLogPage(OperLogBody body);
+
+    /**
+     * 清空操作日志
+     */
+    void cleanOperLog();
+}

+ 47 - 0
src/main/java/com/zhiyun/project/monitor/service/ISysUserOnlineService.java

@@ -0,0 +1,47 @@
+package com.zhiyun.project.monitor.service;
+
+import com.zhiyun.project.monitor.domain.SysUserOnline;
+import com.zhiyun.project.system.domain.dto.LoginUser;
+
+/**
+ * 在线用户 服务层
+ *
+ * @author ruoyi
+ */
+public interface ISysUserOnlineService {
+    /**
+     * 通过登录地址查询信息
+     *
+     * @param ipaddr 登录地址
+     * @param user   用户信息
+     * @return 在线用户信息
+     */
+    SysUserOnline selectOnlineByIpaddr(String ipaddr, LoginUser user);
+
+    /**
+     * 通过用户名称查询信息
+     *
+     * @param userName 用户名称
+     * @param user     用户信息
+     * @return 在线用户信息
+     */
+    SysUserOnline selectOnlineByUserName(String userName, LoginUser user);
+
+    /**
+     * 通过登录地址/用户名称查询信息
+     *
+     * @param ipaddr   登录地址
+     * @param userName 用户名称
+     * @param user     用户信息
+     * @return 在线用户信息
+     */
+    SysUserOnline selectOnlineByInfo(String ipaddr, String userName, LoginUser user);
+
+    /**
+     * 设置在线用户信息
+     *
+     * @param user 用户信息
+     * @return 在线用户
+     */
+    SysUserOnline loginUserToUserOnline(LoginUser user);
+}

+ 31 - 0
src/main/java/com/zhiyun/project/monitor/service/impl/SysLoginInfoServiceImpl.java

@@ -0,0 +1,31 @@
+package com.zhiyun.project.monitor.service.impl;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.zhiyun.project.monitor.domain.SysLoginInfo;
+import com.zhiyun.project.monitor.domain.body.LoginInfoBody;
+import com.zhiyun.project.monitor.mapper.SysLoginInfoMapper;
+import com.zhiyun.project.monitor.service.ISysLoginInfoService;
+import org.springframework.stereotype.Service;
+
+/**
+ * 系统访问日志情况信息 服务层处理
+ *
+ * @author ruoyi
+ */
+@Service
+public class SysLoginInfoServiceImpl extends ServiceImpl<SysLoginInfoMapper, SysLoginInfo> implements ISysLoginInfoService {
+
+
+    @Override
+    public Page<SysLoginInfo> pageLoginInfo(LoginInfoBody body) {
+        Page<SysLoginInfo> page = new Page<>(body.getPageNum(), body.getPageSize());
+        baseMapper.listLoginInfo(page, body);
+        return page;
+    }
+
+    @Override
+    public void cleanLoginInfo() {
+        baseMapper.cleanLoginInfo();
+    }
+}

+ 30 - 0
src/main/java/com/zhiyun/project/monitor/service/impl/SysOperLogServiceImpl.java

@@ -0,0 +1,30 @@
+package com.zhiyun.project.monitor.service.impl;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.zhiyun.project.monitor.domain.SysOperLog;
+import com.zhiyun.project.monitor.domain.body.OperLogBody;
+import com.zhiyun.project.monitor.mapper.SysOperLogMapper;
+import com.zhiyun.project.monitor.service.ISysOperLogService;
+import org.springframework.stereotype.Service;
+
+/**
+ * 操作日志 服务层处理
+ *
+ * @author ruoyi
+ */
+@Service
+public class SysOperLogServiceImpl extends ServiceImpl<SysOperLogMapper, SysOperLog> implements ISysOperLogService {
+
+    @Override
+    public Page<SysOperLog> selectOperLogPage(OperLogBody body) {
+        Page<SysOperLog> page = new Page<>(body.getPageNum(), body.getPageSize());
+        baseMapper.selectOperLogList(page, body);
+        return page;
+    }
+
+    @Override
+    public void cleanOperLog() {
+        baseMapper.cleanOperLog();
+    }
+}

+ 86 - 0
src/main/java/com/zhiyun/project/monitor/service/impl/SysUserOnlineServiceImpl.java

@@ -0,0 +1,86 @@
+package com.zhiyun.project.monitor.service.impl;
+
+import com.zhiyun.common.utils.StringUtils;
+import com.zhiyun.project.monitor.domain.SysUserOnline;
+import com.zhiyun.project.monitor.service.ISysUserOnlineService;
+import com.zhiyun.project.system.domain.dto.LoginUser;
+import org.springframework.stereotype.Service;
+
+/**
+ * 在线用户 服务层处理
+ *
+ * @author ruoyi
+ */
+@Service
+public class SysUserOnlineServiceImpl implements ISysUserOnlineService {
+    /**
+     * 通过登录地址查询信息
+     *
+     * @param ipaddr 登录地址
+     * @param user   用户信息
+     * @return 在线用户信息
+     */
+    @Override
+    public SysUserOnline selectOnlineByIpaddr(String ipaddr, LoginUser user) {
+        if (StringUtils.equals(ipaddr, user.getIpaddr())) {
+            return loginUserToUserOnline(user);
+        }
+        return null;
+    }
+
+    /**
+     * 通过用户名称查询信息
+     *
+     * @param userName 用户名称
+     * @param user     用户信息
+     * @return 在线用户信息
+     */
+    @Override
+    public SysUserOnline selectOnlineByUserName(String userName, LoginUser user) {
+        if (StringUtils.equals(userName, user.getUsername())) {
+            return loginUserToUserOnline(user);
+        }
+        return null;
+    }
+
+    /**
+     * 通过登录地址/用户名称查询信息
+     *
+     * @param ipaddr   登录地址
+     * @param userName 用户名称
+     * @param user     用户信息
+     * @return 在线用户信息
+     */
+    @Override
+    public SysUserOnline selectOnlineByInfo(String ipaddr, String userName, LoginUser user) {
+        if (StringUtils.equals(ipaddr, user.getIpaddr()) && StringUtils.equals(userName, user.getUsername())) {
+            return loginUserToUserOnline(user);
+        }
+        return null;
+    }
+
+    /**
+     * 设置在线用户信息
+     *
+     * @param user 用户信息
+     * @return 在线用户
+     */
+    @Override
+    public SysUserOnline loginUserToUserOnline(LoginUser user) {
+        if (StringUtils.isNull(user) || StringUtils.isNull(user.getUser())) {
+            return null;
+        }
+        SysUserOnline sysUserOnline = new SysUserOnline();
+        sysUserOnline.setTokenId(user.getToken());
+        sysUserOnline.setUserName(user.getUsername());
+        sysUserOnline.setIpaddr(user.getIpaddr());
+        sysUserOnline.setLoginLocation(user.getLoginLocation());
+        sysUserOnline.setBrowser(user.getBrowser());
+        sysUserOnline.setOs(user.getOs());
+        sysUserOnline.setLoginTime(user.getLoginTime());
+        if (StringUtils.isNotNull(user.getDept())) {
+            sysUserOnline.setDeptName(user.getDept().getDeptName());
+        }
+        return sysUserOnline;
+    }
+}

+ 0 - 33
src/main/java/com/zhiyun/project/project/controller/CommandController.java

@@ -1,33 +0,0 @@
-package com.zhiyun.project.project.controller;
-
-import com.zhiyun.common.model.ApiResult;
-import com.zhiyun.project.project.domain.entity.Command;
-import com.zhiyun.project.project.service.CommandService;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Controller;
-import org.springframework.web.bind.annotation.*;
-
-@RestController
-@RequestMapping("/command")
-public class CommandController {
-    @Autowired
-    private CommandService commandService;
-
-
-    @GetMapping("/listCommandOptions")
-    public ApiResult listCompanyOptions() {
-        return ApiResult.success(commandService.listCommandOptions());
-    }
-
-
-    @GetMapping("/getCommandList")
-    public ApiResult getCommandList(){
-        return ApiResult.success(commandService.list());
-    }
-
-    @PostMapping("/save")
-    public ApiResult saveCommand(@RequestBody Command command){
-        return ApiResult.success(commandService.save(command));
-    }
-
-}

+ 0 - 69
src/main/java/com/zhiyun/project/project/controller/CompanyController.java

@@ -1,69 +0,0 @@
-package com.zhiyun.project.project.controller;
-
-import com.zhiyun.common.model.ApiResult;
-import com.zhiyun.common.model.BaseBody;
-import com.zhiyun.common.model.TableResult;
-import com.zhiyun.project.common.BaseController;
-import com.zhiyun.project.project.domain.entity.Company;
-import com.zhiyun.project.project.service.CompanyService;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.web.bind.annotation.*;
-
-/**
- * 公司 前端控制器
- *
- * @author zhiyun
- * @since 2023-05-24
- */
-@RestController
-@RequestMapping("/company")
-public class CompanyController extends BaseController {
-    @Autowired
-    private CompanyService companyService;
-
-    /**
-     * 公司筛选项
-     */
-    @GetMapping("/listCompanyOptions")
-    public ApiResult listCompanyOptions() {
-        return ApiResult.success(companyService.listCompanyOptions());
-    }
-
-    /**
-     * 获取公司数据
-     */
-    @GetMapping("/listPage")
-    public TableResult listPage(BaseBody body) {
-        return TableResult.getTableResult(companyService.page(body.getPage()));
-    }
-
-    /**
-     * 添加公司
-     */
-    @PreAuthorize("@ss.checkAdmin()")
-    @PostMapping("/save")
-    public ApiResult save(@RequestBody Company entity) {
-        return toApiResult(companyService.save(entity));
-    }
-
-    /**
-     * 修改公司
-     */
-    @PreAuthorize("@ss.checkAdmin()")
-    @PutMapping("/modify")
-    public ApiResult modify(@RequestBody Company entity) {
-        return toApiResult(companyService.updateById(entity));
-    }
-
-    /**
-     * 删除公司
-     */
-    @PreAuthorize("@ss.checkAdmin()")
-    @DeleteMapping("/remove/{cpyid}")
-    public ApiResult remove(@PathVariable Integer cpyid) {
-        return toApiResult(companyService.removeById(cpyid));
-    }
-
-}
-

+ 0 - 90
src/main/java/com/zhiyun/project/project/controller/DeviceController.java

@@ -1,90 +0,0 @@
-package com.zhiyun.project.project.controller;
-
-import com.zhiyun.common.model.ApiResult;
-import com.zhiyun.common.model.TableResult;
-import com.zhiyun.framework.web.SysPermissionService;
-import com.zhiyun.project.common.BaseController;
-import com.zhiyun.project.project.domain.body.DeviceBody;
-import com.zhiyun.project.project.domain.entity.Device;
-import com.zhiyun.project.project.service.DeviceService;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.web.bind.annotation.*;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.UUID;
-import java.util.stream.Collectors;
-
-/**
- * 设备表 前端控制器
- *
- * @author zhiyun
- * @since 2023-05-24
- */
-@RestController
-@RequestMapping("/device")
-public class DeviceController extends BaseController {
-    @Autowired
-    private DeviceService deviceService;
-    @Autowired
-    private SysPermissionService sysPermissionService;
-
-    /**
-     * 查询未分配的设备
-     */
-    @GetMapping("/listNoAllotDevice")
-    public TableResult listNoAllotDevice() {
-        return TableResult.getTableResult(deviceService.listNoAllotDevice());
-    }
-
-    /**
-     * 站点信息详查
-     */
-    @GetMapping("/listPage")
-    public TableResult listPage(DeviceBody body) {
-        return TableResult.getTableResult(deviceService.listPage(body));
-    }
-
-    /**
-     * 站点信息详查
-     */
-    @GetMapping("/listDeviceOptions")
-    public ApiResult listDeviceOptions() {
-        return ApiResult.success(deviceService.listDeviceOptions());
-    }
-
-
-    /**
-     * 添加设备
-     */
-    @PreAuthorize("@ss.checkAdmin()")
-    @PostMapping("/save")
-    public ApiResult saveDevice(@RequestBody Device entity) {
-        entity.setDevicename(UUID.randomUUID().toString());
-        return toApiResult(deviceService.save(entity));
-    }
-
-    /**
-     * 修改设备基础信息
-     */
-    @PreAuthorize("@ss.checkAdmin()")
-    @PutMapping("/modify")
-    public ApiResult modify(@RequestBody Device entity) {
-        sysPermissionService.checkUserDevicePerm(entity.getDevicename());
-        return toApiResult(deviceService.modify(entity));
-    }
-
-    /**
-     * 删除设备
-     */
-    @PreAuthorize("@ss.checkAdmin()")
-    @DeleteMapping("/remove/{devicenames}")
-    public ApiResult remove(@PathVariable String[] devicenames) {
-        List<String> idList = Arrays.stream(devicenames).collect(Collectors.toList());
-        sysPermissionService.checkUserDevicePerm(idList);
-        return toApiResult(deviceService.remove(idList));
-    }
-
-}
-

+ 0 - 47
src/main/java/com/zhiyun/project/project/controller/HomeController.java

@@ -1,47 +0,0 @@
-package com.zhiyun.project.project.controller;
-
-import com.zhiyun.common.annotation.Anonymous;
-import com.zhiyun.common.model.ApiResult;
-import com.zhiyun.project.project.service.HomeService;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-@RestController
-@RequestMapping("/home")
-public class HomeController {
-
-    @Autowired
-    private HomeService homeService;
-
-    /**
-     * 各总数集合
-     * @return
-     */
-    @GetMapping("/getIndexNum")
-    @Anonymous
-    public ApiResult getIndexNum() {
-        return ApiResult.success(homeService.getIndexNum());
-    }
-
-    /**
-     * 设备各类型数量
-     * @return
-     */
-    @GetMapping("/getDeviceTypeNum")
-    @Anonymous
-    public ApiResult getDeviceTypeNum() {
-        return ApiResult.success(homeService.getDeviceTypeNum());
-    }
-
-    /**
-     * 获取分配数量
-     */
-    @GetMapping("/getOrAllotNum")
-    @Anonymous
-    public ApiResult getOrAllotNum() {
-        return ApiResult.success(homeService.getOrAllotNum());
-    }
-
-}

+ 0 - 45
src/main/java/com/zhiyun/project/project/controller/LogController.java

@@ -1,45 +0,0 @@
-package com.zhiyun.project.project.controller;
-
-import com.zhiyun.common.model.ApiResult;
-import com.zhiyun.common.model.TableResult;
-import com.zhiyun.project.project.domain.body.LogBody;
-import com.zhiyun.project.project.domain.body.ProjectBody;
-import com.zhiyun.project.project.service.LogService;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.web.bind.annotation.*;
-
-import java.util.Date;
-
-@RestController
-@RequestMapping("/log")
-public class LogController {
-    @Autowired
-    private LogService logService;
-
-    /**
-     * 分页查询项目
-     */
-    @GetMapping("/listPage")
-    public TableResult listPage(LogBody body) {
-        return TableResult.getTableResult(logService.listPage(body));
-    }
-
-    /**
-     * 删除项目
-     */
-    @PreAuthorize("@ss.checkAdmin()")
-    @DeleteMapping("/remove/{logid}")
-    public ApiResult remove(@PathVariable Integer logid) {
-        return ApiResult.success(logService.removeById(logid));
-    }
-
-
-    /**
-     * 实时日志
-     */
-    @GetMapping("/nowLog")
-    public ApiResult nowLog(String devicename) {
-        return ApiResult.success(logService.nowLog(devicename));
-    }
-}

+ 0 - 28
src/main/java/com/zhiyun/project/project/controller/MQTTController.java

@@ -1,28 +0,0 @@
-package com.zhiyun.project.project.controller;
-
-import com.zhiyun.common.annotation.Anonymous;
-import com.zhiyun.common.model.ApiResult;
-import com.zhiyun.project.project.domain.body.MqttBody;
-import com.zhiyun.project.project.mqtt.sender.CommonSender;
-import com.zhiyun.project.project.service.MqttService;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-@RestController
-@RequestMapping("/mqtt")
-public class MQTTController {
-
-    @Autowired
-    private MqttService mqttService;
-
-    @PostMapping("/send")
-    @Anonymous
-    public ApiResult send(@RequestBody MqttBody mqttBody) {
-        return ApiResult.success(mqttService.send(mqttBody));
-    }
-
-
-}

+ 0 - 92
src/main/java/com/zhiyun/project/project/controller/ProjectController.java

@@ -1,92 +0,0 @@
-package com.zhiyun.project.project.controller;
-
-import com.zhiyun.common.model.ApiResult;
-import com.zhiyun.common.model.TableResult;
-import com.zhiyun.framework.web.TokenService;
-import com.zhiyun.project.common.BaseController;
-import com.zhiyun.project.project.domain.body.ProjectBody;
-import com.zhiyun.project.project.domain.entity.Project;
-import com.zhiyun.project.project.service.ProjectService;
-import com.zhiyun.project.system.domain.dto.LoginUser;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.web.bind.annotation.*;
-
-/**
- * 项目 前端控制器
- *
- * @author zhiyun
- * @since 2023-05-24
- */
-@RestController
-@RequestMapping("/project")
-public class ProjectController extends BaseController {
-    @Autowired
-    private ProjectService projectService;
-    @Autowired
-    TokenService tokenService;
-
-    /**
-     * 选择系统当前项目
-     */
-    @PostMapping("setCurrentProject")
-    public ApiResult setCurrentProject(Integer pjtid) {
-        LoginUser loginUser = getLoginUser();
-        loginUser.setCurrentProjectId(pjtid);
-        tokenService.setLoginUser(loginUser);
-        return ApiResult.success();
-    }
-
-    /**
-     * 获取系统当前项目
-     */
-    @GetMapping("getCurrentProject")
-    public ApiResult getCurrentProject() {
-        return ApiResult.success(projectService.getById(getLoginUser().getCurrentProjectId()));
-    }
-
-    /**
-     * 分页查询项目
-     */
-    @GetMapping("/listPage")
-    public TableResult listPage(ProjectBody body) {
-        return TableResult.getTableResult(projectService.listPage(body));
-    }
-
-    /**
-     * 查询所有项目
-     */
-    @GetMapping("/list")
-    public ApiResult list() {
-        return ApiResult.success(projectService.listProject());
-    }
-
-    /**
-     * 添加项目
-     */
-    @PreAuthorize("@ss.checkAdmin()")
-    @PostMapping("/save")
-    public ApiResult save(@RequestBody Project entity) {
-        return toApiResult(projectService.save(entity));
-    }
-
-    /**
-     * 修改项目
-     */
-    @PreAuthorize("@ss.checkAdmin()")
-    @PutMapping("/modify")
-    public ApiResult modify(@RequestBody Project entity) {
-        return toApiResult(projectService.updateById(entity));
-    }
-
-    /**
-     * 删除项目
-     */
-    @PreAuthorize("@ss.checkAdmin()")
-    @DeleteMapping("/remove/{pjtid}")
-    public ApiResult remove(@PathVariable Integer pjtid) {
-        return toApiResult(projectService.removeById(pjtid));
-    }
-
-}
-

+ 0 - 18
src/main/java/com/zhiyun/project/project/domain/body/DeviceBody.java

@@ -1,18 +0,0 @@
-package com.zhiyun.project.project.domain.body;
-
-import com.zhiyun.common.model.BaseBody;
-import lombok.Data;
-
-/**
- * 设备查询参数
- *
- * @author yang xiao kun
- * create on 2023/5/23
- */
-@Data
-public class DeviceBody extends BaseBody {
-    /**
-     * 设备名称
-     */
-    private String devicename;
-}

+ 0 - 10
src/main/java/com/zhiyun/project/project/domain/body/LogBody.java

@@ -1,10 +0,0 @@
-package com.zhiyun.project.project.domain.body;
-
-import com.zhiyun.common.model.BaseBody;
-import lombok.Data;
-
-@Data
-public class LogBody extends BaseBody {
-    private String devicename;
-    private Integer cmdid;
-}

+ 0 - 27
src/main/java/com/zhiyun/project/project/domain/body/MqttBody.java

@@ -1,27 +0,0 @@
-package com.zhiyun.project.project.domain.body;
-
-import lombok.Data;
-
-import java.util.Map;
-
-/**
- * @author yxk
- * @since 2024/11/21 9:19
- */
-@Data
-public class MqttBody {
-    /**
-     * 指令ID
-     */
-    private Integer cmdid;
-    /**
-     * 设备ID
-     */
-    private String devicename;
-    /**
-     * 内容
-     */
-    private String content;
-
-    private Map<String, String> cmdData;
-}

+ 0 - 18
src/main/java/com/zhiyun/project/project/domain/body/ProjectBody.java

@@ -1,18 +0,0 @@
-package com.zhiyun.project.project.domain.body;
-
-import com.zhiyun.common.model.BaseBody;
-import lombok.Data;
-
-/**
- * 设备查询参数
- *
- * @author yang xiao kun
- * create on 2023/5/23
- */
-@Data
-public class ProjectBody extends BaseBody {
-    /**
-     * 设备名称
-     */
-    private String projectName;
-}

+ 0 - 114
src/main/java/com/zhiyun/project/project/domain/dto/MqttDTO.java

@@ -1,114 +0,0 @@
-package com.zhiyun.project.project.domain.dto;
-
-import com.alibaba.fastjson2.JSON;
-import com.zhiyun.common.utils.DatePatternUtil;
-import com.zhiyun.common.utils.DateUtils;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-
-import java.time.LocalDateTime;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * MQTT 消息模板类
- *
- * @author yang xiao kun
- * create on 2021/1/21
- */
-@Data
-@NoArgsConstructor
-public class MqttDTO {
-    /**
-     * M 指令
-     */
-    private String m;
-    /**
-     * 数据项
-     */
-    private Map<String, Object> data;
-
-    /**
-     * 通用构造器
-     *
-     * @param m 报文协议 code值
-     */
-    public MqttDTO(String m) {
-        this.m = m;
-        this.data = new HashMap<>();
-    }
-
-    /**
-     * 由 JSON 字符串 转 MqttMsgDto 对象
-     */
-    public static MqttDTO parse(String jsonStr) {
-        return JSON.parseObject(jsonStr, MqttDTO.class);
-    }
-
-    /**
-     * 往data中添加数据 链式
-     *
-     * @param key   键
-     * @param value 值
-     */
-    public MqttDTO put(String key, Object value) {
-        data.put(key, value);
-        return this;
-    }
-
-    /**
-     * 获取json 对象
-     */
-    public String json() {
-        return JSON.toJSONString(this);
-    }
-
-    /**
-     * 获取 Object 数据
-     */
-    public Object getObject(String key) {
-        return data.get(key);
-    }
-
-    /**
-     * 获取String 数据
-     */
-    public String getString(String key) {
-        return data.containsKey(key) ? data.get(key).toString() : null;
-    }
-
-    /**
-     * 获取 Integer 数据
-     */
-    public Integer getInt(String key) {
-        return isNull(key) ? null : Integer.parseInt(data.get(key).toString());
-    }
-
-    /**
-     * 获取 Double 数据
-     */
-    public Double getDouble(String key) {
-        return isNull(key) ? null : Double.parseDouble(data.get(key).toString());
-    }
-
-    /**
-     * 获取 日期数据 数据
-     */
-    public LocalDateTime getDate(String key) {
-        if (isNull(key)) return null;
-        try {
-            return LocalDateTime.parse(data.get(key).toString(), DatePatternUtil.NORM_DATETIME_FORMATTER);
-        } catch (Exception e) {
-            return LocalDateTime.parse(data.get(key).toString(), DatePatternUtil.NORM_DATETIME_FORMATTER_2);
-        }
-    }
-
-    /**
-     * 判断是否为空
-     *
-     * @param key key
-     */
-    private boolean isNull(String key) {
-        return (!data.containsKey(key) || data.get(key).toString().equals(""));
-    }
-}

+ 0 - 29
src/main/java/com/zhiyun/project/project/domain/dto/Perm.java

@@ -1,29 +0,0 @@
-package com.zhiyun.project.project.domain.dto;
-
-import lombok.Data;
-
-/**
- * 数据权限
- *
- * @author yang xiao kun
- * create on 2023/11/15
- */
-@Data
-public class Perm {
-
-    /**
-     * 当前登录用户名
-     */
-    private Integer userId = null;
-
-    /**
-     * 当前项目ID
-     */
-    private Integer crtPjtid = null;
-
-    /**
-     * 项目权限过滤SQL
-     */
-    private String project = null;
-
-}

+ 0 - 47
src/main/java/com/zhiyun/project/project/domain/entity/Command.java

@@ -1,47 +0,0 @@
-package com.zhiyun.project.project.domain.entity;
-
-import com.baomidou.mybatisplus.annotation.TableId;
-import lombok.Data;
-
-import java.io.Serializable;
-import java.util.Date;
-
-@Data
-public class Command implements Serializable {
-    /**
-     * 主键id
-     */
-    @TableId
-    private Integer id;
-
-    /**
-     * 命令名称
-     */
-    private String title;
-
-    /**
-     * 命令内容
-     */
-    private String label;
-
-    /**
-     * 是否弹出
-     */
-    private Integer ifCustom;
-
-    /**
-     * 是否开关
-     */
-    private Integer ifSwitch;
-
-    /**
-     * 是否板卡指令
-     */
-    private Integer ifCard;
-
-    /**
-     * 创建时间
-     */
-    private Date createTime;
-
-}

+ 0 - 39
src/main/java/com/zhiyun/project/project/domain/entity/Company.java

@@ -1,39 +0,0 @@
-package com.zhiyun.project.project.domain.entity;
-
-import com.baomidou.mybatisplus.annotation.TableId;
-import lombok.Data;
-
-import java.io.Serializable;
-import java.time.LocalDateTime;
-
-/**
- * 公司
- *
- * @author zhiyun
- * @since 2023-05-23
- */
-@Data
-public class Company implements Serializable {
-
-    /**
-     * 主键ID
-     */
-    @TableId
-    private Integer cpyid;
-
-    /**
-     * 公司名称
-     */
-    private String companyName;
-
-    /**
-     * 备注
-     */
-    private String remark;
-
-    /**
-     * 创建时间
-     */
-    private LocalDateTime createTime;
-
-}

+ 0 - 70
src/main/java/com/zhiyun/project/project/domain/entity/Device.java

@@ -1,70 +0,0 @@
-package com.zhiyun.project.project.domain.entity;
-
-import com.baomidou.mybatisplus.annotation.TableId;
-import lombok.Data;
-
-import java.io.Serializable;
-
-/**
- * 设备表
- *
- * @author zhiyun
- * @since 2023-05-24
- */
-@Data
-public class Device implements Serializable {
-
-    /**
-     * 序号
-     */
-    @TableId
-    private Integer id;
-
-    private Integer pjtid;
-
-    /**
-     * 设备名称
-     */
-    private String devicename;
-
-    /**
-     * 设备编号
-     */
-    private String aliasName;
-
-    /**
-     * 设备类型
-     */
-    private String deviceType;
-
-    private String mqttUsername;
-    private String mqttPassword;
-    private String groupId;
-    private String sn;
-
-    /**
-     * 经度
-     */
-    private String longitude;
-
-    /**
-     * 纬度
-     */
-    private String latitude;
-
-    /**
-     * 备注
-     */
-    private String remark;
-
-    /**
-     * mqtt设备类型
-     */
-    private String type;
-
-    /**
-     * sim卡号
-     */
-    private String simNo;
-
-}

+ 0 - 76
src/main/java/com/zhiyun/project/project/domain/entity/DeviceState.java

@@ -1,76 +0,0 @@
-package com.zhiyun.project.project.domain.entity;
-
-import com.baomidou.mybatisplus.annotation.TableId;
-import lombok.Data;
-
-import java.io.Serializable;
-import java.math.BigDecimal;
-import java.time.LocalDateTime;
-import java.util.Date;
-
-/**
- * 设备状态表
- *
- * @author zhiyun
- * @since 2023-05-24
- */
-@Data
-public class DeviceState implements Serializable {
-
-    /**
-     * 序号
-     */
-    @TableId
-    private Integer id;
-
-    /**
-     * 设备名称
-     */
-    private String devicename;
-
-    /**
-     * 相应频率
-     */
-    private Integer freq;
-
-    /**
-     * 电压
-     */
-    private BigDecimal powerVolt;
-
-    /**
-     * 卫星颗数
-     */
-    private Integer satNum;
-
-    /**
-     * 4g信号强度
-     */
-    private String signal4g;
-
-    /**
-     * 经度
-     */
-    private String lon;
-
-    /**
-     * 纬度
-     */
-    private String lat;
-
-    /**
-     * 备注
-     */
-    private String oemType;
-
-
-    /**
-     * 版本
-     */
-    private String version;
-
-    /**
-     * 更新时间
-     */
-    private LocalDateTime uploadTime;
-}

+ 0 - 80
src/main/java/com/zhiyun/project/project/domain/entity/MqttLog.java

@@ -1,80 +0,0 @@
-package com.zhiyun.project.project.domain.entity;
-
-import com.baomidou.mybatisplus.annotation.TableId;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-
-import java.util.Date;
-
-@Data
-@NoArgsConstructor
-public class MqttLog {
-
-    @TableId
-    private Integer id;
-
-    /**
-     * 日志类型
-     */
-    private Integer type;
-
-    /**
-     * 主题
-     */
-    private String topic;
-
-    /**
-     * 设备名称
-     */
-    private String devicename;
-
-    /**
-     * 命令表ID
-     */
-    private Integer cmdid;
-    private String commandTitle;
-
-    /**
-     * 发送内容
-     */
-    private String content;
-
-    /**
-     * 状态
-     */
-    private Integer status;
-
-    private Date createTime;
-
-    public MqttLog(String topic, String devicename, Integer type, Integer cmdid, String content,Integer status) {
-        this.topic = topic;
-        this.type = type;
-        this.devicename = devicename;
-        this.cmdid = cmdid;
-        this.content = content;
-        this.status = status;
-    }
-
-    public MqttLog(String topic, String devicename, Integer type, String content, Integer status) {
-        this.topic = topic;
-        this.type = type;
-        this.devicename = devicename;
-        this.content = content;
-        this.status = status;
-    }
-
-    /**
-     * 创建普通日志
-     */
-    public static MqttLog createNormal(String topic, String devicename, Integer type, String content,Integer status) {
-        return new MqttLog(topic, devicename, type, content,status);
-    }
-
-    /**
-     * 创建普通日志
-     * 包含指令
-     */
-    public static MqttLog createWithCmd(String topic, String devicename, Integer type, Integer cmdid, String content,Integer status) {
-        return new MqttLog(topic, devicename, type, cmdid, content,status);
-    }
-}

+ 0 - 48
src/main/java/com/zhiyun/project/project/domain/entity/Project.java

@@ -1,48 +0,0 @@
-package com.zhiyun.project.project.domain.entity;
-
-import com.baomidou.mybatisplus.annotation.TableField;
-import com.baomidou.mybatisplus.annotation.TableId;
-import lombok.Data;
-
-import java.io.Serializable;
-import java.time.LocalDateTime;
-
-/**
- * 项目
- *
- * @author zhiyun
- * @since 2023-05-23
- */
-@Data
-public class Project implements Serializable {
-
-    /**
-     * 主键ID
-     */
-    @TableId
-    private Integer pjtid;
-
-    /**
-     * 公司ID
-     */
-    private Integer cpyid;
-
-    @TableField(exist = false)
-    private String companyName;
-
-    /**
-     * 项目名称
-     */
-    private String projectName;
-
-    /**
-     * 备注
-     */
-    private String remark;
-
-    /**
-     * 创建时间
-     */
-    private LocalDateTime createTime;
-
-}

+ 0 - 91
src/main/java/com/zhiyun/project/project/domain/vo/DeviceVo.java

@@ -1,91 +0,0 @@
-package com.zhiyun.project.project.domain.vo;
-
-import lombok.Data;
-
-import java.math.BigDecimal;
-import java.util.Date;
-
-/**
- * 设备基础信息视图
- *
- * @author yang xiao kun
- * create on 2023/5/24
- */
-@Data
-public class DeviceVo {
-
-    /**
-     * 序号
-     */
-    private Integer id;
-
-    /**
-     * 设备编号
-     */
-    private String devicename;
-
-    /**
-     * 设备名称
-     */
-    private String aliasName;
-
-    /**
-     * 设备类型
-     */
-    private String deviceType;
-
-    /**
-     * 经度
-     */
-    private String longitude;
-
-    /**
-     * 纬度
-     */
-    private String latitude;
-
-    /**
-     * 设备状态
-     */
-    private Integer status;
-
-    /**
-     * 更新时间
-     */
-    private Date updateTime;
-
-    /**
-     * 备注
-     */
-    private String remark;
-
-    /**
-     * sim卡号
-     */
-    private String simNo;
-
-    /**
-     * 数据上传时间间隔
-     */
-    private Integer freq;
-    /**
-     * 电压
-     */
-    private BigDecimal powerVolt;
-
-    /**
-     * 卫星颗数
-     */
-    private Integer satNum;
-
-    /**
-     * 4g信号强度
-     */
-    private Integer signal4g;
-
-    /**
-     * 版本
-     */
-    private String version;
-
-}

+ 0 - 21
src/main/java/com/zhiyun/project/project/domain/vo/SelectOptionsVo.java

@@ -1,21 +0,0 @@
-package com.zhiyun.project.project.domain.vo;
-
-import lombok.Data;
-import lombok.NoArgsConstructor;
-
-/**
- * 下拉筛选项视图
- */
-@Data
-@NoArgsConstructor
-public class SelectOptionsVo {
-    /**
-     * 展示字段
-     */
-    private String label;
-    /**
-     * 传参字段
-     */
-    private Object value;
-
-}

+ 0 - 13
src/main/java/com/zhiyun/project/project/mapper/CommandMapper.java

@@ -1,13 +0,0 @@
-package com.zhiyun.project.project.mapper;
-
-import com.baomidou.mybatisplus.core.mapper.BaseMapper;
-import com.zhiyun.project.project.domain.entity.Command;
-import com.zhiyun.project.project.domain.vo.SelectOptionsVo;
-import org.apache.ibatis.annotations.Mapper;
-
-import java.util.List;
-
-@Mapper
-public interface CommandMapper extends BaseMapper<Command> {
-    List<SelectOptionsVo> listCommandOptions();
-}

+ 0 - 19
src/main/java/com/zhiyun/project/project/mapper/CompanyMapper.java

@@ -1,19 +0,0 @@
-package com.zhiyun.project.project.mapper;
-
-import com.baomidou.mybatisplus.core.mapper.BaseMapper;
-import com.zhiyun.project.project.domain.entity.Company;
-import com.zhiyun.project.project.domain.vo.SelectOptionsVo;
-import org.apache.ibatis.annotations.Mapper;
-
-import java.util.List;
-
-/**
- * 公司表 Mapper 接口
- *
- * @author zhiyun
- * @since 2023-05-24
- */
-@Mapper
-public interface CompanyMapper extends BaseMapper<Company> {
-    List<SelectOptionsVo> listCompanyOptions();
-}

+ 0 - 60
src/main/java/com/zhiyun/project/project/mapper/DeviceMapper.java

@@ -1,60 +0,0 @@
-package com.zhiyun.project.project.mapper;
-
-import com.baomidou.mybatisplus.core.mapper.BaseMapper;
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.zhiyun.project.project.domain.body.DeviceBody;
-import com.zhiyun.project.project.domain.dto.Perm;
-import com.zhiyun.project.project.domain.entity.Device;
-import com.zhiyun.project.project.domain.vo.DeviceVo;
-import com.zhiyun.project.project.domain.vo.SelectOptionsVo;
-import org.apache.ibatis.annotations.Mapper;
-import org.apache.ibatis.annotations.Param;
-
-import java.util.List;
-import java.util.Map;
-
-/**
- * 设备表 Mapper 接口
- *
- * @author zhiyun
- * @since 2023-05-24
- */
-@Mapper
-public interface DeviceMapper extends BaseMapper<Device> {
-
-    /**
-     * 获取未分配项目的设备
-     */
-    List<DeviceVo> listNoAllotDevice();
-
-    /**
-     * 站点信息详查列表
-     */
-    Page<DeviceVo> listPage(Page<DeviceVo> page, @Param("perm") Perm perm, @Param("param") DeviceBody body);
-
-    /**
-     * 设备筛选项
-     */
-    List<SelectOptionsVo> listDeviceOption(@Param("perm") Perm perm);
-
-    /**
-     * 校验用户设备权限
-     */
-    int checkUserPrem(@Param("list") List<String> devicename, @Param("cpyid") Integer cpyid);
-
-    /**
-     * 逻辑批量删除设备
-     */
-    void removeByDevicename(@Param("list") List<String> devicenames);
-
-    /**
-     * 获取设备类型数量
-     * @return
-     */
-    List<Map<String,Integer>> getDeviceCount();
-
-    /**
-     * 获取未分配数量
-     */
-    Long noAllotNum();
-}

Some files were not shown because too many files changed in this diff