init code

This commit is contained in:
cuixuan 2025-04-15 09:42:38 +08:00
parent 9afeba53db
commit 46af9a06a5
684 changed files with 70899 additions and 0 deletions

47
.gitignore vendored Normal file
View File

@ -0,0 +1,47 @@
######################################################################
# Build Tools
.gradle
/build/
!gradle/wrapper/gradle-wrapper.jar
target/
!.mvn/wrapper/maven-wrapper.jar
######################################################################
# IDE
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### JRebel ###
rebel.xml
### NetBeans ###
nbproject/private/
build/*
nbbuild/
dist/
nbdist/
.nb-gradle/
######################################################################
# Others
*.log
*.xml.versionsBackup
*.swp
!*/build/*.java
!*/build/*.html
!*/build/*.xml

20
LICENSE Normal file
View File

@ -0,0 +1,20 @@
The MIT License (MIT)
Copyright (c) 2018 RuoYi
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

95
README.md Normal file
View File

@ -0,0 +1,95 @@
<p align="center">
<img alt="logo" src="https://oscimg.oschina.net/oscnet/up-d3d0a9303e11d522a06cd263f3079027715.png">
</p>
<h1 align="center" style="margin: 30px 0 30px; font-weight: bold;">RuoYi v3.8.9</h1>
<h4 align="center">基于SpringBoot+Vue前后端分离的Java快速开发框架</h4>
<p align="center">
<a href="https://gitee.com/y_project/RuoYi-Vue/stargazers"><img src="https://gitee.com/y_project/RuoYi-Vue/badge/star.svg?theme=dark"></a>
<a href="https://gitee.com/y_project/RuoYi-Vue"><img src="https://img.shields.io/badge/RuoYi-v3.8.9-brightgreen.svg"></a>
<a href="https://gitee.com/y_project/RuoYi-Vue/blob/master/LICENSE"><img src="https://img.shields.io/github/license/mashape/apistatus.svg"></a>
</p>
## 平台简介
若依是一套全部开源的快速开发平台,毫无保留给个人及企业免费使用。
* 前端采用Vue、Element UI。
* 后端采用Spring Boot、Spring Security、Redis & Jwt。
* 权限认证使用Jwt支持多终端认证系统。
* 支持加载动态权限菜单,多方式轻松权限控制。
* 高效率开发,使用代码生成器可以一键生成前后端代码。
* 提供了技术栈([Vue3](https://v3.cn.vuejs.org) [Element Plus](https://element-plus.org/zh-CN) [Vite](https://cn.vitejs.dev))版本[RuoYi-Vue3](https://gitcode.com/yangzongzhuan/RuoYi-Vue3),保持同步更新。
* 提供了单应用版本[RuoYi-Vue-fast](https://gitcode.com/yangzongzhuan/RuoYi-Vue-fast)Oracle版本[RuoYi-Vue-Oracle](https://gitcode.com/yangzongzhuan/RuoYi-Vue-Oracle),保持同步更新。
* 不分离版本,请移步[RuoYi](https://gitee.com/y_project/RuoYi),微服务版本,请移步[RuoYi-Cloud](https://gitee.com/y_project/RuoYi-Cloud)
* 阿里云折扣场:[点我进入](http://aly.ruoyi.vip),腾讯云秒杀场:[点我进入](http://txy.ruoyi.vip)&nbsp;&nbsp;
## 内置功能
1. 用户管理:用户是系统操作者,该功能主要完成系统用户配置。
2. 部门管理:配置系统组织机构(公司、部门、小组),树结构展现支持数据权限。
3. 岗位管理:配置系统用户所属担任职务。
4. 菜单管理:配置系统菜单,操作权限,按钮权限标识等。
5. 角色管理:角色菜单权限分配、设置角色按机构进行数据范围权限划分。
6. 字典管理:对系统中经常使用的一些较为固定的数据进行维护。
7. 参数管理:对系统动态配置常用参数。
8. 通知公告:系统通知公告信息发布维护。
9. 操作日志:系统正常操作日志记录和查询;系统异常信息日志记录和查询。
10. 登录日志:系统登录日志记录查询包含登录异常。
11. 在线用户:当前系统中活跃用户状态监控。
12. 定时任务:在线(添加、修改、删除)任务调度包含执行结果日志。
13. 代码生成前后端代码的生成java、html、xml、sql支持CRUD下载 。
14. 系统接口根据业务代码自动生成相关的api接口文档。
15. 服务监控监视当前系统CPU、内存、磁盘、堆栈等相关信息。
16. 缓存监控:对系统的缓存信息查询,命令统计等。
17. 在线构建器拖动表单元素生成相应的HTML代码。
18. 连接池监视监视当前系统数据库连接池状态可进行分析SQL找出系统性能瓶颈。
## 在线体验
- admin/admin123
- 陆陆续续收到一些打赏,为了更好的体验已用于演示服务器升级。谢谢各位小伙伴。
演示地址http://vue.ruoyi.vip
文档地址http://doc.ruoyi.vip
## 演示图
<table>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/cd1f90be5f2684f4560c9519c0f2a232ee8.jpg"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/1cbcf0e6f257c7d3a063c0e3f2ff989e4b3.jpg"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/up-8074972883b5ba0622e13246738ebba237a.png"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-9f88719cdfca9af2e58b352a20e23d43b12.png"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/up-39bf2584ec3a529b0d5a3b70d15c9b37646.png"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-936ec82d1f4872e1bc980927654b6007307.png"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/up-b2d62ceb95d2dd9b3fbe157bb70d26001e9.png"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-d67451d308b7a79ad6819723396f7c3d77a.png"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/5e8c387724954459291aafd5eb52b456f53.jpg"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/644e78da53c2e92a95dfda4f76e6d117c4b.jpg"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/up-8370a0d02977eebf6dbf854c8450293c937.png"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-49003ed83f60f633e7153609a53a2b644f7.png"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/up-d4fe726319ece268d4746602c39cffc0621.png"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-c195234bbcd30be6927f037a6755e6ab69c.png"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/b6115bc8c31de52951982e509930b20684a.jpg"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-5e4daac0bb59612c5038448acbcef235e3a.png"/></td>
</tr>
</table>
## 若依前后端分离交流群
QQ群 [![加入QQ群](https://img.shields.io/badge/已满-937441-blue.svg)](https://jq.qq.com/?_wv=1027&k=5bVB1og) [![加入QQ群](https://img.shields.io/badge/已满-887144332-blue.svg)](https://jq.qq.com/?_wv=1027&k=5eiA4DH) [![加入QQ群](https://img.shields.io/badge/已满-180251782-blue.svg)](https://jq.qq.com/?_wv=1027&k=5AxMKlC) [![加入QQ群](https://img.shields.io/badge/已满-104180207-blue.svg)](https://jq.qq.com/?_wv=1027&k=51G72yr) [![加入QQ群](https://img.shields.io/badge/已满-186866453-blue.svg)](https://jq.qq.com/?_wv=1027&k=VvjN2nvu) [![加入QQ群](https://img.shields.io/badge/已满-201396349-blue.svg)](https://jq.qq.com/?_wv=1027&k=5vYAqA05) [![加入QQ群](https://img.shields.io/badge/已满-101456076-blue.svg)](https://jq.qq.com/?_wv=1027&k=kOIINEb5) [![加入QQ群](https://img.shields.io/badge/已满-101539465-blue.svg)](https://jq.qq.com/?_wv=1027&k=UKtX5jhs) [![加入QQ群](https://img.shields.io/badge/已满-264312783-blue.svg)](https://jq.qq.com/?_wv=1027&k=EI9an8lJ) [![加入QQ群](https://img.shields.io/badge/已满-167385320-blue.svg)](https://jq.qq.com/?_wv=1027&k=SWCtLnMz) [![加入QQ群](https://img.shields.io/badge/已满-104748341-blue.svg)](https://jq.qq.com/?_wv=1027&k=96Dkdq0k) [![加入QQ群](https://img.shields.io/badge/已满-160110482-blue.svg)](https://jq.qq.com/?_wv=1027&k=0fsNiYZt) [![加入QQ群](https://img.shields.io/badge/已满-170801498-blue.svg)](https://jq.qq.com/?_wv=1027&k=7xw4xUG1) [![加入QQ群](https://img.shields.io/badge/已满-108482800-blue.svg)](https://jq.qq.com/?_wv=1027&k=eCx8eyoJ) [![加入QQ群](https://img.shields.io/badge/已满-101046199-blue.svg)](https://jq.qq.com/?_wv=1027&k=SpyH2875) [![加入QQ群](https://img.shields.io/badge/已满-136919097-blue.svg)](https://jq.qq.com/?_wv=1027&k=tKEt51dz) [![加入QQ群](https://img.shields.io/badge/已满-143961921-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=0vBbSb0ztbBgVtn3kJS-Q4HUNYwip89G&authKey=8irq5PhutrZmWIvsUsklBxhj57l%2F1nOZqjzigkXZVoZE451GG4JHPOqW7AW6cf0T&noverify=0&group_code=143961921) [![加入QQ群](https://img.shields.io/badge/已满-174951577-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=ZFAPAbp09S2ltvwrJzp7wGlbopsc0rwi&authKey=HB2cxpxP2yspk%2Bo3WKTBfktRCccVkU26cgi5B16u0KcAYrVu7sBaE7XSEqmMdFQp&noverify=0&group_code=174951577) [![加入QQ群](https://img.shields.io/badge/已满-161281055-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=Fn2aF5IHpwsy8j6VlalNJK6qbwFLFHat&authKey=uyIT%2B97x2AXj3odyXpsSpVaPMC%2Bidw0LxG5MAtEqlrcBcWJUA%2FeS43rsF1Tg7IRJ&noverify=0&group_code=161281055) [![加入QQ群](https://img.shields.io/badge/已满-138988063-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=XIzkm_mV2xTsUtFxo63bmicYoDBA6Ifm&authKey=dDW%2F4qsmw3x9govoZY9w%2FoWAoC4wbHqGal%2BbqLzoS6VBarU8EBptIgPKN%2FviyC8j&noverify=0&group_code=138988063) [![加入QQ群](https://img.shields.io/badge/已满-151450850-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=DkugnCg68PevlycJSKSwjhFqfIgrWWwR&authKey=pR1Pa5lPIeGF%2FFtIk6d%2FGB5qFi0EdvyErtpQXULzo03zbhopBHLWcuqdpwY241R%2F&noverify=0&group_code=151450850) [![加入QQ群](https://img.shields.io/badge/已满-224622315-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=F58bgRa-Dp-rsQJThiJqIYv8t4-lWfXh&authKey=UmUs4CVG5OPA1whvsa4uSespOvyd8%2FAr9olEGaWAfdLmfKQk%2FVBp2YU3u2xXXt76&noverify=0&group_code=224622315) [![加入QQ群](https://img.shields.io/badge/已满-287842588-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=Nxb2EQ5qozWa218Wbs7zgBnjLSNk_tVT&authKey=obBKXj6SBKgrFTJZx0AqQnIYbNOvBB2kmgwWvGhzxR67RoRr84%2Bus5OadzMcdJl5&noverify=0&group_code=287842588) [![加入QQ群](https://img.shields.io/badge/已满-187944233-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=numtK1M_I4eVd2Gvg8qtbuL8JgX42qNh&authKey=giV9XWMaFZTY%2FqPlmWbkB9g3fi0Ev5CwEtT9Tgei0oUlFFCQLDp4ozWRiVIzubIm&noverify=0&group_code=187944233) [![加入QQ群](https://img.shields.io/badge/228578329-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=G6r5KGCaa3pqdbUSXNIgYloyb8e0_L0D&authKey=4w8tF1eGW7%2FedWn%2FHAypQksdrML%2BDHolQSx7094Agm7Luakj9EbfPnSTxSi2T1LQ&noverify=0&group_code=228578329) 点击按钮入群。

12
bin/clean.bat Normal file
View File

@ -0,0 +1,12 @@
@echo off
echo.
echo [信息] 清理工程target生成路径。
echo.
%~d0
cd %~dp0
cd ..
call mvn clean
pause

12
bin/package.bat Normal file
View File

@ -0,0 +1,12 @@
@echo off
echo.
echo [信息] 打包Web工程生成war/jar包文件。
echo.
%~d0
cd %~dp0
cd ..
call mvn clean package -Dmaven.test.skip=true
pause

14
bin/run.bat Normal file
View File

@ -0,0 +1,14 @@
@echo off
echo.
echo [信息] 使用Jar命令运行Web工程。
echo.
cd %~dp0
cd ../ruoyi-admin/target
set JAVA_OPTS=-Xms256m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m
java -jar %JAVA_OPTS% ruoyi-admin.jar
cd bin
pause

Binary file not shown.

275
pom.xml Normal file
View File

@ -0,0 +1,275 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi</artifactId>
<version>3.8.9</version>
<name>ruoyi</name>
<url>http://www.ruoyi.vip</url>
<description>若依管理系统</description>
<properties>
<ruoyi.version>3.8.9</ruoyi.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<maven-jar-plugin.version>3.1.1</maven-jar-plugin.version>
<spring-boot.version>2.5.15</spring-boot.version>
<druid.version>1.2.23</druid.version>
<bitwalker.version>1.21</bitwalker.version>
<swagger.version>3.0.0</swagger.version>
<kaptcha.version>2.3.3</kaptcha.version>
<mybatis-plus.version>3.5.2</mybatis-plus.version>
<pagehelper.boot.version>1.4.7</pagehelper.boot.version>
<fastjson.version>2.0.53</fastjson.version>
<oshi.version>6.6.5</oshi.version>
<commons.io.version>2.13.0</commons.io.version>
<poi.version>4.1.2</poi.version>
<velocity.version>2.3</velocity.version>
<jwt.version>0.9.1</jwt.version>
<!-- override dependency version -->
<tomcat.version>9.0.102</tomcat.version>
<logback.version>1.2.13</logback.version>
<spring-security.version>5.7.12</spring-security.version>
<spring-framework.version>5.3.39</spring-framework.version>
</properties>
<!-- 依赖声明 -->
<dependencyManagement>
<dependencies>
<!-- 覆盖SpringFramework的依赖配置-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-framework-bom</artifactId>
<version>${spring-framework.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- 覆盖SpringSecurity的依赖配置-->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-bom</artifactId>
<version>${spring-security.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- SpringBoot的依赖配置-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- 覆盖logback的依赖配置-->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>${logback.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
</dependency>
<!-- 覆盖tomcat的依赖配置-->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
<version>${tomcat.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-el</artifactId>
<version>${tomcat.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-websocket</artifactId>
<version>${tomcat.version}</version>
</dependency>
<!-- 阿里数据库连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>${druid.version}</version>
</dependency>
<!-- 解析客户端操作系统、浏览器等 -->
<dependency>
<groupId>eu.bitwalker</groupId>
<artifactId>UserAgentUtils</artifactId>
<version>${bitwalker.version}</version>
</dependency>
<!-- pagehelper 分页插件 -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>${pagehelper.boot.version}</version>
</dependency>
<!-- 获取系统信息 -->
<dependency>
<groupId>com.github.oshi</groupId>
<artifactId>oshi-core</artifactId>
<version>${oshi.version}</version>
</dependency>
<!-- Swagger3依赖 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>${swagger.version}</version>
<exclusions>
<exclusion>
<groupId>io.swagger</groupId>
<artifactId>swagger-models</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- io常用工具类 -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons.io.version}</version>
</dependency>
<!-- excel工具 -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>${poi.version}</version>
</dependency>
<!-- velocity代码生成使用模板 -->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>${velocity.version}</version>
</dependency>
<!-- 阿里JSON解析器 -->
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
<version>${fastjson.version}</version>
</dependency>
<!-- Token生成与解析-->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>${jwt.version}</version>
</dependency>
<!-- 验证码 -->
<dependency>
<groupId>pro.fessional</groupId>
<artifactId>kaptcha</artifactId>
<version>${kaptcha.version}</version>
</dependency>
<!-- 定时任务-->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-quartz</artifactId>
<version>${ruoyi.version}</version>
</dependency>
<!-- 代码生成-->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-generator</artifactId>
<version>${ruoyi.version}</version>
</dependency>
<!-- 核心模块-->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-framework</artifactId>
<version>${ruoyi.version}</version>
</dependency>
<!-- 系统模块-->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-system</artifactId>
<version>${ruoyi.version}</version>
</dependency>
<!-- 通用工具-->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common</artifactId>
<version>${ruoyi.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<modules>
<module>ruoyi-admin</module>
<module>ruoyi-framework</module>
<module>ruoyi-system</module>
<module>ruoyi-quartz</module>
<module>ruoyi-generator</module>
<module>ruoyi-common</module>
</modules>
<packaging>pom</packaging>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>public</id>
<name>aliyun nexus</name>
<url>https://maven.aliyun.com/repository/public</url>
<releases>
<enabled>true</enabled>
</releases>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>public</id>
<name>aliyun nexus</name>
<url>https://maven.aliyun.com/repository/public</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</project>

141
ruoyi-admin/pom.xml Normal file
View File

@ -0,0 +1,141 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>ruoyi</artifactId>
<groupId>com.ruoyi</groupId>
<version>3.8.9</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging>
<artifactId>ruoyi-admin</artifactId>
<description>
web服务入口
</description>
<dependencies>
<!-- spring-boot-devtools -->
<!-- <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-devtools</artifactId>-->
<!-- <optional>false</optional> &lt;!&ndash; 表示依赖不会传递 &ndash;&gt;-->
<!-- </dependency>-->
<!-- swagger3-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
</dependency>
<!-- 防止进入swagger页面报类型转换错误排除3.0.0中的引用手动增加1.6.2版本 -->
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-models</artifactId>
<version>1.6.2</version>
</dependency>
<!-- Mysql驱动包 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- 核心模块-->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-framework</artifactId>
</dependency>
<!-- 定时任务-->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-quartz</artifactId>
</dependency>
<!-- 代码生成-->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-generator</artifactId>
</dependency>
<dependency>
<groupId>com.github.dozermapper</groupId>
<artifactId>dozer-spring-boot-starter</artifactId>
<version>6.5.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-integration</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.paho</groupId>
<artifactId>org.eclipse.paho.client.mqttv3</artifactId>
<version>1.2.5</version> <!-- 检查最新版本 -->
</dependency>
<!-- Spring Integration MQTT -->
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-mqtt</artifactId>
</dependency>
<!-- MinIO存储 -->
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>8.5.7</version>
</dependency>
<!--okhttp3 依赖-->
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.9.3</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.5.15</version>
<configuration>
<fork>true</fork> <!-- 如果没有该配置devtools不会生效 -->
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
<warName>${project.artifactId}</warName>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>16</source>
<target>16</target>
</configuration>
</plugin>
</plugins>
<finalName>${project.artifactId}</finalName>
</build>
</project>

View File

@ -0,0 +1,30 @@
package com.ruoyi;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
/**
* 启动程序
*
* @author ruoyi
*/
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
public class RuoYiApplication
{
public static void main(String[] args)
{
// System.setProperty("spring.devtools.restart.enabled", "false");
SpringApplication.run(RuoYiApplication.class, args);
System.out.println("(♥◠‿◠)ノ゙ 若依启动成功 ლ(´ڡ`ლ)゙ \n" +
" .-------. ____ __ \n" +
" | _ _ \\ \\ \\ / / \n" +
" | ( ' ) | \\ _. / ' \n" +
" |(_ o _) / _( )_ .' \n" +
" | (_,_).' __ ___(_ o _)' \n" +
" | |\\ \\ | || |(_,_)' \n" +
" | | \\ `' /| `-' / \n" +
" | | \\ / \\ / \n" +
" ''-' `'-' `-..-' ");
}
}

View File

@ -0,0 +1,18 @@
package com.ruoyi;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
/**
* web容器中进行部署
*
* @author ruoyi
*/
public class RuoYiServletInitializer extends SpringBootServletInitializer
{
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application)
{
return application.sources(RuoYiApplication.class);
}
}

View File

@ -0,0 +1,289 @@
package com.ruoyi.web.client;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.*;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.function.BiConsumer;
/**
* EMQX 物联网MQTT客户端工具类
* 功能连接管理自动重连消息发布/订阅QoS支持遗嘱消息SSL支持等
*/
@Slf4j
//@Component
public class EmqxIotClient implements MqttCallbackExtended {
// ========== 配置参数 ==========
@Value("${emqx.broker-url:tcp://127.0.0.1:1883}")
private String brokerUrl;
@Value("${emqx.username:}")
private String username;
@Value("${emqx.password:}")
private String password;
@Value("${emqx.client-id-prefix:iot-client}")
private String clientIdPrefix;
@Value("${emqx.auto-reconnect:true}")
private boolean autoReconnect;
@Value("${emqx.connection-timeout:10}")
private int connectionTimeout;
@Value("${emqx.keep-alive-interval:60}")
private int keepAliveInterval;
@Value("${emqx.clean-session:false}")
private boolean cleanSession;
@Value("${emqx.max-inflight:1000}")
private int maxInflight;
@Value("${emqx.will.topic:}")
private String willTopic;
@Value("${emqx.will.payload:}")
private String willPayload;
@Value("${emqx.will.qos:1}")
private int willQos;
@Value("${emqx.will.retained:false}")
private boolean willRetained;
// ========== 运行时组件 ==========
private IMqttAsyncClient mqttClient;
private final ConcurrentHashMap<String, BiConsumer<String, String>> topicCallbacks = new ConcurrentHashMap<>();
private ScheduledExecutorService reconnectExecutor;
private final MemoryPersistence persistence = new MemoryPersistence();
private volatile boolean isConnected = false;
// ========== 初始化方法 ==========
@PostConstruct
public void init() {
connect();
this.reconnectExecutor = Executors.newSingleThreadScheduledExecutor();
}
@PreDestroy
public void destroy() {
disconnect();
if (reconnectExecutor != null) {
reconnectExecutor.shutdownNow();
}
}
// ========== 连接管理 ==========
public synchronized void connect() {
if (isConnected) {
return;
}
try {
String clientId = clientIdPrefix + "-" + UUID.randomUUID().toString().substring(0, 8);
mqttClient = new MqttAsyncClient(brokerUrl, clientId, persistence);
MqttConnectOptions options = new MqttConnectOptions();
options.setUserName(username);
options.setPassword(password.toCharArray());
options.setAutomaticReconnect(autoReconnect);
options.setConnectionTimeout(connectionTimeout);
options.setKeepAliveInterval(keepAliveInterval);
options.setCleanSession(cleanSession);
options.setMaxInflight(maxInflight);
// 配置遗嘱消息
if (willTopic != null && !willTopic.isEmpty()) {
options.setWill(willTopic, willPayload.getBytes(), willQos, willRetained);
}
// SSL配置示例
/*
if (useSSL) {
options.setSocketFactory(sslContext.getSocketFactory());
}
*/
mqttClient.setCallback(this);
mqttClient.connect(options, null, new IMqttActionListener() {
@Override
public void onSuccess(IMqttToken asyncActionToken) {
isConnected = true;
log.info("EMQX连接成功, clientId: {}", clientId);
// 重新订阅之前注册的主题
resubscribeTopics();
}
@Override
public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
log.error("EMQX连接失败", exception);
scheduleReconnect();
}
});
} catch (MqttException e) {
log.error("EMQX客户端初始化异常", e);
scheduleReconnect();
}
}
public synchronized void disconnect() {
if (!isConnected || mqttClient == null) {
return;
}
try {
mqttClient.disconnect().waitForCompletion();
isConnected = false;
log.info("EMQX连接已断开");
} catch (MqttException e) {
log.error("EMQX断开连接异常", e);
}
}
private void scheduleReconnect() {
if (!autoReconnect || reconnectExecutor == null || reconnectExecutor.isShutdown()) {
return;
}
reconnectExecutor.schedule(() -> {
log.info("尝试重新连接EMQX...");
connect();
}, 5, TimeUnit.SECONDS);
}
// ========== 消息发布 ==========
public void publish(String topic, String payload) throws MqttException {
publish(topic, payload, 1, false);
}
public void publish(String topic, String payload, int qos, boolean retained) throws MqttException {
if (!isConnected) {
throw new MqttException(MqttException.REASON_CODE_CLIENT_NOT_CONNECTED);
}
MqttMessage message = new MqttMessage(payload.getBytes());
message.setQos(qos);
message.setRetained(retained);
mqttClient.publish(topic, message, null, new IMqttActionListener() {
@Override
public void onSuccess(IMqttToken asyncActionToken) {
log.debug("消息发布成功, topic: {}, qos: {}", topic, qos);
}
@Override
public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
log.error("消息发布失败, topic: {}", topic, exception);
}
});
}
// ========== 消息订阅 ==========
public void subscribe(String topic, BiConsumer<String, String> messageHandler) throws MqttException {
subscribe(topic, 1, messageHandler);
}
public void subscribe(String topic, int qos, BiConsumer<String, String> messageHandler) throws MqttException {
if (!isConnected) {
throw new MqttException(MqttException.REASON_CODE_CLIENT_NOT_CONNECTED);
}
topicCallbacks.put(topic, messageHandler);
mqttClient.subscribe(topic, qos, null, new IMqttActionListener() {
@Override
public void onSuccess(IMqttToken asyncActionToken) {
log.info("订阅成功, topic: {}, qos: {}", topic, qos);
}
@Override
public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
log.error("订阅失败, topic: {}", topic, exception);
topicCallbacks.remove(topic);
}
});
}
public void unsubscribe(String topic) throws MqttException {
if (!isConnected) {
throw new MqttException(MqttException.REASON_CODE_CLIENT_NOT_CONNECTED);
}
mqttClient.unsubscribe(topic);
topicCallbacks.remove(topic);
log.info("取消订阅, topic: {}", topic);
}
private void resubscribeTopics() {
if (topicCallbacks.isEmpty()) {
return;
}
topicCallbacks.forEach((topic, handler) -> {
try {
mqttClient.subscribe(topic, 1);
} catch (MqttException e) {
log.error("重新订阅失败, topic: {}", topic, e);
}
});
}
// ========== MQTT回调接口 ==========
@Override
public void connectComplete(boolean reconnect, String serverURI) {
isConnected = true;
log.info("MQTT连接{}成功: {}", reconnect ? "重连" : "建立", serverURI);
}
@Override
public void connectionLost(Throwable cause) {
isConnected = false;
log.warn("MQTT连接丢失", cause);
if (autoReconnect) {
scheduleReconnect();
}
}
@Override
public void messageArrived(String topic, MqttMessage message) throws Exception {
String payload = new String(message.getPayload());
log.debug("收到消息, topic: {}, qos: {}, payload: {}", topic, message.getQos(), payload);
BiConsumer<String, String> handler = topicCallbacks.get(topic);
if (handler != null) {
try {
handler.accept(topic, payload);
} catch (Exception e) {
log.error("消息处理异常, topic: {}", topic, e);
}
} else {
log.warn("未找到对应的消息处理器, topic: {}", topic);
}
}
@Override
public void deliveryComplete(IMqttDeliveryToken token) {
// 消息发布完成回调
}
// ========== 状态检查 ==========
public boolean isConnected() {
return isConnected && mqttClient != null && mqttClient.isConnected();
}
public String getClientId() {
return mqttClient != null ? mqttClient.getClientId() : null;
}
}

