作者 钟来

模块调整

正在显示 56 个修改的文件 包含 4783 行增加0 行删除

要显示太多修改。

为保证性能只显示 56 of 56+ 个文件。

  1 +<p align="center">
  2 + <img alt="logo" src="https://oscimg.oschina.net/oscnet/up-d3d0a9303e11d522a06cd263f3079027715.png">
  3 +</p>
  4 +<h1 align="center" style="margin: 30px 0 30px; font-weight: bold;">RuoYi v3.8.7</h1>
  5 +<h4 align="center">基于SpringBoot+Vue前后端分离的Java快速开发框架</h4>
  6 +<p align="center">
  7 + <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>
  8 + <a href="https://gitee.com/y_project/RuoYi-Vue"><img src="https://img.shields.io/badge/RuoYi-v3.8.7-brightgreen.svg"></a>
  9 + <a href="https://gitee.com/y_project/RuoYi-Vue/blob/master/LICENSE"><img src="https://img.shields.io/github/license/mashape/apistatus.svg"></a>
  10 +</p>
  11 +
  12 +## 平台简介
  13 +
  14 +若依是一套全部开源的快速开发平台,毫无保留给个人及企业免费使用。
  15 +
  16 +* 前端采用Vue、Element UI。
  17 +* 后端采用Spring Boot、Spring Security、Redis & Jwt。
  18 +* 权限认证使用Jwt,支持多终端认证系统。
  19 +* 支持加载动态权限菜单,多方式轻松权限控制。
  20 +* 高效率开发,使用代码生成器可以一键生成前后端代码。
  21 +* 提供了技术栈([Vue3](https://v3.cn.vuejs.org) [Element Plus](https://element-plus.org/zh-CN) [Vite](https://cn.vitejs.dev))版本[RuoYi-Vue3](https://github.com/yangzongzhuan/RuoYi-Vue3),保持同步更新。
  22 +* 提供了单应用版本[RuoYi-Vue-fast](https://github.com/yangzongzhuan/RuoYi-Vue-fast),Oracle版本[RuoYi-Vue-Oracle](https://github.com/yangzongzhuan/RuoYi-Vue-Oracle),保持同步更新。
  23 +* 不分离版本,请移步[RuoYi](https://gitee.com/y_project/RuoYi),微服务版本,请移步[RuoYi-Cloud](https://gitee.com/y_project/RuoYi-Cloud)
  24 +* 阿里云折扣场:[点我进入](http://aly.ruoyi.vip),腾讯云秒杀场:[点我进入](http://txy.ruoyi.vip)&nbsp;&nbsp;
  25 +* 阿里云优惠券:[点我领取](https://www.aliyun.com/minisite/goods?userCode=brki8iof&share_source=copy_link),腾讯云优惠券:[点我领取](https://cloud.tencent.com/redirect.php?redirect=1025&cps_key=198c8df2ed259157187173bc7f4f32fd&from=console)&nbsp;&nbsp;
  26 +
  27 +## 内置功能
  28 +
  29 +1. 用户管理:用户是系统操作者,该功能主要完成系统用户配置。
  30 +2. 部门管理:配置系统组织机构(公司、部门、小组),树结构展现支持数据权限。
  31 +3. 岗位管理:配置系统用户所属担任职务。
  32 +4. 菜单管理:配置系统菜单,操作权限,按钮权限标识等。
  33 +5. 角色管理:角色菜单权限分配、设置角色按机构进行数据范围权限划分。
  34 +6. 字典管理:对系统中经常使用的一些较为固定的数据进行维护。
  35 +7. 参数管理:对系统动态配置常用参数。
  36 +8. 通知公告:系统通知公告信息发布维护。
  37 +9. 操作日志:系统正常操作日志记录和查询;系统异常信息日志记录和查询。
  38 +10. 登录日志:系统登录日志记录查询包含登录异常。
  39 +11. 在线用户:当前系统中活跃用户状态监控。
  40 +12. 定时任务:在线(添加、修改、删除)任务调度包含执行结果日志。
  41 +13. 代码生成:前后端代码的生成(java、html、xml、sql)支持CRUD下载 。
  42 +14. 系统接口:根据业务代码自动生成相关的api接口文档。
  43 +15. 服务监控:监视当前系统CPU、内存、磁盘、堆栈等相关信息。
  44 +16. 缓存监控:对系统的缓存信息查询,命令统计等。
  45 +17. 在线构建器:拖动表单元素生成相应的HTML代码。
  46 +18. 连接池监视:监视当前系统数据库连接池状态,可进行分析SQL找出系统性能瓶颈。
  47 +
  48 +## 在线体验
  49 +
  50 +- admin/admin123
  51 +- 陆陆续续收到一些打赏,为了更好的体验已用于演示服务器升级。谢谢各位小伙伴。
  52 +
  53 +演示地址:http://vue.ruoyi.vip
  54 +文档地址:http://doc.ruoyi.vip
  55 +
  56 +## 演示图
  57 +
  58 +<table>
  59 + <tr>
  60 + <td><img src="https://oscimg.oschina.net/oscnet/cd1f90be5f2684f4560c9519c0f2a232ee8.jpg"/></td>
  61 + <td><img src="https://oscimg.oschina.net/oscnet/1cbcf0e6f257c7d3a063c0e3f2ff989e4b3.jpg"/></td>
  62 + </tr>
  63 + <tr>
  64 + <td><img src="https://oscimg.oschina.net/oscnet/up-8074972883b5ba0622e13246738ebba237a.png"/></td>
  65 + <td><img src="https://oscimg.oschina.net/oscnet/up-9f88719cdfca9af2e58b352a20e23d43b12.png"/></td>
  66 + </tr>
  67 + <tr>
  68 + <td><img src="https://oscimg.oschina.net/oscnet/up-39bf2584ec3a529b0d5a3b70d15c9b37646.png"/></td>
  69 + <td><img src="https://oscimg.oschina.net/oscnet/up-936ec82d1f4872e1bc980927654b6007307.png"/></td>
  70 + </tr>
  71 + <tr>
  72 + <td><img src="https://oscimg.oschina.net/oscnet/up-b2d62ceb95d2dd9b3fbe157bb70d26001e9.png"/></td>
  73 + <td><img src="https://oscimg.oschina.net/oscnet/up-d67451d308b7a79ad6819723396f7c3d77a.png"/></td>
  74 + </tr>
  75 + <tr>
  76 + <td><img src="https://oscimg.oschina.net/oscnet/5e8c387724954459291aafd5eb52b456f53.jpg"/></td>
  77 + <td><img src="https://oscimg.oschina.net/oscnet/644e78da53c2e92a95dfda4f76e6d117c4b.jpg"/></td>
  78 + </tr>
  79 + <tr>
  80 + <td><img src="https://oscimg.oschina.net/oscnet/up-8370a0d02977eebf6dbf854c8450293c937.png"/></td>
  81 + <td><img src="https://oscimg.oschina.net/oscnet/up-49003ed83f60f633e7153609a53a2b644f7.png"/></td>
  82 + </tr>
  83 + <tr>
  84 + <td><img src="https://oscimg.oschina.net/oscnet/up-d4fe726319ece268d4746602c39cffc0621.png"/></td>
  85 + <td><img src="https://oscimg.oschina.net/oscnet/up-c195234bbcd30be6927f037a6755e6ab69c.png"/></td>
  86 + </tr>
  87 + <tr>
  88 + <td><img src="https://oscimg.oschina.net/oscnet/b6115bc8c31de52951982e509930b20684a.jpg"/></td>
  89 + <td><img src="https://oscimg.oschina.net/oscnet/up-5e4daac0bb59612c5038448acbcef235e3a.png"/></td>
  90 + </tr>
  91 +</table>
  92 +
  93 +
  94 +## 若依前后端分离交流群
  95 +
  96 +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) 点击按钮入群。
  1 +@echo off
  2 +echo.
  3 +echo [信息] 清理工程target生成路径。
  4 +echo.
  5 +
  6 +%~d0
  7 +cd %~dp0
  8 +
  9 +cd ..
  10 +call mvn clean
  11 +
  12 +pause
  1 +@echo off
  2 +echo.
  3 +echo [信息] 打包Web工程,生成war/jar包文件。
  4 +echo.
  5 +
  6 +%~d0
  7 +cd %~dp0
  8 +
  9 +cd ..
  10 +call mvn clean package -Dmaven.test.skip=true
  11 +
  12 +pause
  1 +@echo off
  2 +echo.
  3 +echo [信息] 使用Jar命令运行Web工程。
  4 +echo.
  5 +
  6 +cd %~dp0
  7 +cd ../ruoyi-admin/target
  8 +
  9 +set JAVA_OPTS=-Xms256m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m
  10 +
  11 +java -jar %JAVA_OPTS% ruoyi-admin.jar
  12 +
  13 +cd bin
  14 +pause
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<project xmlns="http://maven.apache.org/POM/4.0.0"
  3 + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5 + <parent>
  6 + <artifactId>lh-ruoyi</artifactId>
  7 + <groupId>com.zhonglai.luhui</groupId>
  8 + <version>1.0.0</version>
  9 + </parent>
  10 + <modelVersion>4.0.0</modelVersion>
  11 + <packaging>jar</packaging>
  12 + <artifactId>ruoyi-admin</artifactId>
  13 +
  14 + <description>
  15 + web服务入口
  16 + </description>
  17 +
  18 + <dependencies>
  19 +
  20 + <!-- spring-boot-devtools -->
  21 + <dependency>
  22 + <groupId>org.springframework.boot</groupId>
  23 + <artifactId>spring-boot-devtools</artifactId>
  24 + <optional>true</optional> <!-- 表示依赖不会传递 -->
  25 + </dependency>
  26 +
  27 + <!-- 文档 -->
  28 + <dependency>
  29 + <groupId>com.github.xiaoymin</groupId>
  30 + <artifactId>knife4j-spring-boot-starter</artifactId>
  31 + </dependency>
  32 +
  33 + <!-- 防止进入swagger页面报类型转换错误,排除3.0.0中的引用,手动增加1.6.2版本 -->
  34 + <dependency>
  35 + <groupId>io.swagger</groupId>
  36 + <artifactId>swagger-models</artifactId>
  37 + <version>1.6.2</version>
  38 + </dependency>
  39 +
  40 + <!-- Mysql驱动包 -->
  41 + <dependency>
  42 + <groupId>mysql</groupId>
  43 + <artifactId>mysql-connector-java</artifactId>
  44 + </dependency>
  45 +
  46 + <!-- 核心模块-->
  47 + <dependency>
  48 + <groupId>com.zhonglai.luhui</groupId>
  49 + <artifactId>ruoyi-framework</artifactId>
  50 + </dependency>
  51 +
  52 + <!-- 定时任务-->
  53 + <dependency>
  54 + <groupId>com.zhonglai.luhui</groupId>
  55 + <artifactId>ruoyi-quartz</artifactId>
  56 + </dependency>
  57 +
  58 + <!-- 代码生成-->
  59 + <dependency>
  60 + <groupId>com.zhonglai.luhui</groupId>
  61 + <artifactId>ruoyi-generator</artifactId>
  62 + </dependency>
  63 +
  64 + </dependencies>
  65 +
  66 + <build>
  67 + <plugins>
  68 + <plugin>
  69 + <groupId>org.springframework.boot</groupId>
  70 + <artifactId>spring-boot-maven-plugin</artifactId>
  71 + <version>2.5.15</version>
  72 + <configuration>
  73 + <fork>true</fork> <!-- 如果没有该配置,devtools不会生效 -->
  74 + </configuration>
  75 + <executions>
  76 + <execution>
  77 + <goals>
  78 + <goal>repackage</goal>
  79 + </goals>
  80 + </execution>
  81 + </executions>
  82 + </plugin>
  83 + <plugin>
  84 + <groupId>org.apache.maven.plugins</groupId>
  85 + <artifactId>maven-war-plugin</artifactId>
  86 + <version>3.1.0</version>
  87 + <configuration>
  88 + <failOnMissingWebXml>false</failOnMissingWebXml>
  89 + <warName>${project.artifactId}</warName>
  90 + </configuration>
  91 + </plugin>
  92 + </plugins>
  93 + <finalName>${project.artifactId}</finalName>
  94 + </build>
  95 +
  96 +</project>
  1 +package com.ruoyi;
  2 +
  3 +import org.springframework.boot.SpringApplication;
  4 +import org.springframework.boot.autoconfigure.SpringBootApplication;
  5 +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
  6 +
  7 +/**
  8 + * 启动程序
  9 + *
  10 + * @author ruoyi
  11 + */
  12 +@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
  13 +public class RuoYiApplication
  14 +{
  15 + public static void main(String[] args)
  16 + {
  17 + // System.setProperty("spring.devtools.restart.enabled", "false");
  18 + SpringApplication.run(RuoYiApplication.class, args);
  19 + System.out.println("(♥◠‿◠)ノ゙ 若依启动成功 ლ(´ڡ`ლ)゙ \n" +
  20 + " .-------. ____ __ \n" +
  21 + " | _ _ \\ \\ \\ / / \n" +
  22 + " | ( ' ) | \\ _. / ' \n" +
  23 + " |(_ o _) / _( )_ .' \n" +
  24 + " | (_,_).' __ ___(_ o _)' \n" +
  25 + " | |\\ \\ | || |(_,_)' \n" +
  26 + " | | \\ `' /| `-' / \n" +
  27 + " | | \\ / \\ / \n" +
  28 + " ''-' `'-' `-..-' ");
  29 + }
  30 +}
  1 +package com.ruoyi;
  2 +
  3 +import org.springframework.boot.builder.SpringApplicationBuilder;
  4 +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
  5 +
  6 +/**
  7 + * web容器中进行部署
  8 + *
  9 + * @author ruoyi
  10 + */
  11 +public class RuoYiServletInitializer extends SpringBootServletInitializer
  12 +{
  13 + @Override
  14 + protected SpringApplicationBuilder configure(SpringApplicationBuilder application)
  15 + {
  16 + return application.sources(RuoYiApplication.class);
  17 + }
  18 +}
  1 +package com.ruoyi.web.controller.common;
  2 +
  3 +import java.awt.image.BufferedImage;
  4 +import java.io.IOException;
  5 +import java.util.concurrent.TimeUnit;
  6 +import javax.annotation.Resource;
  7 +import javax.imageio.ImageIO;
  8 +import javax.servlet.http.HttpServletResponse;
  9 +import org.springframework.beans.factory.annotation.Autowired;
  10 +import org.springframework.util.FastByteArrayOutputStream;
  11 +import org.springframework.web.bind.annotation.GetMapping;
  12 +import org.springframework.web.bind.annotation.RestController;
  13 +import com.google.code.kaptcha.Producer;
  14 +import com.ruoyi.common.config.RuoYiConfig;
  15 +import com.ruoyi.common.constant.CacheConstants;
  16 +import com.ruoyi.common.constant.Constants;
  17 +import com.ruoyi.common.core.domain.AjaxResult;
  18 +import com.ruoyi.common.core.redis.RedisCache;
  19 +import com.ruoyi.common.utils.sign.Base64;
  20 +import com.ruoyi.common.utils.uuid.IdUtils;
  21 +import com.ruoyi.system.service.ISysConfigService;
  22 +
  23 +/**
  24 + * 验证码操作处理
  25 + *
  26 + * @author ruoyi
  27 + */
  28 +@RestController
  29 +public class CaptchaController
  30 +{
  31 + @Resource(name = "captchaProducer")
  32 + private Producer captchaProducer;
  33 +
  34 + @Resource(name = "captchaProducerMath")
  35 + private Producer captchaProducerMath;
  36 +
  37 + @Autowired
  38 + private RedisCache redisCache;
  39 +
  40 + @Autowired
  41 + private ISysConfigService configService;
  42 + /**
  43 + * 生成验证码
  44 + */
  45 + @GetMapping("/captchaImage")
  46 + public AjaxResult getCode(HttpServletResponse response) throws IOException
  47 + {
  48 + AjaxResult ajax = AjaxResult.success();
  49 + boolean captchaEnabled = configService.selectCaptchaEnabled();
  50 + ajax.put("captchaEnabled", captchaEnabled);
  51 + if (!captchaEnabled)
  52 + {
  53 + return ajax;
  54 + }
  55 +
  56 + // 保存验证码信息
  57 + String uuid = IdUtils.simpleUUID();
  58 + String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + uuid;
  59 +
  60 + String capStr = null, code = null;
  61 + BufferedImage image = null;
  62 +
  63 + // 生成验证码
  64 + String captchaType = RuoYiConfig.getCaptchaType();
  65 + if ("math".equals(captchaType))
  66 + {
  67 + String capText = captchaProducerMath.createText();
  68 + capStr = capText.substring(0, capText.lastIndexOf("@"));
  69 + code = capText.substring(capText.lastIndexOf("@") + 1);
  70 + image = captchaProducerMath.createImage(capStr);
  71 + }
  72 + else if ("char".equals(captchaType))
  73 + {
  74 + capStr = code = captchaProducer.createText();
  75 + image = captchaProducer.createImage(capStr);
  76 + }
  77 +
  78 + redisCache.setCacheObject(verifyKey, code, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES);
  79 + // 转换流信息写出
  80 + FastByteArrayOutputStream os = new FastByteArrayOutputStream();
  81 + try
  82 + {
  83 + ImageIO.write(image, "jpg", os);
  84 + }
  85 + catch (IOException e)
  86 + {
  87 + return AjaxResult.error(e.getMessage());
  88 + }
  89 +
  90 + ajax.put("uuid", uuid);
  91 + ajax.put("img", Base64.encode(os.toByteArray()));
  92 + return ajax;
  93 + }
  94 +}
  1 +package com.ruoyi.web.controller.common;
  2 +
  3 +import java.util.ArrayList;
  4 +import java.util.List;
  5 +import javax.servlet.http.HttpServletRequest;
  6 +import javax.servlet.http.HttpServletResponse;
  7 +import org.slf4j.Logger;
  8 +import org.slf4j.LoggerFactory;
  9 +import org.springframework.beans.factory.annotation.Autowired;
  10 +import org.springframework.http.MediaType;
  11 +import org.springframework.web.bind.annotation.GetMapping;
  12 +import org.springframework.web.bind.annotation.PostMapping;
  13 +import org.springframework.web.bind.annotation.RequestMapping;
  14 +import org.springframework.web.bind.annotation.RestController;
  15 +import org.springframework.web.multipart.MultipartFile;
  16 +import com.ruoyi.common.config.RuoYiConfig;
  17 +import com.ruoyi.common.constant.Constants;
  18 +import com.ruoyi.common.core.domain.AjaxResult;
  19 +import com.ruoyi.common.utils.StringUtils;
  20 +import com.ruoyi.common.utils.file.FileUploadUtils;
  21 +import com.ruoyi.common.utils.file.FileUtils;
  22 +import com.ruoyi.framework.config.ServerConfig;
  23 +
  24 +/**
  25 + * 通用请求处理
  26 + *
  27 + * @author ruoyi
  28 + */
  29 +@RestController
  30 +@RequestMapping("/common")
  31 +public class CommonController
  32 +{
  33 + private static final Logger log = LoggerFactory.getLogger(CommonController.class);
  34 +
  35 + @Autowired
  36 + private ServerConfig serverConfig;
  37 +
  38 + private static final String FILE_DELIMETER = ",";
  39 +
  40 + /**
  41 + * 通用下载请求
  42 + *
  43 + * @param fileName 文件名称
  44 + * @param delete 是否删除
  45 + */
  46 + @GetMapping("/download")
  47 + public void fileDownload(String fileName, Boolean delete, HttpServletResponse response, HttpServletRequest request)
  48 + {
  49 + try
  50 + {
  51 + if (!FileUtils.checkAllowDownload(fileName))
  52 + {
  53 + throw new Exception(StringUtils.format("文件名称({})非法,不允许下载。 ", fileName));
  54 + }
  55 + String realFileName = System.currentTimeMillis() + fileName.substring(fileName.indexOf("_") + 1);
  56 + String filePath = RuoYiConfig.getDownloadPath() + fileName;
  57 +
  58 + response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
  59 + FileUtils.setAttachmentResponseHeader(response, realFileName);
  60 + FileUtils.writeBytes(filePath, response.getOutputStream());
  61 + if (delete)
  62 + {
  63 + FileUtils.deleteFile(filePath);
  64 + }
  65 + }
  66 + catch (Exception e)
  67 + {
  68 + log.error("下载文件失败", e);
  69 + }
  70 + }
  71 +
  72 + /**
  73 + * 通用上传请求(单个)
  74 + */
  75 + @PostMapping("/upload")
  76 + public AjaxResult uploadFile(MultipartFile file) throws Exception
  77 + {
  78 + try
  79 + {
  80 + // 上传文件路径
  81 + String filePath = RuoYiConfig.getUploadPath();
  82 + // 上传并返回新文件名称
  83 + String fileName = FileUploadUtils.upload(filePath, file);
  84 + String url = serverConfig.getUrl() + fileName;
  85 + AjaxResult ajax = AjaxResult.success();
  86 + ajax.put("url", url);
  87 + ajax.put("fileName", fileName);
  88 + ajax.put("newFileName", FileUtils.getName(fileName));
  89 + ajax.put("originalFilename", file.getOriginalFilename());
  90 + return ajax;
  91 + }
  92 + catch (Exception e)
  93 + {
  94 + return AjaxResult.error(e.getMessage());
  95 + }
  96 + }
  97 +
  98 + /**
  99 + * 通用上传请求(多个)
  100 + */
  101 + @PostMapping("/uploads")
  102 + public AjaxResult uploadFiles(List<MultipartFile> files) throws Exception
  103 + {
  104 + try
  105 + {
  106 + // 上传文件路径
  107 + String filePath = RuoYiConfig.getUploadPath();
  108 + List<String> urls = new ArrayList<String>();
  109 + List<String> fileNames = new ArrayList<String>();
  110 + List<String> newFileNames = new ArrayList<String>();
  111 + List<String> originalFilenames = new ArrayList<String>();
  112 + for (MultipartFile file : files)
  113 + {
  114 + // 上传并返回新文件名称
  115 + String fileName = FileUploadUtils.upload(filePath, file);
  116 + String url = serverConfig.getUrl() + fileName;
  117 + urls.add(url);
  118 + fileNames.add(fileName);
  119 + newFileNames.add(FileUtils.getName(fileName));
  120 + originalFilenames.add(file.getOriginalFilename());
  121 + }
  122 + AjaxResult ajax = AjaxResult.success();
  123 + ajax.put("urls", StringUtils.join(urls, FILE_DELIMETER));
  124 + ajax.put("fileNames", StringUtils.join(fileNames, FILE_DELIMETER));
  125 + ajax.put("newFileNames", StringUtils.join(newFileNames, FILE_DELIMETER));
  126 + ajax.put("originalFilenames", StringUtils.join(originalFilenames, FILE_DELIMETER));
  127 + return ajax;
  128 + }
  129 + catch (Exception e)
  130 + {
  131 + return AjaxResult.error(e.getMessage());
  132 + }
  133 + }
  134 +
  135 + /**
  136 + * 本地资源通用下载
  137 + */
  138 + @GetMapping("/download/resource")
  139 + public void resourceDownload(String resource, HttpServletRequest request, HttpServletResponse response)
  140 + throws Exception
  141 + {
  142 + try
  143 + {
  144 + if (!FileUtils.checkAllowDownload(resource))
  145 + {
  146 + throw new Exception(StringUtils.format("资源文件({})非法,不允许下载。 ", resource));
  147 + }
  148 + // 本地资源路径
  149 + String localPath = RuoYiConfig.getProfile();
  150 + // 数据库资源地址
  151 + String downloadPath = localPath + StringUtils.substringAfter(resource, Constants.RESOURCE_PREFIX);
  152 + // 下载名称
  153 + String downloadName = StringUtils.substringAfterLast(downloadPath, "/");
  154 + response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
  155 + FileUtils.setAttachmentResponseHeader(response, downloadName);
  156 + FileUtils.writeBytes(downloadPath, response.getOutputStream());
  157 + }
  158 + catch (Exception e)
  159 + {
  160 + log.error("下载文件失败", e);
  161 + }
  162 + }
  163 +}
  1 +package com.ruoyi.web.controller.monitor;
  2 +
  3 +import java.util.ArrayList;
  4 +import java.util.Collection;
  5 +import java.util.HashMap;
  6 +import java.util.List;
  7 +import java.util.Map;
  8 +import java.util.Properties;
  9 +import java.util.Set;
  10 +import org.springframework.beans.factory.annotation.Autowired;
  11 +import org.springframework.data.redis.core.RedisCallback;
  12 +import org.springframework.data.redis.core.RedisTemplate;
  13 +import org.springframework.security.access.prepost.PreAuthorize;
  14 +import org.springframework.web.bind.annotation.DeleteMapping;
  15 +import org.springframework.web.bind.annotation.GetMapping;
  16 +import org.springframework.web.bind.annotation.PathVariable;
  17 +import org.springframework.web.bind.annotation.RequestMapping;
  18 +import org.springframework.web.bind.annotation.RestController;
  19 +import com.ruoyi.common.constant.CacheConstants;
  20 +import com.ruoyi.common.core.domain.AjaxResult;
  21 +import com.ruoyi.common.utils.StringUtils;
  22 +import com.ruoyi.system.domain.SysCache;
  23 +
  24 +/**
  25 + * 缓存监控
  26 + *
  27 + * @author ruoyi
  28 + */
  29 +@RestController
  30 +@RequestMapping("/monitor/cache")
  31 +public class CacheController
  32 +{
  33 + @Autowired
  34 + private RedisTemplate<String, String> redisTemplate;
  35 +
  36 + private final static List<SysCache> caches = new ArrayList<SysCache>();
  37 + {
  38 + caches.add(new SysCache(CacheConstants.LOGIN_TOKEN_KEY, "用户信息"));
  39 + caches.add(new SysCache(CacheConstants.SYS_CONFIG_KEY, "配置信息"));
  40 + caches.add(new SysCache(CacheConstants.SYS_DICT_KEY, "数据字典"));
  41 + caches.add(new SysCache(CacheConstants.CAPTCHA_CODE_KEY, "验证码"));
  42 + caches.add(new SysCache(CacheConstants.REPEAT_SUBMIT_KEY, "防重提交"));
  43 + caches.add(new SysCache(CacheConstants.RATE_LIMIT_KEY, "限流处理"));
  44 + caches.add(new SysCache(CacheConstants.PWD_ERR_CNT_KEY, "密码错误次数"));
  45 + }
  46 +
  47 + @PreAuthorize("@ss.hasPermi('monitor:cache:list')")
  48 + @GetMapping()
  49 + public AjaxResult getInfo() throws Exception
  50 + {
  51 + Properties info = (Properties) redisTemplate.execute((RedisCallback<Object>) connection -> connection.info());
  52 + Properties commandStats = (Properties) redisTemplate.execute((RedisCallback<Object>) connection -> connection.info("commandstats"));
  53 + Object dbSize = redisTemplate.execute((RedisCallback<Object>) connection -> connection.dbSize());
  54 +
  55 + Map<String, Object> result = new HashMap<>(3);
  56 + result.put("info", info);
  57 + result.put("dbSize", dbSize);
  58 +
  59 + List<Map<String, String>> pieList = new ArrayList<>();
  60 + commandStats.stringPropertyNames().forEach(key -> {
  61 + Map<String, String> data = new HashMap<>(2);
  62 + String property = commandStats.getProperty(key);
  63 + data.put("name", StringUtils.removeStart(key, "cmdstat_"));
  64 + data.put("value", StringUtils.substringBetween(property, "calls=", ",usec"));
  65 + pieList.add(data);
  66 + });
  67 + result.put("commandStats", pieList);
  68 + return AjaxResult.success(result);
  69 + }
  70 +
  71 + @PreAuthorize("@ss.hasPermi('monitor:cache:list')")
  72 + @GetMapping("/getNames")
  73 + public AjaxResult cache()
  74 + {
  75 + return AjaxResult.success(caches);
  76 + }
  77 +
  78 + @PreAuthorize("@ss.hasPermi('monitor:cache:list')")
  79 + @GetMapping("/getKeys/{cacheName}")
  80 + public AjaxResult getCacheKeys(@PathVariable String cacheName)
  81 + {
  82 + Set<String> cacheKeys = redisTemplate.keys(cacheName + "*");
  83 + return AjaxResult.success(cacheKeys);
  84 + }
  85 +
  86 + @PreAuthorize("@ss.hasPermi('monitor:cache:list')")
  87 + @GetMapping("/getValue/{cacheName}/{cacheKey}")
  88 + public AjaxResult getCacheValue(@PathVariable String cacheName, @PathVariable String cacheKey)
  89 + {
  90 + String cacheValue = redisTemplate.opsForValue().get(cacheKey);
  91 + SysCache sysCache = new SysCache(cacheName, cacheKey, cacheValue);
  92 + return AjaxResult.success(sysCache);
  93 + }
  94 +
  95 + @PreAuthorize("@ss.hasPermi('monitor:cache:list')")
  96 + @DeleteMapping("/clearCacheName/{cacheName}")
  97 + public AjaxResult clearCacheName(@PathVariable String cacheName)
  98 + {
  99 + Collection<String> cacheKeys = redisTemplate.keys(cacheName + "*");
  100 + redisTemplate.delete(cacheKeys);
  101 + return AjaxResult.success();
  102 + }
  103 +
  104 + @PreAuthorize("@ss.hasPermi('monitor:cache:list')")
  105 + @DeleteMapping("/clearCacheKey/{cacheKey}")
  106 + public AjaxResult clearCacheKey(@PathVariable String cacheKey)
  107 + {
  108 + redisTemplate.delete(cacheKey);
  109 + return AjaxResult.success();
  110 + }
  111 +
  112 + @PreAuthorize("@ss.hasPermi('monitor:cache:list')")
  113 + @DeleteMapping("/clearCacheAll")
  114 + public AjaxResult clearCacheAll()
  115 + {
  116 + Collection<String> cacheKeys = redisTemplate.keys("*");
  117 + redisTemplate.delete(cacheKeys);
  118 + return AjaxResult.success();
  119 + }
  120 +}
  1 +package com.ruoyi.web.controller.monitor;
  2 +
  3 +import org.springframework.security.access.prepost.PreAuthorize;
  4 +import org.springframework.web.bind.annotation.GetMapping;
  5 +import org.springframework.web.bind.annotation.RequestMapping;
  6 +import org.springframework.web.bind.annotation.RestController;
  7 +import com.ruoyi.common.core.domain.AjaxResult;
  8 +import com.ruoyi.framework.web.domain.Server;
  9 +
  10 +/**
  11 + * 服务器监控
  12 + *
  13 + * @author ruoyi
  14 + */
  15 +@RestController
  16 +@RequestMapping("/monitor/server")
  17 +public class ServerController
  18 +{
  19 + @PreAuthorize("@ss.hasPermi('monitor:server:list')")
  20 + @GetMapping()
  21 + public AjaxResult getInfo() throws Exception
  22 + {
  23 + Server server = new Server();
  24 + server.copyTo();
  25 + return AjaxResult.success(server);
  26 + }
  27 +}
  1 +package com.ruoyi.web.controller.monitor;
  2 +
  3 +import java.util.List;
  4 +import javax.servlet.http.HttpServletResponse;
  5 +import org.springframework.beans.factory.annotation.Autowired;
  6 +import org.springframework.security.access.prepost.PreAuthorize;
  7 +import org.springframework.web.bind.annotation.DeleteMapping;
  8 +import org.springframework.web.bind.annotation.GetMapping;
  9 +import org.springframework.web.bind.annotation.PathVariable;
  10 +import org.springframework.web.bind.annotation.PostMapping;
  11 +import org.springframework.web.bind.annotation.RequestMapping;
  12 +import org.springframework.web.bind.annotation.RestController;
  13 +import com.ruoyi.common.annotation.Log;
  14 +import com.ruoyi.common.core.controller.BaseController;
  15 +import com.ruoyi.common.core.domain.AjaxResult;
  16 +import com.ruoyi.common.core.page.TableDataInfo;
  17 +import com.ruoyi.common.enums.BusinessType;
  18 +import com.ruoyi.common.utils.poi.ExcelUtil;
  19 +import com.ruoyi.framework.web.service.SysPasswordService;
  20 +import com.ruoyi.system.domain.SysLogininfor;
  21 +import com.ruoyi.system.service.ISysLogininforService;
  22 +
  23 +/**
  24 + * 系统访问记录
  25 + *
  26 + * @author ruoyi
  27 + */
  28 +@RestController
  29 +@RequestMapping("/monitor/logininfor")
  30 +public class SysLogininforController extends BaseController
  31 +{
  32 + @Autowired
  33 + private ISysLogininforService logininforService;
  34 +
  35 + @Autowired
  36 + private SysPasswordService passwordService;
  37 +
  38 + @PreAuthorize("@ss.hasPermi('monitor:logininfor:list')")
  39 + @GetMapping("/list")
  40 + public TableDataInfo list(SysLogininfor logininfor)
  41 + {
  42 + startPage();
  43 + List<SysLogininfor> list = logininforService.selectLogininforList(logininfor);
  44 + return getDataTable(list);
  45 + }
  46 +
  47 + @Log(title = "登录日志", businessType = BusinessType.EXPORT)
  48 + @PreAuthorize("@ss.hasPermi('monitor:logininfor:export')")
  49 + @PostMapping("/export")
  50 + public void export(HttpServletResponse response, SysLogininfor logininfor)
  51 + {
  52 + List<SysLogininfor> list = logininforService.selectLogininforList(logininfor);
  53 + ExcelUtil<SysLogininfor> util = new ExcelUtil<SysLogininfor>(SysLogininfor.class);
  54 + util.exportExcel(response, list, "登录日志");
  55 + }
  56 +
  57 + @PreAuthorize("@ss.hasPermi('monitor:logininfor:remove')")
  58 + @Log(title = "登录日志", businessType = BusinessType.DELETE)
  59 + @DeleteMapping("/{infoIds}")
  60 + public AjaxResult remove(@PathVariable Long[] infoIds)
  61 + {
  62 + return toAjax(logininforService.deleteLogininforByIds(infoIds));
  63 + }
  64 +
  65 + @PreAuthorize("@ss.hasPermi('monitor:logininfor:remove')")
  66 + @Log(title = "登录日志", businessType = BusinessType.CLEAN)
  67 + @DeleteMapping("/clean")
  68 + public AjaxResult clean()
  69 + {
  70 + logininforService.cleanLogininfor();
  71 + return success();
  72 + }
  73 +
  74 + @PreAuthorize("@ss.hasPermi('monitor:logininfor:unlock')")
  75 + @Log(title = "账户解锁", businessType = BusinessType.OTHER)
  76 + @GetMapping("/unlock/{userName}")
  77 + public AjaxResult unlock(@PathVariable("userName") String userName)
  78 + {
  79 + passwordService.clearLoginRecordCache(userName);
  80 + return success();
  81 + }
  82 +}
  1 +package com.ruoyi.web.controller.monitor;
  2 +
  3 +import java.util.List;
  4 +import javax.servlet.http.HttpServletResponse;
  5 +import org.springframework.beans.factory.annotation.Autowired;
  6 +import org.springframework.security.access.prepost.PreAuthorize;
  7 +import org.springframework.web.bind.annotation.DeleteMapping;
  8 +import org.springframework.web.bind.annotation.GetMapping;
  9 +import org.springframework.web.bind.annotation.PathVariable;
  10 +import org.springframework.web.bind.annotation.PostMapping;
  11 +import org.springframework.web.bind.annotation.RequestMapping;
  12 +import org.springframework.web.bind.annotation.RestController;
  13 +import com.ruoyi.common.annotation.Log;
  14 +import com.ruoyi.common.core.controller.BaseController;
  15 +import com.ruoyi.common.core.domain.AjaxResult;
  16 +import com.ruoyi.common.core.page.TableDataInfo;
  17 +import com.ruoyi.common.enums.BusinessType;
  18 +import com.ruoyi.common.utils.poi.ExcelUtil;
  19 +import com.ruoyi.system.domain.SysOperLog;
  20 +import com.ruoyi.system.service.ISysOperLogService;
  21 +
  22 +/**
  23 + * 操作日志记录
  24 + *
  25 + * @author ruoyi
  26 + */
  27 +@RestController
  28 +@RequestMapping("/monitor/operlog")
  29 +public class SysOperlogController extends BaseController
  30 +{
  31 + @Autowired
  32 + private ISysOperLogService operLogService;
  33 +
  34 + @PreAuthorize("@ss.hasPermi('monitor:operlog:list')")
  35 + @GetMapping("/list")
  36 + public TableDataInfo list(SysOperLog operLog)
  37 + {
  38 + startPage();
  39 + List<SysOperLog> list = operLogService.selectOperLogList(operLog);
  40 + return getDataTable(list);
  41 + }
  42 +
  43 + @Log(title = "操作日志", businessType = BusinessType.EXPORT)
  44 + @PreAuthorize("@ss.hasPermi('monitor:operlog:export')")
  45 + @PostMapping("/export")
  46 + public void export(HttpServletResponse response, SysOperLog operLog)
  47 + {
  48 + List<SysOperLog> list = operLogService.selectOperLogList(operLog);
  49 + ExcelUtil<SysOperLog> util = new ExcelUtil<SysOperLog>(SysOperLog.class);
  50 + util.exportExcel(response, list, "操作日志");
  51 + }
  52 +
  53 + @Log(title = "操作日志", businessType = BusinessType.DELETE)
  54 + @PreAuthorize("@ss.hasPermi('monitor:operlog:remove')")
  55 + @DeleteMapping("/{operIds}")
  56 + public AjaxResult remove(@PathVariable Long[] operIds)
  57 + {
  58 + return toAjax(operLogService.deleteOperLogByIds(operIds));
  59 + }
  60 +
  61 + @Log(title = "操作日志", businessType = BusinessType.CLEAN)
  62 + @PreAuthorize("@ss.hasPermi('monitor:operlog:remove')")
  63 + @DeleteMapping("/clean")
  64 + public AjaxResult clean()
  65 + {
  66 + operLogService.cleanOperLog();
  67 + return success();
  68 + }
  69 +}
  1 +package com.ruoyi.web.controller.monitor;
  2 +
  3 +import java.util.ArrayList;
  4 +import java.util.Collection;
  5 +import java.util.Collections;
  6 +import java.util.List;
  7 +import org.springframework.beans.factory.annotation.Autowired;
  8 +import org.springframework.security.access.prepost.PreAuthorize;
  9 +import org.springframework.web.bind.annotation.DeleteMapping;
  10 +import org.springframework.web.bind.annotation.GetMapping;
  11 +import org.springframework.web.bind.annotation.PathVariable;
  12 +import org.springframework.web.bind.annotation.RequestMapping;
  13 +import org.springframework.web.bind.annotation.RestController;
  14 +import com.ruoyi.common.annotation.Log;
  15 +import com.ruoyi.common.constant.CacheConstants;
  16 +import com.ruoyi.common.core.controller.BaseController;
  17 +import com.ruoyi.common.core.domain.AjaxResult;
  18 +import com.ruoyi.common.core.domain.model.LoginUser;
  19 +import com.ruoyi.common.core.page.TableDataInfo;
  20 +import com.ruoyi.common.core.redis.RedisCache;
  21 +import com.ruoyi.common.enums.BusinessType;
  22 +import com.ruoyi.common.utils.StringUtils;
  23 +import com.ruoyi.system.domain.SysUserOnline;
  24 +import com.ruoyi.system.service.ISysUserOnlineService;
  25 +
  26 +/**
  27 + * 在线用户监控
  28 + *
  29 + * @author ruoyi
  30 + */
  31 +@RestController
  32 +@RequestMapping("/monitor/online")
  33 +public class SysUserOnlineController extends BaseController
  34 +{
  35 + @Autowired
  36 + private ISysUserOnlineService userOnlineService;
  37 +
  38 + @Autowired
  39 + private RedisCache redisCache;
  40 +
  41 + @PreAuthorize("@ss.hasPermi('monitor:online:list')")
  42 + @GetMapping("/list")
  43 + public TableDataInfo list(String ipaddr, String userName)
  44 + {
  45 + Collection<String> keys = redisCache.keys(CacheConstants.LOGIN_TOKEN_KEY + "*");
  46 + List<SysUserOnline> userOnlineList = new ArrayList<SysUserOnline>();
  47 + for (String key : keys)
  48 + {
  49 + LoginUser user = redisCache.getCacheObject(key);
  50 + if (StringUtils.isNotEmpty(ipaddr) && StringUtils.isNotEmpty(userName))
  51 + {
  52 + userOnlineList.add(userOnlineService.selectOnlineByInfo(ipaddr, userName, user));
  53 + }
  54 + else if (StringUtils.isNotEmpty(ipaddr))
  55 + {
  56 + userOnlineList.add(userOnlineService.selectOnlineByIpaddr(ipaddr, user));
  57 + }
  58 + else if (StringUtils.isNotEmpty(userName) && StringUtils.isNotNull(user.getUser()))
  59 + {
  60 + userOnlineList.add(userOnlineService.selectOnlineByUserName(userName, user));
  61 + }
  62 + else
  63 + {
  64 + userOnlineList.add(userOnlineService.loginUserToUserOnline(user));
  65 + }
  66 + }
  67 + Collections.reverse(userOnlineList);
  68 + userOnlineList.removeAll(Collections.singleton(null));
  69 + return getDataTable(userOnlineList);
  70 + }
  71 +
  72 + /**
  73 + * 强退用户
  74 + */
  75 + @PreAuthorize("@ss.hasPermi('monitor:online:forceLogout')")
  76 + @Log(title = "在线用户", businessType = BusinessType.FORCE)
  77 + @DeleteMapping("/{tokenId}")
  78 + public AjaxResult forceLogout(@PathVariable String tokenId)
  79 + {
  80 + redisCache.deleteObject(CacheConstants.LOGIN_TOKEN_KEY + tokenId);
  81 + return success();
  82 + }
  83 +}
  1 +package com.ruoyi.web.controller.system;
  2 +
  3 +import java.util.List;
  4 +import javax.servlet.http.HttpServletResponse;
  5 +import org.springframework.beans.factory.annotation.Autowired;
  6 +import org.springframework.security.access.prepost.PreAuthorize;
  7 +import org.springframework.validation.annotation.Validated;
  8 +import org.springframework.web.bind.annotation.DeleteMapping;
  9 +import org.springframework.web.bind.annotation.GetMapping;
  10 +import org.springframework.web.bind.annotation.PathVariable;
  11 +import org.springframework.web.bind.annotation.PostMapping;
  12 +import org.springframework.web.bind.annotation.PutMapping;
  13 +import org.springframework.web.bind.annotation.RequestBody;
  14 +import org.springframework.web.bind.annotation.RequestMapping;
  15 +import org.springframework.web.bind.annotation.RestController;
  16 +import com.ruoyi.common.annotation.Log;
  17 +import com.ruoyi.common.core.controller.BaseController;
  18 +import com.ruoyi.common.core.domain.AjaxResult;
  19 +import com.ruoyi.common.core.page.TableDataInfo;
  20 +import com.ruoyi.common.enums.BusinessType;
  21 +import com.ruoyi.common.utils.poi.ExcelUtil;
  22 +import com.ruoyi.system.domain.SysConfig;
  23 +import com.ruoyi.system.service.ISysConfigService;
  24 +
  25 +/**
  26 + * 参数配置 信息操作处理
  27 + *
  28 + * @author ruoyi
  29 + */
  30 +@RestController
  31 +@RequestMapping("/system/config")
  32 +public class SysConfigController extends BaseController
  33 +{
  34 + @Autowired
  35 + private ISysConfigService configService;
  36 +
  37 + /**
  38 + * 获取参数配置列表
  39 + */
  40 + @PreAuthorize("@ss.hasPermi('system:config:list')")
  41 + @GetMapping("/list")
  42 + public TableDataInfo list(SysConfig config)
  43 + {
  44 + startPage();
  45 + List<SysConfig> list = configService.selectConfigList(config);
  46 + return getDataTable(list);
  47 + }
  48 +
  49 + @Log(title = "参数管理", businessType = BusinessType.EXPORT)
  50 + @PreAuthorize("@ss.hasPermi('system:config:export')")
  51 + @PostMapping("/export")
  52 + public void export(HttpServletResponse response, SysConfig config)
  53 + {
  54 + List<SysConfig> list = configService.selectConfigList(config);
  55 + ExcelUtil<SysConfig> util = new ExcelUtil<SysConfig>(SysConfig.class);
  56 + util.exportExcel(response, list, "参数数据");
  57 + }
  58 +
  59 + /**
  60 + * 根据参数编号获取详细信息
  61 + */
  62 + @PreAuthorize("@ss.hasPermi('system:config:query')")
  63 + @GetMapping(value = "/{configId}")
  64 + public AjaxResult getInfo(@PathVariable Long configId)
  65 + {
  66 + return success(configService.selectConfigById(configId));
  67 + }
  68 +
  69 + /**
  70 + * 根据参数键名查询参数值
  71 + */
  72 + @GetMapping(value = "/configKey/{configKey}")
  73 + public AjaxResult getConfigKey(@PathVariable String configKey)
  74 + {
  75 + return success(configService.selectConfigByKey(configKey));
  76 + }
  77 +
  78 + /**
  79 + * 新增参数配置
  80 + */
  81 + @PreAuthorize("@ss.hasPermi('system:config:add')")
  82 + @Log(title = "参数管理", businessType = BusinessType.INSERT)
  83 + @PostMapping
  84 + public AjaxResult add(@Validated @RequestBody SysConfig config)
  85 + {
  86 + if (!configService.checkConfigKeyUnique(config))
  87 + {
  88 + return error("新增参数'" + config.getConfigName() + "'失败,参数键名已存在");
  89 + }
  90 + config.setCreateBy(getUsername());
  91 + return toAjax(configService.insertConfig(config));
  92 + }
  93 +
  94 + /**
  95 + * 修改参数配置
  96 + */
  97 + @PreAuthorize("@ss.hasPermi('system:config:edit')")
  98 + @Log(title = "参数管理", businessType = BusinessType.UPDATE)
  99 + @PutMapping
  100 + public AjaxResult edit(@Validated @RequestBody SysConfig config)
  101 + {
  102 + if (!configService.checkConfigKeyUnique(config))
  103 + {
  104 + return error("修改参数'" + config.getConfigName() + "'失败,参数键名已存在");
  105 + }
  106 + config.setUpdateBy(getUsername());
  107 + return toAjax(configService.updateConfig(config));
  108 + }
  109 +
  110 + /**
  111 + * 删除参数配置
  112 + */
  113 + @PreAuthorize("@ss.hasPermi('system:config:remove')")
  114 + @Log(title = "参数管理", businessType = BusinessType.DELETE)
  115 + @DeleteMapping("/{configIds}")
  116 + public AjaxResult remove(@PathVariable Long[] configIds)
  117 + {
  118 + configService.deleteConfigByIds(configIds);
  119 + return success();
  120 + }
  121 +
  122 + /**
  123 + * 刷新参数缓存
  124 + */
  125 + @PreAuthorize("@ss.hasPermi('system:config:remove')")
  126 + @Log(title = "参数管理", businessType = BusinessType.CLEAN)
  127 + @DeleteMapping("/refreshCache")
  128 + public AjaxResult refreshCache()
  129 + {
  130 + configService.resetConfigCache();
  131 + return success();
  132 + }
  133 +}
  1 +package com.ruoyi.web.controller.system;
  2 +
  3 +import java.util.List;
  4 +import org.apache.commons.lang3.ArrayUtils;
  5 +import org.springframework.beans.factory.annotation.Autowired;
  6 +import org.springframework.security.access.prepost.PreAuthorize;
  7 +import org.springframework.validation.annotation.Validated;
  8 +import org.springframework.web.bind.annotation.DeleteMapping;
  9 +import org.springframework.web.bind.annotation.GetMapping;
  10 +import org.springframework.web.bind.annotation.PathVariable;
  11 +import org.springframework.web.bind.annotation.PostMapping;
  12 +import org.springframework.web.bind.annotation.PutMapping;
  13 +import org.springframework.web.bind.annotation.RequestBody;
  14 +import org.springframework.web.bind.annotation.RequestMapping;
  15 +import org.springframework.web.bind.annotation.RestController;
  16 +import com.ruoyi.common.annotation.Log;
  17 +import com.ruoyi.common.constant.UserConstants;
  18 +import com.ruoyi.common.core.controller.BaseController;
  19 +import com.ruoyi.common.core.domain.AjaxResult;
  20 +import com.ruoyi.common.core.domain.entity.SysDept;
  21 +import com.ruoyi.common.enums.BusinessType;
  22 +import com.ruoyi.common.utils.StringUtils;
  23 +import com.ruoyi.system.service.ISysDeptService;
  24 +
  25 +/**
  26 + * 部门信息
  27 + *
  28 + * @author ruoyi
  29 + */
  30 +@RestController
  31 +@RequestMapping("/system/dept")
  32 +public class SysDeptController extends BaseController
  33 +{
  34 + @Autowired
  35 + private ISysDeptService deptService;
  36 +
  37 + /**
  38 + * 获取部门列表
  39 + */
  40 + @PreAuthorize("@ss.hasPermi('system:dept:list')")
  41 + @GetMapping("/list")
  42 + public AjaxResult list(SysDept dept)
  43 + {
  44 + List<SysDept> depts = deptService.selectDeptList(dept);
  45 + return success(depts);
  46 + }
  47 +
  48 + /**
  49 + * 查询部门列表(排除节点)
  50 + */
  51 + @PreAuthorize("@ss.hasPermi('system:dept:list')")
  52 + @GetMapping("/list/exclude/{deptId}")
  53 + public AjaxResult excludeChild(@PathVariable(value = "deptId", required = false) Long deptId)
  54 + {
  55 + List<SysDept> depts = deptService.selectDeptList(new SysDept());
  56 + depts.removeIf(d -> d.getDeptId().intValue() == deptId || ArrayUtils.contains(StringUtils.split(d.getAncestors(), ","), deptId + ""));
  57 + return success(depts);
  58 + }
  59 +
  60 + /**
  61 + * 根据部门编号获取详细信息
  62 + */
  63 + @PreAuthorize("@ss.hasPermi('system:dept:query')")
  64 + @GetMapping(value = "/{deptId}")
  65 + public AjaxResult getInfo(@PathVariable Long deptId)
  66 + {
  67 + deptService.checkDeptDataScope(deptId);
  68 + return success(deptService.selectDeptById(deptId));
  69 + }
  70 +
  71 + /**
  72 + * 新增部门
  73 + */
  74 + @PreAuthorize("@ss.hasPermi('system:dept:add')")
  75 + @Log(title = "部门管理", businessType = BusinessType.INSERT)
  76 + @PostMapping
  77 + public AjaxResult add(@Validated @RequestBody SysDept dept)
  78 + {
  79 + if (!deptService.checkDeptNameUnique(dept))
  80 + {
  81 + return error("新增部门'" + dept.getDeptName() + "'失败,部门名称已存在");
  82 + }
  83 + dept.setCreateBy(getUsername());
  84 + return toAjax(deptService.insertDept(dept));
  85 + }
  86 +
  87 + /**
  88 + * 修改部门
  89 + */
  90 + @PreAuthorize("@ss.hasPermi('system:dept:edit')")
  91 + @Log(title = "部门管理", businessType = BusinessType.UPDATE)
  92 + @PutMapping
  93 + public AjaxResult edit(@Validated @RequestBody SysDept dept)
  94 + {
  95 + Long deptId = dept.getDeptId();
  96 + deptService.checkDeptDataScope(deptId);
  97 + if (!deptService.checkDeptNameUnique(dept))
  98 + {
  99 + return error("修改部门'" + dept.getDeptName() + "'失败,部门名称已存在");
  100 + }
  101 + else if (dept.getParentId().equals(deptId))
  102 + {
  103 + return error("修改部门'" + dept.getDeptName() + "'失败,上级部门不能是自己");
  104 + }
  105 + else if (StringUtils.equals(UserConstants.DEPT_DISABLE, dept.getStatus()) && deptService.selectNormalChildrenDeptById(deptId) > 0)
  106 + {
  107 + return error("该部门包含未停用的子部门!");
  108 + }
  109 + dept.setUpdateBy(getUsername());
  110 + return toAjax(deptService.updateDept(dept));
  111 + }
  112 +
  113 + /**
  114 + * 删除部门
  115 + */
  116 + @PreAuthorize("@ss.hasPermi('system:dept:remove')")
  117 + @Log(title = "部门管理", businessType = BusinessType.DELETE)
  118 + @DeleteMapping("/{deptId}")
  119 + public AjaxResult remove(@PathVariable Long deptId)
  120 + {
  121 + if (deptService.hasChildByDeptId(deptId))
  122 + {
  123 + return warn("存在下级部门,不允许删除");
  124 + }
  125 + if (deptService.checkDeptExistUser(deptId))
  126 + {
  127 + return warn("部门存在用户,不允许删除");
  128 + }
  129 + deptService.checkDeptDataScope(deptId);
  130 + return toAjax(deptService.deleteDeptById(deptId));
  131 + }
  132 +}
  1 +package com.ruoyi.web.controller.system;
  2 +
  3 +import java.util.ArrayList;
  4 +import java.util.List;
  5 +import javax.servlet.http.HttpServletResponse;
  6 +import org.springframework.beans.factory.annotation.Autowired;
  7 +import org.springframework.security.access.prepost.PreAuthorize;
  8 +import org.springframework.validation.annotation.Validated;
  9 +import org.springframework.web.bind.annotation.DeleteMapping;
  10 +import org.springframework.web.bind.annotation.GetMapping;
  11 +import org.springframework.web.bind.annotation.PathVariable;
  12 +import org.springframework.web.bind.annotation.PostMapping;
  13 +import org.springframework.web.bind.annotation.PutMapping;
  14 +import org.springframework.web.bind.annotation.RequestBody;
  15 +import org.springframework.web.bind.annotation.RequestMapping;
  16 +import org.springframework.web.bind.annotation.RestController;
  17 +import com.ruoyi.common.annotation.Log;
  18 +import com.ruoyi.common.core.controller.BaseController;
  19 +import com.ruoyi.common.core.domain.AjaxResult;
  20 +import com.ruoyi.common.core.domain.entity.SysDictData;
  21 +import com.ruoyi.common.core.page.TableDataInfo;
  22 +import com.ruoyi.common.enums.BusinessType;
  23 +import com.ruoyi.common.utils.StringUtils;
  24 +import com.ruoyi.common.utils.poi.ExcelUtil;
  25 +import com.ruoyi.system.service.ISysDictDataService;
  26 +import com.ruoyi.system.service.ISysDictTypeService;
  27 +
  28 +/**
  29 + * 数据字典信息
  30 + *
  31 + * @author ruoyi
  32 + */
  33 +@RestController
  34 +@RequestMapping("/system/dict/data")
  35 +public class SysDictDataController extends BaseController
  36 +{
  37 + @Autowired
  38 + private ISysDictDataService dictDataService;
  39 +
  40 + @Autowired
  41 + private ISysDictTypeService dictTypeService;
  42 +
  43 + @PreAuthorize("@ss.hasPermi('system:dict:list')")
  44 + @GetMapping("/list")
  45 + public TableDataInfo list(SysDictData dictData)
  46 + {
  47 + startPage();
  48 + List<SysDictData> list = dictDataService.selectDictDataList(dictData);
  49 + return getDataTable(list);
  50 + }
  51 +
  52 + @Log(title = "字典数据", businessType = BusinessType.EXPORT)
  53 + @PreAuthorize("@ss.hasPermi('system:dict:export')")
  54 + @PostMapping("/export")
  55 + public void export(HttpServletResponse response, SysDictData dictData)
  56 + {
  57 + List<SysDictData> list = dictDataService.selectDictDataList(dictData);
  58 + ExcelUtil<SysDictData> util = new ExcelUtil<SysDictData>(SysDictData.class);
  59 + util.exportExcel(response, list, "字典数据");
  60 + }
  61 +
  62 + /**
  63 + * 查询字典数据详细
  64 + */
  65 + @PreAuthorize("@ss.hasPermi('system:dict:query')")
  66 + @GetMapping(value = "/{dictCode}")
  67 + public AjaxResult getInfo(@PathVariable Long dictCode)
  68 + {
  69 + return success(dictDataService.selectDictDataById(dictCode));
  70 + }
  71 +
  72 + /**
  73 + * 根据字典类型查询字典数据信息
  74 + */
  75 + @GetMapping(value = "/type/{dictType}")
  76 + public AjaxResult dictType(@PathVariable String dictType)
  77 + {
  78 + List<SysDictData> data = dictTypeService.selectDictDataByType(dictType);
  79 + if (StringUtils.isNull(data))
  80 + {
  81 + data = new ArrayList<SysDictData>();
  82 + }
  83 + return success(data);
  84 + }
  85 +
  86 + /**
  87 + * 新增字典类型
  88 + */
  89 + @PreAuthorize("@ss.hasPermi('system:dict:add')")
  90 + @Log(title = "字典数据", businessType = BusinessType.INSERT)
  91 + @PostMapping
  92 + public AjaxResult add(@Validated @RequestBody SysDictData dict)
  93 + {
  94 + dict.setCreateBy(getUsername());
  95 + return toAjax(dictDataService.insertDictData(dict));
  96 + }
  97 +
  98 + /**
  99 + * 修改保存字典类型
  100 + */
  101 + @PreAuthorize("@ss.hasPermi('system:dict:edit')")
  102 + @Log(title = "字典数据", businessType = BusinessType.UPDATE)
  103 + @PutMapping
  104 + public AjaxResult edit(@Validated @RequestBody SysDictData dict)
  105 + {
  106 + dict.setUpdateBy(getUsername());
  107 + return toAjax(dictDataService.updateDictData(dict));
  108 + }
  109 +
  110 + /**
  111 + * 删除字典类型
  112 + */
  113 + @PreAuthorize("@ss.hasPermi('system:dict:remove')")
  114 + @Log(title = "字典类型", businessType = BusinessType.DELETE)
  115 + @DeleteMapping("/{dictCodes}")
  116 + public AjaxResult remove(@PathVariable Long[] dictCodes)
  117 + {
  118 + dictDataService.deleteDictDataByIds(dictCodes);
  119 + return success();
  120 + }
  121 +}
  1 +package com.ruoyi.web.controller.system;
  2 +
  3 +import java.util.List;
  4 +import javax.servlet.http.HttpServletResponse;
  5 +import org.springframework.beans.factory.annotation.Autowired;
  6 +import org.springframework.security.access.prepost.PreAuthorize;
  7 +import org.springframework.validation.annotation.Validated;
  8 +import org.springframework.web.bind.annotation.DeleteMapping;
  9 +import org.springframework.web.bind.annotation.GetMapping;
  10 +import org.springframework.web.bind.annotation.PathVariable;
  11 +import org.springframework.web.bind.annotation.PostMapping;
  12 +import org.springframework.web.bind.annotation.PutMapping;
  13 +import org.springframework.web.bind.annotation.RequestBody;
  14 +import org.springframework.web.bind.annotation.RequestMapping;
  15 +import org.springframework.web.bind.annotation.RestController;
  16 +import com.ruoyi.common.annotation.Log;
  17 +import com.ruoyi.common.core.controller.BaseController;
  18 +import com.ruoyi.common.core.domain.AjaxResult;
  19 +import com.ruoyi.common.core.domain.entity.SysDictType;
  20 +import com.ruoyi.common.core.page.TableDataInfo;
  21 +import com.ruoyi.common.enums.BusinessType;
  22 +import com.ruoyi.common.utils.poi.ExcelUtil;
  23 +import com.ruoyi.system.service.ISysDictTypeService;
  24 +
  25 +/**
  26 + * 数据字典信息
  27 + *
  28 + * @author ruoyi
  29 + */
  30 +@RestController
  31 +@RequestMapping("/system/dict/type")
  32 +public class SysDictTypeController extends BaseController
  33 +{
  34 + @Autowired
  35 + private ISysDictTypeService dictTypeService;
  36 +
  37 + @PreAuthorize("@ss.hasPermi('system:dict:list')")
  38 + @GetMapping("/list")
  39 + public TableDataInfo list(SysDictType dictType)
  40 + {
  41 + startPage();
  42 + List<SysDictType> list = dictTypeService.selectDictTypeList(dictType);
  43 + return getDataTable(list);
  44 + }
  45 +
  46 + @Log(title = "字典类型", businessType = BusinessType.EXPORT)
  47 + @PreAuthorize("@ss.hasPermi('system:dict:export')")
  48 + @PostMapping("/export")
  49 + public void export(HttpServletResponse response, SysDictType dictType)
  50 + {
  51 + List<SysDictType> list = dictTypeService.selectDictTypeList(dictType);
  52 + ExcelUtil<SysDictType> util = new ExcelUtil<SysDictType>(SysDictType.class);
  53 + util.exportExcel(response, list, "字典类型");
  54 + }
  55 +
  56 + /**
  57 + * 查询字典类型详细
  58 + */
  59 + @PreAuthorize("@ss.hasPermi('system:dict:query')")
  60 + @GetMapping(value = "/{dictId}")
  61 + public AjaxResult getInfo(@PathVariable Long dictId)
  62 + {
  63 + return success(dictTypeService.selectDictTypeById(dictId));
  64 + }
  65 +
  66 + /**
  67 + * 新增字典类型
  68 + */
  69 + @PreAuthorize("@ss.hasPermi('system:dict:add')")
  70 + @Log(title = "字典类型", businessType = BusinessType.INSERT)
  71 + @PostMapping
  72 + public AjaxResult add(@Validated @RequestBody SysDictType dict)
  73 + {
  74 + if (!dictTypeService.checkDictTypeUnique(dict))
  75 + {
  76 + return error("新增字典'" + dict.getDictName() + "'失败,字典类型已存在");
  77 + }
  78 + dict.setCreateBy(getUsername());
  79 + return toAjax(dictTypeService.insertDictType(dict));
  80 + }
  81 +
  82 + /**
  83 + * 修改字典类型
  84 + */
  85 + @PreAuthorize("@ss.hasPermi('system:dict:edit')")
  86 + @Log(title = "字典类型", businessType = BusinessType.UPDATE)
  87 + @PutMapping
  88 + public AjaxResult edit(@Validated @RequestBody SysDictType dict)
  89 + {
  90 + if (!dictTypeService.checkDictTypeUnique(dict))
  91 + {
  92 + return error("修改字典'" + dict.getDictName() + "'失败,字典类型已存在");
  93 + }
  94 + dict.setUpdateBy(getUsername());
  95 + return toAjax(dictTypeService.updateDictType(dict));
  96 + }
  97 +
  98 + /**
  99 + * 删除字典类型
  100 + */
  101 + @PreAuthorize("@ss.hasPermi('system:dict:remove')")
  102 + @Log(title = "字典类型", businessType = BusinessType.DELETE)
  103 + @DeleteMapping("/{dictIds}")
  104 + public AjaxResult remove(@PathVariable Long[] dictIds)
  105 + {
  106 + dictTypeService.deleteDictTypeByIds(dictIds);
  107 + return success();
  108 + }
  109 +
  110 + /**
  111 + * 刷新字典缓存
  112 + */
  113 + @PreAuthorize("@ss.hasPermi('system:dict:remove')")
  114 + @Log(title = "字典类型", businessType = BusinessType.CLEAN)
  115 + @DeleteMapping("/refreshCache")
  116 + public AjaxResult refreshCache()
  117 + {
  118 + dictTypeService.resetDictCache();
  119 + return success();
  120 + }
  121 +
  122 + /**
  123 + * 获取字典选择框列表
  124 + */
  125 + @GetMapping("/optionselect")
  126 + public AjaxResult optionselect()
  127 + {
  128 + List<SysDictType> dictTypes = dictTypeService.selectDictTypeAll();
  129 + return success(dictTypes);
  130 + }
  131 +}
  1 +package com.ruoyi.web.controller.system;
  2 +
  3 +import org.springframework.beans.factory.annotation.Autowired;
  4 +import org.springframework.web.bind.annotation.RequestMapping;
  5 +import org.springframework.web.bind.annotation.RestController;
  6 +import com.ruoyi.common.config.RuoYiConfig;
  7 +import com.ruoyi.common.utils.StringUtils;
  8 +
  9 +/**
  10 + * 首页
  11 + *
  12 + * @author ruoyi
  13 + */
  14 +@RestController
  15 +public class SysIndexController
  16 +{
  17 + /** 系统基础配置 */
  18 + @Autowired
  19 + private RuoYiConfig ruoyiConfig;
  20 +
  21 + /**
  22 + * 访问首页,提示语
  23 + */
  24 + @RequestMapping("/")
  25 + public String index()
  26 + {
  27 + return StringUtils.format("欢迎使用{}后台管理框架,当前版本:v{},请通过前端地址访问。", ruoyiConfig.getName(), ruoyiConfig.getVersion());
  28 + }
  29 +}
  1 +package com.ruoyi.web.controller.system;
  2 +
  3 +import java.util.List;
  4 +import java.util.Set;
  5 +import org.springframework.beans.factory.annotation.Autowired;
  6 +import org.springframework.web.bind.annotation.GetMapping;
  7 +import org.springframework.web.bind.annotation.PostMapping;
  8 +import org.springframework.web.bind.annotation.RequestBody;
  9 +import org.springframework.web.bind.annotation.RestController;
  10 +import com.ruoyi.common.constant.Constants;
  11 +import com.ruoyi.common.core.domain.AjaxResult;
  12 +import com.ruoyi.common.core.domain.entity.SysMenu;
  13 +import com.ruoyi.common.core.domain.entity.SysUser;
  14 +import com.ruoyi.common.core.domain.model.LoginBody;
  15 +import com.ruoyi.common.utils.SecurityUtils;
  16 +import com.ruoyi.framework.web.service.SysLoginService;
  17 +import com.ruoyi.framework.web.service.SysPermissionService;
  18 +import com.ruoyi.system.service.ISysMenuService;
  19 +
  20 +/**
  21 + * 登录验证
  22 + *
  23 + * @author ruoyi
  24 + */
  25 +@RestController
  26 +public class SysLoginController
  27 +{
  28 + @Autowired
  29 + private SysLoginService loginService;
  30 +
  31 + @Autowired
  32 + private ISysMenuService menuService;
  33 +
  34 + @Autowired
  35 + private SysPermissionService permissionService;
  36 +
  37 + /**
  38 + * 登录方法
  39 + *
  40 + * @param loginBody 登录信息
  41 + * @return 结果
  42 + */
  43 + @PostMapping("/login")
  44 + public AjaxResult login(@RequestBody LoginBody loginBody)
  45 + {
  46 + AjaxResult ajax = AjaxResult.success();
  47 + // 生成令牌
  48 + String token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(),
  49 + loginBody.getUuid());
  50 + ajax.put(Constants.TOKEN, token);
  51 + return ajax;
  52 + }
  53 +
  54 + /**
  55 + * 获取用户信息
  56 + *
  57 + * @return 用户信息
  58 + */
  59 + @GetMapping("getInfo")
  60 + public AjaxResult getInfo()
  61 + {
  62 + SysUser user = SecurityUtils.getLoginUser().getUser();
  63 + // 角色集合
  64 + Set<String> roles = permissionService.getRolePermission(user);
  65 + // 权限集合
  66 + Set<String> permissions = permissionService.getMenuPermission(user);
  67 + AjaxResult ajax = AjaxResult.success();
  68 + ajax.put("user", user);
  69 + ajax.put("roles", roles);
  70 + ajax.put("permissions", permissions);
  71 + return ajax;
  72 + }
  73 +
  74 + /**
  75 + * 获取路由信息
  76 + *
  77 + * @return 路由信息
  78 + */
  79 + @GetMapping("getRouters")
  80 + public AjaxResult getRouters()
  81 + {
  82 + Long userId = SecurityUtils.getUserId();
  83 + List<SysMenu> menus = menuService.selectMenuTreeByUserId(userId);
  84 + return AjaxResult.success(menuService.buildMenus(menus));
  85 + }
  86 +}
  1 +package com.ruoyi.web.controller.system;
  2 +
  3 +import java.util.List;
  4 +import org.springframework.beans.factory.annotation.Autowired;
  5 +import org.springframework.security.access.prepost.PreAuthorize;
  6 +import org.springframework.validation.annotation.Validated;
  7 +import org.springframework.web.bind.annotation.DeleteMapping;
  8 +import org.springframework.web.bind.annotation.GetMapping;
  9 +import org.springframework.web.bind.annotation.PathVariable;
  10 +import org.springframework.web.bind.annotation.PostMapping;
  11 +import org.springframework.web.bind.annotation.PutMapping;
  12 +import org.springframework.web.bind.annotation.RequestBody;
  13 +import org.springframework.web.bind.annotation.RequestMapping;
  14 +import org.springframework.web.bind.annotation.RestController;
  15 +import com.ruoyi.common.annotation.Log;
  16 +import com.ruoyi.common.constant.UserConstants;
  17 +import com.ruoyi.common.core.controller.BaseController;
  18 +import com.ruoyi.common.core.domain.AjaxResult;
  19 +import com.ruoyi.common.core.domain.entity.SysMenu;
  20 +import com.ruoyi.common.enums.BusinessType;
  21 +import com.ruoyi.common.utils.StringUtils;
  22 +import com.ruoyi.system.service.ISysMenuService;
  23 +
  24 +/**
  25 + * 菜单信息
  26 + *
  27 + * @author ruoyi
  28 + */
  29 +@RestController
  30 +@RequestMapping("/system/menu")
  31 +public class SysMenuController extends BaseController
  32 +{
  33 + @Autowired
  34 + private ISysMenuService menuService;
  35 +
  36 + /**
  37 + * 获取菜单列表
  38 + */
  39 + @PreAuthorize("@ss.hasPermi('system:menu:list')")
  40 + @GetMapping("/list")
  41 + public AjaxResult list(SysMenu menu)
  42 + {
  43 + List<SysMenu> menus = menuService.selectMenuList(menu, getUserId());
  44 + return success(menus);
  45 + }
  46 +
  47 + /**
  48 + * 根据菜单编号获取详细信息
  49 + */
  50 + @PreAuthorize("@ss.hasPermi('system:menu:query')")
  51 + @GetMapping(value = "/{menuId}")
  52 + public AjaxResult getInfo(@PathVariable Long menuId)
  53 + {
  54 + return success(menuService.selectMenuById(menuId));
  55 + }
  56 +
  57 + /**
  58 + * 获取菜单下拉树列表
  59 + */
  60 + @GetMapping("/treeselect")
  61 + public AjaxResult treeselect(SysMenu menu)
  62 + {
  63 + List<SysMenu> menus = menuService.selectMenuList(menu, getUserId());
  64 + return success(menuService.buildMenuTreeSelect(menus));
  65 + }
  66 +
  67 + /**
  68 + * 加载对应角色菜单列表树
  69 + */
  70 + @GetMapping(value = "/roleMenuTreeselect/{roleId}")
  71 + public AjaxResult roleMenuTreeselect(@PathVariable("roleId") Long roleId)
  72 + {
  73 + List<SysMenu> menus = menuService.selectMenuList(getUserId());
  74 + AjaxResult ajax = AjaxResult.success();
  75 + ajax.put("checkedKeys", menuService.selectMenuListByRoleId(roleId));
  76 + ajax.put("menus", menuService.buildMenuTreeSelect(menus));
  77 + return ajax;
  78 + }
  79 +
  80 + /**
  81 + * 新增菜单
  82 + */
  83 + @PreAuthorize("@ss.hasPermi('system:menu:add')")
  84 + @Log(title = "菜单管理", businessType = BusinessType.INSERT)
  85 + @PostMapping
  86 + public AjaxResult add(@Validated @RequestBody SysMenu menu)
  87 + {
  88 + if (!menuService.checkMenuNameUnique(menu))
  89 + {
  90 + return error("新增菜单'" + menu.getMenuName() + "'失败,菜单名称已存在");
  91 + }
  92 + else if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath()))
  93 + {
  94 + return error("新增菜单'" + menu.getMenuName() + "'失败,地址必须以http(s)://开头");
  95 + }
  96 + menu.setCreateBy(getUsername());
  97 + return toAjax(menuService.insertMenu(menu));
  98 + }
  99 +
  100 + /**
  101 + * 修改菜单
  102 + */
  103 + @PreAuthorize("@ss.hasPermi('system:menu:edit')")
  104 + @Log(title = "菜单管理", businessType = BusinessType.UPDATE)
  105 + @PutMapping
  106 + public AjaxResult edit(@Validated @RequestBody SysMenu menu)
  107 + {
  108 + if (!menuService.checkMenuNameUnique(menu))
  109 + {
  110 + return error("修改菜单'" + menu.getMenuName() + "'失败,菜单名称已存在");
  111 + }
  112 + else if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath()))
  113 + {
  114 + return error("修改菜单'" + menu.getMenuName() + "'失败,地址必须以http(s)://开头");
  115 + }
  116 + else if (menu.getMenuId().equals(menu.getParentId()))
  117 + {
  118 + return error("修改菜单'" + menu.getMenuName() + "'失败,上级菜单不能选择自己");
  119 + }
  120 + menu.setUpdateBy(getUsername());
  121 + return toAjax(menuService.updateMenu(menu));
  122 + }
  123 +
  124 + /**
  125 + * 删除菜单
  126 + */
  127 + @PreAuthorize("@ss.hasPermi('system:menu:remove')")
  128 + @Log(title = "菜单管理", businessType = BusinessType.DELETE)
  129 + @DeleteMapping("/{menuId}")
  130 + public AjaxResult remove(@PathVariable("menuId") Long menuId)
  131 + {
  132 + if (menuService.hasChildByMenuId(menuId))
  133 + {
  134 + return warn("存在子菜单,不允许删除");
  135 + }
  136 + if (menuService.checkMenuExistRole(menuId))
  137 + {
  138 + return warn("菜单已分配,不允许删除");
  139 + }
  140 + return toAjax(menuService.deleteMenuById(menuId));
  141 + }
  142 +}
  1 +package com.ruoyi.web.controller.system;
  2 +
  3 +import java.util.List;
  4 +import org.springframework.beans.factory.annotation.Autowired;
  5 +import org.springframework.security.access.prepost.PreAuthorize;
  6 +import org.springframework.validation.annotation.Validated;
  7 +import org.springframework.web.bind.annotation.DeleteMapping;
  8 +import org.springframework.web.bind.annotation.GetMapping;
  9 +import org.springframework.web.bind.annotation.PathVariable;
  10 +import org.springframework.web.bind.annotation.PostMapping;
  11 +import org.springframework.web.bind.annotation.PutMapping;
  12 +import org.springframework.web.bind.annotation.RequestBody;
  13 +import org.springframework.web.bind.annotation.RequestMapping;
  14 +import org.springframework.web.bind.annotation.RestController;
  15 +import com.ruoyi.common.annotation.Log;
  16 +import com.ruoyi.common.core.controller.BaseController;
  17 +import com.ruoyi.common.core.domain.AjaxResult;
  18 +import com.ruoyi.common.core.page.TableDataInfo;
  19 +import com.ruoyi.common.enums.BusinessType;
  20 +import com.ruoyi.system.domain.SysNotice;
  21 +import com.ruoyi.system.service.ISysNoticeService;
  22 +
  23 +/**
  24 + * 公告 信息操作处理
  25 + *
  26 + * @author ruoyi
  27 + */
  28 +@RestController
  29 +@RequestMapping("/system/notice")
  30 +public class SysNoticeController extends BaseController
  31 +{
  32 + @Autowired
  33 + private ISysNoticeService noticeService;
  34 +
  35 + /**
  36 + * 获取通知公告列表
  37 + */
  38 + @PreAuthorize("@ss.hasPermi('system:notice:list')")
  39 + @GetMapping("/list")
  40 + public TableDataInfo list(SysNotice notice)
  41 + {
  42 + startPage();
  43 + List<SysNotice> list = noticeService.selectNoticeList(notice);
  44 + return getDataTable(list);
  45 + }
  46 +
  47 + /**
  48 + * 根据通知公告编号获取详细信息
  49 + */
  50 + @PreAuthorize("@ss.hasPermi('system:notice:query')")
  51 + @GetMapping(value = "/{noticeId}")
  52 + public AjaxResult getInfo(@PathVariable Long noticeId)
  53 + {
  54 + return success(noticeService.selectNoticeById(noticeId));
  55 + }
  56 +
  57 + /**
  58 + * 新增通知公告
  59 + */
  60 + @PreAuthorize("@ss.hasPermi('system:notice:add')")
  61 + @Log(title = "通知公告", businessType = BusinessType.INSERT)
  62 + @PostMapping
  63 + public AjaxResult add(@Validated @RequestBody SysNotice notice)
  64 + {
  65 + notice.setCreateBy(getUsername());
  66 + return toAjax(noticeService.insertNotice(notice));
  67 + }
  68 +
  69 + /**
  70 + * 修改通知公告
  71 + */
  72 + @PreAuthorize("@ss.hasPermi('system:notice:edit')")
  73 + @Log(title = "通知公告", businessType = BusinessType.UPDATE)
  74 + @PutMapping
  75 + public AjaxResult edit(@Validated @RequestBody SysNotice notice)
  76 + {
  77 + notice.setUpdateBy(getUsername());
  78 + return toAjax(noticeService.updateNotice(notice));
  79 + }
  80 +
  81 + /**
  82 + * 删除通知公告
  83 + */
  84 + @PreAuthorize("@ss.hasPermi('system:notice:remove')")
  85 + @Log(title = "通知公告", businessType = BusinessType.DELETE)
  86 + @DeleteMapping("/{noticeIds}")
  87 + public AjaxResult remove(@PathVariable Long[] noticeIds)
  88 + {
  89 + return toAjax(noticeService.deleteNoticeByIds(noticeIds));
  90 + }
  91 +}
  1 +package com.ruoyi.web.controller.system;
  2 +
  3 +import java.util.List;
  4 +import javax.servlet.http.HttpServletResponse;
  5 +import org.springframework.beans.factory.annotation.Autowired;
  6 +import org.springframework.security.access.prepost.PreAuthorize;
  7 +import org.springframework.validation.annotation.Validated;
  8 +import org.springframework.web.bind.annotation.DeleteMapping;
  9 +import org.springframework.web.bind.annotation.GetMapping;
  10 +import org.springframework.web.bind.annotation.PathVariable;
  11 +import org.springframework.web.bind.annotation.PostMapping;
  12 +import org.springframework.web.bind.annotation.PutMapping;
  13 +import org.springframework.web.bind.annotation.RequestBody;
  14 +import org.springframework.web.bind.annotation.RequestMapping;
  15 +import org.springframework.web.bind.annotation.RestController;
  16 +import com.ruoyi.common.annotation.Log;
  17 +import com.ruoyi.common.core.controller.BaseController;
  18 +import com.ruoyi.common.core.domain.AjaxResult;
  19 +import com.ruoyi.common.core.page.TableDataInfo;
  20 +import com.ruoyi.common.enums.BusinessType;
  21 +import com.ruoyi.common.utils.poi.ExcelUtil;
  22 +import com.ruoyi.system.domain.SysPost;
  23 +import com.ruoyi.system.service.ISysPostService;
  24 +
  25 +/**
  26 + * 岗位信息操作处理
  27 + *
  28 + * @author ruoyi
  29 + */
  30 +@RestController
  31 +@RequestMapping("/system/post")
  32 +public class SysPostController extends BaseController
  33 +{
  34 + @Autowired
  35 + private ISysPostService postService;
  36 +
  37 + /**
  38 + * 获取岗位列表
  39 + */
  40 + @PreAuthorize("@ss.hasPermi('system:post:list')")
  41 + @GetMapping("/list")
  42 + public TableDataInfo list(SysPost post)
  43 + {
  44 + startPage();
  45 + List<SysPost> list = postService.selectPostList(post);
  46 + return getDataTable(list);
  47 + }
  48 +
  49 + @Log(title = "岗位管理", businessType = BusinessType.EXPORT)
  50 + @PreAuthorize("@ss.hasPermi('system:post:export')")
  51 + @PostMapping("/export")
  52 + public void export(HttpServletResponse response, SysPost post)
  53 + {
  54 + List<SysPost> list = postService.selectPostList(post);
  55 + ExcelUtil<SysPost> util = new ExcelUtil<SysPost>(SysPost.class);
  56 + util.exportExcel(response, list, "岗位数据");
  57 + }
  58 +
  59 + /**
  60 + * 根据岗位编号获取详细信息
  61 + */
  62 + @PreAuthorize("@ss.hasPermi('system:post:query')")
  63 + @GetMapping(value = "/{postId}")
  64 + public AjaxResult getInfo(@PathVariable Long postId)
  65 + {
  66 + return success(postService.selectPostById(postId));
  67 + }
  68 +
  69 + /**
  70 + * 新增岗位
  71 + */
  72 + @PreAuthorize("@ss.hasPermi('system:post:add')")
  73 + @Log(title = "岗位管理", businessType = BusinessType.INSERT)
  74 + @PostMapping
  75 + public AjaxResult add(@Validated @RequestBody SysPost post)
  76 + {
  77 + if (!postService.checkPostNameUnique(post))
  78 + {
  79 + return error("新增岗位'" + post.getPostName() + "'失败,岗位名称已存在");
  80 + }
  81 + else if (!postService.checkPostCodeUnique(post))
  82 + {
  83 + return error("新增岗位'" + post.getPostName() + "'失败,岗位编码已存在");
  84 + }
  85 + post.setCreateBy(getUsername());
  86 + return toAjax(postService.insertPost(post));
  87 + }
  88 +
  89 + /**
  90 + * 修改岗位
  91 + */
  92 + @PreAuthorize("@ss.hasPermi('system:post:edit')")
  93 + @Log(title = "岗位管理", businessType = BusinessType.UPDATE)
  94 + @PutMapping
  95 + public AjaxResult edit(@Validated @RequestBody SysPost post)
  96 + {
  97 + if (!postService.checkPostNameUnique(post))
  98 + {
  99 + return error("修改岗位'" + post.getPostName() + "'失败,岗位名称已存在");
  100 + }
  101 + else if (!postService.checkPostCodeUnique(post))
  102 + {
  103 + return error("修改岗位'" + post.getPostName() + "'失败,岗位编码已存在");
  104 + }
  105 + post.setUpdateBy(getUsername());
  106 + return toAjax(postService.updatePost(post));
  107 + }
  108 +
  109 + /**
  110 + * 删除岗位
  111 + */
  112 + @PreAuthorize("@ss.hasPermi('system:post:remove')")
  113 + @Log(title = "岗位管理", businessType = BusinessType.DELETE)
  114 + @DeleteMapping("/{postIds}")
  115 + public AjaxResult remove(@PathVariable Long[] postIds)
  116 + {
  117 + return toAjax(postService.deletePostByIds(postIds));
  118 + }
  119 +
  120 + /**
  121 + * 获取岗位选择框列表
  122 + */
  123 + @GetMapping("/optionselect")
  124 + public AjaxResult optionselect()
  125 + {
  126 + List<SysPost> posts = postService.selectPostAll();
  127 + return success(posts);
  128 + }
  129 +}
  1 +package com.ruoyi.web.controller.system;
  2 +
  3 +import org.springframework.beans.factory.annotation.Autowired;
  4 +import org.springframework.web.bind.annotation.GetMapping;
  5 +import org.springframework.web.bind.annotation.PostMapping;
  6 +import org.springframework.web.bind.annotation.PutMapping;
  7 +import org.springframework.web.bind.annotation.RequestBody;
  8 +import org.springframework.web.bind.annotation.RequestMapping;
  9 +import org.springframework.web.bind.annotation.RequestParam;
  10 +import org.springframework.web.bind.annotation.RestController;
  11 +import org.springframework.web.multipart.MultipartFile;
  12 +import com.ruoyi.common.annotation.Log;
  13 +import com.ruoyi.common.config.RuoYiConfig;
  14 +import com.ruoyi.common.core.controller.BaseController;
  15 +import com.ruoyi.common.core.domain.AjaxResult;
  16 +import com.ruoyi.common.core.domain.entity.SysUser;
  17 +import com.ruoyi.common.core.domain.model.LoginUser;
  18 +import com.ruoyi.common.enums.BusinessType;
  19 +import com.ruoyi.common.utils.SecurityUtils;
  20 +import com.ruoyi.common.utils.StringUtils;
  21 +import com.ruoyi.common.utils.file.FileUploadUtils;
  22 +import com.ruoyi.common.utils.file.MimeTypeUtils;
  23 +import com.ruoyi.framework.web.service.TokenService;
  24 +import com.ruoyi.system.service.ISysUserService;
  25 +
  26 +/**
  27 + * 个人信息 业务处理
  28 + *
  29 + * @author ruoyi
  30 + */
  31 +@RestController
  32 +@RequestMapping("/system/user/profile")
  33 +public class SysProfileController extends BaseController
  34 +{
  35 + @Autowired
  36 + private ISysUserService userService;
  37 +
  38 + @Autowired
  39 + private TokenService tokenService;
  40 +
  41 + /**
  42 + * 个人信息
  43 + */
  44 + @GetMapping
  45 + public AjaxResult profile()
  46 + {
  47 + LoginUser loginUser = getLoginUser();
  48 + SysUser user = loginUser.getUser();
  49 + AjaxResult ajax = AjaxResult.success(user);
  50 + ajax.put("roleGroup", userService.selectUserRoleGroup(loginUser.getUsername()));
  51 + ajax.put("postGroup", userService.selectUserPostGroup(loginUser.getUsername()));
  52 + return ajax;
  53 + }
  54 +
  55 + /**
  56 + * 修改用户
  57 + */
  58 + @Log(title = "个人信息", businessType = BusinessType.UPDATE)
  59 + @PutMapping
  60 + public AjaxResult updateProfile(@RequestBody SysUser user)
  61 + {
  62 + LoginUser loginUser = getLoginUser();
  63 + SysUser currentUser = loginUser.getUser();
  64 + currentUser.setNickName(user.getNickName());
  65 + currentUser.setEmail(user.getEmail());
  66 + currentUser.setPhonenumber(user.getPhonenumber());
  67 + currentUser.setSex(user.getSex());
  68 + if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(currentUser))
  69 + {
  70 + return error("修改用户'" + loginUser.getUsername() + "'失败,手机号码已存在");
  71 + }
  72 + if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(currentUser))
  73 + {
  74 + return error("修改用户'" + loginUser.getUsername() + "'失败,邮箱账号已存在");
  75 + }
  76 + if (userService.updateUserProfile(currentUser) > 0)
  77 + {
  78 + // 更新缓存用户信息
  79 + tokenService.setLoginUser(loginUser);
  80 + return success();
  81 + }
  82 + return error("修改个人信息异常,请联系管理员");
  83 + }
  84 +
  85 + /**
  86 + * 重置密码
  87 + */
  88 + @Log(title = "个人信息", businessType = BusinessType.UPDATE)
  89 + @PutMapping("/updatePwd")
  90 + public AjaxResult updatePwd(String oldPassword, String newPassword)
  91 + {
  92 + LoginUser loginUser = getLoginUser();
  93 + String userName = loginUser.getUsername();
  94 + String password = loginUser.getPassword();
  95 + if (!SecurityUtils.matchesPassword(oldPassword, password))
  96 + {
  97 + return error("修改密码失败,旧密码错误");
  98 + }
  99 + if (SecurityUtils.matchesPassword(newPassword, password))
  100 + {
  101 + return error("新密码不能与旧密码相同");
  102 + }
  103 + newPassword = SecurityUtils.encryptPassword(newPassword);
  104 + if (userService.resetUserPwd(userName, newPassword) > 0)
  105 + {
  106 + // 更新缓存用户密码
  107 + loginUser.getUser().setPassword(newPassword);
  108 + tokenService.setLoginUser(loginUser);
  109 + return success();
  110 + }
  111 + return error("修改密码异常,请联系管理员");
  112 + }
  113 +
  114 + /**
  115 + * 头像上传
  116 + */
  117 + @Log(title = "用户头像", businessType = BusinessType.UPDATE)
  118 + @PostMapping("/avatar")
  119 + public AjaxResult avatar(@RequestParam("avatarfile") MultipartFile file) throws Exception
  120 + {
  121 + if (!file.isEmpty())
  122 + {
  123 + LoginUser loginUser = getLoginUser();
  124 + String avatar = FileUploadUtils.upload(RuoYiConfig.getAvatarPath(), file, MimeTypeUtils.IMAGE_EXTENSION);
  125 + if (userService.updateUserAvatar(loginUser.getUsername(), avatar))
  126 + {
  127 + AjaxResult ajax = AjaxResult.success();
  128 + ajax.put("imgUrl", avatar);
  129 + // 更新缓存用户头像
  130 + loginUser.getUser().setAvatar(avatar);
  131 + tokenService.setLoginUser(loginUser);
  132 + return ajax;
  133 + }
  134 + }
  135 + return error("上传图片异常,请联系管理员");
  136 + }
  137 +}
  1 +package com.ruoyi.web.controller.system;
  2 +
  3 +import org.springframework.beans.factory.annotation.Autowired;
  4 +import org.springframework.web.bind.annotation.PostMapping;
  5 +import org.springframework.web.bind.annotation.RequestBody;
  6 +import org.springframework.web.bind.annotation.RestController;
  7 +import com.ruoyi.common.core.controller.BaseController;
  8 +import com.ruoyi.common.core.domain.AjaxResult;
  9 +import com.ruoyi.common.core.domain.model.RegisterBody;
  10 +import com.ruoyi.common.utils.StringUtils;
  11 +import com.ruoyi.framework.web.service.SysRegisterService;
  12 +import com.ruoyi.system.service.ISysConfigService;
  13 +
  14 +/**
  15 + * 注册验证
  16 + *
  17 + * @author ruoyi
  18 + */
  19 +@RestController
  20 +public class SysRegisterController extends BaseController
  21 +{
  22 + @Autowired
  23 + private SysRegisterService registerService;
  24 +
  25 + @Autowired
  26 + private ISysConfigService configService;
  27 +
  28 + @PostMapping("/register")
  29 + public AjaxResult register(@RequestBody RegisterBody user)
  30 + {
  31 + if (!("true".equals(configService.selectConfigByKey("sys.account.registerUser"))))
  32 + {
  33 + return error("当前系统没有开启注册功能!");
  34 + }
  35 + String msg = registerService.register(user);
  36 + return StringUtils.isEmpty(msg) ? success() : error(msg);
  37 + }
  38 +}
  1 +package com.ruoyi.web.controller.system;
  2 +
  3 +import java.util.List;
  4 +import javax.servlet.http.HttpServletResponse;
  5 +import org.springframework.beans.factory.annotation.Autowired;
  6 +import org.springframework.security.access.prepost.PreAuthorize;
  7 +import org.springframework.validation.annotation.Validated;
  8 +import org.springframework.web.bind.annotation.DeleteMapping;
  9 +import org.springframework.web.bind.annotation.GetMapping;
  10 +import org.springframework.web.bind.annotation.PathVariable;
  11 +import org.springframework.web.bind.annotation.PostMapping;
  12 +import org.springframework.web.bind.annotation.PutMapping;
  13 +import org.springframework.web.bind.annotation.RequestBody;
  14 +import org.springframework.web.bind.annotation.RequestMapping;
  15 +import org.springframework.web.bind.annotation.RestController;
  16 +import com.ruoyi.common.annotation.Log;
  17 +import com.ruoyi.common.core.controller.BaseController;
  18 +import com.ruoyi.common.core.domain.AjaxResult;
  19 +import com.ruoyi.common.core.domain.entity.SysDept;
  20 +import com.ruoyi.common.core.domain.entity.SysRole;
  21 +import com.ruoyi.common.core.domain.entity.SysUser;
  22 +import com.ruoyi.common.core.domain.model.LoginUser;
  23 +import com.ruoyi.common.core.page.TableDataInfo;
  24 +import com.ruoyi.common.enums.BusinessType;
  25 +import com.ruoyi.common.utils.StringUtils;
  26 +import com.ruoyi.common.utils.poi.ExcelUtil;
  27 +import com.ruoyi.framework.web.service.SysPermissionService;
  28 +import com.ruoyi.framework.web.service.TokenService;
  29 +import com.ruoyi.system.domain.SysUserRole;
  30 +import com.ruoyi.system.service.ISysDeptService;
  31 +import com.ruoyi.system.service.ISysRoleService;
  32 +import com.ruoyi.system.service.ISysUserService;
  33 +
  34 +/**
  35 + * 角色信息
  36 + *
  37 + * @author ruoyi
  38 + */
  39 +@RestController
  40 +@RequestMapping("/system/role")
  41 +public class SysRoleController extends BaseController
  42 +{
  43 + @Autowired
  44 + private ISysRoleService roleService;
  45 +
  46 + @Autowired
  47 + private TokenService tokenService;
  48 +
  49 + @Autowired
  50 + private SysPermissionService permissionService;
  51 +
  52 + @Autowired
  53 + private ISysUserService userService;
  54 +
  55 + @Autowired
  56 + private ISysDeptService deptService;
  57 +
  58 + @PreAuthorize("@ss.hasPermi('system:role:list')")
  59 + @GetMapping("/list")
  60 + public TableDataInfo list(SysRole role)
  61 + {
  62 + startPage();
  63 + List<SysRole> list = roleService.selectRoleList(role);
  64 + return getDataTable(list);
  65 + }
  66 +
  67 + @Log(title = "角色管理", businessType = BusinessType.EXPORT)
  68 + @PreAuthorize("@ss.hasPermi('system:role:export')")
  69 + @PostMapping("/export")
  70 + public void export(HttpServletResponse response, SysRole role)
  71 + {
  72 + List<SysRole> list = roleService.selectRoleList(role);
  73 + ExcelUtil<SysRole> util = new ExcelUtil<SysRole>(SysRole.class);
  74 + util.exportExcel(response, list, "角色数据");
  75 + }
  76 +
  77 + /**
  78 + * 根据角色编号获取详细信息
  79 + */
  80 + @PreAuthorize("@ss.hasPermi('system:role:query')")
  81 + @GetMapping(value = "/{roleId}")
  82 + public AjaxResult getInfo(@PathVariable Long roleId)
  83 + {
  84 + roleService.checkRoleDataScope(roleId);
  85 + return success(roleService.selectRoleById(roleId));
  86 + }
  87 +
  88 + /**
  89 + * 新增角色
  90 + */
  91 + @PreAuthorize("@ss.hasPermi('system:role:add')")
  92 + @Log(title = "角色管理", businessType = BusinessType.INSERT)
  93 + @PostMapping
  94 + public AjaxResult add(@Validated @RequestBody SysRole role)
  95 + {
  96 + if (!roleService.checkRoleNameUnique(role))
  97 + {
  98 + return error("新增角色'" + role.getRoleName() + "'失败,角色名称已存在");
  99 + }
  100 + else if (!roleService.checkRoleKeyUnique(role))
  101 + {
  102 + return error("新增角色'" + role.getRoleName() + "'失败,角色权限已存在");
  103 + }
  104 + role.setCreateBy(getUsername());
  105 + return toAjax(roleService.insertRole(role));
  106 +
  107 + }
  108 +
  109 + /**
  110 + * 修改保存角色
  111 + */
  112 + @PreAuthorize("@ss.hasPermi('system:role:edit')")
  113 + @Log(title = "角色管理", businessType = BusinessType.UPDATE)
  114 + @PutMapping
  115 + public AjaxResult edit(@Validated @RequestBody SysRole role)
  116 + {
  117 + roleService.checkRoleAllowed(role);
  118 + roleService.checkRoleDataScope(role.getRoleId());
  119 + if (!roleService.checkRoleNameUnique(role))
  120 + {
  121 + return error("修改角色'" + role.getRoleName() + "'失败,角色名称已存在");
  122 + }
  123 + else if (!roleService.checkRoleKeyUnique(role))
  124 + {
  125 + return error("修改角色'" + role.getRoleName() + "'失败,角色权限已存在");
  126 + }
  127 + role.setUpdateBy(getUsername());
  128 +
  129 + if (roleService.updateRole(role) > 0)
  130 + {
  131 + // 更新缓存用户权限
  132 + LoginUser loginUser = getLoginUser();
  133 + if (StringUtils.isNotNull(loginUser.getUser()) && !loginUser.getUser().isAdmin())
  134 + {
  135 + loginUser.setPermissions(permissionService.getMenuPermission(loginUser.getUser()));
  136 + loginUser.setUser(userService.selectUserByUserName(loginUser.getUser().getUserName()));
  137 + tokenService.setLoginUser(loginUser);
  138 + }
  139 + return success();
  140 + }
  141 + return error("修改角色'" + role.getRoleName() + "'失败,请联系管理员");
  142 + }
  143 +
  144 + /**
  145 + * 修改保存数据权限
  146 + */
  147 + @PreAuthorize("@ss.hasPermi('system:role:edit')")
  148 + @Log(title = "角色管理", businessType = BusinessType.UPDATE)
  149 + @PutMapping("/dataScope")
  150 + public AjaxResult dataScope(@RequestBody SysRole role)
  151 + {
  152 + roleService.checkRoleAllowed(role);
  153 + roleService.checkRoleDataScope(role.getRoleId());
  154 + return toAjax(roleService.authDataScope(role));
  155 + }
  156 +
  157 + /**
  158 + * 状态修改
  159 + */
  160 + @PreAuthorize("@ss.hasPermi('system:role:edit')")
  161 + @Log(title = "角色管理", businessType = BusinessType.UPDATE)
  162 + @PutMapping("/changeStatus")
  163 + public AjaxResult changeStatus(@RequestBody SysRole role)
  164 + {
  165 + roleService.checkRoleAllowed(role);
  166 + roleService.checkRoleDataScope(role.getRoleId());
  167 + role.setUpdateBy(getUsername());
  168 + return toAjax(roleService.updateRoleStatus(role));
  169 + }
  170 +
  171 + /**
  172 + * 删除角色
  173 + */
  174 + @PreAuthorize("@ss.hasPermi('system:role:remove')")
  175 + @Log(title = "角色管理", businessType = BusinessType.DELETE)
  176 + @DeleteMapping("/{roleIds}")
  177 + public AjaxResult remove(@PathVariable Long[] roleIds)
  178 + {
  179 + return toAjax(roleService.deleteRoleByIds(roleIds));
  180 + }
  181 +
  182 + /**
  183 + * 获取角色选择框列表
  184 + */
  185 + @PreAuthorize("@ss.hasPermi('system:role:query')")
  186 + @GetMapping("/optionselect")
  187 + public AjaxResult optionselect()
  188 + {
  189 + return success(roleService.selectRoleAll());
  190 + }
  191 +
  192 + /**
  193 + * 查询已分配用户角色列表
  194 + */
  195 + @PreAuthorize("@ss.hasPermi('system:role:list')")
  196 + @GetMapping("/authUser/allocatedList")
  197 + public TableDataInfo allocatedList(SysUser user)
  198 + {
  199 + startPage();
  200 + List<SysUser> list = userService.selectAllocatedList(user);
  201 + return getDataTable(list);
  202 + }
  203 +
  204 + /**
  205 + * 查询未分配用户角色列表
  206 + */
  207 + @PreAuthorize("@ss.hasPermi('system:role:list')")
  208 + @GetMapping("/authUser/unallocatedList")
  209 + public TableDataInfo unallocatedList(SysUser user)
  210 + {
  211 + startPage();
  212 + List<SysUser> list = userService.selectUnallocatedList(user);
  213 + return getDataTable(list);
  214 + }
  215 +
  216 + /**
  217 + * 取消授权用户
  218 + */
  219 + @PreAuthorize("@ss.hasPermi('system:role:edit')")
  220 + @Log(title = "角色管理", businessType = BusinessType.GRANT)
  221 + @PutMapping("/authUser/cancel")
  222 + public AjaxResult cancelAuthUser(@RequestBody SysUserRole userRole)
  223 + {
  224 + return toAjax(roleService.deleteAuthUser(userRole));
  225 + }
  226 +
  227 + /**
  228 + * 批量取消授权用户
  229 + */
  230 + @PreAuthorize("@ss.hasPermi('system:role:edit')")
  231 + @Log(title = "角色管理", businessType = BusinessType.GRANT)
  232 + @PutMapping("/authUser/cancelAll")
  233 + public AjaxResult cancelAuthUserAll(Long roleId, Long[] userIds)
  234 + {
  235 + return toAjax(roleService.deleteAuthUsers(roleId, userIds));
  236 + }
  237 +
  238 + /**
  239 + * 批量选择用户授权
  240 + */
  241 + @PreAuthorize("@ss.hasPermi('system:role:edit')")
  242 + @Log(title = "角色管理", businessType = BusinessType.GRANT)
  243 + @PutMapping("/authUser/selectAll")
  244 + public AjaxResult selectAuthUserAll(Long roleId, Long[] userIds)
  245 + {
  246 + roleService.checkRoleDataScope(roleId);
  247 + return toAjax(roleService.insertAuthUsers(roleId, userIds));
  248 + }
  249 +
  250 + /**
  251 + * 获取对应角色部门树列表
  252 + */
  253 + @PreAuthorize("@ss.hasPermi('system:role:query')")
  254 + @GetMapping(value = "/deptTree/{roleId}")
  255 + public AjaxResult deptTree(@PathVariable("roleId") Long roleId)
  256 + {
  257 + AjaxResult ajax = AjaxResult.success();
  258 + ajax.put("checkedKeys", deptService.selectDeptListByRoleId(roleId));
  259 + ajax.put("depts", deptService.selectDeptTreeList(new SysDept()));
  260 + return ajax;
  261 + }
  262 +}
  1 +package com.ruoyi.web.controller.system;
  2 +
  3 +import java.util.List;
  4 +import java.util.stream.Collectors;
  5 +import javax.servlet.http.HttpServletResponse;
  6 +import org.apache.commons.lang3.ArrayUtils;
  7 +import org.springframework.beans.factory.annotation.Autowired;
  8 +import org.springframework.security.access.prepost.PreAuthorize;
  9 +import org.springframework.validation.annotation.Validated;
  10 +import org.springframework.web.bind.annotation.DeleteMapping;
  11 +import org.springframework.web.bind.annotation.GetMapping;
  12 +import org.springframework.web.bind.annotation.PathVariable;
  13 +import org.springframework.web.bind.annotation.PostMapping;
  14 +import org.springframework.web.bind.annotation.PutMapping;
  15 +import org.springframework.web.bind.annotation.RequestBody;
  16 +import org.springframework.web.bind.annotation.RequestMapping;
  17 +import org.springframework.web.bind.annotation.RestController;
  18 +import org.springframework.web.multipart.MultipartFile;
  19 +import com.ruoyi.common.annotation.Log;
  20 +import com.ruoyi.common.core.controller.BaseController;
  21 +import com.ruoyi.common.core.domain.AjaxResult;
  22 +import com.ruoyi.common.core.domain.entity.SysDept;
  23 +import com.ruoyi.common.core.domain.entity.SysRole;
  24 +import com.ruoyi.common.core.domain.entity.SysUser;
  25 +import com.ruoyi.common.core.page.TableDataInfo;
  26 +import com.ruoyi.common.enums.BusinessType;
  27 +import com.ruoyi.common.utils.SecurityUtils;
  28 +import com.ruoyi.common.utils.StringUtils;
  29 +import com.ruoyi.common.utils.poi.ExcelUtil;
  30 +import com.ruoyi.system.service.ISysDeptService;
  31 +import com.ruoyi.system.service.ISysPostService;
  32 +import com.ruoyi.system.service.ISysRoleService;
  33 +import com.ruoyi.system.service.ISysUserService;
  34 +
  35 +/**
  36 + * 用户信息
  37 + *
  38 + * @author ruoyi
  39 + */
  40 +@RestController
  41 +@RequestMapping("/system/user")
  42 +public class SysUserController extends BaseController
  43 +{
  44 + @Autowired
  45 + private ISysUserService userService;
  46 +
  47 + @Autowired
  48 + private ISysRoleService roleService;
  49 +
  50 + @Autowired
  51 + private ISysDeptService deptService;
  52 +
  53 + @Autowired
  54 + private ISysPostService postService;
  55 +
  56 + /**
  57 + * 获取用户列表
  58 + */
  59 + @PreAuthorize("@ss.hasPermi('system:user:list')")
  60 + @GetMapping("/list")
  61 + public TableDataInfo list(SysUser user)
  62 + {
  63 + startPage();
  64 + List<SysUser> list = userService.selectUserList(user);
  65 + return getDataTable(list);
  66 + }
  67 +
  68 + @Log(title = "用户管理", businessType = BusinessType.EXPORT)
  69 + @PreAuthorize("@ss.hasPermi('system:user:export')")
  70 + @PostMapping("/export")
  71 + public void export(HttpServletResponse response, SysUser user)
  72 + {
  73 + List<SysUser> list = userService.selectUserList(user);
  74 + ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class);
  75 + util.exportExcel(response, list, "用户数据");
  76 + }
  77 +
  78 + @Log(title = "用户管理", businessType = BusinessType.IMPORT)
  79 + @PreAuthorize("@ss.hasPermi('system:user:import')")
  80 + @PostMapping("/importData")
  81 + public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception
  82 + {
  83 + ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class);
  84 + List<SysUser> userList = util.importExcel(file.getInputStream());
  85 + String operName = getUsername();
  86 + String message = userService.importUser(userList, updateSupport, operName);
  87 + return success(message);
  88 + }
  89 +
  90 + @PostMapping("/importTemplate")
  91 + public void importTemplate(HttpServletResponse response)
  92 + {
  93 + ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class);
  94 + util.importTemplateExcel(response, "用户数据");
  95 + }
  96 +
  97 + /**
  98 + * 根据用户编号获取详细信息
  99 + */
  100 + @PreAuthorize("@ss.hasPermi('system:user:query')")
  101 + @GetMapping(value = { "/", "/{userId}" })
  102 + public AjaxResult getInfo(@PathVariable(value = "userId", required = false) Long userId)
  103 + {
  104 + userService.checkUserDataScope(userId);
  105 + AjaxResult ajax = AjaxResult.success();
  106 + List<SysRole> roles = roleService.selectRoleAll();
  107 + ajax.put("roles", SysUser.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList()));
  108 + ajax.put("posts", postService.selectPostAll());
  109 + if (StringUtils.isNotNull(userId))
  110 + {
  111 + SysUser sysUser = userService.selectUserById(userId);
  112 + ajax.put(AjaxResult.DATA_TAG, sysUser);
  113 + ajax.put("postIds", postService.selectPostListByUserId(userId));
  114 + ajax.put("roleIds", sysUser.getRoles().stream().map(SysRole::getRoleId).collect(Collectors.toList()));
  115 + }
  116 + return ajax;
  117 + }
  118 +
  119 + /**
  120 + * 新增用户
  121 + */
  122 + @PreAuthorize("@ss.hasPermi('system:user:add')")
  123 + @Log(title = "用户管理", businessType = BusinessType.INSERT)
  124 + @PostMapping
  125 + public AjaxResult add(@Validated @RequestBody SysUser user)
  126 + {
  127 + if (!userService.checkUserNameUnique(user))
  128 + {
  129 + return error("新增用户'" + user.getUserName() + "'失败,登录账号已存在");
  130 + }
  131 + else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user))
  132 + {
  133 + return error("新增用户'" + user.getUserName() + "'失败,手机号码已存在");
  134 + }
  135 + else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user))
  136 + {
  137 + return error("新增用户'" + user.getUserName() + "'失败,邮箱账号已存在");
  138 + }
  139 + user.setCreateBy(getUsername());
  140 + user.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
  141 + return toAjax(userService.insertUser(user));
  142 + }
  143 +
  144 + /**
  145 + * 修改用户
  146 + */
  147 + @PreAuthorize("@ss.hasPermi('system:user:edit')")
  148 + @Log(title = "用户管理", businessType = BusinessType.UPDATE)
  149 + @PutMapping
  150 + public AjaxResult edit(@Validated @RequestBody SysUser user)
  151 + {
  152 + userService.checkUserAllowed(user);
  153 + userService.checkUserDataScope(user.getUserId());
  154 + if (!userService.checkUserNameUnique(user))
  155 + {
  156 + return error("修改用户'" + user.getUserName() + "'失败,登录账号已存在");
  157 + }
  158 + else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user))
  159 + {
  160 + return error("修改用户'" + user.getUserName() + "'失败,手机号码已存在");
  161 + }
  162 + else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user))
  163 + {
  164 + return error("修改用户'" + user.getUserName() + "'失败,邮箱账号已存在");
  165 + }
  166 + user.setUpdateBy(getUsername());
  167 + return toAjax(userService.updateUser(user));
  168 + }
  169 +
  170 + /**
  171 + * 删除用户
  172 + */
  173 + @PreAuthorize("@ss.hasPermi('system:user:remove')")
  174 + @Log(title = "用户管理", businessType = BusinessType.DELETE)
  175 + @DeleteMapping("/{userIds}")
  176 + public AjaxResult remove(@PathVariable Long[] userIds)
  177 + {
  178 + if (ArrayUtils.contains(userIds, getUserId()))
  179 + {
  180 + return error("当前用户不能删除");
  181 + }
  182 + return toAjax(userService.deleteUserByIds(userIds));
  183 + }
  184 +
  185 + /**
  186 + * 重置密码
  187 + */
  188 + @PreAuthorize("@ss.hasPermi('system:user:resetPwd')")
  189 + @Log(title = "用户管理", businessType = BusinessType.UPDATE)
  190 + @PutMapping("/resetPwd")
  191 + public AjaxResult resetPwd(@RequestBody SysUser user)
  192 + {
  193 + userService.checkUserAllowed(user);
  194 + userService.checkUserDataScope(user.getUserId());
  195 + user.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
  196 + user.setUpdateBy(getUsername());
  197 + return toAjax(userService.resetPwd(user));
  198 + }
  199 +
  200 + /**
  201 + * 状态修改
  202 + */
  203 + @PreAuthorize("@ss.hasPermi('system:user:edit')")
  204 + @Log(title = "用户管理", businessType = BusinessType.UPDATE)
  205 + @PutMapping("/changeStatus")
  206 + public AjaxResult changeStatus(@RequestBody SysUser user)
  207 + {
  208 + userService.checkUserAllowed(user);
  209 + userService.checkUserDataScope(user.getUserId());
  210 + user.setUpdateBy(getUsername());
  211 + return toAjax(userService.updateUserStatus(user));
  212 + }
  213 +
  214 + /**
  215 + * 根据用户编号获取授权角色
  216 + */
  217 + @PreAuthorize("@ss.hasPermi('system:user:query')")
  218 + @GetMapping("/authRole/{userId}")
  219 + public AjaxResult authRole(@PathVariable("userId") Long userId)
  220 + {
  221 + AjaxResult ajax = AjaxResult.success();
  222 + SysUser user = userService.selectUserById(userId);
  223 + List<SysRole> roles = roleService.selectRolesByUserId(userId);
  224 + ajax.put("user", user);
  225 + ajax.put("roles", SysUser.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList()));
  226 + return ajax;
  227 + }
  228 +
  229 + /**
  230 + * 用户授权角色
  231 + */
  232 + @PreAuthorize("@ss.hasPermi('system:user:edit')")
  233 + @Log(title = "用户管理", businessType = BusinessType.GRANT)
  234 + @PutMapping("/authRole")
  235 + public AjaxResult insertAuthRole(Long userId, Long[] roleIds)
  236 + {
  237 + userService.checkUserDataScope(userId);
  238 + userService.insertUserAuth(userId, roleIds);
  239 + return success();
  240 + }
  241 +
  242 + /**
  243 + * 获取部门树列表
  244 + */
  245 + @PreAuthorize("@ss.hasPermi('system:user:list')")
  246 + @GetMapping("/deptTree")
  247 + public AjaxResult deptTree(SysDept dept)
  248 + {
  249 + return success(deptService.selectDeptTreeList(dept));
  250 + }
  251 +}
  1 +package com.ruoyi.web.controller.tool;
  2 +
  3 +import java.util.ArrayList;
  4 +import java.util.LinkedHashMap;
  5 +import java.util.List;
  6 +import java.util.Map;
  7 +import org.springframework.web.bind.annotation.DeleteMapping;
  8 +import org.springframework.web.bind.annotation.GetMapping;
  9 +import org.springframework.web.bind.annotation.PathVariable;
  10 +import org.springframework.web.bind.annotation.PostMapping;
  11 +import org.springframework.web.bind.annotation.PutMapping;
  12 +import org.springframework.web.bind.annotation.RequestBody;
  13 +import org.springframework.web.bind.annotation.RequestMapping;
  14 +import org.springframework.web.bind.annotation.RestController;
  15 +import com.ruoyi.common.core.controller.BaseController;
  16 +import com.ruoyi.common.core.domain.R;
  17 +import com.ruoyi.common.utils.StringUtils;
  18 +import io.swagger.annotations.Api;
  19 +import io.swagger.annotations.ApiImplicitParam;
  20 +import io.swagger.annotations.ApiImplicitParams;
  21 +import io.swagger.annotations.ApiModel;
  22 +import io.swagger.annotations.ApiModelProperty;
  23 +import io.swagger.annotations.ApiOperation;
  24 +
  25 +/**
  26 + * swagger 用户测试方法
  27 + *
  28 + * @author ruoyi
  29 + */
  30 +@Api("用户信息管理")
  31 +@RestController
  32 +@RequestMapping("/test/user")
  33 +public class TestController extends BaseController
  34 +{
  35 + private final static Map<Integer, UserEntity> users = new LinkedHashMap<Integer, UserEntity>();
  36 + {
  37 + users.put(1, new UserEntity(1, "admin", "admin123", "15888888888"));
  38 + users.put(2, new UserEntity(2, "ry", "admin123", "15666666666"));
  39 + }
  40 +
  41 + @ApiOperation("获取用户列表")
  42 + @GetMapping("/list")
  43 + public R<List<UserEntity>> userList()
  44 + {
  45 + List<UserEntity> userList = new ArrayList<UserEntity>(users.values());
  46 + return R.ok(userList);
  47 + }
  48 +
  49 + @ApiOperation("获取用户详细")
  50 + @ApiImplicitParam(name = "userId", value = "用户ID", required = true, dataType = "int", paramType = "path", dataTypeClass = Integer.class)
  51 + @GetMapping("/{userId}")
  52 + public R<UserEntity> getUser(@PathVariable Integer userId)
  53 + {
  54 + if (!users.isEmpty() && users.containsKey(userId))
  55 + {
  56 + return R.ok(users.get(userId));
  57 + }
  58 + else
  59 + {
  60 + return R.fail("用户不存在");
  61 + }
  62 + }
  63 +
  64 + @ApiOperation("新增用户")
  65 + @ApiImplicitParams({
  66 + @ApiImplicitParam(name = "userId", value = "用户id", dataType = "Integer", dataTypeClass = Integer.class),
  67 + @ApiImplicitParam(name = "username", value = "用户名称", dataType = "String", dataTypeClass = String.class),
  68 + @ApiImplicitParam(name = "password", value = "用户密码", dataType = "String", dataTypeClass = String.class),
  69 + @ApiImplicitParam(name = "mobile", value = "用户手机", dataType = "String", dataTypeClass = String.class)
  70 + })
  71 + @PostMapping("/save")
  72 + public R<String> save(UserEntity user)
  73 + {
  74 + if (StringUtils.isNull(user) || StringUtils.isNull(user.getUserId()))
  75 + {
  76 + return R.fail("用户ID不能为空");
  77 + }
  78 + users.put(user.getUserId(), user);
  79 + return R.ok();
  80 + }
  81 +
  82 + @ApiOperation("更新用户")
  83 + @PutMapping("/update")
  84 + public R<String> update(@RequestBody UserEntity user)
  85 + {
  86 + if (StringUtils.isNull(user) || StringUtils.isNull(user.getUserId()))
  87 + {
  88 + return R.fail("用户ID不能为空");
  89 + }
  90 + if (users.isEmpty() || !users.containsKey(user.getUserId()))
  91 + {
  92 + return R.fail("用户不存在");
  93 + }
  94 + users.remove(user.getUserId());
  95 + users.put(user.getUserId(), user);
  96 + return R.ok();
  97 + }
  98 +
  99 + @ApiOperation("删除用户信息")
  100 + @ApiImplicitParam(name = "userId", value = "用户ID", required = true, dataType = "int", paramType = "path", dataTypeClass = Integer.class)
  101 + @DeleteMapping("/{userId}")
  102 + public R<String> delete(@PathVariable Integer userId)
  103 + {
  104 + if (!users.isEmpty() && users.containsKey(userId))
  105 + {
  106 + users.remove(userId);
  107 + return R.ok();
  108 + }
  109 + else
  110 + {
  111 + return R.fail("用户不存在");
  112 + }
  113 + }
  114 +}
  115 +
  116 +@ApiModel(value = "UserEntity", description = "用户实体")
  117 +class UserEntity
  118 +{
  119 + @ApiModelProperty("用户ID")
  120 + private Integer userId;
  121 +
  122 + @ApiModelProperty("用户名称")
  123 + private String username;
  124 +
  125 + @ApiModelProperty("用户密码")
  126 + private String password;
  127 +
  128 + @ApiModelProperty("用户手机")
  129 + private String mobile;
  130 +
  131 + public UserEntity()
  132 + {
  133 +
  134 + }
  135 +
  136 + public UserEntity(Integer userId, String username, String password, String mobile)
  137 + {
  138 + this.userId = userId;
  139 + this.username = username;
  140 + this.password = password;
  141 + this.mobile = mobile;
  142 + }
  143 +
  144 + public Integer getUserId()
  145 + {
  146 + return userId;
  147 + }
  148 +
  149 + public void setUserId(Integer userId)
  150 + {
  151 + this.userId = userId;
  152 + }
  153 +
  154 + public String getUsername()
  155 + {
  156 + return username;
  157 + }
  158 +
  159 + public void setUsername(String username)
  160 + {
  161 + this.username = username;
  162 + }
  163 +
  164 + public String getPassword()
  165 + {
  166 + return password;
  167 + }
  168 +
  169 + public void setPassword(String password)
  170 + {
  171 + this.password = password;
  172 + }
  173 +
  174 + public String getMobile()
  175 + {
  176 + return mobile;
  177 + }
  178 +
  179 + public void setMobile(String mobile)
  180 + {
  181 + this.mobile = mobile;
  182 + }
  183 +}
  1 +package com.ruoyi.web.core.config;
  2 +
  3 +import java.util.ArrayList;
  4 +import java.util.List;
  5 +import org.springframework.beans.factory.annotation.Autowired;
  6 +import org.springframework.beans.factory.annotation.Value;
  7 +import org.springframework.context.annotation.Bean;
  8 +import org.springframework.context.annotation.Configuration;
  9 +import com.ruoyi.common.config.RuoYiConfig;
  10 +import io.swagger.annotations.ApiOperation;
  11 +import io.swagger.models.auth.In;
  12 +import springfox.documentation.builders.ApiInfoBuilder;
  13 +import springfox.documentation.builders.PathSelectors;
  14 +import springfox.documentation.builders.RequestHandlerSelectors;
  15 +import springfox.documentation.service.ApiInfo;
  16 +import springfox.documentation.service.ApiKey;
  17 +import springfox.documentation.service.AuthorizationScope;
  18 +import springfox.documentation.service.Contact;
  19 +import springfox.documentation.service.SecurityReference;
  20 +import springfox.documentation.service.SecurityScheme;
  21 +import springfox.documentation.spi.DocumentationType;
  22 +import springfox.documentation.spi.service.contexts.SecurityContext;
  23 +import springfox.documentation.spring.web.plugins.Docket;
  24 +import springfox.documentation.swagger2.annotations.EnableSwagger2WebMvc;
  25 +
  26 +/**
  27 + * Swagger2的接口配置
  28 + *
  29 + * @author ruoyi
  30 + */
  31 +@Configuration
  32 +@EnableSwagger2WebMvc
  33 +public class SwaggerConfig
  34 +{
  35 + /** 系统基础配置 */
  36 + @Autowired
  37 + private RuoYiConfig ruoyiConfig;
  38 +
  39 + /** 是否开启swagger */
  40 + @Value("${swagger.enabled}")
  41 + private boolean enabled;
  42 +
  43 + /** 设置请求的统一前缀 */
  44 + @Value("${swagger.pathMapping}")
  45 + private String pathMapping;
  46 +
  47 + /**
  48 + * 创建API
  49 + */
  50 + @Bean
  51 + public Docket createRestApi()
  52 + {
  53 + return new Docket(DocumentationType.OAS_30)
  54 + // 是否启用Swagger
  55 + .enable(enabled)
  56 + // 用来创建该API的基本信息,展示在文档的页面中(自定义展示的信息)
  57 + .apiInfo(apiInfo())
  58 + // 设置哪些接口暴露给Swagger展示
  59 + .select()
  60 + // 扫描所有有注解的api,用这种方式更灵活
  61 + .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
  62 + // 扫描指定包中的swagger注解
  63 + // .apis(RequestHandlerSelectors.basePackage("com.ruoyi.project.tool.swagger"))
  64 + // 扫描所有 .apis(RequestHandlerSelectors.any())
  65 + .paths(PathSelectors.any())
  66 + .build()
  67 + /* 设置安全模式,swagger可以设置访问token */
  68 + .securitySchemes(securitySchemes())
  69 + .securityContexts(securityContexts())
  70 + .pathMapping(pathMapping);
  71 + }
  72 +
  73 + /**
  74 + * 安全模式,这里指定token通过Authorization头请求头传递
  75 + */
  76 + private List<SecurityScheme> securitySchemes()
  77 + {
  78 + List<SecurityScheme> apiKeyList = new ArrayList<SecurityScheme>();
  79 + apiKeyList.add(new ApiKey("Authorization", "Authorization", In.HEADER.toValue()));
  80 + return apiKeyList;
  81 + }
  82 +
  83 + /**
  84 + * 安全上下文
  85 + */
  86 + private List<SecurityContext> securityContexts()
  87 + {
  88 + List<SecurityContext> securityContexts = new ArrayList<>();
  89 + securityContexts.add(
  90 + SecurityContext.builder()
  91 + .securityReferences(defaultAuth())
  92 + .operationSelector(o -> o.requestMappingPattern().matches("/.*"))
  93 + .build());
  94 + return securityContexts;
  95 + }
  96 +
  97 + /**
  98 + * 默认的安全上引用
  99 + */
  100 + private List<SecurityReference> defaultAuth()
  101 + {
  102 + AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
  103 + AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
  104 + authorizationScopes[0] = authorizationScope;
  105 + List<SecurityReference> securityReferences = new ArrayList<>();
  106 + securityReferences.add(new SecurityReference("Authorization", authorizationScopes));
  107 + return securityReferences;
  108 + }
  109 +
  110 + /**
  111 + * 添加摘要信息
  112 + */
  113 + private ApiInfo apiInfo()
  114 + {
  115 + // 用ApiInfoBuilder进行定制
  116 + return new ApiInfoBuilder()
  117 + // 设置标题
  118 + .title("标题:若依管理系统_接口文档")
  119 + // 描述
  120 + .description("描述:用于管理集团旗下公司的人员信息,具体包括XXX,XXX模块...")
  121 + // 作者信息
  122 + .contact(new Contact(ruoyiConfig.getName(), null, null))
  123 + // 版本
  124 + .version("版本号:" + ruoyiConfig.getVersion())
  125 + .build();
  126 + }
  127 +}
  1 +restart.include.json=/com.alibaba.fastjson2.*.jar
  1 +# 数据源配置
  2 +spring:
  3 + datasource:
  4 + type: com.alibaba.druid.pool.DruidDataSource
  5 + driverClassName: com.mysql.cj.jdbc.Driver
  6 + druid:
  7 + # 主库数据源
  8 + master:
  9 + url: jdbc:mysql://rm-wz9740un21f09iokuao.mysql.rds.aliyuncs.com:3306/lh-aquaculture-sys?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
  10 + username: luhui
  11 + password: Luhui586
  12 + # 从库数据源
  13 + slave:
  14 + # 从数据源开关/默认关闭
  15 + enabled: false
  16 + url:
  17 + username:
  18 + password:
  19 + # 初始连接数
  20 + initialSize: 5
  21 + # 最小连接池数量
  22 + minIdle: 10
  23 + # 最大连接池数量
  24 + maxActive: 20
  25 + # 配置获取连接等待超时的时间
  26 + maxWait: 60000
  27 + # 配置连接超时时间
  28 + connectTimeout: 30000
  29 + # 配置网络超时时间
  30 + socketTimeout: 60000
  31 + # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
  32 + timeBetweenEvictionRunsMillis: 60000
  33 + # 配置一个连接在池中最小生存的时间,单位是毫秒
  34 + minEvictableIdleTimeMillis: 300000
  35 + # 配置一个连接在池中最大生存的时间,单位是毫秒
  36 + maxEvictableIdleTimeMillis: 900000
  37 + # 配置检测连接是否有效
  38 + validationQuery: SELECT 1 FROM DUAL
  39 + testWhileIdle: true
  40 + testOnBorrow: false
  41 + testOnReturn: false
  42 + webStatFilter:
  43 + enabled: true
  44 + statViewServlet:
  45 + enabled: true
  46 + # 设置白名单,不填则允许所有访问
  47 + allow:
  48 + url-pattern: /druid/*
  49 + # 控制台管理用户名和密码
  50 + login-username: ruoyi
  51 + login-password: 123456
  52 + filter:
  53 + stat:
  54 + enabled: true
  55 + # 慢SQL记录
  56 + log-slow-sql: true
  57 + slow-sql-millis: 1000
  58 + merge-sql: true
  59 + wall:
  60 + config:
  61 + multi-statement-allow: true
  1 +# 项目相关配置
  2 +ruoyi:
  3 + # 名称
  4 + name: RuoYi
  5 + # 版本
  6 + version: 3.8.7
  7 + # 版权年份
  8 + copyrightYear: 2024
  9 + # 文件路径 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)
  10 + profile: D:/ruoyi/uploadPath
  11 + # 获取ip地址开关
  12 + addressEnabled: false
  13 + # 验证码类型 math 数字计算 char 字符验证
  14 + captchaType: math
  15 +
  16 +# 开发环境配置
  17 +server:
  18 + # 服务器的HTTP端口,默认为8080
  19 + port: 8080
  20 + servlet:
  21 + # 应用的访问路径
  22 + context-path: /
  23 + tomcat:
  24 + # tomcat的URI编码
  25 + uri-encoding: UTF-8
  26 + # 连接数满后的排队数,默认为100
  27 + accept-count: 1000
  28 + threads:
  29 + # tomcat最大线程数,默认为200
  30 + max: 800
  31 + # Tomcat启动初始化的线程数,默认值10
  32 + min-spare: 100
  33 +
  34 +# 日志配置
  35 +logging:
  36 + level:
  37 + com.ruoyi: debug
  38 + org.springframework: warn
  39 +
  40 +# 用户配置
  41 +user:
  42 + password:
  43 + # 密码最大错误次数
  44 + maxRetryCount: 5
  45 + # 密码锁定时间(默认10分钟)
  46 + lockTime: 10
  47 +
  48 +# Spring配置
  49 +spring:
  50 + # 资源信息
  51 + messages:
  52 + # 国际化资源文件路径
  53 + basename: i18n/messages
  54 + profiles:
  55 + active: druid
  56 + # 文件上传
  57 + servlet:
  58 + multipart:
  59 + # 单个文件大小
  60 + max-file-size: 10MB
  61 + # 设置总上传的文件大小
  62 + max-request-size: 20MB
  63 + # 服务模块
  64 + devtools:
  65 + restart:
  66 + # 热部署开关
  67 + enabled: true
  68 + # redis 配置
  69 + redis:
  70 + # 地址
  71 + host: 47.112.163.61
  72 + # 端口,默认为6379
  73 + port: 9527
  74 + # 数据库索引
  75 + database: 4
  76 + # 密码
  77 + password: Luhui586
  78 + # 连接超时时间
  79 + timeout: 10s
  80 + lettuce:
  81 + pool:
  82 + # 连接池中的最小空闲连接
  83 + min-idle: 0
  84 + # 连接池中的最大空闲连接
  85 + max-idle: 8
  86 + # 连接池的最大数据库连接数
  87 + max-active: 8
  88 + # #连接池最大阻塞等待时间(使用负值表示没有限制)
  89 + max-wait: -1ms
  90 +
  91 +# token配置
  92 +token:
  93 + # 令牌自定义标识
  94 + header: Authorization
  95 + # 令牌密钥
  96 + secret: abcdefghijklmnopqrstuvwxyz
  97 + # 令牌有效期(默认30分钟)
  98 + expireTime: 30
  99 +
  100 +# MyBatis配置
  101 +mybatis:
  102 + # 搜索指定包别名
  103 + typeAliasesPackage: com.ruoyi.**.domain
  104 + # 配置mapper的扫描,找到所有的mapper.xml映射文件
  105 + mapperLocations: classpath*:mapper/**/*Mapper.xml
  106 + # 加载全局的配置文件
  107 + configLocation: classpath:mybatis/mybatis-config.xml
  108 +
  109 +# PageHelper分页插件
  110 +pagehelper:
  111 + helperDialect: mysql
  112 + supportMethodsArguments: true
  113 + params: count=countSql
  114 +
  115 +# Swagger配置
  116 +swagger:
  117 + # 是否开启swagger
  118 + enabled: true
  119 + # 请求前缀
  120 + pathMapping: /dev-api
  121 +
  122 +# 防止XSS攻击
  123 +xss:
  124 + # 过滤开关
  125 + enabled: true
  126 + # 排除链接(多个用逗号分隔)
  127 + excludes: /system/notice
  128 + # 匹配链接
  129 + urlPatterns: /system/*,/monitor/*,/tool/*
  1 +Application Version: ${ruoyi.version}
  2 +Spring Boot Version: ${spring-boot.version}
  3 +////////////////////////////////////////////////////////////////////
  4 +// _ooOoo_ //
  5 +// o8888888o //
  6 +// 88" . "88 //
  7 +// (| ^_^ |) //
  8 +// O\ = /O //
  9 +// ____/`---'\____ //
  10 +// .' \\| |// `. //
  11 +// / \\||| : |||// \ //
  12 +// / _||||| -:- |||||- \ //
  13 +// | | \\\ - /// | | //
  14 +// | \_| ''\---/'' | | //
  15 +// \ .-\__ `-` ___/-. / //
  16 +// ___`. .' /--.--\ `. . ___ //
  17 +// ."" '< `.___\_<|>_/___.' >'"". //
  18 +// | | : `- \`.;`\ _ /`;.`/ - ` : | | //
  19 +// \ \ `-. \_ __\ /__ _/ .-` / / //
  20 +// ========`-.____`-.___\_____/___.-`____.-'======== //
  21 +// `=---=' //
  22 +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ //
  23 +// 佛祖保佑 永不宕机 永无BUG //
  24 +////////////////////////////////////////////////////////////////////
  1 +#错误消息
  2 +not.null=* 必须填写
  3 +user.jcaptcha.error=验证码错误
  4 +user.jcaptcha.expire=验证码已失效
  5 +user.not.exists=用户不存在/密码错误
  6 +user.password.not.match=用户不存在/密码错误
  7 +user.password.retry.limit.count=密码输入错误{0}次
  8 +user.password.retry.limit.exceed=密码输入错误{0}次,帐户锁定{1}分钟
  9 +user.password.delete=对不起,您的账号已被删除
  10 +user.blocked=用户已封禁,请联系管理员
  11 +role.blocked=角色已封禁,请联系管理员
  12 +login.blocked=很遗憾,访问IP已被列入系统黑名单
  13 +user.logout.success=退出成功
  14 +
  15 +length.not.valid=长度必须在{min}到{max}个字符之间
  16 +
  17 +user.username.not.valid=* 2到20个汉字、字母、数字或下划线组成,且必须以非数字开头
  18 +user.password.not.valid=* 5-50个字符
  19 +
  20 +user.email.not.valid=邮箱格式错误
  21 +user.mobile.phone.number.not.valid=手机号格式错误
  22 +user.login.success=登录成功
  23 +user.register.success=注册成功
  24 +user.notfound=请重新登录
  25 +user.forcelogout=管理员强制退出,请重新登录
  26 +user.unknown.error=未知错误,请重新登录
  27 +
  28 +##文件上传消息
  29 +upload.exceed.maxSize=上传的文件大小超出限制的文件大小!<br/>允许的文件最大大小是:{0}MB!
  30 +upload.filename.exceed.length=上传的文件名最长{0}个字符
  31 +
  32 +##权限
  33 +no.permission=您没有数据的权限,请联系管理员添加权限 [{0}]
  34 +no.create.permission=您没有创建数据的权限,请联系管理员添加权限 [{0}]
  35 +no.update.permission=您没有修改数据的权限,请联系管理员添加权限 [{0}]
  36 +no.delete.permission=您没有删除数据的权限,请联系管理员添加权限 [{0}]
  37 +no.export.permission=您没有导出数据的权限,请联系管理员添加权限 [{0}]
  38 +no.view.permission=您没有查看数据的权限,请联系管理员添加权限 [{0}]
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<configuration>
  3 + <!-- 日志存放路径 -->
  4 + <property name="log.path" value="/home/ruoyi/logs" />
  5 + <!-- 日志输出格式 -->
  6 + <property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" />
  7 +
  8 + <!-- 控制台输出 -->
  9 + <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
  10 + <encoder>
  11 + <pattern>${log.pattern}</pattern>
  12 + </encoder>
  13 + </appender>
  14 +
  15 + <!-- 系统日志输出 -->
  16 + <appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
  17 + <file>${log.path}/sys-info.log</file>
  18 + <!-- 循环政策:基于时间创建日志文件 -->
  19 + <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
  20 + <!-- 日志文件名格式 -->
  21 + <fileNamePattern>${log.path}/sys-info.%d{yyyy-MM-dd}.log</fileNamePattern>
  22 + <!-- 日志最大的历史 60天 -->
  23 + <maxHistory>60</maxHistory>
  24 + </rollingPolicy>
  25 + <encoder>
  26 + <pattern>${log.pattern}</pattern>
  27 + </encoder>
  28 + <filter class="ch.qos.logback.classic.filter.LevelFilter">
  29 + <!-- 过滤的级别 -->
  30 + <level>INFO</level>
  31 + <!-- 匹配时的操作:接收(记录) -->
  32 + <onMatch>ACCEPT</onMatch>
  33 + <!-- 不匹配时的操作:拒绝(不记录) -->
  34 + <onMismatch>DENY</onMismatch>
  35 + </filter>
  36 + </appender>
  37 +
  38 + <appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
  39 + <file>${log.path}/sys-error.log</file>
  40 + <!-- 循环政策:基于时间创建日志文件 -->
  41 + <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
  42 + <!-- 日志文件名格式 -->
  43 + <fileNamePattern>${log.path}/sys-error.%d{yyyy-MM-dd}.log</fileNamePattern>
  44 + <!-- 日志最大的历史 60天 -->
  45 + <maxHistory>60</maxHistory>
  46 + </rollingPolicy>
  47 + <encoder>
  48 + <pattern>${log.pattern}</pattern>
  49 + </encoder>
  50 + <filter class="ch.qos.logback.classic.filter.LevelFilter">
  51 + <!-- 过滤的级别 -->
  52 + <level>ERROR</level>
  53 + <!-- 匹配时的操作:接收(记录) -->
  54 + <onMatch>ACCEPT</onMatch>
  55 + <!-- 不匹配时的操作:拒绝(不记录) -->
  56 + <onMismatch>DENY</onMismatch>
  57 + </filter>
  58 + </appender>
  59 +
  60 + <!-- 用户访问日志输出 -->
  61 + <appender name="sys-user" class="ch.qos.logback.core.rolling.RollingFileAppender">
  62 + <file>${log.path}/sys-user.log</file>
  63 + <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
  64 + <!-- 按天回滚 daily -->
  65 + <fileNamePattern>${log.path}/sys-user.%d{yyyy-MM-dd}.log</fileNamePattern>
  66 + <!-- 日志最大的历史 60天 -->
  67 + <maxHistory>60</maxHistory>
  68 + </rollingPolicy>
  69 + <encoder>
  70 + <pattern>${log.pattern}</pattern>
  71 + </encoder>
  72 + </appender>
  73 +
  74 + <!-- 系统模块日志级别控制 -->
  75 + <logger name="com.ruoyi" level="info" />
  76 + <!-- Spring日志级别控制 -->
  77 + <logger name="org.springframework" level="warn" />
  78 +
  79 + <root level="info">
  80 + <appender-ref ref="console" />
  81 + </root>
  82 +
  83 + <!--系统操作日志-->
  84 + <root level="info">
  85 + <appender-ref ref="file_info" />
  86 + <appender-ref ref="file_error" />
  87 + </root>
  88 +
  89 + <!--系统用户操作日志-->
  90 + <logger name="sys-user" level="info">
  91 + <appender-ref ref="sys-user"/>
  92 + </logger>
  93 +</configuration>
  1 +<?xml version="1.0" encoding="UTF-8" ?>
  2 +<!DOCTYPE configuration
  3 +PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  4 +"http://mybatis.org/dtd/mybatis-3-config.dtd">
  5 +<configuration>
  6 + <!-- 全局参数 -->
  7 + <settings>
  8 + <!-- 使全局的映射器启用或禁用缓存 -->
  9 + <setting name="cacheEnabled" value="true" />
  10 + <!-- 允许JDBC 支持自动生成主键 -->
  11 + <setting name="useGeneratedKeys" value="true" />
  12 + <!-- 配置默认的执行器.SIMPLE就是普通执行器;REUSE执行器会重用预处理语句(prepared statements);BATCH执行器将重用语句并执行批量更新 -->
  13 + <setting name="defaultExecutorType" value="SIMPLE" />
  14 + <!-- 指定 MyBatis 所用日志的具体实现 -->
  15 + <setting name="logImpl" value="SLF4J" />
  16 + <!-- 使用驼峰命名法转换字段 -->
  17 + <!-- <setting name="mapUnderscoreToCamelCase" value="true"/> -->
  18 + </settings>
  19 +
  20 +</configuration>
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<project xmlns="http://maven.apache.org/POM/4.0.0"
  3 + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5 + <parent>
  6 + <artifactId>lh-ruoyi</artifactId>
  7 + <groupId>com.zhonglai.luhui</groupId>
  8 + <version>1.0.0</version>
  9 + </parent>
  10 + <modelVersion>4.0.0</modelVersion>
  11 +
  12 + <artifactId>ruoyi-common</artifactId>
  13 +
  14 + <description>
  15 + common通用工具
  16 + </description>
  17 +
  18 + <dependencies>
  19 +
  20 + <!-- Spring框架基本的核心工具 -->
  21 + <dependency>
  22 + <groupId>org.springframework</groupId>
  23 + <artifactId>spring-context-support</artifactId>
  24 + </dependency>
  25 +
  26 + <!-- SpringWeb模块 -->
  27 + <dependency>
  28 + <groupId>org.springframework</groupId>
  29 + <artifactId>spring-web</artifactId>
  30 + </dependency>
  31 +
  32 + <!-- spring security 安全认证 -->
  33 + <dependency>
  34 + <groupId>org.springframework.boot</groupId>
  35 + <artifactId>spring-boot-starter-security</artifactId>
  36 + </dependency>
  37 +
  38 + <!-- pagehelper 分页插件 -->
  39 + <dependency>
  40 + <groupId>com.github.pagehelper</groupId>
  41 + <artifactId>pagehelper-spring-boot-starter</artifactId>
  42 + </dependency>
  43 +
  44 + <!-- 自定义验证注解 -->
  45 + <dependency>
  46 + <groupId>org.springframework.boot</groupId>
  47 + <artifactId>spring-boot-starter-validation</artifactId>
  48 + </dependency>
  49 +
  50 + <!--常用工具类 -->
  51 + <dependency>
  52 + <groupId>org.apache.commons</groupId>
  53 + <artifactId>commons-lang3</artifactId>
  54 + </dependency>
  55 +
  56 + <!-- JSON工具类 -->
  57 + <dependency>
  58 + <groupId>com.fasterxml.jackson.core</groupId>
  59 + <artifactId>jackson-databind</artifactId>
  60 + </dependency>
  61 +
  62 + <!-- 动态数据源 -->
  63 + <dependency>
  64 + <groupId>com.baomidou</groupId>
  65 + <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
  66 + <version>3.5.2</version>
  67 + </dependency>
  68 +
  69 + <!-- 阿里JSON解析器 -->
  70 + <dependency>
  71 + <groupId>com.alibaba.fastjson2</groupId>
  72 + <artifactId>fastjson2</artifactId>
  73 + </dependency>
  74 +
  75 + <!-- io常用工具类 -->
  76 + <dependency>
  77 + <groupId>commons-io</groupId>
  78 + <artifactId>commons-io</artifactId>
  79 + </dependency>
  80 +
  81 + <!-- excel工具 -->
  82 + <dependency>
  83 + <groupId>org.apache.poi</groupId>
  84 + <artifactId>poi-ooxml</artifactId>
  85 + </dependency>
  86 +
  87 + <!-- yml解析器 -->
  88 + <dependency>
  89 + <groupId>org.yaml</groupId>
  90 + <artifactId>snakeyaml</artifactId>
  91 + </dependency>
  92 +
  93 + <!-- Token生成与解析-->
  94 + <dependency>
  95 + <groupId>io.jsonwebtoken</groupId>
  96 + <artifactId>jjwt</artifactId>
  97 + </dependency>
  98 +
  99 + <!-- Jaxb -->
  100 + <dependency>
  101 + <groupId>javax.xml.bind</groupId>
  102 + <artifactId>jaxb-api</artifactId>
  103 + </dependency>
  104 +
  105 + <!-- redis 缓存操作 -->
  106 + <dependency>
  107 + <groupId>org.springframework.boot</groupId>
  108 + <artifactId>spring-boot-starter-data-redis</artifactId>
  109 + </dependency>
  110 +
  111 + <!-- pool 对象池 -->
  112 + <dependency>
  113 + <groupId>org.apache.commons</groupId>
  114 + <artifactId>commons-pool2</artifactId>
  115 + </dependency>
  116 +
  117 + <!-- 解析客户端操作系统、浏览器等 -->
  118 + <dependency>
  119 + <groupId>eu.bitwalker</groupId>
  120 + <artifactId>UserAgentUtils</artifactId>
  121 + </dependency>
  122 +
  123 + <!-- servlet包 -->
  124 + <dependency>
  125 + <groupId>javax.servlet</groupId>
  126 + <artifactId>javax.servlet-api</artifactId>
  127 + </dependency>
  128 +
  129 + </dependencies>
  130 +
  131 +</project>
  1 +package com.ruoyi.common.annotation;
  2 +
  3 +import java.lang.annotation.Documented;
  4 +import java.lang.annotation.ElementType;
  5 +import java.lang.annotation.Retention;
  6 +import java.lang.annotation.RetentionPolicy;
  7 +import java.lang.annotation.Target;
  8 +
  9 +/**
  10 + * 匿名访问不鉴权注解
  11 + *
  12 + * @author ruoyi
  13 + */
  14 +@Target({ ElementType.METHOD, ElementType.TYPE })
  15 +@Retention(RetentionPolicy.RUNTIME)
  16 +@Documented
  17 +public @interface Anonymous
  18 +{
  19 +}
  1 +package com.ruoyi.common.annotation;
  2 +
  3 +import java.lang.annotation.Documented;
  4 +import java.lang.annotation.ElementType;
  5 +import java.lang.annotation.Retention;
  6 +import java.lang.annotation.RetentionPolicy;
  7 +import java.lang.annotation.Target;
  8 +
  9 +/**
  10 + * 数据权限过滤注解
  11 + *
  12 + * @author ruoyi
  13 + */
  14 +@Target(ElementType.METHOD)
  15 +@Retention(RetentionPolicy.RUNTIME)
  16 +@Documented
  17 +public @interface DataScope
  18 +{
  19 + /**
  20 + * 部门表的别名
  21 + */
  22 + public String deptAlias() default "";
  23 +
  24 + /**
  25 + * 用户表的别名
  26 + */
  27 + public String userAlias() default "";
  28 +
  29 + /**
  30 + * 权限字符(用于多个角色匹配符合要求的权限)默认根据权限注解@ss获取,多个权限用逗号分隔开来
  31 + */
  32 + public String permission() default "";
  33 +}
  1 +package com.ruoyi.common.annotation;
  2 +
  3 +import java.lang.annotation.Documented;
  4 +import java.lang.annotation.ElementType;
  5 +import java.lang.annotation.Inherited;
  6 +import java.lang.annotation.Retention;
  7 +import java.lang.annotation.RetentionPolicy;
  8 +import java.lang.annotation.Target;
  9 +import com.ruoyi.common.enums.DataSourceType;
  10 +
  11 +/**
  12 + * 自定义多数据源切换注解
  13 + *
  14 + * 优先级:先方法,后类,如果方法覆盖了类上的数据源类型,以方法的为准,否则以类上的为准
  15 + *
  16 + * @author ruoyi
  17 + */
  18 +@Target({ ElementType.METHOD, ElementType.TYPE })
  19 +@Retention(RetentionPolicy.RUNTIME)
  20 +@Documented
  21 +@Inherited
  22 +public @interface DataSource
  23 +{
  24 + /**
  25 + * 切换数据源名称
  26 + */
  27 + public DataSourceType value() default DataSourceType.MASTER;
  28 +}
  1 +package com.ruoyi.common.annotation;
  2 +
  3 +import java.lang.annotation.ElementType;
  4 +import java.lang.annotation.Retention;
  5 +import java.lang.annotation.RetentionPolicy;
  6 +import java.lang.annotation.Target;
  7 +import java.math.BigDecimal;
  8 +import org.apache.poi.ss.usermodel.HorizontalAlignment;
  9 +import org.apache.poi.ss.usermodel.IndexedColors;
  10 +import com.ruoyi.common.utils.poi.ExcelHandlerAdapter;
  11 +
  12 +/**
  13 + * 自定义导出Excel数据注解
  14 + *
  15 + * @author ruoyi
  16 + */
  17 +@Retention(RetentionPolicy.RUNTIME)
  18 +@Target(ElementType.FIELD)
  19 +public @interface Excel
  20 +{
  21 + /**
  22 + * 导出时在excel中排序
  23 + */
  24 + public int sort() default Integer.MAX_VALUE;
  25 +
  26 + /**
  27 + * 导出到Excel中的名字.
  28 + */
  29 + public String name() default "";
  30 +
  31 + /**
  32 + * 日期格式, 如: yyyy-MM-dd
  33 + */
  34 + public String dateFormat() default "";
  35 +
  36 + /**
  37 + * 如果是字典类型,请设置字典的type值 (如: sys_user_sex)
  38 + */
  39 + public String dictType() default "";
  40 +
  41 + /**
  42 + * 读取内容转表达式 (如: 0=男,1=女,2=未知)
  43 + */
  44 + public String readConverterExp() default "";
  45 +
  46 + /**
  47 + * 分隔符,读取字符串组内容
  48 + */
  49 + public String separator() default ",";
  50 +
  51 + /**
  52 + * BigDecimal 精度 默认:-1(默认不开启BigDecimal格式化)
  53 + */
  54 + public int scale() default -1;
  55 +
  56 + /**
  57 + * BigDecimal 舍入规则 默认:BigDecimal.ROUND_HALF_EVEN
  58 + */
  59 + public int roundingMode() default BigDecimal.ROUND_HALF_EVEN;
  60 +
  61 + /**
  62 + * 导出时在excel中每个列的高度
  63 + */
  64 + public double height() default 14;
  65 +
  66 + /**
  67 + * 导出时在excel中每个列的宽度
  68 + */
  69 + public double width() default 16;
  70 +
  71 + /**
  72 + * 文字后缀,如% 90 变成90%
  73 + */
  74 + public String suffix() default "";
  75 +
  76 + /**
  77 + * 当值为空时,字段的默认值
  78 + */
  79 + public String defaultValue() default "";
  80 +
  81 + /**
  82 + * 提示信息
  83 + */
  84 + public String prompt() default "";
  85 +
  86 + /**
  87 + * 设置只能选择不能输入的列内容.
  88 + */
  89 + public String[] combo() default {};
  90 +
  91 + /**
  92 + * 是否需要纵向合并单元格,应对需求:含有list集合单元格)
  93 + */
  94 + public boolean needMerge() default false;
  95 +
  96 + /**
  97 + * 是否导出数据,应对需求:有时我们需要导出一份模板,这是标题需要但内容需要用户手工填写.
  98 + */
  99 + public boolean isExport() default true;
  100 +
  101 + /**
  102 + * 另一个类中的属性名称,支持多级获取,以小数点隔开
  103 + */
  104 + public String targetAttr() default "";
  105 +
  106 + /**
  107 + * 是否自动统计数据,在最后追加一行统计数据总和
  108 + */
  109 + public boolean isStatistics() default false;
  110 +
  111 + /**
  112 + * 导出类型(0数字 1字符串 2图片)
  113 + */
  114 + public ColumnType cellType() default ColumnType.STRING;
  115 +
  116 + /**
  117 + * 导出列头背景颜色
  118 + */
  119 + public IndexedColors headerBackgroundColor() default IndexedColors.GREY_50_PERCENT;
  120 +
  121 + /**
  122 + * 导出列头字体颜色
  123 + */
  124 + public IndexedColors headerColor() default IndexedColors.WHITE;
  125 +
  126 + /**
  127 + * 导出单元格背景颜色
  128 + */
  129 + public IndexedColors backgroundColor() default IndexedColors.WHITE;
  130 +
  131 + /**
  132 + * 导出单元格字体颜色
  133 + */
  134 + public IndexedColors color() default IndexedColors.BLACK;
  135 +
  136 + /**
  137 + * 导出字段对齐方式
  138 + */
  139 + public HorizontalAlignment align() default HorizontalAlignment.CENTER;
  140 +
  141 + /**
  142 + * 自定义数据处理器
  143 + */
  144 + public Class<?> handler() default ExcelHandlerAdapter.class;
  145 +
  146 + /**
  147 + * 自定义数据处理器参数
  148 + */
  149 + public String[] args() default {};
  150 +
  151 + /**
  152 + * 字段类型(0:导出导入;1:仅导出;2:仅导入)
  153 + */
  154 + Type type() default Type.ALL;
  155 +
  156 + public enum Type
  157 + {
  158 + ALL(0), EXPORT(1), IMPORT(2);
  159 + private final int value;
  160 +
  161 + Type(int value)
  162 + {
  163 + this.value = value;
  164 + }
  165 +
  166 + public int value()
  167 + {
  168 + return this.value;
  169 + }
  170 + }
  171 +
  172 + public enum ColumnType
  173 + {
  174 + NUMERIC(0), STRING(1), IMAGE(2), TEXT(3);
  175 + private final int value;
  176 +
  177 + ColumnType(int value)
  178 + {
  179 + this.value = value;
  180 + }
  181 +
  182 + public int value()
  183 + {
  184 + return this.value;
  185 + }
  186 + }
  187 +}
  1 +package com.ruoyi.common.annotation;
  2 +
  3 +import java.lang.annotation.ElementType;
  4 +import java.lang.annotation.Retention;
  5 +import java.lang.annotation.RetentionPolicy;
  6 +import java.lang.annotation.Target;
  7 +
  8 +/**
  9 + * Excel注解集
  10 + *
  11 + * @author ruoyi
  12 + */
  13 +@Target(ElementType.FIELD)
  14 +@Retention(RetentionPolicy.RUNTIME)
  15 +public @interface Excels
  16 +{
  17 + public Excel[] value();
  18 +}
  1 +package com.ruoyi.common.annotation;
  2 +
  3 +import java.lang.annotation.Documented;
  4 +import java.lang.annotation.ElementType;
  5 +import java.lang.annotation.Retention;
  6 +import java.lang.annotation.RetentionPolicy;
  7 +import java.lang.annotation.Target;
  8 +import com.ruoyi.common.enums.BusinessType;
  9 +import com.ruoyi.common.enums.OperatorType;
  10 +
  11 +/**
  12 + * 自定义操作日志记录注解
  13 + *
  14 + * @author ruoyi
  15 + *
  16 + */
  17 +@Target({ ElementType.PARAMETER, ElementType.METHOD })
  18 +@Retention(RetentionPolicy.RUNTIME)
  19 +@Documented
  20 +public @interface Log
  21 +{
  22 + /**
  23 + * 模块
  24 + */
  25 + public String title() default "";
  26 +
  27 + /**
  28 + * 功能
  29 + */
  30 + public BusinessType businessType() default BusinessType.OTHER;
  31 +
  32 + /**
  33 + * 操作人类别
  34 + */
  35 + public OperatorType operatorType() default OperatorType.MANAGE;
  36 +
  37 + /**
  38 + * 是否保存请求的参数
  39 + */
  40 + public boolean isSaveRequestData() default true;
  41 +
  42 + /**
  43 + * 是否保存响应的参数
  44 + */
  45 + public boolean isSaveResponseData() default true;
  46 +
  47 + /**
  48 + * 排除指定的请求参数
  49 + */
  50 + public String[] excludeParamNames() default {};
  51 +}
  1 +package com.ruoyi.common.annotation;
  2 +
  3 +import java.lang.annotation.Documented;
  4 +import java.lang.annotation.ElementType;
  5 +import java.lang.annotation.Retention;
  6 +import java.lang.annotation.RetentionPolicy;
  7 +import java.lang.annotation.Target;
  8 +import com.ruoyi.common.constant.CacheConstants;
  9 +import com.ruoyi.common.enums.LimitType;
  10 +
  11 +/**
  12 + * 限流注解
  13 + *
  14 + * @author ruoyi
  15 + */
  16 +@Target(ElementType.METHOD)
  17 +@Retention(RetentionPolicy.RUNTIME)
  18 +@Documented
  19 +public @interface RateLimiter
  20 +{
  21 + /**
  22 + * 限流key
  23 + */
  24 + public String key() default CacheConstants.RATE_LIMIT_KEY;
  25 +
  26 + /**
  27 + * 限流时间,单位秒
  28 + */
  29 + public int time() default 60;
  30 +
  31 + /**
  32 + * 限流次数
  33 + */
  34 + public int count() default 100;
  35 +
  36 + /**
  37 + * 限流类型
  38 + */
  39 + public LimitType limitType() default LimitType.DEFAULT;
  40 +}
  1 +package com.ruoyi.common.annotation;
  2 +
  3 +import java.lang.annotation.Documented;
  4 +import java.lang.annotation.ElementType;
  5 +import java.lang.annotation.Inherited;
  6 +import java.lang.annotation.Retention;
  7 +import java.lang.annotation.RetentionPolicy;
  8 +import java.lang.annotation.Target;
  9 +
  10 +/**
  11 + * 自定义注解防止表单重复提交
  12 + *
  13 + * @author ruoyi
  14 + *
  15 + */
  16 +@Inherited
  17 +@Target(ElementType.METHOD)
  18 +@Retention(RetentionPolicy.RUNTIME)
  19 +@Documented
  20 +public @interface RepeatSubmit
  21 +{
  22 + /**
  23 + * 间隔时间(ms),小于此时间视为重复提交
  24 + */
  25 + public int interval() default 5000;
  26 +
  27 + /**
  28 + * 提示消息
  29 + */
  30 + public String message() default "不允许重复提交,请稍候再试";
  31 +}
  1 +package com.ruoyi.common.annotation;
  2 +
  3 +import java.lang.annotation.ElementType;
  4 +import java.lang.annotation.Retention;
  5 +import java.lang.annotation.RetentionPolicy;
  6 +import java.lang.annotation.Target;
  7 +import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
  8 +import com.fasterxml.jackson.databind.annotation.JsonSerialize;
  9 +import com.ruoyi.common.config.serializer.SensitiveJsonSerializer;
  10 +import com.ruoyi.common.enums.DesensitizedType;
  11 +
  12 +/**
  13 + * 数据脱敏注解
  14 + *
  15 + * @author ruoyi
  16 + */
  17 +@Retention(RetentionPolicy.RUNTIME)
  18 +@Target(ElementType.FIELD)
  19 +@JacksonAnnotationsInside
  20 +@JsonSerialize(using = SensitiveJsonSerializer.class)
  21 +public @interface Sensitive
  22 +{
  23 + DesensitizedType desensitizedType();
  24 +}
  1 +package com.ruoyi.common.config;
  2 +
  3 +import org.springframework.boot.context.properties.ConfigurationProperties;
  4 +import org.springframework.stereotype.Component;
  5 +
  6 +/**
  7 + * 读取项目相关配置
  8 + *
  9 + * @author ruoyi
  10 + */
  11 +@Component
  12 +@ConfigurationProperties(prefix = "ruoyi")
  13 +public class RuoYiConfig
  14 +{
  15 + /** 项目名称 */
  16 + private String name;
  17 +
  18 + /** 版本 */
  19 + private String version;
  20 +
  21 + /** 版权年份 */
  22 + private String copyrightYear;
  23 +
  24 + /** 上传路径 */
  25 + private static String profile;
  26 +
  27 + /** 获取地址开关 */
  28 + private static boolean addressEnabled;
  29 +
  30 + /** 验证码类型 */
  31 + private static String captchaType;
  32 +
  33 + public String getName()
  34 + {
  35 + return name;
  36 + }
  37 +
  38 + public void setName(String name)
  39 + {
  40 + this.name = name;
  41 + }
  42 +
  43 + public String getVersion()
  44 + {
  45 + return version;
  46 + }
  47 +
  48 + public void setVersion(String version)
  49 + {
  50 + this.version = version;
  51 + }
  52 +
  53 + public String getCopyrightYear()
  54 + {
  55 + return copyrightYear;
  56 + }
  57 +
  58 + public void setCopyrightYear(String copyrightYear)
  59 + {
  60 + this.copyrightYear = copyrightYear;
  61 + }
  62 +
  63 + public static String getProfile()
  64 + {
  65 + return profile;
  66 + }
  67 +
  68 + public void setProfile(String profile)
  69 + {
  70 + RuoYiConfig.profile = profile;
  71 + }
  72 +
  73 + public static boolean isAddressEnabled()
  74 + {
  75 + return addressEnabled;
  76 + }
  77 +
  78 + public void setAddressEnabled(boolean addressEnabled)
  79 + {
  80 + RuoYiConfig.addressEnabled = addressEnabled;
  81 + }
  82 +
  83 + public static String getCaptchaType() {
  84 + return captchaType;
  85 + }
  86 +
  87 + public void setCaptchaType(String captchaType) {
  88 + RuoYiConfig.captchaType = captchaType;
  89 + }
  90 +
  91 + /**
  92 + * 获取导入上传路径
  93 + */
  94 + public static String getImportPath()
  95 + {
  96 + return getProfile() + "/import";
  97 + }
  98 +
  99 + /**
  100 + * 获取头像上传路径
  101 + */
  102 + public static String getAvatarPath()
  103 + {
  104 + return getProfile() + "/avatar";
  105 + }
  106 +
  107 + /**
  108 + * 获取下载路径
  109 + */
  110 + public static String getDownloadPath()
  111 + {
  112 + return getProfile() + "/download/";
  113 + }
  114 +
  115 + /**
  116 + * 获取上传路径
  117 + */
  118 + public static String getUploadPath()
  119 + {
  120 + return getProfile() + "/upload";
  121 + }
  122 +}
  1 +package com.ruoyi.common.config.serializer;
  2 +
  3 +import java.io.IOException;
  4 +import java.util.Objects;
  5 +import com.fasterxml.jackson.core.JsonGenerator;
  6 +import com.fasterxml.jackson.databind.BeanProperty;
  7 +import com.fasterxml.jackson.databind.JsonMappingException;
  8 +import com.fasterxml.jackson.databind.JsonSerializer;
  9 +import com.fasterxml.jackson.databind.SerializerProvider;
  10 +import com.fasterxml.jackson.databind.ser.ContextualSerializer;
  11 +import com.ruoyi.common.annotation.Sensitive;
  12 +import com.ruoyi.common.core.domain.model.LoginUser;
  13 +import com.ruoyi.common.enums.DesensitizedType;
  14 +import com.ruoyi.common.utils.SecurityUtils;
  15 +
  16 +/**
  17 + * 数据脱敏序列化过滤
  18 + *
  19 + * @author ruoyi
  20 + */
  21 +public class SensitiveJsonSerializer extends JsonSerializer<String> implements ContextualSerializer
  22 +{
  23 + private DesensitizedType desensitizedType;
  24 +
  25 + @Override
  26 + public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException
  27 + {
  28 + if (desensitization())
  29 + {
  30 + gen.writeString(desensitizedType.desensitizer().apply(value));
  31 + }
  32 + else
  33 + {
  34 + gen.writeString(value);
  35 + }
  36 + }
  37 +
  38 + @Override
  39 + public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property)
  40 + throws JsonMappingException
  41 + {
  42 + Sensitive annotation = property.getAnnotation(Sensitive.class);
  43 + if (Objects.nonNull(annotation) && Objects.equals(String.class, property.getType().getRawClass()))
  44 + {
  45 + this.desensitizedType = annotation.desensitizedType();
  46 + return this;
  47 + }
  48 + return prov.findValueSerializer(property.getType(), property);
  49 + }
  50 +
  51 + /**
  52 + * 是否需要脱敏处理
  53 + */
  54 + private boolean desensitization()
  55 + {
  56 + try
  57 + {
  58 + LoginUser securityUser = SecurityUtils.getLoginUser();
  59 + // 管理员不脱敏
  60 + return !securityUser.getUser().isAdmin();
  61 + }
  62 + catch (Exception e)
  63 + {
  64 + return true;
  65 + }
  66 + }
  67 +}
  1 +package com.ruoyi.common.constant;
  2 +
  3 +/**
  4 + * 缓存的key 常量
  5 + *
  6 + * @author ruoyi
  7 + */
  8 +public class CacheConstants
  9 +{
  10 + /**
  11 + * 登录用户 redis key
  12 + */
  13 + public static final String LOGIN_TOKEN_KEY = "login_tokens:";
  14 +
  15 + /**
  16 + * 验证码 redis key
  17 + */
  18 + public static final String CAPTCHA_CODE_KEY = "captcha_codes:";
  19 +
  20 + /**
  21 + * 参数管理 cache key
  22 + */
  23 + public static final String SYS_CONFIG_KEY = "sys_config:";
  24 +
  25 + /**
  26 + * 字典管理 cache key
  27 + */
  28 + public static final String SYS_DICT_KEY = "sys_dict:";
  29 +
  30 + /**
  31 + * 防重提交 redis key
  32 + */
  33 + public static final String REPEAT_SUBMIT_KEY = "repeat_submit:";
  34 +
  35 + /**
  36 + * 限流 redis key
  37 + */
  38 + public static final String RATE_LIMIT_KEY = "rate_limit:";
  39 +
  40 + /**
  41 + * 登录账户密码错误次数 redis key
  42 + */
  43 + public static final String PWD_ERR_CNT_KEY = "pwd_err_cnt:";
  44 +}
  1 +package com.ruoyi.common.constant;
  2 +
  3 +import java.util.Locale;
  4 +import io.jsonwebtoken.Claims;
  5 +
  6 +/**
  7 + * 通用常量信息
  8 + *
  9 + * @author ruoyi
  10 + */
  11 +public class Constants
  12 +{
  13 + /**
  14 + * UTF-8 字符集
  15 + */
  16 + public static final String UTF8 = "UTF-8";
  17 +
  18 + /**
  19 + * GBK 字符集
  20 + */
  21 + public static final String GBK = "GBK";
  22 +
  23 + /**
  24 + * 系统语言
  25 + */
  26 + public static final Locale DEFAULT_LOCALE = Locale.SIMPLIFIED_CHINESE;
  27 +
  28 + /**
  29 + * www主域
  30 + */
  31 + public static final String WWW = "www.";
  32 +
  33 + /**
  34 + * http请求
  35 + */
  36 + public static final String HTTP = "http://";
  37 +
  38 + /**
  39 + * https请求
  40 + */
  41 + public static final String HTTPS = "https://";
  42 +
  43 + /**
  44 + * 通用成功标识
  45 + */
  46 + public static final String SUCCESS = "0";
  47 +
  48 + /**
  49 + * 通用失败标识
  50 + */
  51 + public static final String FAIL = "1";
  52 +
  53 + /**
  54 + * 登录成功
  55 + */
  56 + public static final String LOGIN_SUCCESS = "Success";
  57 +
  58 + /**
  59 + * 注销
  60 + */
  61 + public static final String LOGOUT = "Logout";
  62 +
  63 + /**
  64 + * 注册
  65 + */
  66 + public static final String REGISTER = "Register";
  67 +
  68 + /**
  69 + * 登录失败
  70 + */
  71 + public static final String LOGIN_FAIL = "Error";
  72 +
  73 + /**
  74 + * 所有权限标识
  75 + */
  76 + public static final String ALL_PERMISSION = "*:*:*";
  77 +
  78 + /**
  79 + * 管理员角色权限标识
  80 + */
  81 + public static final String SUPER_ADMIN = "admin";
  82 +
  83 + /**
  84 + * 角色权限分隔符
  85 + */
  86 + public static final String ROLE_DELIMETER = ",";
  87 +
  88 + /**
  89 + * 权限标识分隔符
  90 + */
  91 + public static final String PERMISSION_DELIMETER = ",";
  92 +
  93 + /**
  94 + * 验证码有效期(分钟)
  95 + */
  96 + public static final Integer CAPTCHA_EXPIRATION = 2;
  97 +
  98 + /**
  99 + * 令牌
  100 + */
  101 + public static final String TOKEN = "token";
  102 +
  103 + /**
  104 + * 令牌前缀
  105 + */
  106 + public static final String TOKEN_PREFIX = "Bearer ";
  107 +
  108 + /**
  109 + * 令牌前缀
  110 + */
  111 + public static final String LOGIN_USER_KEY = "login_user_key";
  112 +
  113 + /**
  114 + * 用户ID
  115 + */
  116 + public static final String JWT_USERID = "userid";
  117 +
  118 + /**
  119 + * 用户名称
  120 + */
  121 + public static final String JWT_USERNAME = Claims.SUBJECT;
  122 +
  123 + /**
  124 + * 用户头像
  125 + */
  126 + public static final String JWT_AVATAR = "avatar";
  127 +
  128 + /**
  129 + * 创建时间
  130 + */
  131 + public static final String JWT_CREATED = "created";
  132 +
  133 + /**
  134 + * 用户权限
  135 + */
  136 + public static final String JWT_AUTHORITIES = "authorities";
  137 +
  138 + /**
  139 + * 资源映射路径 前缀
  140 + */
  141 + public static final String RESOURCE_PREFIX = "/profile";
  142 +
  143 + /**
  144 + * RMI 远程方法调用
  145 + */
  146 + public static final String LOOKUP_RMI = "rmi:";
  147 +
  148 + /**
  149 + * LDAP 远程方法调用
  150 + */
  151 + public static final String LOOKUP_LDAP = "ldap:";
  152 +
  153 + /**
  154 + * LDAPS 远程方法调用
  155 + */
  156 + public static final String LOOKUP_LDAPS = "ldaps:";
  157 +
  158 + /**
  159 + * 自动识别json对象白名单配置(仅允许解析的包名,范围越小越安全)
  160 + */
  161 + public static final String[] JSON_WHITELIST_STR = { "org.springframework", "com.ruoyi" };
  162 +
  163 + /**
  164 + * 定时任务白名单配置(仅允许访问的包名,如其他需要可以自行添加)
  165 + */
  166 + public static final String[] JOB_WHITELIST_STR = { "com.ruoyi.quartz.task" };
  167 +
  168 + /**
  169 + * 定时任务违规的字符
  170 + */
  171 + public static final String[] JOB_ERROR_STR = { "java.net.URL", "javax.naming.InitialContext", "org.yaml.snakeyaml",
  172 + "org.springframework", "org.apache", "com.ruoyi.common.utils.file", "com.ruoyi.common.config", "com.ruoyi.generator" };
  173 +}
  1 +package com.ruoyi.common.constant;
  2 +
  3 +/**
  4 + * 代码生成通用常量
  5 + *
  6 + * @author ruoyi
  7 + */
  8 +public class GenConstants
  9 +{
  10 + /** 单表(增删改查) */
  11 + public static final String TPL_CRUD = "crud";
  12 +
  13 + /** 树表(增删改查) */
  14 + public static final String TPL_TREE = "tree";
  15 +
  16 + /** 主子表(增删改查) */
  17 + public static final String TPL_SUB = "sub";
  18 +
  19 + /** 树编码字段 */
  20 + public static final String TREE_CODE = "treeCode";
  21 +
  22 + /** 树父编码字段 */
  23 + public static final String TREE_PARENT_CODE = "treeParentCode";
  24 +
  25 + /** 树名称字段 */
  26 + public static final String TREE_NAME = "treeName";
  27 +
  28 + /** 上级菜单ID字段 */
  29 + public static final String PARENT_MENU_ID = "parentMenuId";
  30 +
  31 + /** 上级菜单名称字段 */
  32 + public static final String PARENT_MENU_NAME = "parentMenuName";
  33 +
  34 + /** 数据库字符串类型 */
  35 + public static final String[] COLUMNTYPE_STR = { "char", "varchar", "nvarchar", "varchar2" };
  36 +
  37 + /** 数据库文本类型 */
  38 + public static final String[] COLUMNTYPE_TEXT = { "tinytext", "text", "mediumtext", "longtext" };
  39 +
  40 + /** 数据库时间类型 */
  41 + public static final String[] COLUMNTYPE_TIME = { "datetime", "time", "date", "timestamp" };
  42 +
  43 + /** 数据库数字类型 */
  44 + public static final String[] COLUMNTYPE_NUMBER = { "tinyint", "smallint", "mediumint", "int", "number", "integer",
  45 + "bit", "bigint", "float", "double", "decimal" };
  46 +
  47 + /** 页面不需要编辑字段 */
  48 + public static final String[] COLUMNNAME_NOT_EDIT = { "id", "create_by", "create_time", "del_flag" };
  49 +
  50 + /** 页面不需要显示的列表字段 */
  51 + public static final String[] COLUMNNAME_NOT_LIST = { "id", "create_by", "create_time", "del_flag", "update_by",
  52 + "update_time" };
  53 +
  54 + /** 页面不需要查询字段 */
  55 + public static final String[] COLUMNNAME_NOT_QUERY = { "id", "create_by", "create_time", "del_flag", "update_by",
  56 + "update_time", "remark" };
  57 +
  58 + /** Entity基类字段 */
  59 + public static final String[] BASE_ENTITY = { "createBy", "createTime", "updateBy", "updateTime", "remark" };
  60 +
  61 + /** Tree基类字段 */
  62 + public static final String[] TREE_ENTITY = { "parentName", "parentId", "orderNum", "ancestors", "children" };
  63 +
  64 + /** 文本框 */
  65 + public static final String HTML_INPUT = "input";
  66 +
  67 + /** 文本域 */
  68 + public static final String HTML_TEXTAREA = "textarea";
  69 +
  70 + /** 下拉框 */
  71 + public static final String HTML_SELECT = "select";
  72 +
  73 + /** 单选框 */
  74 + public static final String HTML_RADIO = "radio";
  75 +
  76 + /** 复选框 */
  77 + public static final String HTML_CHECKBOX = "checkbox";
  78 +
  79 + /** 日期控件 */
  80 + public static final String HTML_DATETIME = "datetime";
  81 +
  82 + /** 图片上传控件 */
  83 + public static final String HTML_IMAGE_UPLOAD = "imageUpload";
  84 +
  85 + /** 文件上传控件 */
  86 + public static final String HTML_FILE_UPLOAD = "fileUpload";
  87 +
  88 + /** 富文本控件 */
  89 + public static final String HTML_EDITOR = "editor";
  90 +
  91 + /** 字符串类型 */
  92 + public static final String TYPE_STRING = "String";
  93 +
  94 + /** 整型 */
  95 + public static final String TYPE_INTEGER = "Integer";
  96 +
  97 + /** 长整型 */
  98 + public static final String TYPE_LONG = "Long";
  99 +
  100 + /** 浮点型 */
  101 + public static final String TYPE_DOUBLE = "Double";
  102 +
  103 + /** 高精度计算类型 */
  104 + public static final String TYPE_BIGDECIMAL = "BigDecimal";
  105 +
  106 + /** 时间类型 */
  107 + public static final String TYPE_DATE = "Date";
  108 +
  109 + /** 模糊查询 */
  110 + public static final String QUERY_LIKE = "LIKE";
  111 +
  112 + /** 相等查询 */
  113 + public static final String QUERY_EQ = "EQ";
  114 +
  115 + /** 需要 */
  116 + public static final String REQUIRE = "1";
  117 +}
  1 +package com.ruoyi.common.constant;
  2 +
  3 +/**
  4 + * 返回状态码
  5 + *
  6 + * @author ruoyi
  7 + */
  8 +public class HttpStatus
  9 +{
  10 + /**
  11 + * 操作成功
  12 + */
  13 + public static final int SUCCESS = 200;
  14 +
  15 + /**
  16 + * 对象创建成功
  17 + */
  18 + public static final int CREATED = 201;
  19 +
  20 + /**
  21 + * 请求已经被接受
  22 + */
  23 + public static final int ACCEPTED = 202;
  24 +
  25 + /**
  26 + * 操作已经执行成功,但是没有返回数据
  27 + */
  28 + public static final int NO_CONTENT = 204;
  29 +
  30 + /**
  31 + * 资源已被移除
  32 + */
  33 + public static final int MOVED_PERM = 301;
  34 +
  35 + /**
  36 + * 重定向
  37 + */
  38 + public static final int SEE_OTHER = 303;
  39 +
  40 + /**
  41 + * 资源没有被修改
  42 + */
  43 + public static final int NOT_MODIFIED = 304;
  44 +
  45 + /**
  46 + * 参数列表错误(缺少,格式不匹配)
  47 + */
  48 + public static final int BAD_REQUEST = 400;
  49 +
  50 + /**
  51 + * 未授权
  52 + */
  53 + public static final int UNAUTHORIZED = 401;
  54 +
  55 + /**
  56 + * 访问受限,授权过期
  57 + */
  58 + public static final int FORBIDDEN = 403;
  59 +
  60 + /**
  61 + * 资源,服务未找到
  62 + */
  63 + public static final int NOT_FOUND = 404;
  64 +
  65 + /**
  66 + * 不允许的http方法
  67 + */
  68 + public static final int BAD_METHOD = 405;
  69 +
  70 + /**
  71 + * 资源冲突,或者资源被锁
  72 + */
  73 + public static final int CONFLICT = 409;
  74 +
  75 + /**
  76 + * 不支持的数据,媒体类型
  77 + */
  78 + public static final int UNSUPPORTED_TYPE = 415;
  79 +
  80 + /**
  81 + * 系统内部错误
  82 + */
  83 + public static final int ERROR = 500;
  84 +
  85 + /**
  86 + * 接口未实现
  87 + */
  88 + public static final int NOT_IMPLEMENTED = 501;
  89 +
  90 + /**
  91 + * 系统警告消息
  92 + */
  93 + public static final int WARN = 601;
  94 +}
  1 +package com.ruoyi.common.constant;
  2 +
  3 +/**
  4 + * 任务调度通用常量
  5 + *
  6 + * @author ruoyi
  7 + */
  8 +public class ScheduleConstants
  9 +{
  10 + public static final String TASK_CLASS_NAME = "TASK_CLASS_NAME";
  11 +
  12 + /** 执行目标key */
  13 + public static final String TASK_PROPERTIES = "TASK_PROPERTIES";
  14 +
  15 + /** 默认 */
  16 + public static final String MISFIRE_DEFAULT = "0";
  17 +
  18 + /** 立即触发执行 */
  19 + public static final String MISFIRE_IGNORE_MISFIRES = "1";
  20 +
  21 + /** 触发一次执行 */
  22 + public static final String MISFIRE_FIRE_AND_PROCEED = "2";
  23 +
  24 + /** 不触发立即执行 */
  25 + public static final String MISFIRE_DO_NOTHING = "3";
  26 +
  27 + public enum Status
  28 + {
  29 + /**
  30 + * 正常
  31 + */
  32 + NORMAL("0"),
  33 + /**
  34 + * 暂停
  35 + */
  36 + PAUSE("1");
  37 +
  38 + private String value;
  39 +
  40 + private Status(String value)
  41 + {
  42 + this.value = value;
  43 + }
  44 +
  45 + public String getValue()
  46 + {
  47 + return value;
  48 + }
  49 + }
  50 +}
  1 +package com.ruoyi.common.constant;
  2 +
  3 +/**
  4 + * 用户常量信息
  5 + *
  6 + * @author ruoyi
  7 + */
  8 +public class UserConstants
  9 +{
  10 + /**
  11 + * 平台内系统用户的唯一标志
  12 + */
  13 + public static final String SYS_USER = "SYS_USER";
  14 +
  15 + /** 正常状态 */
  16 + public static final String NORMAL = "0";
  17 +
  18 + /** 异常状态 */
  19 + public static final String EXCEPTION = "1";
  20 +
  21 + /** 用户封禁状态 */
  22 + public static final String USER_DISABLE = "1";
  23 +
  24 + /** 角色封禁状态 */
  25 + public static final String ROLE_DISABLE = "1";
  26 +
  27 + /** 部门正常状态 */
  28 + public static final String DEPT_NORMAL = "0";
  29 +
  30 + /** 部门停用状态 */
  31 + public static final String DEPT_DISABLE = "1";
  32 +
  33 + /** 字典正常状态 */
  34 + public static final String DICT_NORMAL = "0";
  35 +
  36 + /** 是否为系统默认(是) */
  37 + public static final String YES = "Y";
  38 +
  39 + /** 是否菜单外链(是) */
  40 + public static final String YES_FRAME = "0";
  41 +
  42 + /** 是否菜单外链(否) */
  43 + public static final String NO_FRAME = "1";
  44 +
  45 + /** 菜单类型(目录) */
  46 + public static final String TYPE_DIR = "M";
  47 +
  48 + /** 菜单类型(菜单) */
  49 + public static final String TYPE_MENU = "C";
  50 +
  51 + /** 菜单类型(按钮) */
  52 + public static final String TYPE_BUTTON = "F";
  53 +
  54 + /** Layout组件标识 */
  55 + public final static String LAYOUT = "Layout";
  56 +
  57 + /** ParentView组件标识 */
  58 + public final static String PARENT_VIEW = "ParentView";
  59 +
  60 + /** InnerLink组件标识 */
  61 + public final static String INNER_LINK = "InnerLink";
  62 +
  63 + /** 校验是否唯一的返回标识 */
  64 + public final static boolean UNIQUE = true;
  65 + public final static boolean NOT_UNIQUE = false;
  66 +
  67 + /**
  68 + * 用户名长度限制
  69 + */
  70 + public static final int USERNAME_MIN_LENGTH = 2;
  71 + public static final int USERNAME_MAX_LENGTH = 20;
  72 +
  73 + /**
  74 + * 密码长度限制
  75 + */
  76 + public static final int PASSWORD_MIN_LENGTH = 5;
  77 + public static final int PASSWORD_MAX_LENGTH = 20;
  78 +}
  1 +package com.ruoyi.common.core.controller;
  2 +
  3 +import java.beans.PropertyEditorSupport;
  4 +import java.util.Date;
  5 +import java.util.List;
  6 +import org.slf4j.Logger;
  7 +import org.slf4j.LoggerFactory;
  8 +import org.springframework.web.bind.WebDataBinder;
  9 +import org.springframework.web.bind.annotation.InitBinder;
  10 +import com.github.pagehelper.PageHelper;
  11 +import com.github.pagehelper.PageInfo;
  12 +import com.ruoyi.common.constant.HttpStatus;
  13 +import com.ruoyi.common.core.domain.AjaxResult;
  14 +import com.ruoyi.common.core.domain.model.LoginUser;
  15 +import com.ruoyi.common.core.page.PageDomain;
  16 +import com.ruoyi.common.core.page.TableDataInfo;
  17 +import com.ruoyi.common.core.page.TableSupport;
  18 +import com.ruoyi.common.utils.DateUtils;
  19 +import com.ruoyi.common.utils.PageUtils;
  20 +import com.ruoyi.common.utils.SecurityUtils;
  21 +import com.ruoyi.common.utils.StringUtils;
  22 +import com.ruoyi.common.utils.sql.SqlUtil;
  23 +
  24 +/**
  25 + * web层通用数据处理
  26 + *
  27 + * @author ruoyi
  28 + */
  29 +public class BaseController
  30 +{
  31 + protected final Logger logger = LoggerFactory.getLogger(this.getClass());
  32 +
  33 + /**
  34 + * 将前台传递过来的日期格式的字符串,自动转化为Date类型
  35 + */
  36 + @InitBinder
  37 + public void initBinder(WebDataBinder binder)
  38 + {
  39 + // Date 类型转换
  40 + binder.registerCustomEditor(Date.class, new PropertyEditorSupport()
  41 + {
  42 + @Override
  43 + public void setAsText(String text)
  44 + {
  45 + setValue(DateUtils.parseDate(text));
  46 + }
  47 + });
  48 + }
  49 +
  50 + /**
  51 + * 设置请求分页数据
  52 + */
  53 + protected void startPage()
  54 + {
  55 + PageUtils.startPage();
  56 + }
  57 +
  58 + /**
  59 + * 设置请求排序数据
  60 + */
  61 + protected void startOrderBy()
  62 + {
  63 + PageDomain pageDomain = TableSupport.buildPageRequest();
  64 + if (StringUtils.isNotEmpty(pageDomain.getOrderBy()))
  65 + {
  66 + String orderBy = SqlUtil.escapeOrderBySql(pageDomain.getOrderBy());
  67 + PageHelper.orderBy(orderBy);
  68 + }
  69 + }
  70 +
  71 + /**
  72 + * 清理分页的线程变量
  73 + */
  74 + protected void clearPage()
  75 + {
  76 + PageUtils.clearPage();
  77 + }
  78 +
  79 + /**
  80 + * 响应请求分页数据
  81 + */
  82 + @SuppressWarnings({ "rawtypes", "unchecked" })
  83 + protected TableDataInfo getDataTable(List<?> list)
  84 + {
  85 + TableDataInfo rspData = new TableDataInfo();
  86 + rspData.setCode(HttpStatus.SUCCESS);
  87 + rspData.setMsg("查询成功");
  88 + rspData.setRows(list);
  89 + rspData.setTotal(new PageInfo(list).getTotal());
  90 + return rspData;
  91 + }
  92 +
  93 + /**
  94 + * 返回成功
  95 + */
  96 + public AjaxResult success()
  97 + {
  98 + return AjaxResult.success();
  99 + }
  100 +
  101 + /**
  102 + * 返回失败消息
  103 + */
  104 + public AjaxResult error()
  105 + {
  106 + return AjaxResult.error();
  107 + }
  108 +
  109 + /**
  110 + * 返回成功消息
  111 + */
  112 + public AjaxResult success(String message)
  113 + {
  114 + return AjaxResult.success(message);
  115 + }
  116 +
  117 + /**
  118 + * 返回成功消息
  119 + */
  120 + public AjaxResult success(Object data)
  121 + {
  122 + return AjaxResult.success(data);
  123 + }
  124 +
  125 + /**
  126 + * 返回失败消息
  127 + */
  128 + public AjaxResult error(String message)
  129 + {
  130 + return AjaxResult.error(message);
  131 + }
  132 +
  133 + /**
  134 + * 返回警告消息
  135 + */
  136 + public AjaxResult warn(String message)
  137 + {
  138 + return AjaxResult.warn(message);
  139 + }
  140 +
  141 + /**
  142 + * 响应返回结果
  143 + *
  144 + * @param rows 影响行数
  145 + * @return 操作结果
  146 + */
  147 + protected AjaxResult toAjax(int rows)
  148 + {
  149 + return rows > 0 ? AjaxResult.success() : AjaxResult.error();
  150 + }
  151 +
  152 + /**
  153 + * 响应返回结果
  154 + *
  155 + * @param result 结果
  156 + * @return 操作结果
  157 + */
  158 + protected AjaxResult toAjax(boolean result)
  159 + {
  160 + return result ? success() : error();
  161 + }
  162 +
  163 + /**
  164 + * 页面跳转
  165 + */
  166 + public String redirect(String url)
  167 + {
  168 + return StringUtils.format("redirect:{}", url);
  169 + }
  170 +
  171 + /**
  172 + * 获取用户缓存信息
  173 + */
  174 + public LoginUser getLoginUser()
  175 + {
  176 + return SecurityUtils.getLoginUser();
  177 + }
  178 +
  179 + /**
  180 + * 获取登录用户id
  181 + */
  182 + public Long getUserId()
  183 + {
  184 + return getLoginUser().getUserId();
  185 + }
  186 +
  187 + /**
  188 + * 获取登录部门id
  189 + */
  190 + public Long getDeptId()
  191 + {
  192 + return getLoginUser().getDeptId();
  193 + }
  194 +
  195 + /**
  196 + * 获取登录用户名
  197 + */
  198 + public String getUsername()
  199 + {
  200 + return getLoginUser().getUsername();
  201 + }
  202 +}