View File

@ -0,0 +1,42 @@
package com.ruoyi.web.client;
import io.minio.MinioClient;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Data
@Configuration
@ConfigurationProperties(prefix = "minio")
public class MinIoConfig {
private String server;
private int port;
private String accessKey;
private String secretKey;
// 桶名
private String bucket;
// 统一前缀
private String urlPrefix;
/**
* 创建minio连接对象
*
* @return
*/
@Bean
public MinioClient minioClient() {
return MinioClient.builder()
.endpoint(server, port, false)
.credentials(accessKey, secretKey)
.build();
}
}

View File

@ -0,0 +1,340 @@
package com.ruoyi.web.client;
import com.ruoyi.web.model.ObjectItem;
import io.minio.*;
import io.minio.messages.DeleteError;
import io.minio.messages.DeleteObject;
import io.minio.messages.Item;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
@Component
@Slf4j
public class MinIoTemplate {
@Value("${minio.urlprefix}")
public String urlprefix;
@Autowired
private MinioClient minioClient;
/**
* 判断bucket是否存在不存在则创建
*
* @param name
*/
public void existBucket(String name) {
try {
boolean exist = minioClient.bucketExists(BucketExistsArgs.builder().bucket(name).build());
if (!exist) {
minioClient.makeBucket(MakeBucketArgs.builder().bucket(name).build());
}
minioClient.setBucketPolicy(SetBucketPolicyArgs.builder()
.bucket(name).config(readwritePolicy().toString())
.build());
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 创建存储bucket
*
* @param bucketName 存储bucket名称
* @return Boolean
*/
public Boolean makeBucket(String bucketName) {
try {
minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
minioClient.setBucketPolicy(SetBucketPolicyArgs.builder()
.bucket(bucketName).config(readwritePolicy().toString())
.build());
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
/**
* 删除存储bucket
*
* @param bucketName 存储bucket名称
* @return Boolean
*/
public Boolean removeBucket(String bucketName) {
try {
minioClient.removeBucket(RemoveBucketArgs.builder()
.bucket(bucketName)
.build());
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
/**
* 文件上传
*
* @param bucketName
* @param file
* @return
*/
public Map<String, String> upload(String bucketName, MultipartFile file) {
String filename = file.getOriginalFilename();
InputStream inputStream = null;
try {
inputStream = file.getInputStream();
// 上传到minio服务器
minioClient.putObject(PutObjectArgs.builder()
.contentType(file.getContentType())
.bucket(bucketName)
.object(filename)
.stream(inputStream, -1L, 10485760L)
.build());
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
inputStream.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
// 返回地址
Map<String, String> resultMap = new HashMap<>();
resultMap.put("url", filename);
return resultMap;
}
/**
* 文件上传
*
* @param bucketName
* @param file
* @return
*/
public Map<String, String> uploadCoverFilename(String bucketName, MultipartFile file, String fileName) {
String filename = fileName;
try {
InputStream inputStream = file.getInputStream();
// 上传到minio服务器
minioClient.putObject(PutObjectArgs.builder()
.contentType(file.getContentType())
.bucket(bucketName)
.object(filename)
.stream(inputStream, -1L, 10485760L)
.build());
} catch (Exception e) {
e.printStackTrace();
}
// 返回地址
Map<String, String> resultMap = new HashMap<>();
resultMap.put("url", filename);
return resultMap;
}
/**
* 文件下载
*
* @param fileName 文件名
* @param delete 是否删除
* @throws IOException
*/
public void fileDownload(String bucketName,
String fileName,
@RequestParam(defaultValue = "false") Boolean delete,
HttpServletResponse response) {
InputStream inputStream = null;
OutputStream outputStream = null;
try {
if (StringUtils.isEmpty(fileName)) {
response.setHeader("Content-type", "text/html;charset=UTF-8");
String data = "文件下载失败";
OutputStream ps = response.getOutputStream();
ps.write(data.getBytes(StandardCharsets.UTF_8));
return;
}
outputStream = response.getOutputStream();
// 获取文件对象
inputStream = minioClient.getObject(GetObjectArgs.builder().bucket(bucketName).object(fileName).build());
byte[] buf = new byte[1024];
int length = 0;
response.reset();
response.setHeader("Content-Disposition", "attachment;filename=" +
URLEncoder.encode(fileName.substring(fileName.lastIndexOf("/") + 1), StandardCharsets.UTF_8));
response.setContentType("application/octet-stream");
response.setCharacterEncoding("UTF-8");
// 输出文件
while ((length = inputStream.read(buf)) > 0) {
outputStream.write(buf, 0, length);
}
inputStream.close();
// 判断下载后是否同时删除minio上的存储文件
if (delete) {
minioClient.removeObject(RemoveObjectArgs.builder().bucket(bucketName).object(fileName).build());
}
} catch (Throwable ex) {
response.setHeader("Content-type", "text/html;charset=UTF-8");
String data = "文件下载失败";
try {
OutputStream ps = response.getOutputStream();
ps.write(data.getBytes(StandardCharsets.UTF_8));
} catch (IOException e) {
e.printStackTrace();
}
} finally {
try {
outputStream.close();
if (inputStream != null) {
inputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 查看文件对象
*
* @param bucketName 存储bucket名称
* @return 存储bucket内文件对象信息
*/
public List<ObjectItem> listObjects(String bucketName) {
Iterable<Result<Item>> results = minioClient.listObjects(ListObjectsArgs.builder().bucket(bucketName).build());
List<ObjectItem> objectItems = new ArrayList<>();
try {
for (Result<Item> result : results) {
Item item = result.get();
ObjectItem objectItem = new ObjectItem();
objectItem.setObjectName(item.objectName());
objectItem.setSize(item.size());
objectItems.add(objectItem);
}
} catch (Exception e) {
e.printStackTrace();
return null;
}
return objectItems;
}
/**
* 批量删除文件对象
*
* @param bucketName 存储bucket名称
* @param objects 对象名称集合
*/
public Map<String, String> removeObjects(String bucketName, List<String> objects) {
Map<String, String> resultMap = new HashMap<>();
List<DeleteObject> dos = objects.stream().map(e -> new DeleteObject(e)).collect(Collectors.toList());
try {
Iterable<Result<DeleteError>> results = minioClient.removeObjects(RemoveObjectsArgs.builder().bucket(bucketName).objects(dos).build());
for (Result<DeleteError> result : results) {
DeleteError error = result.get();
log.error("Error in deleting object " + error.objectName() + "; " + error.message());
}
resultMap.put("mes", "删除成功");
} catch (Exception e) {
e.printStackTrace();
resultMap.put("mes", "网络异常,删除失败");
}
return resultMap;
}
private StringBuilder readwritePolicy() {
StringBuilder builder = new StringBuilder();
builder.append("{\n" +
" \"Version\": \"2012-10-17\",\n" +
" \"Statement\": [\n" +
" {\n" +
" \"Effect\": \"Allow\",\n" +
" \"Action\": [\n" +
" \"admin:*\"\n" +
" ]\n" +
" },\n" +
" {\n" +
" \"Effect\": \"Allow\",\n" +
" \"Action\": [\n" +
" \"kms:*\"\n" +
" ]\n" +
" },\n" +
" {\n" +
" \"Effect\": \"Allow\",\n" +
" \"Action\": [\n" +
" \"s3:*\"\n" +
" ],\n" +
" \"Resource\": [\n" +
" \"arn:aws:s3:::*\"\n" +
" ]\n" +
" }\n" +
" ]\n" +
"}");
return builder;
}
private byte[] compressMultipartFiles(List<MultipartFile> files) throws IOException {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ZipOutputStream zipOut = new ZipOutputStream(outputStream);
for (int i = 0; i < files.size(); i++) {
MultipartFile file = files.get(i);
ZipEntry zipEntry = new ZipEntry(file.getOriginalFilename());
zipOut.putNextEntry(zipEntry);
byte[] bytes = file.getBytes();
zipOut.write(bytes);
zipOut.closeEntry();
}
zipOut.close();
return outputStream.toByteArray();
}
public Map<String, String> uploadZip(String bucketName, MultipartFile[] files) throws IOException {
String name = files[0].getOriginalFilename().split("\\.")[0];
String objectName = name.concat(".zip");
List<MultipartFile> multipartFiles = Lists.newArrayList(Arrays.stream(files).iterator());
byte[] bytes = compressMultipartFiles(multipartFiles);
try {
InputStream inputStream = new ByteArrayInputStream(bytes);
// 上传到minio服务器
minioClient.putObject(PutObjectArgs.builder()
.contentType("application/zip")
.bucket(bucketName)
.object(objectName)
.stream(inputStream, -1L, 10485760L)
.build());
} catch (Exception e) {
e.printStackTrace();
}
// 返回地址
Map<String, String> resultMap = new HashMap<>();
resultMap.put("url", objectName);
return resultMap;
}
}

View File

@ -0,0 +1,94 @@
package com.ruoyi.web.controller.common;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.FastByteArrayOutputStream;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import com.google.code.kaptcha.Producer;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.sign.Base64;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.system.service.ISysConfigService;
/**
* 验证码操作处理
*
* @author ruoyi
*/
@RestController
public class CaptchaController
{
@Resource(name = "captchaProducer")
private Producer captchaProducer;
@Resource(name = "captchaProducerMath")
private Producer captchaProducerMath;
@Autowired
private RedisCache redisCache;
@Autowired
private ISysConfigService configService;
/**
* 生成验证码
*/
@GetMapping("/captchaImage")
public AjaxResult getCode(HttpServletResponse response) throws IOException
{
AjaxResult ajax = AjaxResult.success();
boolean captchaEnabled = configService.selectCaptchaEnabled();
ajax.put("captchaEnabled", captchaEnabled);
if (!captchaEnabled)
{
return ajax;
}
// 保存验证码信息
String uuid = IdUtils.simpleUUID();
String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + uuid;
String capStr = null, code = null;
BufferedImage image = null;
// 生成验证码
String captchaType = RuoYiConfig.getCaptchaType();
if ("math".equals(captchaType))
{
String capText = captchaProducerMath.createText();
capStr = capText.substring(0, capText.lastIndexOf("@"));
code = capText.substring(capText.lastIndexOf("@") + 1);
image = captchaProducerMath.createImage(capStr);
}
else if ("char".equals(captchaType))
{
capStr = code = captchaProducer.createText();
image = captchaProducer.createImage(capStr);
}
redisCache.setCacheObject(verifyKey, code, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES);
// 转换流信息写出
FastByteArrayOutputStream os = new FastByteArrayOutputStream();
try
{
ImageIO.write(image, "jpg", os);
}
catch (IOException e)
{
return AjaxResult.error(e.getMessage());
}
ajax.put("uuid", uuid);
ajax.put("img", Base64.encode(os.toByteArray()));
return ajax;
}
}

View File

@ -0,0 +1,163 @@
package com.ruoyi.web.controller.common;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.common.utils.file.FileUtils;
import com.ruoyi.framework.config.ServerConfig;
/**
* 通用请求处理
*
* @author ruoyi
*/
@RestController
@RequestMapping("/common")
public class CommonController
{
private static final Logger log = LoggerFactory.getLogger(CommonController.class);
@Autowired
private ServerConfig serverConfig;
private static final String FILE_DELIMETER = ",";
/**
* 通用下载请求
*
* @param fileName 文件名称
* @param delete 是否删除
*/
@GetMapping("/download")
public void fileDownload(String fileName, Boolean delete, HttpServletResponse response, HttpServletRequest request)
{
try
{
if (!FileUtils.checkAllowDownload(fileName))
{
throw new Exception(StringUtils.format("文件名称({})非法,不允许下载。 ", fileName));
}
String realFileName = System.currentTimeMillis() + fileName.substring(fileName.indexOf("_") + 1);
String filePath = RuoYiConfig.getDownloadPath() + fileName;
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
FileUtils.setAttachmentResponseHeader(response, realFileName);
FileUtils.writeBytes(filePath, response.getOutputStream());
if (delete)
{
FileUtils.deleteFile(filePath);
}
}
catch (Exception e)
{
log.error("下载文件失败", e);
}
}
/**
* 通用上传请求单个
*/
@PostMapping("/upload")
public AjaxResult uploadFile(MultipartFile file) throws Exception
{
try
{
// 上传文件路径
String filePath = RuoYiConfig.getUploadPath();
// 上传并返回新文件名称
String fileName = FileUploadUtils.upload(filePath, file);
String url = serverConfig.getUrl() + fileName;
AjaxResult ajax = AjaxResult.success();
ajax.put("url", url);
ajax.put("fileName", fileName);
ajax.put("newFileName", FileUtils.getName(fileName));
ajax.put("originalFilename", file.getOriginalFilename());
return ajax;
}
catch (Exception e)
{
return AjaxResult.error(e.getMessage());
}
}
/**
* 通用上传请求多个
*/
@PostMapping("/uploads")
public AjaxResult uploadFiles(List<MultipartFile> files) throws Exception
{
try
{
// 上传文件路径
String filePath = RuoYiConfig.getUploadPath();
List<String> urls = new ArrayList<String>();
List<String> fileNames = new ArrayList<String>();
List<String> newFileNames = new ArrayList<String>();
List<String> originalFilenames = new ArrayList<String>();
for (MultipartFile file : files)
{
// 上传并返回新文件名称
String fileName = FileUploadUtils.upload(filePath, file);
String url = serverConfig.getUrl() + fileName;
urls.add(url);
fileNames.add(fileName);
newFileNames.add(FileUtils.getName(fileName));
originalFilenames.add(file.getOriginalFilename());
}
AjaxResult ajax = AjaxResult.success();
ajax.put("urls", StringUtils.join(urls, FILE_DELIMETER));
ajax.put("fileNames", StringUtils.join(fileNames, FILE_DELIMETER));
ajax.put("newFileNames", StringUtils.join(newFileNames, FILE_DELIMETER));
ajax.put("originalFilenames", StringUtils.join(originalFilenames, FILE_DELIMETER));
return ajax;
}
catch (Exception e)
{
return AjaxResult.error(e.getMessage());
}
}
/**
* 本地资源通用下载
*/
@GetMapping("/download/resource")
public void resourceDownload(String resource, HttpServletRequest request, HttpServletResponse response)
throws Exception
{
try
{
if (!FileUtils.checkAllowDownload(resource))
{
throw new Exception(StringUtils.format("资源文件({})非法,不允许下载。 ", resource));
}
// 本地资源路径
String localPath = RuoYiConfig.getProfile();
// 数据库资源地址
String downloadPath = localPath + StringUtils.substringAfter(resource, Constants.RESOURCE_PREFIX);
// 下载名称
String downloadName = StringUtils.substringAfterLast(downloadPath, "/");
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
FileUtils.setAttachmentResponseHeader(response, downloadName);
FileUtils.writeBytes(downloadPath, response.getOutputStream());
}
catch (Exception e)
{
log.error("下载文件失败", e);
}
}
}

View File

@ -0,0 +1,121 @@
package com.ruoyi.web.controller.monitor;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.TreeSet;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.SysCache;
/**
* 缓存监控
*
* @author ruoyi
*/
@RestController
@RequestMapping("/monitor/cache")
public class CacheController
{
@Autowired
private RedisTemplate<String, String> redisTemplate;
private final static List<SysCache> caches = new ArrayList<SysCache>();
{
caches.add(new SysCache(CacheConstants.LOGIN_TOKEN_KEY, "用户信息"));
caches.add(new SysCache(CacheConstants.SYS_CONFIG_KEY, "配置信息"));
caches.add(new SysCache(CacheConstants.SYS_DICT_KEY, "数据字典"));
caches.add(new SysCache(CacheConstants.CAPTCHA_CODE_KEY, "验证码"));
caches.add(new SysCache(CacheConstants.REPEAT_SUBMIT_KEY, "防重提交"));
caches.add(new SysCache(CacheConstants.RATE_LIMIT_KEY, "限流处理"));
caches.add(new SysCache(CacheConstants.PWD_ERR_CNT_KEY, "密码错误次数"));
}
@PreAuthorize("@ss.hasPermi('monitor:cache:list')")
@GetMapping()
public AjaxResult getInfo() throws Exception
{
Properties info = (Properties) redisTemplate.execute((RedisCallback<Object>) connection -> connection.info());
Properties commandStats = (Properties) redisTemplate.execute((RedisCallback<Object>) connection -> connection.info("commandstats"));
Object dbSize = redisTemplate.execute((RedisCallback<Object>) connection -> connection.dbSize());
Map<String, Object> result = new HashMap<>(3);
result.put("info", info);
result.put("dbSize", dbSize);
List<Map<String, String>> pieList = new ArrayList<>();
commandStats.stringPropertyNames().forEach(key -> {
Map<String, String> data = new HashMap<>(2);
String property = commandStats.getProperty(key);
data.put("name", StringUtils.removeStart(key, "cmdstat_"));
data.put("value", StringUtils.substringBetween(property, "calls=", ",usec"));
pieList.add(data);
});
result.put("commandStats", pieList);
return AjaxResult.success(result);
}
@PreAuthorize("@ss.hasPermi('monitor:cache:list')")
@GetMapping("/getNames")
public AjaxResult cache()
{
return AjaxResult.success(caches);
}
@PreAuthorize("@ss.hasPermi('monitor:cache:list')")
@GetMapping("/getKeys/{cacheName}")
public AjaxResult getCacheKeys(@PathVariable String cacheName)
{
Set<String> cacheKeys = redisTemplate.keys(cacheName + "*");
return AjaxResult.success(new TreeSet<>(cacheKeys));
}
@PreAuthorize("@ss.hasPermi('monitor:cache:list')")
@GetMapping("/getValue/{cacheName}/{cacheKey}")
public AjaxResult getCacheValue(@PathVariable String cacheName, @PathVariable String cacheKey)
{
String cacheValue = redisTemplate.opsForValue().get(cacheKey);
SysCache sysCache = new SysCache(cacheName, cacheKey, cacheValue);
return AjaxResult.success(sysCache);
}
@PreAuthorize("@ss.hasPermi('monitor:cache:list')")
@DeleteMapping("/clearCacheName/{cacheName}")
public AjaxResult clearCacheName(@PathVariable String cacheName)
{
Collection<String> cacheKeys = redisTemplate.keys(cacheName + "*");
redisTemplate.delete(cacheKeys);
return AjaxResult.success();
}
@PreAuthorize("@ss.hasPermi('monitor:cache:list')")
@DeleteMapping("/clearCacheKey/{cacheKey}")
public AjaxResult clearCacheKey(@PathVariable String cacheKey)
{
redisTemplate.delete(cacheKey);
return AjaxResult.success();
}
@PreAuthorize("@ss.hasPermi('monitor:cache:list')")
@DeleteMapping("/clearCacheAll")
public AjaxResult clearCacheAll()
{
Collection<String> cacheKeys = redisTemplate.keys("*");
redisTemplate.delete(cacheKeys);
return AjaxResult.success();
}
}

View File

@ -0,0 +1,27 @@
package com.ruoyi.web.controller.monitor;
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;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.framework.web.domain.Server;
/**
* 服务器监控
*
* @author ruoyi
*/
@RestController
@RequestMapping("/monitor/server")
public class ServerController
{
@PreAuthorize("@ss.hasPermi('monitor:server:list')")
@GetMapping()
public AjaxResult getInfo() throws Exception
{
Server server = new Server();
server.copyTo();
return AjaxResult.success(server);
}
}

View File

@ -0,0 +1,82 @@
package com.ruoyi.web.controller.monitor;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.web.service.SysPasswordService;
import com.ruoyi.system.domain.SysLogininfor;
import com.ruoyi.system.service.ISysLogininforService;
/**
* 系统访问记录
*
* @author ruoyi
*/
@RestController
@RequestMapping("/monitor/logininfor")
public class SysLogininforController extends BaseController
{
@Autowired
private ISysLogininforService logininforService;
@Autowired
private SysPasswordService passwordService;
@PreAuthorize("@ss.hasPermi('monitor:logininfor:list')")
@GetMapping("/list")
public TableDataInfo list(SysLogininfor logininfor)
{
startPage();
List<SysLogininfor> list = logininforService.selectLogininforList(logininfor);
return getDataTable(list);
}
@Log(title = "登录日志", businessType = BusinessType.EXPORT)
@PreAuthorize("@ss.hasPermi('monitor:logininfor:export')")
@PostMapping("/export")
public void export(HttpServletResponse response, SysLogininfor logininfor)
{
List<SysLogininfor> list = logininforService.selectLogininforList(logininfor);
ExcelUtil<SysLogininfor> util = new ExcelUtil<SysLogininfor>(SysLogininfor.class);
util.exportExcel(response, list, "登录日志");
}
@PreAuthorize("@ss.hasPermi('monitor:logininfor:remove')")
@Log(title = "登录日志", businessType = BusinessType.DELETE)
@DeleteMapping("/{infoIds}")
public AjaxResult remove(@PathVariable Long[] infoIds)
{
return toAjax(logininforService.deleteLogininforByIds(infoIds));
}
@PreAuthorize("@ss.hasPermi('monitor:logininfor:remove')")
@Log(title = "登录日志", businessType = BusinessType.CLEAN)
@DeleteMapping("/clean")
public AjaxResult clean()
{
logininforService.cleanLogininfor();
return success();
}
@PreAuthorize("@ss.hasPermi('monitor:logininfor:unlock')")
@Log(title = "账户解锁", businessType = BusinessType.OTHER)
@GetMapping("/unlock/{userName}")
public AjaxResult unlock(@PathVariable("userName") String userName)
{
passwordService.clearLoginRecordCache(userName);
return success();
}
}

View File

@ -0,0 +1,69 @@
package com.ruoyi.web.controller.monitor;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.system.domain.SysOperLog;
import com.ruoyi.system.service.ISysOperLogService;
/**
* 操作日志记录
*
* @author ruoyi
*/
@RestController
@RequestMapping("/monitor/operlog")
public class SysOperlogController extends BaseController
{
@Autowired
private ISysOperLogService operLogService;
@PreAuthorize("@ss.hasPermi('monitor:operlog:list')")
@GetMapping("/list")
public TableDataInfo list(SysOperLog operLog)
{
startPage();
List<SysOperLog> list = operLogService.selectOperLogList(operLog);
return getDataTable(list);
}
@Log(title = "操作日志", businessType = BusinessType.EXPORT)
@PreAuthorize("@ss.hasPermi('monitor:operlog:export')")
@PostMapping("/export")
public void export(HttpServletResponse response, SysOperLog operLog)
{
List<SysOperLog> list = operLogService.selectOperLogList(operLog);
ExcelUtil<SysOperLog> util = new ExcelUtil<SysOperLog>(SysOperLog.class);
util.exportExcel(response, list, "操作日志");
}
@Log(title = "操作日志", businessType = BusinessType.DELETE)
@PreAuthorize("@ss.hasPermi('monitor:operlog:remove')")
@DeleteMapping("/{operIds}")
public AjaxResult remove(@PathVariable Long[] operIds)
{
return toAjax(operLogService.deleteOperLogByIds(operIds));
}
@Log(title = "操作日志", businessType = BusinessType.CLEAN)
@PreAuthorize("@ss.hasPermi('monitor:operlog:remove')")
@DeleteMapping("/clean")
public AjaxResult clean()
{
operLogService.cleanOperLog();
return success();
}
}

View File

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

View File

@ -0,0 +1,133 @@
package com.ruoyi.web.controller.system;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.system.domain.SysConfig;
import com.ruoyi.system.service.ISysConfigService;
/**
* 参数配置 信息操作处理
*
* @author ruoyi
*/
@RestController
@RequestMapping("/system/config")
public class SysConfigController extends BaseController
{
@Autowired
private ISysConfigService configService;
/**
* 获取参数配置列表
*/
@PreAuthorize("@ss.hasPermi('system:config:list')")
@GetMapping("/list")
public TableDataInfo list(SysConfig config)
{
startPage();
List<SysConfig> list = configService.selectConfigList(config);
return getDataTable(list);
}
@Log(title = "参数管理", businessType = BusinessType.EXPORT)
@PreAuthorize("@ss.hasPermi('system:config:export')")
@PostMapping("/export")
public void export(HttpServletResponse response, SysConfig config)
{
List<SysConfig> list = configService.selectConfigList(config);
ExcelUtil<SysConfig> util = new ExcelUtil<SysConfig>(SysConfig.class);
util.exportExcel(response, list, "参数数据");
}
/**
* 根据参数编号获取详细信息
*/
@PreAuthorize("@ss.hasPermi('system:config:query')")
@GetMapping(value = "/{configId}")
public AjaxResult getInfo(@PathVariable Long configId)
{
return success(configService.selectConfigById(configId));
}
/**
* 根据参数键名查询参数值
*/
@GetMapping(value = "/configKey/{configKey}")
public AjaxResult getConfigKey(@PathVariable String configKey)
{
return success(configService.selectConfigByKey(configKey));
}
/**
* 新增参数配置
*/
@PreAuthorize("@ss.hasPermi('system:config:add')")
@Log(title = "参数管理", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@Validated @RequestBody SysConfig config)
{
if (!configService.checkConfigKeyUnique(config))
{
return error("新增参数'" + config.getConfigName() + "'失败,参数键名已存在");
}
config.setCreateBy(getUsername());
return toAjax(configService.insertConfig(config));
}
/**
* 修改参数配置
*/
@PreAuthorize("@ss.hasPermi('system:config:edit')")
@Log(title = "参数管理", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@Validated @RequestBody SysConfig config)
{
if (!configService.checkConfigKeyUnique(config))
{
return error("修改参数'" + config.getConfigName() + "'失败,参数键名已存在");
}
config.setUpdateBy(getUsername());
return toAjax(configService.updateConfig(config));
}
/**
* 删除参数配置
*/
@PreAuthorize("@ss.hasPermi('system:config:remove')")
@Log(title = "参数管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{configIds}")
public AjaxResult remove(@PathVariable Long[] configIds)
{
configService.deleteConfigByIds(configIds);
return success();
}
/**
* 刷新参数缓存
*/
@PreAuthorize("@ss.hasPermi('system:config:remove')")
@Log(title = "参数管理", businessType = BusinessType.CLEAN)
@DeleteMapping("/refreshCache")
public AjaxResult refreshCache()
{
configService.resetConfigCache();
return success();
}
}

View File

@ -0,0 +1,132 @@
package com.ruoyi.web.controller.system;
import java.util.List;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.service.ISysDeptService;
/**
* 部门信息
*
* @author ruoyi
*/
@RestController
@RequestMapping("/system/dept")
public class SysDeptController extends BaseController
{
@Autowired
private ISysDeptService deptService;
/**
* 获取部门列表
*/
@PreAuthorize("@ss.hasPermi('system:dept:list')")
@GetMapping("/list")
public AjaxResult list(SysDept dept)
{
List<SysDept> depts = deptService.selectDeptList(dept);
return success(depts);
}
/**
* 查询部门列表排除节点
*/
@PreAuthorize("@ss.hasPermi('system:dept:list')")
@GetMapping("/list/exclude/{deptId}")
public AjaxResult excludeChild(@PathVariable(value = "deptId", required = false) Long deptId)
{
List<SysDept> depts = deptService.selectDeptList(new SysDept());
depts.removeIf(d -> d.getDeptId().intValue() == deptId || ArrayUtils.contains(StringUtils.split(d.getAncestors(), ","), deptId + ""));
return success(depts);
}
/**
* 根据部门编号获取详细信息
*/
@PreAuthorize("@ss.hasPermi('system:dept:query')")
@GetMapping(value = "/{deptId}")
public AjaxResult getInfo(@PathVariable Long deptId)
{
deptService.checkDeptDataScope(deptId);
return success(deptService.selectDeptById(deptId));
}
/**
* 新增部门
*/
@PreAuthorize("@ss.hasPermi('system:dept:add')")
@Log(title = "部门管理", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@Validated @RequestBody SysDept dept)
{
if (!deptService.checkDeptNameUnique(dept))
{
return error("新增部门'" + dept.getDeptName() + "'失败,部门名称已存在");
}
dept.setCreateBy(getUsername());
return toAjax(deptService.insertDept(dept));
}
/**
* 修改部门
*/
@PreAuthorize("@ss.hasPermi('system:dept:edit')")
@Log(title = "部门管理", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@Validated @RequestBody SysDept dept)
{
Long deptId = dept.getDeptId();
deptService.checkDeptDataScope(deptId);
if (!deptService.checkDeptNameUnique(dept))
{
return error("修改部门'" + dept.getDeptName() + "'失败,部门名称已存在");
}
else if (dept.getParentId().equals(deptId))
{
return error("修改部门'" + dept.getDeptName() + "'失败,上级部门不能是自己");
}
else if (StringUtils.equals(UserConstants.DEPT_DISABLE, dept.getStatus()) && deptService.selectNormalChildrenDeptById(deptId) > 0)
{
return error("该部门包含未停用的子部门!");
}
dept.setUpdateBy(getUsername());
return toAjax(deptService.updateDept(dept));
}
/**
* 删除部门
*/
@PreAuthorize("@ss.hasPermi('system:dept:remove')")
@Log(title = "部门管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{deptId}")
public AjaxResult remove(@PathVariable Long deptId)
{
if (deptService.hasChildByDeptId(deptId))
{
return warn("存在下级部门,不允许删除");
}
if (deptService.checkDeptExistUser(deptId))
{
return warn("部门存在用户,不允许删除");
}
deptService.checkDeptDataScope(deptId);
return toAjax(deptService.deleteDeptById(deptId));
}
}

View File

@ -0,0 +1,121 @@
package com.ruoyi.web.controller.system;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.system.service.ISysDictDataService;
import com.ruoyi.system.service.ISysDictTypeService;
/**
* 数据字典信息
*
* @author ruoyi
*/
@RestController
@RequestMapping("/system/dict/data")
public class SysDictDataController extends BaseController
{
@Autowired
private ISysDictDataService dictDataService;
@Autowired
private ISysDictTypeService dictTypeService;
@PreAuthorize("@ss.hasPermi('system:dict:list')")
@GetMapping("/list")
public TableDataInfo list(SysDictData dictData)
{
startPage();
List<SysDictData> list = dictDataService.selectDictDataList(dictData);
return getDataTable(list);
}
@Log(title = "字典数据", businessType = BusinessType.EXPORT)
@PreAuthorize("@ss.hasPermi('system:dict:export')")
@PostMapping("/export")
public void export(HttpServletResponse response, SysDictData dictData)
{
List<SysDictData> list = dictDataService.selectDictDataList(dictData);
ExcelUtil<SysDictData> util = new ExcelUtil<SysDictData>(SysDictData.class);
util.exportExcel(response, list, "字典数据");
}
/**
* 查询字典数据详细
*/
@PreAuthorize("@ss.hasPermi('system:dict:query')")
@GetMapping(value = "/{dictCode}")
public AjaxResult getInfo(@PathVariable Long dictCode)
{
return success(dictDataService.selectDictDataById(dictCode));
}
/**
* 根据字典类型查询字典数据信息
*/
@GetMapping(value = "/type/{dictType}")
public AjaxResult dictType(@PathVariable String dictType)
{
List<SysDictData> data = dictTypeService.selectDictDataByType(dictType);
if (StringUtils.isNull(data))
{
data = new ArrayList<SysDictData>();
}
return success(data);
}
/**
* 新增字典类型
*/
@PreAuthorize("@ss.hasPermi('system:dict:add')")
@Log(title = "字典数据", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@Validated @RequestBody SysDictData dict)
{
dict.setCreateBy(getUsername());
return toAjax(dictDataService.insertDictData(dict));
}
/**
* 修改保存字典类型
*/
@PreAuthorize("@ss.hasPermi('system:dict:edit')")
@Log(title = "字典数据", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@Validated @RequestBody SysDictData dict)
{
dict.setUpdateBy(getUsername());
return toAjax(dictDataService.updateDictData(dict));
}
/**
* 删除字典类型
*/
@PreAuthorize("@ss.hasPermi('system:dict:remove')")
@Log(title = "字典类型", businessType = BusinessType.DELETE)
@DeleteMapping("/{dictCodes}")
public AjaxResult remove(@PathVariable Long[] dictCodes)
{
dictDataService.deleteDictDataByIds(dictCodes);
return success();
}
}

View File

@ -0,0 +1,131 @@
package com.ruoyi.web.controller.system;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysDictType;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.system.service.ISysDictTypeService;
/**
* 数据字典信息
*
* @author ruoyi
*/
@RestController
@RequestMapping("/system/dict/type")
public class SysDictTypeController extends BaseController
{
@Autowired
private ISysDictTypeService dictTypeService;
@PreAuthorize("@ss.hasPermi('system:dict:list')")
@GetMapping("/list")
public TableDataInfo list(SysDictType dictType)
{
startPage();
List<SysDictType> list = dictTypeService.selectDictTypeList(dictType);
return getDataTable(list);
}
@Log(title = "字典类型", businessType = BusinessType.EXPORT)
@PreAuthorize("@ss.hasPermi('system:dict:export')")
@PostMapping("/export")
public void export(HttpServletResponse response, SysDictType dictType)
{
List<SysDictType> list = dictTypeService.selectDictTypeList(dictType);
ExcelUtil<SysDictType> util = new ExcelUtil<SysDictType>(SysDictType.class);
util.exportExcel(response, list, "字典类型");
}
/**
* 查询字典类型详细
*/
@PreAuthorize("@ss.hasPermi('system:dict:query')")
@GetMapping(value = "/{dictId}")
public AjaxResult getInfo(@PathVariable Long dictId)
{
return success(dictTypeService.selectDictTypeById(dictId));
}
/**
* 新增字典类型
*/
@PreAuthorize("@ss.hasPermi('system:dict:add')")
@Log(title = "字典类型", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@Validated @RequestBody SysDictType dict)
{
if (!dictTypeService.checkDictTypeUnique(dict))
{
return error("新增字典'" + dict.getDictName() + "'失败,字典类型已存在");
}
dict.setCreateBy(getUsername());
return toAjax(dictTypeService.insertDictType(dict));
}
/**
* 修改字典类型
*/
@PreAuthorize("@ss.hasPermi('system:dict:edit')")
@Log(title = "字典类型", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@Validated @RequestBody SysDictType dict)
{
if (!dictTypeService.checkDictTypeUnique(dict))
{
return error("修改字典'" + dict.getDictName() + "'失败,字典类型已存在");
}
dict.setUpdateBy(getUsername());
return toAjax(dictTypeService.updateDictType(dict));
}
/**
* 删除字典类型
*/
@PreAuthorize("@ss.hasPermi('system:dict:remove')")
@Log(title = "字典类型", businessType = BusinessType.DELETE)
@DeleteMapping("/{dictIds}")
public AjaxResult remove(@PathVariable Long[] dictIds)
{
dictTypeService.deleteDictTypeByIds(dictIds);
return success();
}
/**
* 刷新字典缓存
*/
@PreAuthorize("@ss.hasPermi('system:dict:remove')")
@Log(title = "字典类型", businessType = BusinessType.CLEAN)
@DeleteMapping("/refreshCache")
public AjaxResult refreshCache()
{
dictTypeService.resetDictCache();
return success();
}
/**
* 获取字典选择框列表
*/
@GetMapping("/optionselect")
public AjaxResult optionselect()
{
List<SysDictType> dictTypes = dictTypeService.selectDictTypeAll();
return success(dictTypes);
}
}

View File

@ -0,0 +1,29 @@
package com.ruoyi.web.controller.system;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.utils.StringUtils;
/**
* 首页
*
* @author ruoyi
*/
@RestController
public class SysIndexController
{
/** 系统基础配置 */
@Autowired
private RuoYiConfig ruoyiConfig;
/**
* 访问首页提示语
*/
@RequestMapping("/")
public String index()
{
return StringUtils.format("欢迎使用{}后台管理框架当前版本v{},请通过前端地址访问。", ruoyiConfig.getName(), ruoyiConfig.getVersion());
}
}

View File

@ -0,0 +1,97 @@
package com.ruoyi.web.controller.system;
import java.util.List;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysMenu;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginBody;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.framework.web.service.SysLoginService;
import com.ruoyi.framework.web.service.SysPermissionService;
import com.ruoyi.framework.web.service.TokenService;
import com.ruoyi.system.service.ISysMenuService;
/**
* 登录验证
*
* @author ruoyi
*/
@RestController
public class SysLoginController
{
@Autowired
private SysLoginService loginService;
@Autowired
private ISysMenuService menuService;
@Autowired
private SysPermissionService permissionService;
@Autowired
private TokenService tokenService;
/**
* 登录方法
*
* @param loginBody 登录信息
* @return 结果
*/
@PostMapping("/login")
public AjaxResult login(@RequestBody LoginBody loginBody)
{
AjaxResult ajax = AjaxResult.success();
// 生成令牌
String token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(),
loginBody.getUuid());
ajax.put(Constants.TOKEN, token);
return ajax;
}
/**
* 获取用户信息
*
* @return 用户信息
*/
@GetMapping("getInfo")
public AjaxResult getInfo()
{
LoginUser loginUser = SecurityUtils.getLoginUser();
SysUser user = loginUser.getUser();
// 角色集合
Set<String> roles = permissionService.getRolePermission(user);
// 权限集合
Set<String> permissions = permissionService.getMenuPermission(user);
if (!loginUser.getPermissions().equals(permissions))
{
loginUser.setPermissions(permissions);
tokenService.refreshToken(loginUser);
}
AjaxResult ajax = AjaxResult.success();
ajax.put("user", user);
ajax.put("roles", roles);
ajax.put("permissions", permissions);
return ajax;
}
/**
* 获取路由信息
*
* @return 路由信息
*/
@GetMapping("getRouters")
public AjaxResult getRouters()
{
Long userId = SecurityUtils.getUserId();
List<SysMenu> menus = menuService.selectMenuTreeByUserId(userId);
return AjaxResult.success(menuService.buildMenus(menus));
}
}

View File

@ -0,0 +1,142 @@
package com.ruoyi.web.controller.system;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysMenu;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.service.ISysMenuService;
/**
* 菜单信息
*
* @author ruoyi
*/
@RestController
@RequestMapping("/system/menu")
public class SysMenuController extends BaseController
{
@Autowired
private ISysMenuService menuService;
/**
* 获取菜单列表
*/
@PreAuthorize("@ss.hasPermi('system:menu:list')")
@GetMapping("/list")
public AjaxResult list(SysMenu menu)
{
List<SysMenu> menus = menuService.selectMenuList(menu, getUserId());
return success(menus);
}
/**
* 根据菜单编号获取详细信息
*/
@PreAuthorize("@ss.hasPermi('system:menu:query')")
@GetMapping(value = "/{menuId}")
public AjaxResult getInfo(@PathVariable Long menuId)
{
return success(menuService.selectMenuById(menuId));
}
/**
* 获取菜单下拉树列表
*/
@GetMapping("/treeselect")
public AjaxResult treeselect(SysMenu menu)
{
List<SysMenu> menus = menuService.selectMenuList(menu, getUserId());
return success(menuService.buildMenuTreeSelect(menus));
}
/**
* 加载对应角色菜单列表树
*/
@GetMapping(value = "/roleMenuTreeselect/{roleId}")
public AjaxResult roleMenuTreeselect(@PathVariable("roleId") Long roleId)
{
List<SysMenu> menus = menuService.selectMenuList(getUserId());
AjaxResult ajax = AjaxResult.success();
ajax.put("checkedKeys", menuService.selectMenuListByRoleId(roleId));
ajax.put("menus", menuService.buildMenuTreeSelect(menus));
return ajax;
}
/**
* 新增菜单
*/
@PreAuthorize("@ss.hasPermi('system:menu:add')")
@Log(title = "菜单管理", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@Validated @RequestBody SysMenu menu)
{
if (!menuService.checkMenuNameUnique(menu))
{
return error("新增菜单'" + menu.getMenuName() + "'失败,菜单名称已存在");
}
else if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath()))
{
return error("新增菜单'" + menu.getMenuName() + "'失败地址必须以http(s)://开头");
}
menu.setCreateBy(getUsername());
return toAjax(menuService.insertMenu(menu));
}
/**
* 修改菜单
*/
@PreAuthorize("@ss.hasPermi('system:menu:edit')")
@Log(title = "菜单管理", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@Validated @RequestBody SysMenu menu)
{
if (!menuService.checkMenuNameUnique(menu))
{
return error("修改菜单'" + menu.getMenuName() + "'失败,菜单名称已存在");
}
else if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath()))
{
return error("修改菜单'" + menu.getMenuName() + "'失败地址必须以http(s)://开头");
}
else if (menu.getMenuId().equals(menu.getParentId()))
{
return error("修改菜单'" + menu.getMenuName() + "'失败,上级菜单不能选择自己");
}
menu.setUpdateBy(getUsername());
return toAjax(menuService.updateMenu(menu));
}
/**
* 删除菜单
*/
@PreAuthorize("@ss.hasPermi('system:menu:remove')")
@Log(title = "菜单管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{menuId}")
public AjaxResult remove(@PathVariable("menuId") Long menuId)
{
if (menuService.hasChildByMenuId(menuId))
{
return warn("存在子菜单,不允许删除");
}
if (menuService.checkMenuExistRole(menuId))
{
return warn("菜单已分配,不允许删除");
}
return toAjax(menuService.deleteMenuById(menuId));
}
}

View File

@ -0,0 +1,91 @@
package com.ruoyi.web.controller.system;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.system.domain.SysNotice;
import com.ruoyi.system.service.ISysNoticeService;
/**
* 公告 信息操作处理
*
* @author ruoyi
*/
@RestController
@RequestMapping("/system/notice")
public class SysNoticeController extends BaseController
{
@Autowired
private ISysNoticeService noticeService;
/**
* 获取通知公告列表
*/
@PreAuthorize("@ss.hasPermi('system:notice:list')")
@GetMapping("/list")
public TableDataInfo list(SysNotice notice)
{
startPage();
List<SysNotice> list = noticeService.selectNoticeList(notice);
return getDataTable(list);
}
/**
* 根据通知公告编号获取详细信息
*/
@PreAuthorize("@ss.hasPermi('system:notice:query')")
@GetMapping(value = "/{noticeId}")
public AjaxResult getInfo(@PathVariable Long noticeId)
{
return success(noticeService.selectNoticeById(noticeId));
}
/**
* 新增通知公告
*/
@PreAuthorize("@ss.hasPermi('system:notice:add')")
@Log(title = "通知公告", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@Validated @RequestBody SysNotice notice)
{
notice.setCreateBy(getUsername());
return toAjax(noticeService.insertNotice(notice));
}
/**
* 修改通知公告
*/
@PreAuthorize("@ss.hasPermi('system:notice:edit')")
@Log(title = "通知公告", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@Validated @RequestBody SysNotice notice)
{
notice.setUpdateBy(getUsername());
return toAjax(noticeService.updateNotice(notice));
}
/**
* 删除通知公告
*/
@PreAuthorize("@ss.hasPermi('system:notice:remove')")
@Log(title = "通知公告", businessType = BusinessType.DELETE)
@DeleteMapping("/{noticeIds}")
public AjaxResult remove(@PathVariable Long[] noticeIds)
{
return toAjax(noticeService.deleteNoticeByIds(noticeIds));
}
}

View File

@ -0,0 +1,129 @@
package com.ruoyi.web.controller.system;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.system.domain.SysPost;
import com.ruoyi.system.service.ISysPostService;
/**
* 岗位信息操作处理
*
* @author ruoyi
*/
@RestController
@RequestMapping("/system/post")
public class SysPostController extends BaseController
{
@Autowired
private ISysPostService postService;
/**
* 获取岗位列表
*/
@PreAuthorize("@ss.hasPermi('system:post:list')")
@GetMapping("/list")
public TableDataInfo list(SysPost post)
{
startPage();
List<SysPost> list = postService.selectPostList(post);
return getDataTable(list);
}
@Log(title = "岗位管理", businessType = BusinessType.EXPORT)
@PreAuthorize("@ss.hasPermi('system:post:export')")
@PostMapping("/export")
public void export(HttpServletResponse response, SysPost post)
{
List<SysPost> list = postService.selectPostList(post);
ExcelUtil<SysPost> util = new ExcelUtil<SysPost>(SysPost.class);
util.exportExcel(response, list, "岗位数据");
}
/**
* 根据岗位编号获取详细信息
*/
@PreAuthorize("@ss.hasPermi('system:post:query')")
@GetMapping(value = "/{postId}")
public AjaxResult getInfo(@PathVariable Long postId)
{
return success(postService.selectPostById(postId));
}
/**
* 新增岗位
*/
@PreAuthorize("@ss.hasPermi('system:post:add')")
@Log(title = "岗位管理", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@Validated @RequestBody SysPost post)
{
if (!postService.checkPostNameUnique(post))
{
return error("新增岗位'" + post.getPostName() + "'失败,岗位名称已存在");
}
else if (!postService.checkPostCodeUnique(post))
{
return error("新增岗位'" + post.getPostName() + "'失败,岗位编码已存在");
}
post.setCreateBy(getUsername());
return toAjax(postService.insertPost(post));
}
/**
* 修改岗位
*/
@PreAuthorize("@ss.hasPermi('system:post:edit')")
@Log(title = "岗位管理", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@Validated @RequestBody SysPost post)
{
if (!postService.checkPostNameUnique(post))
{
return error("修改岗位'" + post.getPostName() + "'失败,岗位名称已存在");
}
else if (!postService.checkPostCodeUnique(post))
{
return error("修改岗位'" + post.getPostName() + "'失败,岗位编码已存在");
}
post.setUpdateBy(getUsername());
return toAjax(postService.updatePost(post));
}
/**
* 删除岗位
*/
@PreAuthorize("@ss.hasPermi('system:post:remove')")
@Log(title = "岗位管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{postIds}")
public AjaxResult remove(@PathVariable Long[] postIds)
{
return toAjax(postService.deletePostByIds(postIds));
}
/**
* 获取岗位选择框列表
*/
@GetMapping("/optionselect")
public AjaxResult optionselect()
{
List<SysPost> posts = postService.selectPostAll();
return success(posts);
}
}

View File

@ -0,0 +1,140 @@
package com.ruoyi.web.controller.system;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.common.utils.file.MimeTypeUtils;
import com.ruoyi.framework.web.service.TokenService;
import com.ruoyi.system.service.ISysUserService;
/**
* 个人信息 业务处理
*
* @author ruoyi
*/
@RestController
@RequestMapping("/system/user/profile")
public class SysProfileController extends BaseController
{
@Autowired
private ISysUserService userService;
@Autowired
private TokenService tokenService;
/**
* 个人信息
*/
@GetMapping
public AjaxResult profile()
{
LoginUser loginUser = getLoginUser();
SysUser user = loginUser.getUser();
AjaxResult ajax = AjaxResult.success(user);
ajax.put("roleGroup", userService.selectUserRoleGroup(loginUser.getUsername()));
ajax.put("postGroup", userService.selectUserPostGroup(loginUser.getUsername()));
return ajax;
}
/**
* 修改用户
*/
@Log(title = "个人信息", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult updateProfile(@RequestBody SysUser user)
{
LoginUser loginUser = getLoginUser();
SysUser currentUser = loginUser.getUser();
currentUser.setNickName(user.getNickName());
currentUser.setEmail(user.getEmail());
currentUser.setPhonenumber(user.getPhonenumber());
currentUser.setSex(user.getSex());
if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(currentUser))
{
return error("修改用户'" + loginUser.getUsername() + "'失败,手机号码已存在");
}
if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(currentUser))
{
return error("修改用户'" + loginUser.getUsername() + "'失败,邮箱账号已存在");
}
if (userService.updateUserProfile(currentUser) > 0)
{
// 更新缓存用户信息
tokenService.setLoginUser(loginUser);
return success();
}
return error("修改个人信息异常,请联系管理员");
}
/**
* 重置密码
*/
@Log(title = "个人信息", businessType = BusinessType.UPDATE)
@PutMapping("/updatePwd")
public AjaxResult updatePwd(@RequestBody Map<String, String> params)
{
String oldPassword = params.get("oldPassword");
String newPassword = params.get("newPassword");
LoginUser loginUser = getLoginUser();
String userName = loginUser.getUsername();
String password = loginUser.getPassword();
if (!SecurityUtils.matchesPassword(oldPassword, password))
{
return error("修改密码失败,旧密码错误");
}
if (SecurityUtils.matchesPassword(newPassword, password))
{
return error("新密码不能与旧密码相同");
}
newPassword = SecurityUtils.encryptPassword(newPassword);
if (userService.resetUserPwd(userName, newPassword) > 0)
{
// 更新缓存用户密码
loginUser.getUser().setPassword(newPassword);
tokenService.setLoginUser(loginUser);
return success();
}
return error("修改密码异常,请联系管理员");
}
/**
* 头像上传
*/
@Log(title = "用户头像", businessType = BusinessType.UPDATE)
@PostMapping("/avatar")
public AjaxResult avatar(@RequestParam("avatarfile") MultipartFile file) throws Exception
{
if (!file.isEmpty())
{
LoginUser loginUser = getLoginUser();
String avatar = FileUploadUtils.upload(RuoYiConfig.getAvatarPath(), file, MimeTypeUtils.IMAGE_EXTENSION);
if (userService.updateUserAvatar(loginUser.getUsername(), avatar))
{
AjaxResult ajax = AjaxResult.success();
ajax.put("imgUrl", avatar);
// 更新缓存用户头像
loginUser.getUser().setAvatar(avatar);
tokenService.setLoginUser(loginUser);
return ajax;
}
}
return error("上传图片异常,请联系管理员");
}
}

View File

@ -0,0 +1,38 @@
package com.ruoyi.web.controller.system;
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.RestController;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.model.RegisterBody;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.web.service.SysRegisterService;
import com.ruoyi.system.service.ISysConfigService;
/**
* 注册验证
*
* @author ruoyi
*/
@RestController
public class SysRegisterController extends BaseController
{
@Autowired
private SysRegisterService registerService;
@Autowired
private ISysConfigService configService;
@PostMapping("/register")
public AjaxResult register(@RequestBody RegisterBody user)
{
if (!("true".equals(configService.selectConfigByKey("sys.account.registerUser"))))
{
return error("当前系统没有开启注册功能!");
}
String msg = registerService.register(user);
return StringUtils.isEmpty(msg) ? success() : error(msg);
}
}

View File

@ -0,0 +1,262 @@
package com.ruoyi.web.controller.system;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.web.service.SysPermissionService;
import com.ruoyi.framework.web.service.TokenService;
import com.ruoyi.system.domain.SysUserRole;
import com.ruoyi.system.service.ISysDeptService;
import com.ruoyi.system.service.ISysRoleService;
import com.ruoyi.system.service.ISysUserService;
/**
* 角色信息
*
* @author ruoyi
*/
@RestController
@RequestMapping("/system/role")
public class SysRoleController extends BaseController
{
@Autowired
private ISysRoleService roleService;
@Autowired
private TokenService tokenService;
@Autowired
private SysPermissionService permissionService;
@Autowired
private ISysUserService userService;
@Autowired
private ISysDeptService deptService;
@PreAuthorize("@ss.hasPermi('system:role:list')")
@GetMapping("/list")
public TableDataInfo list(SysRole role)
{
startPage();
List<SysRole> list = roleService.selectRoleList(role);
return getDataTable(list);
}
@Log(title = "角色管理", businessType = BusinessType.EXPORT)
@PreAuthorize("@ss.hasPermi('system:role:export')")
@PostMapping("/export")
public void export(HttpServletResponse response, SysRole role)
{
List<SysRole> list = roleService.selectRoleList(role);
ExcelUtil<SysRole> util = new ExcelUtil<SysRole>(SysRole.class);
util.exportExcel(response, list, "角色数据");
}
/**
* 根据角色编号获取详细信息
*/
@PreAuthorize("@ss.hasPermi('system:role:query')")
@GetMapping(value = "/{roleId}")
public AjaxResult getInfo(@PathVariable Long roleId)
{
roleService.checkRoleDataScope(roleId);
return success(roleService.selectRoleById(roleId));
}
/**
* 新增角色
*/
@PreAuthorize("@ss.hasPermi('system:role:add')")
@Log(title = "角色管理", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@Validated @RequestBody SysRole role)
{
if (!roleService.checkRoleNameUnique(role))
{
return error("新增角色'" + role.getRoleName() + "'失败,角色名称已存在");
}
else if (!roleService.checkRoleKeyUnique(role))
{
return error("新增角色'" + role.getRoleName() + "'失败,角色权限已存在");
}
role.setCreateBy(getUsername());
return toAjax(roleService.insertRole(role));
}
/**
* 修改保存角色
*/
@PreAuthorize("@ss.hasPermi('system:role:edit')")
@Log(title = "角色管理", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@Validated @RequestBody SysRole role)
{
roleService.checkRoleAllowed(role);
roleService.checkRoleDataScope(role.getRoleId());
if (!roleService.checkRoleNameUnique(role))
{
return error("修改角色'" + role.getRoleName() + "'失败,角色名称已存在");
}
else if (!roleService.checkRoleKeyUnique(role))
{
return error("修改角色'" + role.getRoleName() + "'失败,角色权限已存在");
}
role.setUpdateBy(getUsername());
if (roleService.updateRole(role) > 0)
{
// 更新缓存用户权限
LoginUser loginUser = getLoginUser();
if (StringUtils.isNotNull(loginUser.getUser()) && !loginUser.getUser().isAdmin())
{
loginUser.setUser(userService.selectUserByUserName(loginUser.getUser().getUserName()));
loginUser.setPermissions(permissionService.getMenuPermission(loginUser.getUser()));
tokenService.setLoginUser(loginUser);
}
return success();
}
return error("修改角色'" + role.getRoleName() + "'失败,请联系管理员");
}
/**
* 修改保存数据权限
*/
@PreAuthorize("@ss.hasPermi('system:role:edit')")
@Log(title = "角色管理", businessType = BusinessType.UPDATE)
@PutMapping("/dataScope")
public AjaxResult dataScope(@RequestBody SysRole role)
{
roleService.checkRoleAllowed(role);
roleService.checkRoleDataScope(role.getRoleId());
return toAjax(roleService.authDataScope(role));
}
/**
* 状态修改
*/
@PreAuthorize("@ss.hasPermi('system:role:edit')")
@Log(title = "角色管理", businessType = BusinessType.UPDATE)
@PutMapping("/changeStatus")
public AjaxResult changeStatus(@RequestBody SysRole role)
{
roleService.checkRoleAllowed(role);
roleService.checkRoleDataScope(role.getRoleId());
role.setUpdateBy(getUsername());
return toAjax(roleService.updateRoleStatus(role));
}
/**
* 删除角色
*/
@PreAuthorize("@ss.hasPermi('system:role:remove')")
@Log(title = "角色管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{roleIds}")
public AjaxResult remove(@PathVariable Long[] roleIds)
{
return toAjax(roleService.deleteRoleByIds(roleIds));
}
/**
* 获取角色选择框列表
*/
@PreAuthorize("@ss.hasPermi('system:role:query')")
@GetMapping("/optionselect")
public AjaxResult optionselect()
{
return success(roleService.selectRoleAll());
}
/**
* 查询已分配用户角色列表
*/
@PreAuthorize("@ss.hasPermi('system:role:list')")
@GetMapping("/authUser/allocatedList")
public TableDataInfo allocatedList(SysUser user)
{
startPage();
List<SysUser> list = userService.selectAllocatedList(user);
return getDataTable(list);
}
/**
* 查询未分配用户角色列表
*/
@PreAuthorize("@ss.hasPermi('system:role:list')")
@GetMapping("/authUser/unallocatedList")
public TableDataInfo unallocatedList(SysUser user)
{
startPage();
List<SysUser> list = userService.selectUnallocatedList(user);
return getDataTable(list);
}
/**
* 取消授权用户
*/
@PreAuthorize("@ss.hasPermi('system:role:edit')")
@Log(title = "角色管理", businessType = BusinessType.GRANT)
@PutMapping("/authUser/cancel")
public AjaxResult cancelAuthUser(@RequestBody SysUserRole userRole)
{
return toAjax(roleService.deleteAuthUser(userRole));
}
/**
* 批量取消授权用户
*/
@PreAuthorize("@ss.hasPermi('system:role:edit')")
@Log(title = "角色管理", businessType = BusinessType.GRANT)
@PutMapping("/authUser/cancelAll")
public AjaxResult cancelAuthUserAll(Long roleId, Long[] userIds)
{
return toAjax(roleService.deleteAuthUsers(roleId, userIds));
}
/**
* 批量选择用户授权
*/
@PreAuthorize("@ss.hasPermi('system:role:edit')")
@Log(title = "角色管理", businessType = BusinessType.GRANT)
@PutMapping("/authUser/selectAll")
public AjaxResult selectAuthUserAll(Long roleId, Long[] userIds)
{
roleService.checkRoleDataScope(roleId);
return toAjax(roleService.insertAuthUsers(roleId, userIds));
}
/**
* 获取对应角色部门树列表
*/
@PreAuthorize("@ss.hasPermi('system:role:query')")
@GetMapping(value = "/deptTree/{roleId}")
public AjaxResult deptTree(@PathVariable("roleId") Long roleId)
{
AjaxResult ajax = AjaxResult.success();
ajax.put("checkedKeys", deptService.selectDeptListByRoleId(roleId));
ajax.put("depts", deptService.selectDeptTreeList(new SysDept(), false));
return ajax;
}
}

View File

@ -0,0 +1,261 @@
package com.ruoyi.web.controller.system;
import java.util.List;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletResponse;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.system.service.ISysDeptService;
import com.ruoyi.system.service.ISysPostService;
import com.ruoyi.system.service.ISysRoleService;
import com.ruoyi.system.service.ISysUserService;
/**
* 用户信息
*
* @author ruoyi
*/
@Api("用户信息")
@RestController
@RequestMapping("/system/user")
public class SysUserController extends BaseController
{
@Autowired
private ISysUserService userService;
@Autowired
private ISysRoleService roleService;
@Autowired
private ISysDeptService deptService;
@Autowired
private ISysPostService postService;
/**
* 获取用户列表
*/
@ApiOperation("用户列表")
@PreAuthorize("@ss.hasPermi('system:user:list')")
@GetMapping("/list")
public TableDataInfo list(SysUser user)
{
startPage();
List<SysUser> list = userService.selectUserList(user);
return getDataTable(list);
}
@Log(title = "用户管理", businessType = BusinessType.EXPORT)
@PreAuthorize("@ss.hasPermi('system:user:export')")
@PostMapping("/export")
public void export(HttpServletResponse response, SysUser user)
{
List<SysUser> list = userService.selectUserList(user);
ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class);
util.exportExcel(response, list, "用户数据");
}
@Log(title = "用户管理", businessType = BusinessType.IMPORT)
@PreAuthorize("@ss.hasPermi('system:user:import')")
@PostMapping("/importData")
public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception
{
ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class);
List<SysUser> userList = util.importExcel(file.getInputStream());
String operName = getUsername();
String message = userService.importUser(userList, updateSupport, operName);
return success(message);
}
@PostMapping("/importTemplate")
public void importTemplate(HttpServletResponse response)
{
ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class);
util.importTemplateExcel(response, "用户数据");
}
/**
* 根据用户编号获取详细信息
*/
@PreAuthorize("@ss.hasPermi('system:user:query')")
@GetMapping(value = { "/", "/{userId}" })
public AjaxResult getInfo(@PathVariable(value = "userId", required = false) Long userId)
{
AjaxResult ajax = AjaxResult.success();
if (StringUtils.isNotNull(userId))
{
userService.checkUserDataScope(userId);
SysUser sysUser = userService.selectUserById(userId);
ajax.put(AjaxResult.DATA_TAG, sysUser);
ajax.put("postIds", postService.selectPostListByUserId(userId));
ajax.put("roleIds", sysUser.getRoles().stream().map(SysRole::getRoleId).collect(Collectors.toList()));
}
List<SysRole> roles = roleService.selectRoleAll();
ajax.put("roles", SysUser.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList()));
ajax.put("posts", postService.selectPostAll());
return ajax;
}
/**
* 新增用户
*/
@PreAuthorize("@ss.hasPermi('system:user:add')")
@Log(title = "用户管理", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@Validated @RequestBody SysUser user)
{
deptService.checkDeptDataScope(user.getDeptId());
roleService.checkRoleDataScope(user.getRoleIds());
if (!userService.checkUserNameUnique(user))
{
return error("新增用户'" + user.getUserName() + "'失败,登录账号已存在");
}
else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user))
{
return error("新增用户'" + user.getUserName() + "'失败,手机号码已存在");
}
else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user))
{
return error("新增用户'" + user.getUserName() + "'失败,邮箱账号已存在");
}
user.setCreateBy(getUsername());
user.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
return toAjax(userService.insertUser(user));
}
/**
* 修改用户
*/
@PreAuthorize("@ss.hasPermi('system:user:edit')")
@Log(title = "用户管理", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@Validated @RequestBody SysUser user)
{
userService.checkUserAllowed(user);
userService.checkUserDataScope(user.getUserId());
deptService.checkDeptDataScope(user.getDeptId());
roleService.checkRoleDataScope(user.getRoleIds());
if (!userService.checkUserNameUnique(user))
{
return error("修改用户'" + user.getUserName() + "'失败,登录账号已存在");
}
else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user))
{
return error("修改用户'" + user.getUserName() + "'失败,手机号码已存在");
}
else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user))
{
return error("修改用户'" + user.getUserName() + "'失败,邮箱账号已存在");
}
user.setUpdateBy(getUsername());
return toAjax(userService.updateUser(user));
}
/**
* 删除用户
*/
@PreAuthorize("@ss.hasPermi('system:user:remove')")
@Log(title = "用户管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{userIds}")
public AjaxResult remove(@PathVariable Long[] userIds)
{
if (ArrayUtils.contains(userIds, getUserId()))
{
return error("当前用户不能删除");
}
return toAjax(userService.deleteUserByIds(userIds));
}
/**
* 重置密码
*/
@PreAuthorize("@ss.hasPermi('system:user:resetPwd')")
@Log(title = "用户管理", businessType = BusinessType.UPDATE)
@PutMapping("/resetPwd")
public AjaxResult resetPwd(@RequestBody SysUser user)
{
userService.checkUserAllowed(user);
userService.checkUserDataScope(user.getUserId());
user.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
user.setUpdateBy(getUsername());
return toAjax(userService.resetPwd(user));
}
/**
* 状态修改
*/
@PreAuthorize("@ss.hasPermi('system:user:edit')")
@Log(title = "用户管理", businessType = BusinessType.UPDATE)
@PutMapping("/changeStatus")
public AjaxResult changeStatus(@RequestBody SysUser user)
{
userService.checkUserAllowed(user);
userService.checkUserDataScope(user.getUserId());
user.setUpdateBy(getUsername());
return toAjax(userService.updateUserStatus(user));
}
/**
* 根据用户编号获取授权角色
*/
@PreAuthorize("@ss.hasPermi('system:user:query')")
@GetMapping("/authRole/{userId}")
public AjaxResult authRole(@PathVariable("userId") Long userId)
{
AjaxResult ajax = AjaxResult.success();
SysUser user = userService.selectUserById(userId);
List<SysRole> roles = roleService.selectRolesByUserId(userId);
ajax.put("user", user);
ajax.put("roles", SysUser.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList()));
return ajax;
}
/**
* 用户授权角色
*/
@PreAuthorize("@ss.hasPermi('system:user:edit')")
@Log(title = "用户管理", businessType = BusinessType.GRANT)
@PutMapping("/authRole")
public AjaxResult insertAuthRole(Long userId, Long[] roleIds)
{
userService.checkUserDataScope(userId);
roleService.checkRoleDataScope(roleIds);
userService.insertUserAuth(userId, roleIds);
return success();
}
/**
* 获取部门树列表
*/
@PreAuthorize("@ss.hasPermi('system:user:list')")
@GetMapping("/deptTree")
public AjaxResult deptTree(SysDept dept, boolean filterParent)
{
return success(deptService.selectDeptTreeList(dept, filterParent));
}
}

View File

@ -0,0 +1,94 @@
package com.ruoyi.web.controller.tg;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.web.domain.CustomerDeptPostRel;
import com.ruoyi.web.model.dto.CustomerDeptPostRelDto;
import com.ruoyi.web.service.ICustomerDeptPostRelService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 客户-部门-岗位关联Controller
*
* @author ruoyi
* @date 2025-04-08
*/
@Api(tags = "客户-部门-岗位关联管理")
@RestController
@RequiredArgsConstructor
@RequestMapping("/customer/dept/post/rel")
public class CustomerDeptPostRelController extends BaseController {
private final ICustomerDeptPostRelService customerDeptPostRelService;
/**
* 查询客户-部门-岗位关联列表
*/
@ApiOperation("查询客户-部门-岗位关联列表")
@ApiImplicitParams({
@ApiImplicitParam(name = "pageNum", value = "页码", dataType = "int", paramType = "query"),
@ApiImplicitParam(name = "pageSize", value = "每页大小", dataType = "int", paramType = "query")
})
@PreAuthorize("@ss.hasPermi('web:rel:list')")
@GetMapping("/list")
public TableDataInfo list(CustomerDeptPostRel customerDeptPostRel) {
startPage();
List<CustomerDeptPostRelDto> list = customerDeptPostRelService.selectCustomerDeptPostRelList(customerDeptPostRel);
return getDataTable(list);
}
/**
* 获取客户-部门-岗位关联详细信息
*/
@ApiOperation("获取客户-部门-岗位关联详细信息")
@ApiImplicitParam(name = "id", value = "主键ID", required = true, dataType = "Long")
@PreAuthorize("@ss.hasPermi('web:rel:query')")
@GetMapping("/{id}")
public AjaxResult getInfo(@PathVariable Long id) {
return AjaxResult.success(customerDeptPostRelService.selectCustomerDeptPostRelById(id));
}
/**
* 新增客户-部门-岗位关联
*/
@ApiOperation("新增客户-部门-岗位关联")
@PreAuthorize("@ss.hasPermi('web:rel:add')")
@Log(title = "客户-部门-岗位关联", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody CustomerDeptPostRel customerDeptPostRel) {
return toAjax(customerDeptPostRelService.insertCustomerDeptPostRel(customerDeptPostRel));
}
/**
* 修改客户-部门-岗位关联
*/
@ApiOperation("修改客户-部门-岗位关联")
@PreAuthorize("@ss.hasPermi('web:rel:edit')")
@Log(title = "客户-部门-岗位关联", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody CustomerDeptPostRel customerDeptPostRel) {
return toAjax(customerDeptPostRelService.updateCustomerDeptPostRel(customerDeptPostRel));
}
/**
* 删除客户-部门-岗位关联
*/
@ApiOperation("删除客户-部门-岗位关联")
@PreAuthorize("@ss.hasPermi('web:rel:remove')")
@Log(title = "客户-部门-岗位关联", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable Long[] ids) {
return toAjax(customerDeptPostRelService.deleteCustomerDeptPostRelByIds(ids));
}
}

View File

@ -0,0 +1,33 @@
package com.ruoyi.web.controller.tg;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.web.model.dto.CreateCustomerDto;
import com.ruoyi.web.service.impl.CustomerUserRelServiceImpl;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
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;
/**
* 客户信息Controller
*
* @author cx
* @date 2025-04-05
*/
@Api(tags = "客户信息管理")
@RestController
@RequiredArgsConstructor
@RequestMapping("/customer/rel")
public class CustomerUserRelController extends BaseController {
private final CustomerUserRelServiceImpl customerUserRelService;
@ApiOperation("新建客户")
@PostMapping("/addCustomer")
public void addCustomer(@RequestBody CreateCustomerDto createCustomerDto) {
customerUserRelService.addCustomer(createCustomerDto);
}
}

View File

@ -0,0 +1,109 @@
package com.ruoyi.web.controller.tg;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.web.domain.DeviceInfo;
import com.ruoyi.web.model.dto.CreateDeviceInfoDto;
import com.ruoyi.web.model.dto.DeviceListDto;
import com.ruoyi.web.service.IDeviceInfoService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 设备信息Controller
*
* @author cx
* @date 2025-04-05
*/
@Api(tags = "设备信息管理")
@RestController
@RequiredArgsConstructor
@RequestMapping("/device/info")
public class DeviceInfoController extends BaseController {
private final IDeviceInfoService deviceInfoService;
/**
* 查询设备信息列表
*/
@ApiOperation("查询设备信息列表")
@ApiImplicitParams({
@ApiImplicitParam(name = "pageNum", value = "页码", dataType = "int", paramType = "query"),
@ApiImplicitParam(name = "pageSize", value = "每页大小", dataType = "int", paramType = "query")
})
@PreAuthorize("@ss.hasPermi('web:info:list')")
@GetMapping("/list")
public TableDataInfo list(DeviceInfo deviceInfo) {
startPage();
List<DeviceListDto> list = deviceInfoService.selectDeviceInfoList(deviceInfo);
return getDataTable(list);
}
/**
* 导出设备信息列表
*/
@ApiOperation("导出设备信息列表")
@PreAuthorize("@ss.hasPermi('web:info:export')")
@Log(title = "设备信息", businessType = BusinessType.EXPORT)
@GetMapping("/export")
public AjaxResult export(DeviceInfo deviceInfo) {
List<DeviceListDto> list = deviceInfoService.selectDeviceInfoList(deviceInfo);
ExcelUtil<DeviceListDto> util = new ExcelUtil<DeviceListDto>(DeviceListDto.class);
return util.exportExcel(list, "设备信息数据");
}
/**
* 获取设备信息详细信息
*/
@ApiOperation("获取设备信息详细信息")
@ApiImplicitParam(name = "id", value = "主键ID", required = true, dataType = "String")
@PreAuthorize("@ss.hasPermi('web:info:query')")
@GetMapping("/{id}")
public AjaxResult getInfo(@PathVariable String id) {
return AjaxResult.success(deviceInfoService.selectDeviceInfoById(id));
}
/**
* 新增设备信息
*/
@ApiOperation("新增设备信息")
@PreAuthorize("@ss.hasPermi('web:info:add')")
@Log(title = "设备信息", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@Validated @RequestBody CreateDeviceInfoDto deviceInfo) {
return toAjax(deviceInfoService.createDeviceInfo(deviceInfo));
}
/**
* 修改设备信息
*/
@ApiOperation("修改设备信息")
@PreAuthorize("@ss.hasPermi('web:info:edit')")
@Log(title = "设备信息", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody DeviceInfo deviceInfo) {
return toAjax(deviceInfoService.updateDeviceInfo(deviceInfo));
}
/**
* 删除设备信息
*/
@ApiOperation("删除设备信息")
@PreAuthorize("@ss.hasPermi('web:info:remove')")
@Log(title = "设备信息", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable String[] ids) {
return toAjax(deviceInfoService.deleteDeviceInfoByIds(ids));
}
}

View File

@ -0,0 +1,110 @@
package com.ruoyi.web.controller.tg;
import java.util.List;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.web.domain.DeviceModel;
import com.ruoyi.web.service.IDeviceModelService;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;
import io.swagger.annotations.*;
import lombok.RequiredArgsConstructor;
/**
* 设备型号Controller
*
* @author cx
* @date 2025-04-05
*/
@Api(tags = "设备型号管理")
@RestController
@RequiredArgsConstructor
@RequestMapping("/device/model")
public class DeviceModelController extends BaseController
{
private final IDeviceModelService deviceModelService;
/**
* 查询设备型号列表
*/
@ApiOperation("查询设备型号列表")
@ApiImplicitParams({
@ApiImplicitParam(name = "pageNum", value = "页码", dataType = "int", paramType = "query"),
@ApiImplicitParam(name = "pageSize", value = "每页大小", dataType = "int", paramType = "query")
})
@PreAuthorize("@ss.hasPermi('web:model:list')")
@GetMapping("/list")
public TableDataInfo list(DeviceModel deviceModel)
{
startPage();
List<DeviceModel> list = deviceModelService.selectDeviceModelList(deviceModel);
return getDataTable(list);
}
/**
* 导出设备型号列表
*/
@ApiOperation("导出设备型号列表")
@PreAuthorize("@ss.hasPermi('web:model:export')")
@Log(title = "设备型号", businessType = BusinessType.EXPORT)
@GetMapping("/export")
public AjaxResult export(DeviceModel deviceModel)
{
List<DeviceModel> list = deviceModelService.selectDeviceModelList(deviceModel);
ExcelUtil<DeviceModel> util = new ExcelUtil<DeviceModel>(DeviceModel.class);
return util.exportExcel(list, "设备型号数据");
}
/**
* 获取设备型号详细信息
*/
@ApiOperation("获取设备型号详细信息")
@ApiImplicitParam(name = "id", value = "主键ID", required = true, dataType = "String")
@PreAuthorize("@ss.hasPermi('web:model:query')")
@GetMapping("/{id}")
public AjaxResult getInfo(@PathVariable String id)
{
return AjaxResult.success(deviceModelService.selectDeviceModelById(id));
}
/**
* 新增设备型号
*/
@ApiOperation("新增设备型号")
@PreAuthorize("@ss.hasPermi('web:model:add')")
@Log(title = "设备型号", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody DeviceModel deviceModel)
{
return toAjax(deviceModelService.insertDeviceModel(deviceModel));
}
/**
* 修改设备型号
*/
@ApiOperation("修改设备型号")
@PreAuthorize("@ss.hasPermi('web:model:edit')")
@Log(title = "设备型号", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody DeviceModel deviceModel)
{
return toAjax(deviceModelService.updateDeviceModel(deviceModel));
}
/**
* 删除设备型号
*/
@ApiOperation("删除设备型号")
@PreAuthorize("@ss.hasPermi('web:model:remove')")
@Log(title = "设备型号", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable String[] ids)
{
throw new RuntimeException("额外一场");
// return toAjax(deviceModelService.deleteDeviceModelByIds(ids));
}
}

View File

@ -0,0 +1,86 @@
package com.ruoyi.web.controller.tg;
import java.util.ArrayList;
import java.util.List;
import com.ruoyi.web.domain.DeviceModel;
import org.apache.commons.compress.utils.Lists;
import org.springframework.beans.BeanUtils;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.web.domain.DeviceThreshold;
import com.ruoyi.web.service.IDeviceThresholdService;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;
import io.swagger.annotations.*;
import lombok.RequiredArgsConstructor;
/**
* 设备指标阈值信息Controller
*
* @author cx
* @date 2025-04-05
*/
@Api(tags = "设备指标阈值信息管理")
@RestController
@RequiredArgsConstructor
@RequestMapping("/device/threshold")
public class DeviceThresholdController extends BaseController {
private final IDeviceThresholdService deviceThresholdService;
@PreAuthorize("@ss.hasPermi('web:threshold:list')")
@GetMapping("/list")
public TableDataInfo list(DeviceThreshold deviceThreshold)
{
startPage();
List<DeviceThreshold> list = deviceThresholdService.selectDeviceThresholdList(deviceThreshold);
return getDataTable(list);
}
/**
* 获取设备指标阈值信息详细信息
*/
@ApiOperation("获取设备指标阈值信息详细信息")
@ApiImplicitParam(name = "deviceCode", value = "设备编码", required = true, dataType = "String")
@PreAuthorize("@ss.hasPermi('web:threshold:query')")
@GetMapping("/{deviceCode}")
public AjaxResult getInfo(@PathVariable String deviceCode) {
return AjaxResult.success(deviceThresholdService.selectDeviceThresholdById(deviceCode));
}
/**
* 修改设备指标阈值信息
*/
@ApiOperation("修改设备指标阈值信息")
@PreAuthorize("@ss.hasPermi('web:threshold:edit')")
@Log(title = "设备指标阈值信息", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody DeviceThreshold deviceThreshold) {
return toAjax(deviceThresholdService.updateDeviceThreshold(deviceThreshold));
}
/**
* 批量复制设备指标阈值信息
*/
@ApiOperation("批量复制设备指标阈值信息")
@PreAuthorize("@ss.hasPermi('web:threshold:edit')")
@Log(title = "批量复制设备指标阈值信息", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult batchInsert() {
DeviceThreshold sourceData = deviceThresholdService.getById(1);
ArrayList<DeviceThreshold> batchResult = Lists.newArrayList();
for (int i = 50000; i < 50020; i++) {
DeviceThreshold deviceThreshold = new DeviceThreshold();
BeanUtils.copyProperties(sourceData, deviceThreshold);
deviceThreshold.setDeviceCode(String.valueOf(i));
deviceThreshold.setId(null);
batchResult.add(deviceThreshold);
}
return toAjax(deviceThresholdService.saveBatch(batchResult));
}
}

View File

@ -0,0 +1,108 @@
package com.ruoyi.web.controller.tg;
import java.util.List;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.web.domain.DeviceUserRel;
import com.ruoyi.web.service.IDeviceUserRelService;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;
import io.swagger.annotations.*;
import lombok.RequiredArgsConstructor;
/**
* 设备用户关联信息Controller
*
* @author cx
* @date 2025-04-05
*/
@Api(tags = "设备用户关联信息管理")
@RestController
@RequiredArgsConstructor
@RequestMapping("/device/user/rel")
public class DeviceUserRelController extends BaseController
{
private final IDeviceUserRelService deviceUserRelService;
/**
* 查询设备用户关联信息列表
*/
@ApiOperation("查询设备用户关联信息列表")
@ApiImplicitParams({
@ApiImplicitParam(name = "pageNum", value = "页码", dataType = "int", paramType = "query"),
@ApiImplicitParam(name = "pageSize", value = "每页大小", dataType = "int", paramType = "query")
})
@PreAuthorize("@ss.hasPermi('web:rel:list')")
@GetMapping("/list")
public TableDataInfo list(DeviceUserRel deviceUserRel)
{
startPage();
List<DeviceUserRel> list = deviceUserRelService.selectDeviceUserRelList(deviceUserRel);
return getDataTable(list);
}
/**
* 导出设备用户关联信息列表
*/
@ApiOperation("导出设备用户关联信息列表")
@PreAuthorize("@ss.hasPermi('web:rel:export')")
@Log(title = "设备用户关联信息", businessType = BusinessType.EXPORT)
@GetMapping("/export")
public AjaxResult export(DeviceUserRel deviceUserRel)
{
List<DeviceUserRel> list = deviceUserRelService.selectDeviceUserRelList(deviceUserRel);
ExcelUtil<DeviceUserRel> util = new ExcelUtil<DeviceUserRel>(DeviceUserRel.class);
return util.exportExcel(list, "设备用户关联信息数据");
}
/**
* 获取设备用户关联信息详细信息
*/
@ApiOperation("获取设备用户关联信息详细信息")
@ApiImplicitParam(name = "id", value = "主键ID", required = true, dataType = "String")
@PreAuthorize("@ss.hasPermi('web:rel:query')")
@GetMapping("/{id}")
public AjaxResult getInfo(@PathVariable String id)
{
return AjaxResult.success(deviceUserRelService.selectDeviceUserRelById(id));
}
/**
* 新增设备用户关联信息
*/
@ApiOperation("新增设备用户关联信息")
@PreAuthorize("@ss.hasPermi('web:rel:add')")
@Log(title = "设备用户关联信息", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody DeviceUserRel deviceUserRel)
{
return toAjax(deviceUserRelService.insertDeviceUserRel(deviceUserRel));
}
/**
* 修改设备用户关联信息
*/
@ApiOperation("修改设备用户关联信息")
@PreAuthorize("@ss.hasPermi('web:rel:edit')")
@Log(title = "设备用户关联信息", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody DeviceUserRel deviceUserRel)
{
return toAjax(deviceUserRelService.updateDeviceUserRel(deviceUserRel));
}
/**
* 删除设备用户关联信息
*/
@ApiOperation("删除设备用户关联信息")
@PreAuthorize("@ss.hasPermi('web:rel:remove')")
@Log(title = "设备用户关联信息", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable String[] ids)
{
return toAjax(deviceUserRelService.deleteDeviceUserRelByIds(ids));
}
}

View File

@ -0,0 +1,92 @@
package com.ruoyi.web.controller.tg;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.web.domain.EmqxAuth;
import com.ruoyi.web.service.IEmqxAuthService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 设备-EMQX鉴权信息Controller
*
* @author ruoyi
* @date 2025-04-08
*/
@Api(tags = "设备-EMQX鉴权信息管理")
@RestController
@RequiredArgsConstructor
@RequestMapping("/emqx/auth")
public class EmqxAuthController extends BaseController {
private final IEmqxAuthService emqxAuthService;
/**
* 查询设备-EMQX鉴权信息列表
*/
@ApiOperation("查询设备-EMQX鉴权信息列表")
@ApiImplicitParams({
@ApiImplicitParam(name = "pageNum", value = "页码", dataType = "int", paramType = "query"),
@ApiImplicitParam(name = "pageSize", value = "每页大小", dataType = "int", paramType = "query")
})
@PreAuthorize("@ss.hasPermi('web:auth:list')")
@GetMapping("/list")
public TableDataInfo list(EmqxAuth emqxAuth) {
startPage();
List<EmqxAuth> list = emqxAuthService.selectEmqxAuthList(emqxAuth);
return getDataTable(list);
}
/**
* 获取设备-EMQX鉴权信息详细信息
*/
@ApiOperation("获取设备-EMQX鉴权信息详细信息")
@ApiImplicitParam(name = "id", value = "主键ID", required = true, dataType = "String")
@PreAuthorize("@ss.hasPermi('web:auth:query')")
@GetMapping("/{id}")
public AjaxResult getInfo(@PathVariable String id) {
return AjaxResult.success(emqxAuthService.selectEmqxAuthById(id));
}
/**
* 新增设备-EMQX鉴权信息
*/
@ApiOperation("新增设备-EMQX鉴权信息")
@PreAuthorize("@ss.hasPermi('web:auth:add')")
@Log(title = "设备-EMQX鉴权信息", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody EmqxAuth emqxAuth) {
return toAjax(emqxAuthService.insertEmqxAuth(emqxAuth));
}
/**
* 修改设备-EMQX鉴权信息
*/
@ApiOperation("修改设备-EMQX鉴权信息")
@PreAuthorize("@ss.hasPermi('web:auth:edit')")
@Log(title = "设备-EMQX鉴权信息", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody EmqxAuth emqxAuth) {
return toAjax(emqxAuthService.updateEmqxAuth(emqxAuth));
}
/**
* 删除设备-EMQX鉴权信息
*/
@ApiOperation("删除设备-EMQX鉴权信息")
@PreAuthorize("@ss.hasPermi('web:auth:remove')")
@Log(title = "设备-EMQX鉴权信息", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable String[] ids) {
return toAjax(emqxAuthService.deleteEmqxAuthByIds(ids));
}
}

View File

@ -0,0 +1,46 @@
package com.ruoyi.web.controller.tg;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.system.service.ISysDeptService;
import com.ruoyi.web.model.index.OverViewDto;
import com.ruoyi.web.service.IDeviceInfoService;
import com.ruoyi.web.service.IMaintenanceRecordService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 首页-展示统计接口
*
* @author cx
* @date 2025-04-09
*/
@Api(tags = "首页接口统计信息管理")
@RestController
@RequiredArgsConstructor
@RequestMapping("/index")
public class IndexController {
private final ISysDeptService sysDeptService;
private final IDeviceInfoService deviceInfoService;
private final IMaintenanceRecordService maintenanceRecordService;
@ApiOperation("首页-数据概览")
@GetMapping("/overview")
public OverViewDto overview(){
OverViewDto overViewDto = deviceInfoService.overview();
Long maintainCount = maintenanceRecordService.count();
overViewDto.setMaintainCount(maintainCount.intValue());
LambdaQueryWrapper<SysDept> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(SysDept::getParentId,100L);
Long customerCount = sysDeptService.count(queryWrapper);
overViewDto.setCustomerCount(customerCount.intValue());
return overViewDto;
}
}

View File

@ -0,0 +1,103 @@
package com.ruoyi.web.controller.tg;
import java.util.List;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.web.domain.MaintenanceRecord;
import com.ruoyi.web.service.IMaintenanceRecordService;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;
import io.swagger.annotations.*;
import lombok.RequiredArgsConstructor;
/**
* 设备维保记录Controller
*
* @author cx
* @date 2025-04-05
*/
@Api(tags = "设备维保记录管理")
@RestController
@RequiredArgsConstructor
@RequestMapping("/maintain/record")
public class MaintenanceRecordController extends BaseController {
private final IMaintenanceRecordService maintenanceRecordService;
/**
* 查询设备维保记录列表
*/
@ApiOperation("查询设备维保记录列表")
@ApiImplicitParams({
@ApiImplicitParam(name = "pageNum", value = "页码", dataType = "int", paramType = "query"),
@ApiImplicitParam(name = "pageSize", value = "每页大小", dataType = "int", paramType = "query")
})
@PreAuthorize("@ss.hasPermi('web:record:list')")
@GetMapping("/list")
public TableDataInfo list(MaintenanceRecord maintenanceRecord) {
startPage();
List<MaintenanceRecord> list = maintenanceRecordService.selectMaintenanceRecordList(maintenanceRecord);
return getDataTable(list);
}
/**
* 导出设备维保记录列表
*/
@ApiOperation("导出设备维保记录列表")
@PreAuthorize("@ss.hasPermi('web:record:export')")
@Log(title = "设备维保记录", businessType = BusinessType.EXPORT)
@GetMapping("/export")
public AjaxResult export(MaintenanceRecord maintenanceRecord) {
List<MaintenanceRecord> list = maintenanceRecordService.selectMaintenanceRecordList(maintenanceRecord);
ExcelUtil<MaintenanceRecord> util = new ExcelUtil<MaintenanceRecord>(MaintenanceRecord.class);
return util.exportExcel(list, "设备维保记录数据");
}
/**
* 获取设备维保记录详细信息
*/
@ApiOperation("获取设备维保记录详细信息")
@ApiImplicitParam(name = "id", value = "主键ID", required = true, dataType = "String")
@PreAuthorize("@ss.hasPermi('web:record:query')")
@GetMapping("/{id}")
public AjaxResult getInfo(@PathVariable String id) {
return AjaxResult.success(maintenanceRecordService.selectMaintenanceRecordById(id));
}
/**
* 新增设备维保记录
*/
@ApiOperation("新增设备维保记录")
@PreAuthorize("@ss.hasPermi('web:record:add')")
@Log(title = "设备维保记录", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody MaintenanceRecord maintenanceRecord) {
return toAjax(maintenanceRecordService.insertMaintenanceRecord(maintenanceRecord));
}
/**
* 修改设备维保记录
*/
@ApiOperation("修改设备维保记录")
@PreAuthorize("@ss.hasPermi('web:record:edit')")
@Log(title = "设备维保记录", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody MaintenanceRecord maintenanceRecord) {
return toAjax(maintenanceRecordService.updateMaintenanceRecord(maintenanceRecord));
}
/**
* 删除设备维保记录
*/
@ApiOperation("删除设备维保记录")
@PreAuthorize("@ss.hasPermi('web:record:remove')")
@Log(title = "设备维保记录", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable String[] ids) {
return toAjax(maintenanceRecordService.deleteMaintenanceRecordByIds(ids));
}
}

View File

@ -0,0 +1,193 @@
package com.ruoyi.web.controller.tool;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import com.ruoyi.web.client.MinIoTemplate;
import org.springframework.web.bind.annotation.*;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.utils.StringUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
/**
* swagger 用户测试方法
*
* @author ruoyi
*/
@Api("用户信息管理")
@RestController
@RequestMapping("/test/user")
public class TestController extends BaseController
{
private final static Map<Integer, UserEntity> users = new LinkedHashMap<Integer, UserEntity>();
{
users.put(1, new UserEntity(1, "admin", "admin123", "15888888888"));
users.put(2, new UserEntity(2, "ry", "admin123", "15666666666"));
}
@ApiOperation("获取用户列表")
@GetMapping("/list")
public R<List<UserEntity>> userList()
{
List<UserEntity> userList = new ArrayList<UserEntity>(users.values());
return R.ok(userList);
}
@ApiOperation("获取用户详细")
@ApiImplicitParam(name = "userId", value = "用户ID", required = true, dataType = "int", paramType = "path", dataTypeClass = Integer.class)
@GetMapping("/{userId}")
public R<UserEntity> getUser(@PathVariable Integer userId)
{
if (!users.isEmpty() && users.containsKey(userId))
{
return R.ok(users.get(userId));
}
else
{
return R.fail("用户不存在");
}
}
@ApiOperation("新增用户")
@ApiImplicitParams({
@ApiImplicitParam(name = "userId", value = "用户id", dataType = "Integer", dataTypeClass = Integer.class),
@ApiImplicitParam(name = "username", value = "用户名称", dataType = "String", dataTypeClass = String.class),
@ApiImplicitParam(name = "password", value = "用户密码", dataType = "String", dataTypeClass = String.class),
@ApiImplicitParam(name = "mobile", value = "用户手机", dataType = "String", dataTypeClass = String.class)
})
@PostMapping("/save")
public R<String> save(UserEntity user)
{
if (StringUtils.isNull(user) || StringUtils.isNull(user.getUserId()))
{
return R.fail("用户ID不能为空");
}
users.put(user.getUserId(), user);
return R.ok();
}
@ApiOperation("更新用户")
@PutMapping("/update")
public R<String> update(@RequestBody UserEntity user)
{
if (StringUtils.isNull(user) || StringUtils.isNull(user.getUserId()))
{
return R.fail("用户ID不能为空");
}
if (users.isEmpty() || !users.containsKey(user.getUserId()))
{
return R.fail("用户不存在");
}
users.remove(user.getUserId());
users.put(user.getUserId(), user);
return R.ok();
}
@ApiOperation("删除用户信息")
@ApiImplicitParam(name = "userId", value = "用户ID", required = true, dataType = "int", paramType = "path", dataTypeClass = Integer.class)
@DeleteMapping("/{userId}")
public R<String> delete(@PathVariable Integer userId)
{
if (!users.isEmpty() && users.containsKey(userId))
{
users.remove(userId);
return R.ok();
}
else
{
return R.fail("用户不存在");
}
}
@Resource
private MinIoTemplate minIoTemplate;
@ApiOperation("上传文件")
@PostMapping("/upload")
public R<String> delete(@RequestParam("file") MultipartFile file){
// minIoTemplate.existBucket("test");
Map<String, String> resultMap = minIoTemplate.upload("test",file);
System.out.printf("result => ", resultMap.toString());
return R.ok(resultMap.get("url"));
}
}
@ApiModel(value = "UserEntity", description = "用户实体")
class UserEntity
{
@ApiModelProperty("用户ID")
private Integer userId;
@ApiModelProperty("用户名称")
private String username;
@ApiModelProperty("用户密码")
private String password;
@ApiModelProperty("用户手机")
private String mobile;
public UserEntity()
{
}
public UserEntity(Integer userId, String username, String password, String mobile)
{
this.userId = userId;
this.username = username;
this.password = password;
this.mobile = mobile;
}
public Integer getUserId()
{
return userId;
}
public void setUserId(Integer userId)
{
this.userId = userId;
}
public String getUsername()
{
return username;
}
public void setUsername(String username)
{
this.username = username;
}
public String getPassword()
{
return password;
}
public void setPassword(String password)
{
this.password = password;
}
public String getMobile()
{
return mobile;
}
public void setMobile(String mobile)
{
this.mobile = mobile;
}
}

View File

@ -0,0 +1,125 @@
package com.ruoyi.web.core.config;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.ruoyi.common.config.RuoYiConfig;
import io.swagger.annotations.ApiOperation;
import io.swagger.models.auth.In;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.ApiKey;
import springfox.documentation.service.AuthorizationScope;
import springfox.documentation.service.Contact;
import springfox.documentation.service.SecurityReference;
import springfox.documentation.service.SecurityScheme;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket;
/**
* Swagger2的接口配置
*
* @author ruoyi
*/
@Configuration
public class SwaggerConfig
{
/** 系统基础配置 */
@Autowired
private RuoYiConfig ruoyiConfig;
/** 是否开启swagger */
@Value("${swagger.enabled}")
private boolean enabled;
/** 设置请求的统一前缀 */
/*@Value("${swagger.pathMapping}")
private String pathMapping;*/
/**
* 创建API
*/
@Bean
public Docket createRestApi()
{
return new Docket(DocumentationType.OAS_30)
// 是否启用Swagger
.enable(enabled)
// 用来创建该API的基本信息展示在文档的页面中自定义展示的信息
.apiInfo(apiInfo())
// 设置哪些接口暴露给Swagger展示
.select()
// 扫描所有有注解的api用这种方式更灵活
.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
// 扫描指定包中的swagger注解
// .apis(RequestHandlerSelectors.basePackage("com.ruoyi.project.tool.swagger"))
// 扫描所有 .apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any())
.build()
/* 设置安全模式swagger可以设置访问token */
.securitySchemes(securitySchemes())
.securityContexts(securityContexts());
// .pathMapping(pathMapping);
}
/**
* 安全模式这里指定token通过Authorization头请求头传递
*/
private List<SecurityScheme> securitySchemes()
{
List<SecurityScheme> apiKeyList = new ArrayList<SecurityScheme>();
apiKeyList.add(new ApiKey("Authorization", "Authorization", In.HEADER.toValue()));
return apiKeyList;
}
/**
* 安全上下文
*/
private List<SecurityContext> securityContexts()
{
List<SecurityContext> securityContexts = new ArrayList<>();
securityContexts.add(
SecurityContext.builder()
.securityReferences(defaultAuth())
.operationSelector(o -> o.requestMappingPattern().matches("/.*"))
.build());
return securityContexts;
}
/**
* 默认的安全上引用
*/
private List<SecurityReference> defaultAuth()
{
AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
authorizationScopes[0] = authorizationScope;
List<SecurityReference> securityReferences = new ArrayList<>();
securityReferences.add(new SecurityReference("Authorization", authorizationScopes));
return securityReferences;
}
/**
* 添加摘要信息
*/
private ApiInfo apiInfo()
{
// 用ApiInfoBuilder进行定制
return new ApiInfoBuilder()
// 设置标题
.title("标题若依管理系统_接口文档")
// 描述
.description("描述:用于管理集团旗下公司的人员信息,具体包括XXX,XXX模块...")
// 作者信息
.contact(new Contact(ruoyiConfig.getName(), null, null))
// 版本
.version("版本号:" + ruoyiConfig.getVersion())
.build();
}
}

View File

@ -0,0 +1,45 @@
package com.ruoyi.web.domain;
import com.baomidou.mybatisplus.annotation.*;
import com.ruoyi.common.annotation.Excel;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import com.ruoyi.common.core.domain.BaseEntity;
/**
* 客户-部门-岗位关联对象 tg_customer_dept_post_rel
*
* @author ruoyi
* @date 2025-04-08
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@Builder
@TableName("tg_customer_dept_post_rel")
public class CustomerDeptPostRel
{
private static final long serialVersionUID = 1L;
/** 主键 */
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/** 客户id */
@Excel(name = "客户id")
@TableField("customer_id")
private Long customerId;
/** 部门id */
@Excel(name = "部门id")
@TableField("dept_id")
private Long deptId;
/** 岗位id */
@Excel(name = "岗位id")
@TableField("post_id")
private Long postId;
}

View File

@ -0,0 +1,70 @@
package com.ruoyi.web.domain;
import com.baomidou.mybatisplus.annotation.*;
import com.ruoyi.common.annotation.Excel;
import lombok.*;
import lombok.experimental.Accessors;
import com.ruoyi.common.core.domain.BaseEntity;
/**
* 设备信息对象 tg_device_info
*
* @author cx
* @date 2025-04-05
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
@TableName("tg_device_info")
public class DeviceInfo extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 设备信息表-主键 */
@TableId(value = "id", type = IdType.AUTO)
private String id;
/** 设备名称 */
@Excel(name = "设备名称")
@TableField("device_name")
private String deviceName;
/** 设备型号 */
@Excel(name = "设备型号")
@TableField("device_model")
private String deviceModel;
/** 设备编码 */
@Excel(name = "设备编码")
@TableField("device_code")
private String deviceCode;
/** 客户id */
@Excel(name = "客户id")
@TableField("customer_id")
private Long customerId;
/** 耗材寿命(h) */
@Excel(name = "耗材寿命(h)")
@TableField("lifespan")
private Long lifespan;
/** 已使用时长(h) */
@Excel(name = "已使用时长(h)")
@TableField("used_time")
private Long usedTime;
/** 设备状态 */
@Excel(name = "设备状态")
@TableField("device_status")
private Long deviceStatus;
/** 服务状态 */
@Excel(name = "服务状态")
@TableField("service_status")
private Long serviceStatus;
}

View File

@ -0,0 +1,38 @@
package com.ruoyi.web.domain;
import com.baomidou.mybatisplus.annotation.*;
import com.ruoyi.common.annotation.Excel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import com.ruoyi.common.core.domain.BaseEntity;
/**
* 设备型号对象 tg_device_model
*
* @author cx
* @date 2025-04-05
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("tg_device_model")
public class DeviceModel extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 设备型号id */
@TableId(value = "id", type = IdType.AUTO)
private String id;
/** 设备型号 */
@Excel(name = "设备型号")
@TableField("device_model")
private String deviceModel;
/** 设备图片 */
@Excel(name = "设备图片")
@TableField("device_pic")
private String devicePic;
}

View File

@ -0,0 +1,148 @@
package com.ruoyi.web.domain;
import com.baomidou.mybatisplus.annotation.*;
import com.ruoyi.common.annotation.Excel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import com.ruoyi.common.core.domain.BaseEntity;
/**
* 设备指标阈值信息对象 tg_device_threshold
*
* @author cx
* @date 2025-04-05
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("tg_device_threshold")
public class DeviceThreshold {
private static final long serialVersionUID = 1L;
/**
* 设备信息指标标准值 id
*/
@TableId(value = "id", type = IdType.AUTO)
private String id;
/**
* 设备编码
*/
@Excel(name = "设备编码")
@TableField("device_code")
private String deviceCode;
/**
* 油温上限 ()
*/
@Excel(name = "油温上限 (℃)")
@TableField("outl")
private Long outl;
/**
* 水温上限 ()
*/
@Excel(name = "水温上限 (℃)")
@TableField("wtl")
private Long wtl;
/**
* 气温上限 ()
*/
@Excel(name = "气温上限 (℃)")
@TableField("atl")
private Long atl;
/**
* 采集板温报警戒线 ()
*/
@Excel(name = "采集板温报警戒线 (℃)")
@TableField("btl")
private Long btl;
/**
* 出风设定温度 ()
*/
@Excel(name = "出风设定温度 (℃)")
@TableField("owst")
private Long owst;
/**
* 水流下限 (L/min)
*/
@Excel(name = "水流下限 (L/min)")
@TableField("wfl")
private Long wfl;
/**
* 扫描臂速度(mm/s)
*/
@Excel(name = "扫描臂速度(mm/s)")
@TableField("sas")
private Long sas;
/**
* 自定义时间间隔 min
*/
@Excel(name = "自定义时间间隔 min")
@TableField("cti")
private Long cti;
/**
* 射线电源设定电压1 V
*/
@Excel(name = "射线电源设定电压1 V")
@TableField("rpssv1")
private Long rpssv1;
/**
* 射线电源设定电流1 μA
*/
@Excel(name = "射线电源设定电流1 μA")
@TableField("rpssc1")
private Long rpssc1;
/**
* 灯丝设定电流1 μA
*/
@Excel(name = "灯丝设定电流1 μA")
@TableField("fsc1")
private Long fsc1;
/**
* 灯丝预热设定电流1 μA
*/
@Excel(name = "灯丝预热设定电流1 μA")
@TableField("fpsc1")
private Long fpsc1;
/**
* 射线电源设定电压2 V
*/
@Excel(name = "射线电源设定电压2 V")
@TableField("rpssv2")
private Long rpssv2;
/**
* 射线电源设定电流2 μA
*/
@Excel(name = "射线电源设定电流2 μA")
@TableField("rpssc2")
private Long rpssc2;
/**
* 灯丝设定电流2 μA
*/
@Excel(name = "灯丝设定电流2 μA")
@TableField("fsc2")
private Long fsc2;
/**
* 灯丝预热设定电流2 μA
*/
@Excel(name = "灯丝预热设定电流2 μA")
@TableField("fpsc2")
private Long fpsc2;
}

View File

@ -0,0 +1,52 @@
package com.ruoyi.web.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.ruoyi.common.annotation.Excel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* 设备用户关联信息对象 tg_device_user_rel
*
* @author cx
* @date 2025-04-05
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("tg_device_user_rel")
public class DeviceUserRel {
private static final long serialVersionUID = 1L;
/**
* 设备-用户 关联表 id
*/
@TableId(value = "id", type = IdType.AUTO)
private String id;
/**
* 设备编码
*/
@Excel(name = "设备编码")
@TableField("device_code")
private String deviceCode;
/**
* 设备编码
*/
@Excel(name = "客户id")
@TableField("customer_id")
private Long customerId;
/**
* 用户id
*/
@Excel(name = "用户id")
@TableField("user_id")
private Long userId;
}

View File

@ -0,0 +1,64 @@
package com.ruoyi.web.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* 设备-EMQX鉴权信息对象 tg_emqx_auth
*
* @author ruoyi
* @date 2025-04-08
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("tg_emqx_auth")
public class EmqxAuth {
private static final long serialVersionUID = 1L;
/**
* 设备-EMQX鉴权表
*/
@TableId(value = "id", type = IdType.AUTO)
private String id;
/**
* 设备编码
*/
private String deviceCode;
/**
* 本地用户名
*/
@ApiModelProperty(name = "本地用户名")
@TableField("local_user_name")
private String localUserName;
/**
* 本地pass
*/
@ApiModelProperty(name = "本地pass")
@TableField("local_pass")
private String localPass;
/**
* 云用户名
*/
@ApiModelProperty(name = "云用户名")
@TableField("cloud_user_name")
private String cloudUserName;
/**
* 云密码
*/
@ApiModelProperty(name = "云密码")
@TableField("cloud_pass")
private String cloudPass;
}

View File

@ -0,0 +1,71 @@
package com.ruoyi.web.domain;
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.common.annotation.Excel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import com.ruoyi.common.core.domain.BaseEntity;
import java.util.Date;
/**
* 设备维保记录对象 tg_maintenance_record
*
* @author cx
* @date 2025-04-05
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("tg_maintenance_record")
public class MaintenanceRecord extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 设备维保记录-主键 */
@TableId(value = "id", type = IdType.AUTO)
private String id;
/** 设备名称 */
@Excel(name = "设备名称")
@TableField("device_name")
private String deviceName;
/** 设备型号 */
@Excel(name = "设备型号")
@TableField("device_model")
private String deviceModel;
/** 设备编码 */
@Excel(name = "设备编码")
@TableField("device_code")
private String deviceCode;
/** 所属客户 */
@Excel(name = "所属客户")
@TableField("customer_name")
private String customerName;
/** 维保类型,字典表维护 */
@Excel(name = "维保类型,字典表维护")
@TableField("maintenance_type")
private Long maintenanceType;
/** 维护人 */
@Excel(name = "维护人")
@TableField("maintenance_user")
private String maintenanceUser;
/** 维护日期 */
@Excel(name = "维护日期", width = 30, dateFormat = "yyyy-MM-dd")
@TableField("maintenance_date")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date maintenanceDate;
@Excel(name = "备注")
@TableField("comments")
private String comments;
}

View File

@ -0,0 +1,16 @@
package com.ruoyi.web.mapper;
import com.ruoyi.web.domain.CustomerDeptPostRel;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* 客户-部门-岗位关联Mapper接口
*
* @author ruoyi
* @date 2025-04-08
*/
@Mapper
public interface CustomerDeptPostRelMapper extends BaseMapper<CustomerDeptPostRel>
{
}

View File

@ -0,0 +1,62 @@
package com.ruoyi.web.mapper;
import java.util.List;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.web.domain.DeviceInfo;
/**
* 设备信息Mapper接口
*
* @author cx
* @date 2025-04-03
*/
public interface DeviceInfoMapper extends BaseMapper<DeviceInfo>
{ /**
* 查询设备信息
*
* @param id 设备信息主键
* @return 设备信息
*/
public DeviceInfo selectDeviceInfoById(String id);
/**
* 查询设备信息列表
*
* @param deviceInfo 设备信息
* @return 设备信息集合
*/
public List<DeviceInfo> selectDeviceInfoList(DeviceInfo deviceInfo);
/**
* 新增设备信息
*
* @param deviceInfo 设备信息
* @return 结果
*/
public int insertDeviceInfo(DeviceInfo deviceInfo);
/**
* 修改设备信息
*
* @param deviceInfo 设备信息
* @return 结果
*/
public int updateDeviceInfo(DeviceInfo deviceInfo);
/**
* 删除设备信息
*
* @param id 设备信息主键
* @return 结果
*/
public int deleteDeviceInfoById(String id);
/**
* 批量删除设备信息
*
* @param ids 需要删除的数据主键集合
* @return 结果
*/
public int deleteDeviceInfoByIds(String[] ids);
}

View File

@ -0,0 +1,70 @@
package com.ruoyi.web.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.web.domain.DeviceModel;
import com.ruoyi.web.model.index.OverViewDto;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import java.util.List;
/**
* 设备型号Mapper接口
*
* @author cx
* @date 2025-04-03
*/
@Mapper
public interface DeviceModelMapper extends BaseMapper<DeviceModel> {
/**
* 查询设备型号
*
* @param id 设备型号主键
* @return 设备型号
*/
@Select("select * from tg_device_model")
DeviceModel selectDeviceModelById(String id);
/**
* 查询设备型号列表
*
* @param deviceModel 设备型号
* @return 设备型号集合
*/
List<DeviceModel> selectDeviceModelList(DeviceModel deviceModel);
/**
* 新增设备型号
*
* @param deviceModel 设备型号
* @return 结果
*/
int insertDeviceModel(DeviceModel deviceModel);
/**
* 修改设备型号
*
* @param deviceModel 设备型号
* @return 结果
*/
int updateDeviceModel(DeviceModel deviceModel);
/**
* 删除设备型号
*
* @param id 设备型号主键
* @return 结果
*/
int deleteDeviceModelById(String id);
/**
* 批量删除设备型号
*
* @param ids 需要删除的数据主键集合
* @return 结果
*/
int deleteDeviceModelByIds(String[] ids);
OverViewDto overview();
}

View File

@ -0,0 +1,62 @@
package com.ruoyi.web.mapper;
import java.util.List;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.web.domain.DeviceThreshold;
/**
* 设备指标阈值信息Mapper接口
*
* @author cx
* @date 2025-04-03
*/
public interface DeviceThresholdMapper extends BaseMapper<DeviceThreshold>
{
/**
* 查询设备指标阈值信息
*
* @param id 设备指标阈值信息主键
* @return 设备指标阈值信息
*/
public DeviceThreshold selectDeviceThresholdById(String id);
/**
* 查询设备指标阈值信息列表
*
* @param deviceThreshold 设备指标阈值信息
* @return 设备指标阈值信息集合
*/
public List<DeviceThreshold> selectDeviceThresholdList(DeviceThreshold deviceThreshold);
/**
* 新增设备指标阈值信息
*
* @param deviceThreshold 设备指标阈值信息
* @return 结果
*/
public int insertDeviceThreshold(DeviceThreshold deviceThreshold);
/**
* 修改设备指标阈值信息
*
* @param deviceThreshold 设备指标阈值信息
* @return 结果
*/
public int updateDeviceThreshold(DeviceThreshold deviceThreshold);
/**
* 删除设备指标阈值信息
*
* @param id 设备指标阈值信息主键
* @return 结果
*/
public int deleteDeviceThresholdById(String id);
/**
* 批量删除设备指标阈值信息
*
* @param ids 需要删除的数据主键集合
* @return 结果
*/
public int deleteDeviceThresholdByIds(String[] ids);
}

View File

@ -0,0 +1,62 @@
package com.ruoyi.web.mapper;
import java.util.List;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.web.domain.DeviceUserRel;
/**
* 设备用户关联信息Mapper接口
*
* @author cx
* @date 2025-04-03
*/
public interface DeviceUserRelMapper extends BaseMapper<DeviceUserRel>
{
/**
* 查询设备用户关联信息
*
* @param id 设备用户关联信息主键
* @return 设备用户关联信息
*/
public DeviceUserRel selectDeviceUserRelById(String id);
/**
* 查询设备用户关联信息列表
*
* @param deviceUserRel 设备用户关联信息
* @return 设备用户关联信息集合
*/
public List<DeviceUserRel> selectDeviceUserRelList(DeviceUserRel deviceUserRel);
/**
* 新增设备用户关联信息
*
* @param deviceUserRel 设备用户关联信息
* @return 结果
*/
public int insertDeviceUserRel(DeviceUserRel deviceUserRel);
/**
* 修改设备用户关联信息
*
* @param deviceUserRel 设备用户关联信息
* @return 结果
*/
public int updateDeviceUserRel(DeviceUserRel deviceUserRel);
/**
* 删除设备用户关联信息
*
* @param id 设备用户关联信息主键
* @return 结果
*/
public int deleteDeviceUserRelById(String id);
/**
* 批量删除设备用户关联信息
*
* @param ids 需要删除的数据主键集合
* @return 结果
*/
public int deleteDeviceUserRelByIds(String[] ids);
}

View File

@ -0,0 +1,16 @@
package com.ruoyi.web.mapper;
import com.ruoyi.web.domain.EmqxAuth;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* 设备-EMQX鉴权信息Mapper接口
*
* @author ruoyi
* @date 2025-04-08
*/
@Mapper
public interface EmqxAuthMapper extends BaseMapper<EmqxAuth>
{
}

View File

@ -0,0 +1,39 @@
package com.ruoyi.web.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.web.domain.MaintenanceRecord;
import com.ruoyi.web.model.index.MaintainCountDto;
import java.util.List;
/**
* 设备维保记录Mapper接口
*
* @author cx
* @date 2025-04-03
*/
public interface MaintenanceRecordMapper extends BaseMapper<MaintenanceRecord> {
/**
* 查询设备维保记录列表
*
* @param maintenanceRecord 设备维保记录
* @return 设备维保记录集合
*/
List<MaintenanceRecord> selectMaintenanceRecordList(MaintenanceRecord maintenanceRecord);
/**
* 查询维保统计数量
* @return
*/
MaintainCountDto selectOverViewMaintainCount();
/**
* 按照客户维度统计维保情况
* @return
*/
MaintainCountDto selectMaintainCountGroupByCustomer();
}

View File

@ -0,0 +1,14 @@
package com.ruoyi.web.model;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ObjectItem {
private String objectName;
private long size;
}

View File

@ -0,0 +1,4 @@
package com.ruoyi.web.model;
public class Test {
}

View File

@ -0,0 +1,30 @@
package com.ruoyi.web.model.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* 新建客户DTO
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@ApiModel("新建客户DTO")
public class CreateCustomerDto {
@ApiModelProperty(name = "客户名称")
private String customerName;
@ApiModelProperty(name = "负责人")
private String leader;
@ApiModelProperty(name = "联系方式")
private String phone;
@ApiModelProperty(name = "联系地址")
private String address;
}

View File

@ -0,0 +1,57 @@
package com.ruoyi.web.model.dto;
import com.ruoyi.web.domain.EmqxAuth;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.List;
/**
* 新建设备信息DTO
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@ApiModel("新建设备信息DTO")
public class CreateDeviceInfoDto {
/**
* 设备名称
*/
@ApiModelProperty(value = "设备名称", required = true)
@NotNull(message = "设备名称不能为空")
private String deviceName;
/**
* 设备型号
*/
@ApiModelProperty(value = "设备型号", required = true)
@NotBlank(message = "设备型号不能为空")
private String deviceModel;
/**
* 设备编码
*/
@ApiModelProperty(value = "设备编码", required = true)
@NotBlank(message = "设备编码不能为空")
private String deviceCode;
/**
* 客户id
*/
@ApiModelProperty(value = "客户id", required = true)
@NotNull(message = "客户id不能为空")
private Long customerId;
@ApiModelProperty("用户idList")
private List<Long> userIdList;
@ApiModelProperty(value = "EMQX认证信息",required = true)
private EmqxAuth emqxAuth;
}

View File

@ -0,0 +1,43 @@
package com.ruoyi.web.model.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.util.Date;
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@ApiModel("客户岗位列表DTO")
public class CustomerDeptPostRelDto {
@ApiModelProperty(name = "id")
private Long id;
@ApiModelProperty(name = "客户id")
private Long customerId;
@ApiModelProperty(name = "部门id")
private Long deptId;
@ApiModelProperty(name = "岗位id")
private Long postId;
@ApiModelProperty(name = "岗位名称")
private String postName;
@ApiModelProperty(name = "部门名称")
private String deptName;
@ApiModelProperty(name = "客户名称")
private String customerName;
@ApiModelProperty(name = "创建人")
private String createBy;
@ApiModelProperty(name = "创建时间")
private Date createTime;
}

View File

@ -0,0 +1,25 @@
package com.ruoyi.web.model.dto;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* 设备基础信息表
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
public class DeviceInfoBaseInfoDto {
@ApiModelProperty(name = "设备名称")
private String deviceName;
@ApiModelProperty(name = "设备型号")
private String deviceModel;
@ApiModelProperty(name = "设备编码")
private String deviceCode;
}

View File

@ -0,0 +1,14 @@
package com.ruoyi.web.model.dto;
import com.ruoyi.web.domain.DeviceInfo;
import com.ruoyi.web.domain.DeviceUserRel;
import lombok.Data;
import java.util.List;
@Data
public class DeviceListDto extends DeviceInfo {
private List<DeviceUserRelDto> userRelList;
}

View File

@ -0,0 +1,22 @@
package com.ruoyi.web.model.dto;
import com.ruoyi.web.domain.DeviceUserRel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
public class DeviceUserRelDto extends DeviceUserRel {
@ApiModelProperty(value = "用户名称")
private String userName;
@ApiModelProperty(value = "用户电话")
private String phone;
@ApiModelProperty(value = "所属部门")
private String deptName;
@ApiModelProperty(value = "用户状态0正常 1停用")
private String status;
}

View File

@ -0,0 +1,19 @@
package com.ruoyi.web.model.dto;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@ApiModel("首页-维保信息概览DTO")
public class MaintainOverViewDto {
private String customerName;
private Long maintainCount;
}

View File

@ -0,0 +1,39 @@
package com.ruoyi.web.model.index;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@ApiModel("首页-展示统计接口,维保概览")
@Data
@AllArgsConstructor
@NoArgsConstructor
public class MaintainCountDto {
@ApiModelProperty("客户名称")
private String customerName;
@ApiModelProperty("设备编码")
private String deviceCode;
@ApiModelProperty("设备出厂测试结果数量")
private Long factoryTestCount;
@ApiModelProperty("设备安装数量")
private Long installationCount;
@ApiModelProperty("设备维护保养数量")
private Long maintainCount;
@ApiModelProperty("设备维修数量")
private Long repairCount;
@ApiModelProperty("耗材更换数量")
private Long consumableCount;
@ApiModelProperty("维保总数量")
private Long totalCount;
}

View File

@ -0,0 +1,29 @@
package com.ruoyi.web.model.index;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@ApiModel("首页-展示统计接口,数据概览")
@Data
@AllArgsConstructor
@NoArgsConstructor
public class OverViewDto {
@ApiModelProperty(value = "客户总数")
private Integer customerCount;
@ApiModelProperty(value = "设备数")
private Integer deviceCount;
@ApiModelProperty(value = "维保数")
private Integer maintainCount;
@ApiModelProperty(value = "在线设备数")
private Integer onlineCount;
@ApiModelProperty(value = "离线设备数")
private Integer offlineCount;
}

View File

@ -0,0 +1,179 @@
package com.ruoyi.web.mqTask.callback;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.web.mqTask.mqtt.*;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.springframework.context.annotation.Configuration;
import javax.annotation.Resource;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.Objects;
/**
* @author cx
* @date 2025/04/09 10:25
*/
@Configuration
@Slf4j
public class MqttCallBackImpl implements MqttCallback {
public final static String KEY_VALUE_SEPARATOR = ":";
@Resource
private Map<String, MqttListener> consumers;
@Resource
private Map<String, MqttBatchListener> batchConsumers;
@Resource
private Map<String, RegularMqttListener> regularConsumers;
@Override
public void connectionLost(Throwable throwable) {
log.error("Mqtt 连接断开", throwable);
}
@Override
public void messageArrived(String topic, MqttMessage mqttMessage) {
try {
// 单topic消费者
consumers.values().forEach(consumer -> {
MqttSubscription mqttSubscription = consumer.getClass().getAnnotation(MqttSubscription.class);
//主题或者表达式匹配的消息
if (mqttSubscription != null && Objects.equals(topic, mqttSubscription.topic())
&& containsExpression(mqttMessage, mqttSubscription.expression())) {
consumer.consume(mqttMessage);
}
});
// 通配符单topic消费者
regularConsumers.values().forEach(consumer -> {
RegularMqttSubscription regularMqttSubscription = consumer.getClass().getAnnotation(RegularMqttSubscription.class);
//主题或者表达式匹配的消息
if (regularMqttSubscription != null && regularTopicMatch(regularMqttSubscription.topic(), topic)
&& containsExpression(mqttMessage, regularMqttSubscription.expression())) {
consumer.consume(topic, mqttMessage);
}
});
// 批量topic消费者
batchConsumers.values().forEach(consumer -> {
Method[] methods = consumer.getClass().getMethods();
for (Method method : methods) {
MqttSubscriptionOnMethod mqttSubscriptionOnMethod = method.getAnnotation(MqttSubscriptionOnMethod.class);
if (mqttSubscriptionOnMethod != null && Objects.equals(topic, mqttSubscriptionOnMethod.topic())
&& containsExpression(mqttMessage, mqttSubscriptionOnMethod.expression())) {
consumeMsg(mqttMessage, consumer, method);
continue;
}
RegularMqttSubscriptionOnMethod regularMqttSubscriptionOnMethod = method.getAnnotation(RegularMqttSubscriptionOnMethod.class);
if (regularMqttSubscriptionOnMethod != null && regularTopicMatch(regularMqttSubscriptionOnMethod.topic(), topic)
&& containsExpression(mqttMessage, regularMqttSubscriptionOnMethod.expression())) {
consumeMsg(topic, mqttMessage, consumer, method);
}
}
});
} catch (Exception e) {
log.error("mqtt消息回调出错", e);
}
}
/**
* 处理消息 批量通配符订阅
*
* @param topic 主题
* @param mqttMessage 消息内容
* @param consumer 消费者
* @param method 方法
*/
private void consumeMsg(String topic, MqttMessage mqttMessage, MqttBatchListener consumer, Method method) {
try {
method.invoke(consumer, topic, mqttMessage);
} catch (Exception e) {
log.error("MqttCallBackImpl consumeMsg error methodName={}", method.getName(), e);
}
}
/**
* 通配符topic是否匹配
* 通配符需要满足的条件 /+/+/action/forward 匹配 /product/device/action/forward
*
* @param regularTopic 通配符topic
* @param topic 订阅topic
* @return 通配符topic是否匹配
*/
private boolean regularTopicMatch(String regularTopic, String topic) {
if (regularTopic == null || topic == null) {
return false;
}
String[] regularTopicStr = regularTopic.split("/");
String[] topicStr = topic.split("/");
if (regularTopicStr.length > topicStr.length) {
return false;
}
for (int i = 0; i < regularTopicStr.length; i++) {
if (Objects.equals(regularTopicStr[i], "+")) {
continue;
}
if (!Objects.equals(regularTopicStr[i], topicStr[i])) {
return false;
}
}
return true;
}
/**
* 判断表达式是否匹配
*
* @param mqttMessage 消息
* @param expression 注解表达式
* @return 表达式是否匹配
*/
private boolean containsExpression(MqttMessage mqttMessage, String expression) {
if (mqttMessage == null) {
return false;
}
String content = new String(mqttMessage.getPayload());
if ("".equals(expression)) {
return true;
}
if (expression.contains(KEY_VALUE_SEPARATOR)) {
String[] kv = expression.split(KEY_VALUE_SEPARATOR);
JSONObject jsonObject = com.alibaba.fastjson2.JSON.parseObject(content);
if (Objects.equals(jsonObject.get(kv[0]), kv[1])) {
return true;
}
}
return content.contains(expression);
}
/**
* 处理消息
*
* @param mqttMessage 消息
* @param consumer 消费者
* @param method 方法
*/
private void consumeMsg(MqttMessage mqttMessage, MqttBatchListener consumer, Method method) {
try {
method.invoke(consumer, mqttMessage);
} catch (Exception e) {
log.error("MqttCallBackImpl consumeMsg error methodName={}", method.getName(), e);
}
}
@Override
public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
String[] topics = iMqttDeliveryToken.getTopics();
if (topics == null) {
return;
}
for (String topic : topics) {
log.info("topics: " + topic + " clientId: " + iMqttDeliveryToken.getClient().getClientId() + " " + "消息发布成功");
}
}
}

View File

@ -0,0 +1,109 @@
package com.ruoyi.web.mqTask.conf;
import com.ruoyi.web.mqTask.mqtt.*;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.annotation.Resource;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* @author cx
* @date 2025/04/09 10:19
*/
@Configuration
@Slf4j
public class MqttConnectConf {
@Resource
private MqttConnectConfPros mqttConnectConfPros;
@Resource
private MqttCallback mqttCallback;
@Resource
private Map<String, MqttListener> consumers;
@Resource
private Map<String, MqttBatchListener> batchConsumers;
@Resource
private Map<String, RegularMqttListener> regularConsumers;
/**
* 初始化mqtt链接
*
* @return mqttClient
*/
@Bean("mqttClient")
public MqttClient connect() {
try {
MqttClient mqttClient = new MqttClient(
mqttConnectConfPros.getServerUri(),
mqttConnectConfPros.getClientId(),
new MemoryPersistence()
);
MqttConnectOptions options = new MqttConnectOptions();
options.setUserName(mqttConnectConfPros.getUsername());
options.setPassword(mqttConnectConfPros.getPassword().toCharArray());
options.setAutomaticReconnect(true);
options.setCleanSession(true);
options.setKeepAliveInterval(mqttConnectConfPros.getKeepAliveInterval());
options.setConnectionTimeout(mqttConnectConfPros.getConnectionTimeout());
options.setWill(mqttConnectConfPros.getWillTopic(), (mqttConnectConfPros.getClientId() + "与服务器断开连接").getBytes(), 0, false);
// 配置 ssl
mqttClient.setCallback(mqttCallback);
mqttClient.connect(options);
log.info("Mqtt connect success");
String[] topics = getTopics();
mqttClient.subscribe(topics);
return mqttClient;
} catch (Exception e) {
log.error("Mqtt connect error", e);
throw new RuntimeException("Connect Mqtt Failed");
}
}
/**
* 获取topics topics 来自Consumer的注解
*
* @return topic 数组
*/
private String[] getTopics() {
List<String> topicList = new ArrayList<>();
consumers.values().forEach(consumer -> {
MqttSubscription mqttSubscription = consumer.getClass().getAnnotation(MqttSubscription.class);
if (mqttSubscription != null) {
topicList.add(mqttSubscription.topic());
}
});
regularConsumers.values().forEach(consumer -> {
RegularMqttSubscription regularMqttSubscription = consumer.getClass().getAnnotation(RegularMqttSubscription.class);
if (regularMqttSubscription != null) {
topicList.add(regularMqttSubscription.topic());
}
});
batchConsumers.values().forEach(consumer -> {
Method[] methods = consumer.getClass().getMethods();
for (Method method : methods) {
MqttSubscriptionOnMethod mqttSubscriptionOnMethod = method.getAnnotation(MqttSubscriptionOnMethod.class);
if (mqttSubscriptionOnMethod != null) {
topicList.add(mqttSubscriptionOnMethod.topic());
}
RegularMqttSubscriptionOnMethod regularMqttSubscriptionOnMethod = method.getAnnotation(RegularMqttSubscriptionOnMethod.class);
if (regularMqttSubscriptionOnMethod != null) {
topicList.add(regularMqttSubscriptionOnMethod.topic());
}
}
});
return topicList.toArray(new String[]{});
}
}

View File

@ -0,0 +1,24 @@
package com.ruoyi.web.mqTask.conf;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
/**
* @author cx
* @date 2025/04/09 10:12
*/
@Configuration
@Data
@ConfigurationProperties(prefix = "mqtt.config")
public class MqttConnectConfPros {
private String serverUri;
private String username;
private String password;
private String clientId;
private Integer keepAliveInterval;
private Integer connectionTimeout;
private String willTopic;
}

View File

@ -0,0 +1,24 @@
package com.ruoyi.web.mqTask.impl;
import com.ruoyi.web.mqTask.mqtt.RegularMqttListener;
import com.ruoyi.web.mqTask.mqtt.RegularMqttSubscription;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.MqttMessage;
/**
* 监听设备计算数据信息Topic
*
* @author cx
* @date 2025/04/09 11:27
*/
@RegularMqttSubscription(topic = "v1/cpy/+/calculation")
@Slf4j
public class DeviceCalculateConsumer implements RegularMqttListener {
@Override
public void consume(String topic, MqttMessage mqttMessage) {
log.info("接受到设备 【{}】 计算Msg -> {}",
topic.substring(topic.lastIndexOf("v1/cpy/") + 7, topic.indexOf("/calculation")),
new String(mqttMessage.getPayload()));
}
}

View File

@ -0,0 +1,22 @@
package com.ruoyi.web.mqTask.impl;
import com.ruoyi.web.mqTask.mqtt.RegularMqttListener;
import com.ruoyi.web.mqTask.mqtt.RegularMqttSubscription;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.MqttMessage;
/**
* 监听设备采集数据信息Topic
*
* @author cx
* @date 2025/04/09 11:27
*/
@RegularMqttSubscription(topic = "v1/cpy/+/collect")
@Slf4j
public class DeviceCollectConsumer implements RegularMqttListener {
@Override
public void consume(String topic, MqttMessage mqttMessage) {
log.info("Received Topic: {} , Message: {}", topic, new String(mqttMessage.getPayload()));
}
}

View File

@ -0,0 +1,22 @@
package com.ruoyi.web.mqTask.impl;
import com.ruoyi.web.mqTask.mqtt.RegularMqttListener;
import com.ruoyi.web.mqTask.mqtt.RegularMqttSubscription;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.MqttMessage;
/**
* 监听设备信息Topic
*
* @author cx
* @date 2025/04/09 11:27
*/
@RegularMqttSubscription(topic = "v1/cpy/+/infos")
@Slf4j
public class DeviceConsumer implements RegularMqttListener {
@Override
public void consume(String topic, MqttMessage mqttMessage) {
log.info("Received Topic: {} , Message: {}", topic, new String(mqttMessage.getPayload()));
}
}

View File

@ -0,0 +1,15 @@
package com.ruoyi.web.mqTask.impl;
import com.ruoyi.web.mqTask.mqtt.MqttBatchListener;
import org.springframework.stereotype.Component;
/**
* 空实现
*
* @author cx
* @date 2025/04/09 11:42
*/
@Component
public class VoidBatchConsumer implements MqttBatchListener {
}

View File

@ -0,0 +1,20 @@
package com.ruoyi.web.mqTask.impl;
import com.ruoyi.web.mqTask.mqtt.MqttListener;
import com.ruoyi.web.mqTask.mqtt.MqttSubscription;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.MqttMessage;
/**
* @author cx
* @date 2025/04/09 10:38
*/
@MqttSubscription(topic = "test1")
@Slf4j
public class VoidConsumer implements MqttListener {
@Override
public void consume(MqttMessage mqttMessage) {
log.info("Topic {} Received Message: {}", mqttMessage.getPayload(), new String(mqttMessage.getPayload()));
}
}

View File

@ -0,0 +1,8 @@
package com.ruoyi.web.mqTask.mqtt;
/**
* @author cx
* @date 2025/04/09 11:42
*/
public interface MqttBatchListener {
}

View File

@ -0,0 +1,17 @@
package com.ruoyi.web.mqTask.mqtt;
import org.eclipse.paho.client.mqttv3.MqttMessage;
/**
* @author cx
* @date 2025/04/09 11:42
*/
public interface MqttListener {
/**
* consume mqtt msg
*
* @param mqttMessage msg
*/
void consume(MqttMessage mqttMessage);
}

View File

@ -0,0 +1,20 @@
package com.ruoyi.web.mqTask.mqtt;
import org.springframework.stereotype.Component;
import java.lang.annotation.*;
/**
* @author cx
* @date 2025/04/09 11:42
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Component
public @interface MqttSubscription {
String topic();
String expression() default "";
}

View File

@ -0,0 +1,17 @@
package com.ruoyi.web.mqTask.mqtt;
import java.lang.annotation.*;
/**
* @author cx
* @date 2025/04/09 11:42
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface MqttSubscriptionOnMethod {
String topic();
String expression() default "";
}

View File

@ -0,0 +1,18 @@
package com.ruoyi.web.mqTask.mqtt;
import org.eclipse.paho.client.mqttv3.MqttMessage;
/**
* @author cx
* @date 2025/04/09 11:42
*/
public interface RegularMqttListener {
/**
* consume mqtt msg
*
* @param topic topic
* @param mqttMessage msg
*/
void consume(String topic, MqttMessage mqttMessage);
}

View File

@ -0,0 +1,20 @@
package com.ruoyi.web.mqTask.mqtt;
import org.springframework.stereotype.Component;
import java.lang.annotation.*;
/**
* @author cx
* @date 2025/04/09 11:45
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Component
public @interface RegularMqttSubscription {
String topic();
String expression() default "";
}

View File

@ -0,0 +1,17 @@
package com.ruoyi.web.mqTask.mqtt;
import java.lang.annotation.*;
/**
* @author cx
* @date 2025/04/09 11:45
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface RegularMqttSubscriptionOnMethod {
String topic();
String expression() default "";
}

View File

@ -0,0 +1,151 @@
package com.ruoyi.web.mqTask.publish;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.eclipse.paho.client.mqttv3.MqttTopic;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* mqtt消息发布
*
* @author cx
* @date 2025/04/09 11:50
*/
@Component
@Slf4j
@Data
public class MqttPublisher {
private Integer qos = 1;
private Boolean retained = false;
private String topic;
private String message;
@Resource
private MqttClient mqttClient;
/**
* mqtt 发送消息
*
* @param qos 消息服务质量
* @param retained 是否保留消息
* @param topic 主题
* @param message 消息内容
* @return 发布结果
*/
public boolean publish(Integer qos, Boolean retained, String topic, String message) {
try {
if (qos == null) {
qos = this.qos;
}
if (retained == null) {
retained = this.retained;
}
if (topic == null || message == null) {
throw new RuntimeException("topic and message can not been null");
}
MqttMessage mqttMessage = new MqttMessage();
mqttMessage.setQos(qos);
mqttMessage.setRetained(retained);
mqttMessage.setPayload(message.getBytes());
MqttTopic mqttTopic = mqttClient.getTopic(topic);
log.info("MqttPublisher publish topic={} message={}", topic, message);
MqttDeliveryToken mqttDeliveryToken = mqttTopic.publish(mqttMessage);
mqttDeliveryToken.waitForCompletion();
log.info("MqttPublisher publish success");
return true;
} catch (Exception e) {
log.error("MqttPublisher publish error topic={} message={}", topic, message, e);
return false;
}
}
/**
* 构建器
*
* @return this
*/
public MqttPublisherBuilder builder() {
return new MqttPublisherBuilder(this);
}
public static class MqttPublisherBuilder {
private final MqttPublisher mqttPublisher;
public MqttPublisherBuilder(MqttPublisher mqttPublisher) {
this.mqttPublisher = mqttPublisher;
}
/**
* 设置qos
*
* @param qos 消息服务质量
* @return this
*/
public MqttPublisherBuilder qos(int qos) {
this.mqttPublisher.setQos(qos);
return this;
}
/**
* 设置retained
*
* @param retained 是否保留消息
* @return this
*/
public MqttPublisherBuilder retained(boolean retained) {
this.mqttPublisher.setRetained(retained);
return this;
}
/**
* 设置topic
*
* @param topic 主題
* @return this
*/
public MqttPublisherBuilder topic(String topic) {
this.mqttPublisher.setTopic(topic);
return this;
}
/**
* 设置message
*
* @param message 消息内容
* @return this
*/
public MqttPublisherBuilder message(String message) {
this.mqttPublisher.setMessage(message);
return this;
}
/**
* 发布消息
*
* @return 发布结果
*/
public boolean publish() {
return this.mqttPublisher.publish(
this.mqttPublisher.getQos(),
this.mqttPublisher.getRetained(),
this.mqttPublisher.getTopic(),
this.mqttPublisher.getMessage()
);
}
}
}

View File

@ -0,0 +1,63 @@
package com.ruoyi.web.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.web.domain.CustomerDeptPostRel;
import com.ruoyi.web.model.dto.CustomerDeptPostRelDto;
import java.util.List;
/**
* 客户-部门-岗位关联Service接口
*
* @author ruoyi
* @date 2025-04-08
*/
public interface ICustomerDeptPostRelService extends IService<CustomerDeptPostRel> {
/**
* 查询客户-部门-岗位关联
*
* @param id 客户-部门-岗位关联主键
* @return 客户-部门-岗位关联
*/
CustomerDeptPostRel selectCustomerDeptPostRelById(Long id);
/**
* 查询客户-部门-岗位关联列表
*
* @param customerDeptPostRel 客户-部门-岗位关联
* @return 客户-部门-岗位关联
*/
List<CustomerDeptPostRelDto> selectCustomerDeptPostRelList(CustomerDeptPostRel customerDeptPostRel);
/**
* 新增客户-部门-岗位关联
*
* @param customerDeptPostRel 客户-部门-岗位关联
* @return 结果
*/
int insertCustomerDeptPostRel(CustomerDeptPostRel customerDeptPostRel);
/**
* 修改客户-部门-岗位关联
*
* @param customerDeptPostRel 客户-部门-岗位关联
* @return 结果
*/
int updateCustomerDeptPostRel(CustomerDeptPostRel customerDeptPostRel);
/**
* 批量删除客户-部门-岗位关联
*
* @param ids 需要删除的客户-部门-岗位关联主键
* @return 结果
*/
int deleteCustomerDeptPostRelByIds(Long[] ids);
/**
* 删除客户-部门-岗位关联信息
*
* @param id 客户-部门-岗位关联主键
* @return 结果
*/
int deleteCustomerDeptPostRelById(Long id);
}

View File

@ -0,0 +1,79 @@
package com.ruoyi.web.service;
import java.util.List;
import com.ruoyi.web.domain.DeviceInfo;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.web.model.dto.CreateDeviceInfoDto;
import com.ruoyi.web.model.dto.DeviceListDto;
import com.ruoyi.web.model.index.OverViewDto;
/**
* 设备信息Service接口
*
* @author cx
* @date 2025-04-05
*/
public interface IDeviceInfoService extends IService<DeviceInfo>
{
/**
* 查询设备信息
*
* @param id 设备信息主键
* @return 设备信息
*/
public DeviceInfo selectDeviceInfoById(String id);
/**
* 查询设备信息列表
*
* @param deviceInfo 设备信息
* @return 设备信息
*/
public List<DeviceListDto> selectDeviceInfoList(DeviceInfo deviceInfo);
/**
* 新增设备信息
*
* @param deviceInfo 设备信息
* @return 结果
*/
public int insertDeviceInfo(DeviceInfo deviceInfo);
/**
* 创建设备信息
* @param deviceInfo
* @return
*/
public int createDeviceInfo(CreateDeviceInfoDto deviceInfo);
/**
* 修改设备信息
*
* @param deviceInfo 设备信息
* @return 结果
*/
public int updateDeviceInfo(DeviceInfo deviceInfo);
/**
* 批量删除设备信息
*
* @param ids 需要删除的设备信息主键
* @return 结果
*/
public int deleteDeviceInfoByIds(String[] ids);
/**
* 删除设备信息信息
*
* @param id 设备信息主键
* @return 结果
*/
public int deleteDeviceInfoById(String id);
/**
* 查询设备数量
* @return
*/
OverViewDto overview();
}

View File

@ -0,0 +1,62 @@
package com.ruoyi.web.service;
import java.util.List;
import com.ruoyi.web.domain.DeviceModel;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* 设备型号Service接口
*
* @author cx
* @date 2025-04-05
*/
public interface IDeviceModelService extends IService<DeviceModel>
{
/**
* 查询设备型号
*
* @param id 设备型号主键
* @return 设备型号
*/
public DeviceModel selectDeviceModelById(String id);
/**
* 查询设备型号列表
*
* @param deviceModel 设备型号
* @return 设备型号
*/
public List<DeviceModel> selectDeviceModelList(DeviceModel deviceModel);
/**
* 新增设备型号
*
* @param deviceModel 设备型号
* @return 结果
*/
public int insertDeviceModel(DeviceModel deviceModel);
/**
* 修改设备型号
*
* @param deviceModel 设备型号
* @return 结果
*/
public int updateDeviceModel(DeviceModel deviceModel);
/**
* 批量删除设备型号
*
* @param ids 需要删除的设备型号主键
* @return 结果
*/
public int deleteDeviceModelByIds(String[] ids);
/**
* 删除设备型号信息
*
* @param id 设备型号主键
* @return 结果
*/
public int deleteDeviceModelById(String id);
}

View File

@ -0,0 +1,71 @@
package com.ruoyi.web.service;
import java.util.List;
import com.ruoyi.web.domain.DeviceThreshold;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* 设备指标阈值信息Service接口
*
* @author cx
* @date 2025-04-05
*/
public interface IDeviceThresholdService extends IService<DeviceThreshold> {
String DEFULT_DEVICE_CODE= "000000";
/**
* 查询设备指标阈值信息
*
* @param deviceCode 设备编码
* @return 设备指标阈值信息
*/
public DeviceThreshold selectDeviceThresholdById(String deviceCode);
/**
* 查询设备指标阈值信息列表
*
* @param deviceThreshold 设备指标阈值信息
* @return 设备指标阈值信息
*/
public List<DeviceThreshold> selectDeviceThresholdList(DeviceThreshold deviceThreshold);
/**
* 新增设备指标阈值信息
*
* @param deviceThreshold 设备指标阈值信息
* @return 结果
*/
public int insertDeviceThreshold(DeviceThreshold deviceThreshold);
/**
* 修改设备指标阈值信息
*
* @param deviceThreshold 设备指标阈值信息
* @return 结果
*/
public int updateDeviceThreshold(DeviceThreshold deviceThreshold);
/**
* 批量删除设备指标阈值信息
*
* @param ids 需要删除的设备指标阈值信息主键
* @return 结果
*/
public int deleteDeviceThresholdByIds(String[] ids);
/**
* 删除设备指标阈值信息信息
*
* @param id 设备指标阈值信息主键
* @return 结果
*/
public int deleteDeviceThresholdById(String id);
/**
* 根据设备编码查询设备指标阈值信息
*
* @param deviceCode 设备编码
* @return 设备指标阈值信息
*/
void initDeviceThreshold(String deviceCode);
}

View File

@ -0,0 +1,62 @@
package com.ruoyi.web.service;
import java.util.List;
import com.ruoyi.web.domain.DeviceUserRel;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* 设备用户关联信息Service接口
*
* @author cx
* @date 2025-04-05
*/
public interface IDeviceUserRelService extends IService<DeviceUserRel>
{
/**
* 查询设备用户关联信息
*
* @param id 设备用户关联信息主键
* @return 设备用户关联信息
*/
public DeviceUserRel selectDeviceUserRelById(String id);
/**
* 查询设备用户关联信息列表
*
* @param deviceUserRel 设备用户关联信息
* @return 设备用户关联信息
*/
public List<DeviceUserRel> selectDeviceUserRelList(DeviceUserRel deviceUserRel);
/**
* 新增设备用户关联信息
*
* @param deviceUserRel 设备用户关联信息
* @return 结果
*/
public int insertDeviceUserRel(DeviceUserRel deviceUserRel);
/**
* 修改设备用户关联信息
*
* @param deviceUserRel 设备用户关联信息
* @return 结果
*/
public int updateDeviceUserRel(DeviceUserRel deviceUserRel);
/**
* 批量删除设备用户关联信息
*
* @param ids 需要删除的设备用户关联信息主键
* @return 结果
*/
public int deleteDeviceUserRelByIds(String[] ids);
/**
* 删除设备用户关联信息信息
*
* @param id 设备用户关联信息主键
* @return 结果
*/
public int deleteDeviceUserRelById(String id);
}

View File

@ -0,0 +1,62 @@
package com.ruoyi.web.service;
import java.util.List;
import com.ruoyi.web.domain.EmqxAuth;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* 设备-EMQX鉴权信息Service接口
*
* @author ruoyi
* @date 2025-04-08
*/
public interface IEmqxAuthService extends IService<EmqxAuth>
{
/**
* 查询设备-EMQX鉴权信息
*
* @param id 设备-EMQX鉴权信息主键
* @return 设备-EMQX鉴权信息
*/
public EmqxAuth selectEmqxAuthById(String id);
/**
* 查询设备-EMQX鉴权信息列表
*
* @param emqxAuth 设备-EMQX鉴权信息
* @return 设备-EMQX鉴权信息
*/
public List<EmqxAuth> selectEmqxAuthList(EmqxAuth emqxAuth);
/**
* 新增设备-EMQX鉴权信息
*
* @param emqxAuth 设备-EMQX鉴权信息
* @return 结果
*/
public int insertEmqxAuth(EmqxAuth emqxAuth);
/**
* 修改设备-EMQX鉴权信息
*
* @param emqxAuth 设备-EMQX鉴权信息
* @return 结果
*/
public int updateEmqxAuth(EmqxAuth emqxAuth);
/**
* 批量删除设备-EMQX鉴权信息
*
* @param ids 需要删除的设备-EMQX鉴权信息主键
* @return 结果
*/
public int deleteEmqxAuthByIds(String[] ids);
/**
* 删除设备-EMQX鉴权信息信息
*
* @param id 设备-EMQX鉴权信息主键
* @return 结果
*/
public int deleteEmqxAuthById(String id);
}

View File

@ -0,0 +1,62 @@
package com.ruoyi.web.service;
import java.util.List;
import com.ruoyi.web.domain.MaintenanceRecord;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* 设备维保记录Service接口
*
* @author cx
* @date 2025-04-05
*/
public interface IMaintenanceRecordService extends IService<MaintenanceRecord>
{
/**
* 查询设备维保记录
*
* @param id 设备维保记录主键
* @return 设备维保记录
*/
public MaintenanceRecord selectMaintenanceRecordById(String id);
/**
* 查询设备维保记录列表
*
* @param maintenanceRecord 设备维保记录
* @return 设备维保记录
*/
public List<MaintenanceRecord> selectMaintenanceRecordList(MaintenanceRecord maintenanceRecord);
/**
* 新增设备维保记录
*
* @param maintenanceRecord 设备维保记录
* @return 结果
*/
public int insertMaintenanceRecord(MaintenanceRecord maintenanceRecord);
/**
* 修改设备维保记录
*
* @param maintenanceRecord 设备维保记录
* @return 结果
*/
public int updateMaintenanceRecord(MaintenanceRecord maintenanceRecord);
/**
* 批量删除设备维保记录
*
* @param ids 需要删除的设备维保记录主键
* @return 结果
*/
public int deleteMaintenanceRecordByIds(String[] ids);
/**
* 删除设备维保记录信息
*
* @param id 设备维保记录主键
* @return 结果
*/
public int deleteMaintenanceRecordById(String id);
}

View File

@ -0,0 +1,140 @@
package com.ruoyi.web.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.system.domain.SysPost;
import com.ruoyi.system.mapper.SysDeptMapper;
import com.ruoyi.system.mapper.SysPostMapper;
import com.ruoyi.web.domain.CustomerDeptPostRel;
import com.ruoyi.web.mapper.CustomerDeptPostRelMapper;
import com.ruoyi.web.model.dto.CustomerDeptPostRelDto;
import com.ruoyi.web.service.ICustomerDeptPostRelService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* 客户-部门-岗位关联Service业务层处理
*
* @author ruoyi
* @date 2025-04-08
*/
@Service
@RequiredArgsConstructor
public class CustomerDeptPostRelServiceImpl extends ServiceImpl<CustomerDeptPostRelMapper, CustomerDeptPostRel> implements ICustomerDeptPostRelService {
private final CustomerDeptPostRelMapper customerDeptPostRelMapper;
private final SysPostMapper sysPostMapper;
private final SysDeptMapper sysDeptMapper;
/**
* 查询客户-部门-岗位关联
*
* @param id 客户-部门-岗位关联主键
* @return 客户-部门-岗位关联
*/
@Override
public CustomerDeptPostRel selectCustomerDeptPostRelById(Long id) {
return getById(id);
}
/**
* 查询客户-部门-岗位关联列表
*
* @param customerDeptPostRel 客户-部门-岗位关联
* @return 客户-部门-岗位关联
*/
@Override
public List<CustomerDeptPostRelDto> selectCustomerDeptPostRelList(CustomerDeptPostRel customerDeptPostRel) {
LambdaQueryWrapper<CustomerDeptPostRel> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(customerDeptPostRel.getCustomerId() != null, CustomerDeptPostRel::getCustomerId, customerDeptPostRel.getCustomerId());
wrapper.eq(customerDeptPostRel.getDeptId() != null, CustomerDeptPostRel::getDeptId, customerDeptPostRel.getDeptId());
wrapper.eq(customerDeptPostRel.getPostId() != null, CustomerDeptPostRel::getPostId, customerDeptPostRel.getPostId());
List<CustomerDeptPostRel> list = list(wrapper);
return assembleName(list);
}
/**
* 组装Name属性
*
* @param list
* @return
*/
private List<CustomerDeptPostRelDto> assembleName(List<CustomerDeptPostRel> list) {
if (CollectionUtils.isEmpty(list)) {
return Collections.emptyList();
}
List<Long> deptIdList = list.stream()
.flatMap(rel -> Stream.of(rel.getCustomerId(), rel.getDeptId()))
.toList();
List<SysDept> deptList = sysDeptMapper.selectBatchIds(deptIdList);
Map<Long, SysDept> deptMap = deptList.stream().collect(Collectors.toMap(SysDept::getDeptId, Function.identity()));
List<Long> postIdList = list.stream().map(CustomerDeptPostRel::getPostId).toList();
List<SysPost> sysPosts = sysPostMapper.selectBatchIds(postIdList);
Map<Long, SysPost> postMap = sysPosts.stream().collect(Collectors.toMap(SysPost::getPostId, Function.identity()));
return list.stream().map(item -> {
CustomerDeptPostRelDto dto = new CustomerDeptPostRelDto();
BeanUtils.copyProperties(item, dto);
dto.setCustomerName(deptMap.get(item.getCustomerId()).getDeptName());
dto.setDeptName(deptMap.get(item.getDeptId()).getDeptName());
dto.setPostName(postMap.get(item.getPostId()).getPostName());
dto.setCreateBy(postMap.get(item.getPostId()).getCreateBy());
dto.setCreateTime(postMap.get(item.getPostId()).getCreateTime());
return dto;
}).toList();
}
/**
* 新增客户-部门-岗位关联
*
* @param customerDeptPostRel 客户-部门-岗位关联
* @return 结果
*/
@Override
public int insertCustomerDeptPostRel(CustomerDeptPostRel customerDeptPostRel) {
return save(customerDeptPostRel) ? 1 : 0;
}
/**
* 修改客户-部门-岗位关联
*
* @param customerDeptPostRel 客户-部门-岗位关联
* @return 结果
*/
@Override
public int updateCustomerDeptPostRel(CustomerDeptPostRel customerDeptPostRel) {
return updateById(customerDeptPostRel) ? 1 : 0;
}
/**
* 批量删除客户-部门-岗位关联
*
* @param ids 需要删除的客户-部门-岗位关联主键
* @return 结果
*/
@Override
public int deleteCustomerDeptPostRelByIds(Long[] ids) {
return removeByIds(Arrays.asList(ids)) ? 1 : 0;
}
/**
* 删除客户-部门-岗位关联信息
*
* @param id 客户-部门-岗位关联主键
* @return 结果
*/
@Override
public int deleteCustomerDeptPostRelById(Long id) {
return removeById(id) ? 1 : 0;
}
}

View File

@ -0,0 +1,112 @@
package com.ruoyi.web.service.impl;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.system.service.ISysDeptService;
import com.ruoyi.system.service.ISysPostService;
import com.ruoyi.web.domain.CustomerDeptPostRel;
import com.ruoyi.web.model.dto.CreateCustomerDto;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* 客户用户关联信息Service业务层处理
*
* @author cx
* @date 2025-04-05
*/
@Service
@RequiredArgsConstructor
@Slf4j
public class CustomerUserRelServiceImpl {
private final ISysDeptService sysDeptService;
private final ISysPostService sysPostService;
private final CustomerDeptPostRelServiceImpl customerDeptPostRelServiceImpl;
public void addCustomer(CreateCustomerDto createCustomerDto) {
//天宫制造公司目录下进行创建对应的部门
SysDept sysDept = assembleSysDept(createCustomerDto);
sysDeptService.insertDept(sysDept);
log.info("SysDept insert success,and Return Id : {}", sysDept.getDeptId());
List<SysDept> deptList = initDefaultDept(sysDept);
initDefaultPost(sysDept, deptList);
}
/**
* 每个部门默认创建两个岗位
*
* @param sysDept
* @param deptList
*/
private void initDefaultPost(SysDept sysDept, List<SysDept> deptList) {
Long customerId = sysDept.getDeptId();
ArrayList<CustomerDeptPostRel> customerDeptPostRels = new ArrayList<>();
deptList.forEach(dept -> {
CustomerDeptPostRel customerDeptPostRel1 = CustomerDeptPostRel.builder()
.customerId(customerId)
.deptId(dept.getDeptId())
.postId(5L)
.build();
CustomerDeptPostRel customerDeptPostRel2 = CustomerDeptPostRel.builder()
.customerId(customerId)
.deptId(dept.getDeptId())
.postId(6L)
.build();
customerDeptPostRels.add(customerDeptPostRel1);
customerDeptPostRels.add(customerDeptPostRel2);
});
customerDeptPostRelServiceImpl.saveBatch(customerDeptPostRels);
}
/**
* 初始化默认部门
* @param sysDept
* @return
*/
private List<SysDept> initDefaultDept(SysDept sysDept) {
ArrayList<SysDept> deptList = new ArrayList<>();
SysDept dept1 = new SysDept();
dept1.setCreateBy(sysDept.getCreateBy());
dept1.setDeptName("运维部");
dept1.setParentId(sysDept.getDeptId());
dept1.setAncestors(sysDept.getAncestors() + "," + sysDept.getDeptId());
dept1.setCreateTime(new Date());
deptList.add(dept1);
SysDept dept2 = new SysDept();
dept2.setCreateBy(sysDept.getCreateBy());
dept2.setDeptName("研发部");
dept2.setParentId(sysDept.getDeptId());
dept2.setAncestors(sysDept.getAncestors() + "," + sysDept.getDeptId());
dept2.setCreateTime(new Date());
deptList.add(dept2);
sysDeptService.saveBatch(deptList);
return deptList;
}
/**
* 组装部门信息
*
* @param createCustomerDto
* @return
*/
private SysDept assembleSysDept(CreateCustomerDto createCustomerDto) {
SysDept sysDept = new SysDept();
sysDept.setDeptName(createCustomerDto.getCustomerName());
sysDept.setAddress(createCustomerDto.getAddress());
sysDept.setPhone(createCustomerDto.getPhone());
sysDept.setLeader(createCustomerDto.getLeader());
sysDept.setCreateBy(SecurityUtils.getUsername());
//default setting
sysDept.setParentId(100L);
sysDept.setAncestors("0,100");
return sysDept;
}
}

View File

@ -0,0 +1,201 @@
package com.ruoyi.web.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.system.mapper.SysUserMapper;
import com.ruoyi.web.domain.DeviceInfo;
import com.ruoyi.web.domain.DeviceUserRel;
import com.ruoyi.web.domain.EmqxAuth;
import com.ruoyi.web.mapper.DeviceInfoMapper;
import com.ruoyi.web.mapper.DeviceModelMapper;
import com.ruoyi.web.model.dto.CreateDeviceInfoDto;
import com.ruoyi.web.model.dto.DeviceListDto;
import com.ruoyi.web.model.dto.DeviceUserRelDto;
import com.ruoyi.web.model.index.OverViewDto;
import com.ruoyi.web.service.IDeviceInfoService;
import com.ruoyi.web.service.IDeviceThresholdService;
import com.ruoyi.web.service.IDeviceUserRelService;
import com.ruoyi.web.service.IEmqxAuthService;
import lombok.RequiredArgsConstructor;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import java.beans.Transient;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* 设备信息Service业务层处理
*
* @author cx
* @date 2025-04-05
*/
@Service
@RequiredArgsConstructor
public class DeviceInfoServiceImpl extends ServiceImpl<DeviceInfoMapper, DeviceInfo> implements IDeviceInfoService {
private final IDeviceUserRelService deviceUserRelService;
private final IEmqxAuthService emqxAuthService;
private final IDeviceThresholdService deviceThresholdService;
private final SysUserMapper sysUserMapper;
private final DeviceModelMapper deviceModelMapper;
/**
* 查询设备信息
*
* @param id 设备信息主键
* @return 设备信息
*/
@Override
public DeviceInfo selectDeviceInfoById(String id) {
return getById(id);
}
/**
* 查询设备信息列表
*
* @param deviceInfo 设备信息
* @return 设备信息
*/
@Override
public List<DeviceListDto> selectDeviceInfoList(DeviceInfo deviceInfo) {
LambdaQueryWrapper<DeviceInfo> wrapper = new LambdaQueryWrapper<>();
wrapper.like(deviceInfo.getDeviceName() != null, DeviceInfo::getDeviceName, deviceInfo.getDeviceName());
wrapper.eq(deviceInfo.getDeviceModel() != null, DeviceInfo::getDeviceModel, deviceInfo.getDeviceModel());
wrapper.eq(deviceInfo.getDeviceCode() != null, DeviceInfo::getDeviceCode, deviceInfo.getDeviceCode());
wrapper.eq(deviceInfo.getCustomerId() != null, DeviceInfo::getCustomerId, deviceInfo.getCustomerId());
wrapper.eq(deviceInfo.getLifespan() != null, DeviceInfo::getLifespan, deviceInfo.getLifespan());
wrapper.eq(deviceInfo.getUsedTime() != null, DeviceInfo::getUsedTime, deviceInfo.getUsedTime());
wrapper.eq(deviceInfo.getDeviceStatus() != null, DeviceInfo::getDeviceStatus, deviceInfo.getDeviceStatus());
wrapper.eq(deviceInfo.getServiceStatus() != null, DeviceInfo::getServiceStatus, deviceInfo.getServiceStatus());
List<DeviceInfo> deviceInfoList = list(wrapper);
if (CollectionUtils.isEmpty(deviceInfoList)) {
return Collections.emptyList();
}
List<String> deviceCodeList = deviceInfoList.stream().map(DeviceInfo::getDeviceCode).toList();
LambdaQueryWrapper<DeviceUserRel> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.in(DeviceUserRel::getDeviceCode, deviceCodeList);
List<DeviceUserRel> deviceUserRelList = deviceUserRelService.list(queryWrapper);
List<SysUser> sysUsers = sysUserMapper.selectUserListBatchById();
Map<Long, SysUser> userMap = sysUsers.stream().collect(Collectors.toMap(SysUser::getUserId, Function.identity()));
Map<String, List<DeviceUserRelDto>> deviceUserMap = deviceUserRelList.stream().map(rel-> {
DeviceUserRelDto deviceUserRelDto = new DeviceUserRelDto();
deviceUserRelDto.setDeviceCode(rel.getDeviceCode());
deviceUserRelDto.setUserId(rel.getUserId());
deviceUserRelDto.setUserName(userMap.get(rel.getUserId()).getUserName());
deviceUserRelDto.setDeptName(userMap.get(rel.getUserId()).getDeptName());
deviceUserRelDto.setStatus(userMap.get(rel.getUserId()).getStatus());
deviceUserRelDto.setPhone(userMap.get(rel.getUserId()).getPhonenumber());
return deviceUserRelDto;
}).collect(Collectors.groupingBy(DeviceUserRel::getDeviceCode));
return deviceInfoList.stream().map(info -> {
DeviceListDto deviceListDto = new DeviceListDto();
BeanUtils.copyProperties(info, deviceListDto);
deviceListDto.setUserRelList(deviceUserMap.get(deviceListDto.getDeviceCode()));
return deviceListDto;
}).toList();
}
/**
* 新增设备信息
*
* @param deviceInfo 设备信息
* @return 结果
*/
@Override
public int insertDeviceInfo(DeviceInfo deviceInfo) {
return save(deviceInfo) ? 1 : 0;
}
@Override
@Transactional(rollbackFor = Exception.class)
public int createDeviceInfo(CreateDeviceInfoDto dto) {
validModelCode(dto);
//step1 组装设备信息保存
DeviceInfo deviceInfo = new DeviceInfo();
BeanUtils.copyProperties(dto, deviceInfo);
deviceInfo.setCreateBy(SecurityUtils.getUsername());
deviceInfo.setCreateTime(new Date());
((DeviceInfoServiceImpl) AopContext.currentProxy()).save(deviceInfo);
//step2 保存Emqx 鉴权信息
EmqxAuth emqxAuth = new EmqxAuth();
BeanUtils.copyProperties(dto.getEmqxAuth(), emqxAuth);
emqxAuth.setDeviceCode(dto.getDeviceCode());
emqxAuthService.save(emqxAuth);
//step3 初始化设备指标阈值
deviceThresholdService.initDeviceThreshold(deviceInfo.getDeviceCode());
//step4 保存设备-客户-用户信息
if (CollectionUtils.isEmpty(dto.getUserIdList())) {
return 1;
}
List<DeviceUserRel> deviceUserRels = dto.getUserIdList().stream().map(userId -> {
DeviceUserRel deviceUserRel = new DeviceUserRel();
deviceUserRel.setDeviceCode(deviceInfo.getDeviceCode());
deviceUserRel.setCustomerId(deviceInfo.getCustomerId());
deviceUserRel.setUserId(userId);
return deviceUserRel;
}).toList();
deviceUserRelService.saveBatch(deviceUserRels);
return 1;
}
/**
* 校验参数
* @param dto
*/
private void validModelCode(CreateDeviceInfoDto dto) {
LambdaQueryWrapper<DeviceInfo> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(DeviceInfo::getDeviceCode, dto.getDeviceCode());
List<DeviceInfo> resultList = this.list(queryWrapper);
if (!resultList.isEmpty()) {
throw new ServiceException("设备编码已存在");
}
}
/**
* 修改设备信息
*
* @param deviceInfo 设备信息
* @return 结果
*/
@Override
public int updateDeviceInfo(DeviceInfo deviceInfo) {
return updateById(deviceInfo) ? 1 : 0;
}
/**
* 批量删除设备信息
*
* @param ids 需要删除的设备信息主键
* @return 结果
*/
@Override
public int deleteDeviceInfoByIds(String[] ids) {
return removeByIds(Arrays.asList(ids)) ? 1 : 0;
}
/**
* 删除设备信息信息
*
* @param id 设备信息主键
* @return 结果
*/
@Override
public int deleteDeviceInfoById(String id) {
return removeById(id) ? 1 : 0;
}
@Override
public OverViewDto overview() {
return deviceModelMapper.overview();
}
}

View File

@ -0,0 +1,136 @@
package com.ruoyi.web.service.impl;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.web.domain.DeviceInfo;
import com.ruoyi.web.service.IDeviceInfoService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.web.mapper.DeviceModelMapper;
import com.ruoyi.web.domain.DeviceModel;
import com.ruoyi.web.service.IDeviceModelService;
import lombok.RequiredArgsConstructor;
/**
* 设备型号Service业务层处理
*
* @author cx
* @date 2025-04-05
*/
@Service
@RequiredArgsConstructor
@Slf4j
public class DeviceModelServiceImpl extends ServiceImpl<DeviceModelMapper, DeviceModel> implements IDeviceModelService
{
private final DeviceModelMapper deviceModelMapper;
private final IDeviceInfoService deviceInfoService;
/**
* 查询设备型号
*
* @param id 设备型号主键
* @return 设备型号
*/
@Override
public DeviceModel selectDeviceModelById(String id)
{
return getById(id);
}
/**
* 查询设备型号列表
*
* @param deviceModel 设备型号
* @return 设备型号
*/
@Override
public List<DeviceModel> selectDeviceModelList(DeviceModel deviceModel)
{
LambdaQueryWrapper<DeviceModel> wrapper = new LambdaQueryWrapper<>();
wrapper.like(deviceModel.getDeviceModel() != null, DeviceModel::getDeviceModel, deviceModel.getDeviceModel());
wrapper.eq(deviceModel.getDevicePic() != null, DeviceModel::getDevicePic, deviceModel.getDevicePic());
return list(wrapper);
}
/**
* 新增设备型号
*
* @param deviceModel 设备型号
* @return 结果
*/
@Override
public int insertDeviceModel(DeviceModel deviceModel)
{
validModelCode(deviceModel);
LoginUser user = SecurityUtils.getLoginUser();
deviceModel.setCreateBy(user.getUsername());
deviceModel.setUpdateBy(user.getUsername());
return save(deviceModel) ? 1 : 0;
}
private void validModelCode(DeviceModel deviceModel) {
LambdaQueryWrapper<DeviceModel> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(DeviceModel::getDeviceModel, deviceModel.getDeviceModel());
List<DeviceModel> list = this.list(queryWrapper);
if (!list.isEmpty()) {
throw new ServiceException("该设备型号已存在,不能重复录入相同型号");
}
}
/**
* 修改设备型号
*
* @param deviceModel 设备型号
* @return 结果
*/
@Override
public int updateDeviceModel(DeviceModel deviceModel)
{
String username = SecurityUtils.getUsername();
deviceModel.setUpdateBy(username);
return updateById(deviceModel) ? 1 : 0;
}
/**
* 批量删除设备型号
*
* @param ids 需要删除的设备型号主键
* @return 结果
*/
@Override
public int deleteDeviceModelByIds(String[] ids)
{
List<DeviceModel> deviceModels = this.listByIds(Arrays.asList(ids));
List<String> deviceCodeList = deviceModels.stream().map(DeviceModel::getDeviceModel).collect(Collectors.toList());
LambdaQueryWrapper<DeviceInfo> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.in(DeviceInfo::getDeviceCode, deviceCodeList.toArray());
List<DeviceInfo> infoList = deviceInfoService.list(queryWrapper);
if (!infoList.isEmpty()) {
log.warn("设备型号 {} 已绑定设备,无法删除", JSON.toJSONString(deviceCodeList));
return 0;
}
return removeByIds(Arrays.asList(ids)) ? 1 : 0;
}
/**
* 删除设备型号信息
*
* @param id 设备型号主键
* @return 结果
*/
@Override
public int deleteDeviceModelById(String id)
{
return removeById(id) ? 1 : 0;
}
}

View File

@ -0,0 +1,120 @@
package com.ruoyi.web.service.impl;
import java.util.Arrays;
import java.util.List;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.web.mapper.DeviceThresholdMapper;
import com.ruoyi.web.domain.DeviceThreshold;
import com.ruoyi.web.service.IDeviceThresholdService;
import lombok.RequiredArgsConstructor;
/**
* 设备指标阈值信息Service业务层处理
*
* @author cx
* @date 2025-04-05
*/
@Service
@RequiredArgsConstructor
public class DeviceThresholdServiceImpl extends ServiceImpl<DeviceThresholdMapper, DeviceThreshold> implements IDeviceThresholdService {
private final DeviceThresholdMapper deviceThresholdMapper;
/**
* 查询设备指标阈值信息
*
* @param deviceCode 设备编码
* @return 设备指标阈值信息
*/
@Override
public DeviceThreshold selectDeviceThresholdById(String deviceCode) {
LambdaQueryWrapper<DeviceThreshold> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(DeviceThreshold::getDeviceCode, deviceCode);
return getOne(queryWrapper);
}
/**
* 查询设备指标阈值信息列表
*
* @param deviceThreshold 设备指标阈值信息
* @return 设备指标阈值信息
*/
@Override
public List<DeviceThreshold> selectDeviceThresholdList(DeviceThreshold deviceThreshold) {
LambdaQueryWrapper<DeviceThreshold> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(deviceThreshold.getDeviceCode() != null, DeviceThreshold::getDeviceCode, deviceThreshold.getDeviceCode());
wrapper.eq(deviceThreshold.getOutl() != null, DeviceThreshold::getOutl, deviceThreshold.getOutl());
wrapper.eq(deviceThreshold.getWtl() != null, DeviceThreshold::getWtl, deviceThreshold.getWtl());
wrapper.eq(deviceThreshold.getAtl() != null, DeviceThreshold::getAtl, deviceThreshold.getAtl());
wrapper.eq(deviceThreshold.getBtl() != null, DeviceThreshold::getBtl, deviceThreshold.getBtl());
wrapper.eq(deviceThreshold.getOwst() != null, DeviceThreshold::getOwst, deviceThreshold.getOwst());
wrapper.eq(deviceThreshold.getWfl() != null, DeviceThreshold::getWfl, deviceThreshold.getWfl());
wrapper.eq(deviceThreshold.getSas() != null, DeviceThreshold::getSas, deviceThreshold.getSas());
wrapper.eq(deviceThreshold.getCti() != null, DeviceThreshold::getCti, deviceThreshold.getCti());
wrapper.eq(deviceThreshold.getRpssv1() != null, DeviceThreshold::getRpssv1, deviceThreshold.getRpssv1());
wrapper.eq(deviceThreshold.getRpssc1() != null, DeviceThreshold::getRpssc1, deviceThreshold.getRpssc1());
wrapper.eq(deviceThreshold.getFsc1() != null, DeviceThreshold::getFsc1, deviceThreshold.getFsc1());
wrapper.eq(deviceThreshold.getFpsc1() != null, DeviceThreshold::getFpsc1, deviceThreshold.getFpsc1());
wrapper.eq(deviceThreshold.getRpssv2() != null, DeviceThreshold::getRpssv2, deviceThreshold.getRpssv2());
wrapper.eq(deviceThreshold.getRpssc2() != null, DeviceThreshold::getRpssc2, deviceThreshold.getRpssc2());
wrapper.eq(deviceThreshold.getFsc2() != null, DeviceThreshold::getFsc2, deviceThreshold.getFsc2());
wrapper.eq(deviceThreshold.getFpsc2() != null, DeviceThreshold::getFpsc2, deviceThreshold.getFpsc2());
return list(wrapper);
}
/**
* 新增设备指标阈值信息
*
* @param deviceThreshold 设备指标阈值信息
* @return 结果
*/
@Override
public int insertDeviceThreshold(DeviceThreshold deviceThreshold) {
return save(deviceThreshold) ? 1 : 0;
}
/**
* 修改设备指标阈值信息
*
* @param deviceThreshold 设备指标阈值信息
* @return 结果
*/
@Override
public int updateDeviceThreshold(DeviceThreshold deviceThreshold) {
return updateById(deviceThreshold) ? 1 : 0;
}
/**
* 批量删除设备指标阈值信息
*
* @param ids 需要删除的设备指标阈值信息主键
* @return 结果
*/
@Override
public int deleteDeviceThresholdByIds(String[] ids) {
return removeByIds(Arrays.asList(ids)) ? 1 : 0;
}
/**
* 删除设备指标阈值信息信息
*
* @param id 设备指标阈值信息主键
* @return 结果
*/
@Override
public int deleteDeviceThresholdById(String id) {
return removeById(id) ? 1 : 0;
}
@Override
public void initDeviceThreshold(String deviceCode) {
DeviceThreshold sourceData = deviceThresholdMapper.selectById(1);
sourceData.setId(null);
sourceData.setDeviceCode(deviceCode);
deviceThresholdMapper.insert(sourceData);
}
}

View File

@ -0,0 +1,100 @@
package com.ruoyi.web.service.impl;
import java.util.Arrays;
import java.util.List;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.web.mapper.DeviceUserRelMapper;
import com.ruoyi.web.domain.DeviceUserRel;
import com.ruoyi.web.service.IDeviceUserRelService;
import lombok.RequiredArgsConstructor;
/**
* 设备用户关联信息Service业务层处理
*
* @author cx
* @date 2025-04-05
*/
@Service
@RequiredArgsConstructor
public class DeviceUserRelServiceImpl extends ServiceImpl<DeviceUserRelMapper, DeviceUserRel> implements IDeviceUserRelService
{
private final DeviceUserRelMapper deviceUserRelMapper;
/**
* 查询设备用户关联信息
*
* @param id 设备用户关联信息主键
* @return 设备用户关联信息
*/
@Override
public DeviceUserRel selectDeviceUserRelById(String id)
{
return getById(id);
}
/**
* 查询设备用户关联信息列表
*
* @param deviceUserRel 设备用户关联信息
* @return 设备用户关联信息
*/
@Override
public List<DeviceUserRel> selectDeviceUserRelList(DeviceUserRel deviceUserRel)
{
LambdaQueryWrapper<DeviceUserRel> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(deviceUserRel.getDeviceCode() != null, DeviceUserRel::getDeviceCode, deviceUserRel.getDeviceCode());
wrapper.eq(deviceUserRel.getUserId() != null, DeviceUserRel::getUserId, deviceUserRel.getUserId());
return list(wrapper);
}
/**
* 新增设备用户关联信息
*
* @param deviceUserRel 设备用户关联信息
* @return 结果
*/
@Override
public int insertDeviceUserRel(DeviceUserRel deviceUserRel)
{
return save(deviceUserRel) ? 1 : 0;
}
/**
* 修改设备用户关联信息
*
* @param deviceUserRel 设备用户关联信息
* @return 结果
*/
@Override
public int updateDeviceUserRel(DeviceUserRel deviceUserRel)
{
return updateById(deviceUserRel) ? 1 : 0;
}
/**
* 批量删除设备用户关联信息
*
* @param ids 需要删除的设备用户关联信息主键
* @return 结果
*/
@Override
public int deleteDeviceUserRelByIds(String[] ids)
{
return removeByIds(Arrays.asList(ids)) ? 1 : 0;
}
/**
* 删除设备用户关联信息信息
*
* @param id 设备用户关联信息主键
* @return 结果
*/
@Override
public int deleteDeviceUserRelById(String id)
{
return removeById(id) ? 1 : 0;
}
}

View File

@ -0,0 +1,95 @@
package com.ruoyi.web.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.web.domain.EmqxAuth;
import com.ruoyi.web.mapper.EmqxAuthMapper;
import com.ruoyi.web.service.IEmqxAuthService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.Arrays;
import java.util.List;
/**
* 设备-EMQX鉴权信息Service业务层处理
*
* @author ruoyi
* @date 2025-04-08
*/
@Service
@RequiredArgsConstructor
public class EmqxAuthServiceImpl extends ServiceImpl<EmqxAuthMapper, EmqxAuth> implements IEmqxAuthService {
private final EmqxAuthMapper emqxAuthMapper;
/**
* 查询设备-EMQX鉴权信息
*
* @param id 设备-EMQX鉴权信息主键
* @return 设备-EMQX鉴权信息
*/
@Override
public EmqxAuth selectEmqxAuthById(String id) {
return getById(id);
}
/**
* 查询设备-EMQX鉴权信息列表
*
* @param emqxAuth 设备-EMQX鉴权信息
* @return 设备-EMQX鉴权信息
*/
@Override
public List<EmqxAuth> selectEmqxAuthList(EmqxAuth emqxAuth) {
LambdaQueryWrapper<EmqxAuth> wrapper = new LambdaQueryWrapper<>();
wrapper.like(emqxAuth.getLocalUserName() != null, EmqxAuth::getLocalUserName, emqxAuth.getLocalUserName());
wrapper.eq(emqxAuth.getLocalPass() != null, EmqxAuth::getLocalPass, emqxAuth.getLocalPass());
wrapper.like(emqxAuth.getCloudUserName() != null, EmqxAuth::getCloudUserName, emqxAuth.getCloudUserName());
wrapper.eq(emqxAuth.getCloudPass() != null, EmqxAuth::getCloudPass, emqxAuth.getCloudPass());
return list(wrapper);
}
/**
* 新增设备-EMQX鉴权信息
*
* @param emqxAuth 设备-EMQX鉴权信息
* @return 结果
*/
@Override
public int insertEmqxAuth(EmqxAuth emqxAuth) {
return save(emqxAuth) ? 1 : 0;
}
/**
* 修改设备-EMQX鉴权信息
*
* @param emqxAuth 设备-EMQX鉴权信息
* @return 结果
*/
@Override
public int updateEmqxAuth(EmqxAuth emqxAuth) {
return updateById(emqxAuth) ? 1 : 0;
}
/**
* 批量删除设备-EMQX鉴权信息
*
* @param ids 需要删除的设备-EMQX鉴权信息主键
* @return 结果
*/
@Override
public int deleteEmqxAuthByIds(String[] ids) {
return removeByIds(Arrays.asList(ids)) ? 1 : 0;
}
/**
* 删除设备-EMQX鉴权信息信息
*
* @param id 设备-EMQX鉴权信息主键
* @return 结果
*/
@Override
public int deleteEmqxAuthById(String id) {
return removeById(id) ? 1 : 0;
}
}

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