mirror of
https://gitee.com/y_project/RuoYi-Vue.git
synced 2025-12-08 15:02:29 +08:00
Compare commits
261 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 99e66bf11c | |||
| a96d4bf2ed | |||
| 8264b8fb31 | |||
| 4ec32367fd | |||
| 9e8aa14348 | |||
| 10f68b97af | |||
| 8eff83e2b4 | |||
| 7b064d84bb | |||
| 88560a7aa5 | |||
| e14f40670a | |||
| 5b98495067 | |||
| 259dc67728 | |||
| bc7a607033 | |||
| 161cd2b1ea | |||
| 7480fb4020 | |||
| 906c3a68b8 | |||
| 084bab3494 | |||
| cc0efa3330 | |||
| f46b1bbebd | |||
| e5f30b1a19 | |||
| 1140a6c333 | |||
| 86ca404dbf | |||
| 11320b2e13 | |||
| 905c08fb2c | |||
| 9386645150 | |||
| bf3e2115e3 | |||
| 61eb54e4a1 | |||
| d93e2b9df0 | |||
| 50339c6f73 | |||
| b83f2ff60b | |||
| 66128f140f | |||
| 8c990ae9fc | |||
| 8836d31d77 | |||
| 2f624ab5f4 | |||
| 80f96b4915 | |||
| 7e9d050432 | |||
| 649cfe8652 | |||
| e9ae7ae5f3 | |||
| 3cc6fb5535 | |||
| a7bfd3b2d6 | |||
| 08d0326718 | |||
| 3f4ac65a31 | |||
| 94d5c174aa | |||
| e719ac8cff | |||
| a9bcfc66c3 | |||
| 36b900cef8 | |||
| ac9302e2a2 | |||
| 0f7e3a744e | |||
| 45656b271a | |||
| 323e3b7371 | |||
| bfbaa9e7b5 | |||
| 2253a146b3 | |||
| 2070a9252a | |||
| e231d78469 | |||
| f74454b61a | |||
| d71ee5dba1 | |||
| 78b1ac4a60 | |||
| 966a17123f | |||
| 42bb8f6445 | |||
| 72e4cd9fb3 | |||
| 1525bd8b54 | |||
| b8e2eeaaf8 | |||
| cbcfabee2a | |||
| e6d0599b25 | |||
| b224cebab7 | |||
| f880dee7a4 | |||
| f16875c9af | |||
| a90355eb5e | |||
| 386f32a3b7 | |||
| 4ca30f08d6 | |||
| 73f881c7d3 | |||
| b357aedaa3 | |||
| 8cf8c8acd0 | |||
| fbab383bd7 | |||
| d8255edf84 | |||
| eff42d8b0f | |||
| 1f753e3d84 | |||
| 72d4069537 | |||
| 76205588f0 | |||
| 7b4ba0146b | |||
| 3963e86537 | |||
| 7098acc968 | |||
| 079ac841f3 | |||
| 0434b4ca7a | |||
| 8873dc9b64 | |||
| 078a3aad5a | |||
| 207a9ce855 | |||
| 9ced1e9766 | |||
| 1926840204 | |||
| 006d46ad07 | |||
| f5a1b0c550 | |||
| 4a78fe116d | |||
| 3e95dd21f2 | |||
| 491b0f3db8 | |||
| 16d8b71e21 | |||
| 90260ce2f9 | |||
| d58942c506 | |||
| 6a742e1d1b | |||
| 5b61aea064 | |||
| 45ef542687 | |||
| 4ac7a1aa1f | |||
| c5e4459bb8 | |||
| 8f67bf416b | |||
| ab99a72b65 | |||
| 7c9423657e | |||
| 128b186b8e | |||
| 68ac40eda9 | |||
| 5557433235 | |||
| 2517e9dddb | |||
| a0595711ca | |||
| 1ffb6379f7 | |||
| 4d5c204b9a | |||
| 8ee740ef49 | |||
| 6a811d9824 | |||
| 1c9c076280 | |||
| 918f94d8da | |||
| 5db610d16f | |||
| cc6f983ee3 | |||
| afe2852bbb | |||
| 9c7d302b94 | |||
| 9e66ada9c1 | |||
| a63eec3be4 | |||
| 51990695f5 | |||
| a7b8f2ee90 | |||
| 67ba621db6 | |||
| 05feef34c7 | |||
| be0b36f6b9 | |||
| 69bbccbd76 | |||
| 1eb7b3a03f | |||
| 4661edf7f0 | |||
| 8485605145 | |||
| a4fe88ca61 | |||
| af15a3b274 | |||
| 571393c32c | |||
| eff06c110f | |||
| 6a18e06339 | |||
| f04ca57f7a | |||
| b4f2a4f7dd | |||
| de0a43285f | |||
| 4952ac0a3d | |||
| 6ad345331d | |||
| 5a634a4ecd | |||
| f5b865a2e1 | |||
| f7595e4998 | |||
| 64e71302e4 | |||
| 2e99c68ed0 | |||
| af0e0a110e | |||
| bef86e041f | |||
| 1067567f1c | |||
| 0a670fdfd7 | |||
| a33090c90e | |||
| 5061558e94 | |||
| e7f088552f | |||
| 5c4682e060 | |||
| 5d5ebbec1a | |||
| 23544bab5e | |||
| c5ef0336a4 | |||
| a907f8485c | |||
| 66200c4203 | |||
| 5a25212509 | |||
| 95742bf5bd | |||
| 4eea8cdbb0 | |||
| cfce89be7d | |||
| ce7e12ec1d | |||
| 4f02f3c6f7 | |||
| 5ca9bd6876 | |||
| 020a2d4670 | |||
| 635d621b7b | |||
| 4cbd56cbd7 | |||
| dcb9cb3d13 | |||
| 628bc94a9a | |||
| 38ddefe2e6 | |||
| 7a090bda1e | |||
| 4e8dd706d5 | |||
| 641e550d7f | |||
| 81a01a1d9d | |||
| 6523fe59a2 | |||
| 90970eb9fe | |||
| 3402b69556 | |||
| 2c5e3e429f | |||
| 96ba768f50 | |||
| 1268637e58 | |||
| 61caa7966b | |||
| a5f95eddab | |||
| ade70583e9 | |||
| 5676cf9ad4 | |||
| c3d0cd5f8c | |||
| eb96afee64 | |||
| 5873da87ae | |||
| 4f1933e2e4 | |||
| 9926f73cd0 | |||
| 492919d4af | |||
| a7ff50e695 | |||
| 71e7e1d6dd | |||
| 5073f95ccd | |||
| c3a727b2fd | |||
| 19eaad0129 | |||
| 565cbb8c7a | |||
| b2cf949956 | |||
| 3fec133c69 | |||
| c9de6fcd82 | |||
| 22ee2c2e94 | |||
| f11db02ff8 | |||
| d5f5c5d066 | |||
| 4536906b21 | |||
| 9748e10339 | |||
| b08a6ce3f6 | |||
| 3039b745a9 | |||
| 39298d803c | |||
| 09bb3e15c6 | |||
| 3b8a68c4cf | |||
| 9aae863ce3 | |||
| 963247df43 | |||
| 7d874e31cf | |||
| 1bb6342bcb | |||
| 27acbe5b73 | |||
| 6474a17100 | |||
| 142f6ad6a0 | |||
| b4bdd4f306 | |||
| 74ba681fee | |||
| 8f2b3ac465 | |||
| 7eee3b9f02 | |||
| 27e34c2f0a | |||
| 836180fe0e | |||
| 06fbda5324 | |||
| bf313b17da | |||
| a8b9485a29 | |||
| 101e15d83f | |||
| ebb9f15a75 | |||
| cd137bd9fc | |||
| 07bde5f88a | |||
| 6fffa02acf | |||
| dc48f9858b | |||
| a6b2ac5dcd | |||
| c0685b7f7f | |||
| fb2d616c57 | |||
| 6ff6853082 | |||
| f8014ae969 | |||
| 1de2b7a57e | |||
| f01aa37394 | |||
| 4517dea98d | |||
| e21396870f | |||
| b67f6a0fec | |||
| 42d8104505 | |||
| f40a0eab23 | |||
| b6153d1aef | |||
| a2c585daa4 | |||
| 5a60bf0b0a | |||
| 9dcddc7876 | |||
| b970185536 | |||
| a64a029323 | |||
| 78f4d1c85b | |||
| bf83fe568b | |||
| 6505432bf4 | |||
| a32a931d24 | |||
| 4d72fb4289 | |||
| 186c04d90a | |||
| c542b7ac32 | |||
| 3607e008a3 | |||
| 5b8edbf381 | |||
| 03f7bc0f3f |
@ -1,11 +1,11 @@
|
|||||||
<p align="center">
|
<p align="center">
|
||||||
<img alt="logo" src="https://oscimg.oschina.net/oscnet/up-d3d0a9303e11d522a06cd263f3079027715.png">
|
<img alt="logo" src="https://oscimg.oschina.net/oscnet/up-d3d0a9303e11d522a06cd263f3079027715.png">
|
||||||
</p>
|
</p>
|
||||||
<h1 align="center" style="margin: 30px 0 30px; font-weight: bold;">RuoYi v3.8.4</h1>
|
<h1 align="center" style="margin: 30px 0 30px; font-weight: bold;">RuoYi v3.8.8</h1>
|
||||||
<h4 align="center">基于SpringBoot+Vue前后端分离的Java快速开发框架</h4>
|
<h4 align="center">基于SpringBoot+Vue前后端分离的Java快速开发框架</h4>
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://gitee.com/y_project/RuoYi-Vue/stargazers"><img src="https://gitee.com/y_project/RuoYi-Vue/badge/star.svg?theme=dark"></a>
|
<a href="https://gitee.com/y_project/RuoYi-Vue/stargazers"><img src="https://gitee.com/y_project/RuoYi-Vue/badge/star.svg?theme=dark"></a>
|
||||||
<a href="https://gitee.com/y_project/RuoYi-Vue"><img src="https://img.shields.io/badge/RuoYi-v3.8.4-brightgreen.svg"></a>
|
<a href="https://gitee.com/y_project/RuoYi-Vue"><img src="https://img.shields.io/badge/RuoYi-v3.8.8-brightgreen.svg"></a>
|
||||||
<a href="https://gitee.com/y_project/RuoYi-Vue/blob/master/LICENSE"><img src="https://img.shields.io/github/license/mashape/apistatus.svg"></a>
|
<a href="https://gitee.com/y_project/RuoYi-Vue/blob/master/LICENSE"><img src="https://img.shields.io/github/license/mashape/apistatus.svg"></a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
@ -21,7 +21,6 @@
|
|||||||
* 提供了技术栈([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),保持同步更新。
|
* 提供了技术栈([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),保持同步更新。
|
||||||
* 提供了单应用版本[RuoYi-Vue-fast](https://github.com/yangzongzhuan/RuoYi-Vue-fast),Oracle版本[RuoYi-Vue-Oracle](https://github.com/yangzongzhuan/RuoYi-Vue-Oracle),保持同步更新。
|
* 提供了单应用版本[RuoYi-Vue-fast](https://github.com/yangzongzhuan/RuoYi-Vue-fast),Oracle版本[RuoYi-Vue-Oracle](https://github.com/yangzongzhuan/RuoYi-Vue-Oracle),保持同步更新。
|
||||||
* 不分离版本,请移步[RuoYi](https://gitee.com/y_project/RuoYi),微服务版本,请移步[RuoYi-Cloud](https://gitee.com/y_project/RuoYi-Cloud)
|
* 不分离版本,请移步[RuoYi](https://gitee.com/y_project/RuoYi),微服务版本,请移步[RuoYi-Cloud](https://gitee.com/y_project/RuoYi-Cloud)
|
||||||
* 特别鸣谢:[element](https://github.com/ElemeFE/element),[vue-element-admin](https://github.com/PanJiaChen/vue-element-admin),[eladmin-web](https://github.com/elunez/eladmin-web)。
|
|
||||||
* 阿里云折扣场:[点我进入](http://aly.ruoyi.vip),腾讯云秒杀场:[点我进入](http://txy.ruoyi.vip)
|
* 阿里云折扣场:[点我进入](http://aly.ruoyi.vip),腾讯云秒杀场:[点我进入](http://txy.ruoyi.vip)
|
||||||
* 阿里云优惠券:[点我领取](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)
|
* 阿里云优惠券:[点我领取](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)
|
||||||
|
|
||||||
@ -94,4 +93,4 @@
|
|||||||
|
|
||||||
## 若依前后端分离交流群
|
## 若依前后端分离交流群
|
||||||
|
|
||||||
QQ群: [](https://jq.qq.com/?_wv=1027&k=5bVB1og) [](https://jq.qq.com/?_wv=1027&k=5eiA4DH) [](https://jq.qq.com/?_wv=1027&k=5AxMKlC) [](https://jq.qq.com/?_wv=1027&k=51G72yr) [](https://jq.qq.com/?_wv=1027&k=VvjN2nvu) [](https://jq.qq.com/?_wv=1027&k=5vYAqA05) [](https://jq.qq.com/?_wv=1027&k=kOIINEb5) [](https://jq.qq.com/?_wv=1027&k=UKtX5jhs) [](https://jq.qq.com/?_wv=1027&k=EI9an8lJ) [](https://jq.qq.com/?_wv=1027&k=SWCtLnMz) [](https://jq.qq.com/?_wv=1027&k=96Dkdq0k) [](https://jq.qq.com/?_wv=1027&k=0fsNiYZt) 点击按钮入群。
|
QQ群: [](https://jq.qq.com/?_wv=1027&k=5bVB1og) [](https://jq.qq.com/?_wv=1027&k=5eiA4DH) [](https://jq.qq.com/?_wv=1027&k=5AxMKlC) [](https://jq.qq.com/?_wv=1027&k=51G72yr) [](https://jq.qq.com/?_wv=1027&k=VvjN2nvu) [](https://jq.qq.com/?_wv=1027&k=5vYAqA05) [](https://jq.qq.com/?_wv=1027&k=kOIINEb5) [](https://jq.qq.com/?_wv=1027&k=UKtX5jhs) [](https://jq.qq.com/?_wv=1027&k=EI9an8lJ) [](https://jq.qq.com/?_wv=1027&k=SWCtLnMz) [](https://jq.qq.com/?_wv=1027&k=96Dkdq0k) [](https://jq.qq.com/?_wv=1027&k=0fsNiYZt) [](https://jq.qq.com/?_wv=1027&k=7xw4xUG1) [](https://jq.qq.com/?_wv=1027&k=eCx8eyoJ) [](https://jq.qq.com/?_wv=1027&k=SpyH2875) [](https://jq.qq.com/?_wv=1027&k=tKEt51dz) [](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=0vBbSb0ztbBgVtn3kJS-Q4HUNYwip89G&authKey=8irq5PhutrZmWIvsUsklBxhj57l%2F1nOZqjzigkXZVoZE451GG4JHPOqW7AW6cf0T&noverify=0&group_code=143961921) [](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=ZFAPAbp09S2ltvwrJzp7wGlbopsc0rwi&authKey=HB2cxpxP2yspk%2Bo3WKTBfktRCccVkU26cgi5B16u0KcAYrVu7sBaE7XSEqmMdFQp&noverify=0&group_code=174951577) [](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=Fn2aF5IHpwsy8j6VlalNJK6qbwFLFHat&authKey=uyIT%2B97x2AXj3odyXpsSpVaPMC%2Bidw0LxG5MAtEqlrcBcWJUA%2FeS43rsF1Tg7IRJ&noverify=0&group_code=161281055) [](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=XIzkm_mV2xTsUtFxo63bmicYoDBA6Ifm&authKey=dDW%2F4qsmw3x9govoZY9w%2FoWAoC4wbHqGal%2BbqLzoS6VBarU8EBptIgPKN%2FviyC8j&noverify=0&group_code=138988063) [](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=DkugnCg68PevlycJSKSwjhFqfIgrWWwR&authKey=pR1Pa5lPIeGF%2FFtIk6d%2FGB5qFi0EdvyErtpQXULzo03zbhopBHLWcuqdpwY241R%2F&noverify=0&group_code=151450850) 点击按钮入群。
|
||||||
71
pom.xml
71
pom.xml
@ -6,43 +6,60 @@
|
|||||||
|
|
||||||
<groupId>com.ruoyi</groupId>
|
<groupId>com.ruoyi</groupId>
|
||||||
<artifactId>ruoyi</artifactId>
|
<artifactId>ruoyi</artifactId>
|
||||||
<version>3.8.4</version>
|
<version>3.8.8</version>
|
||||||
|
|
||||||
<name>ruoyi</name>
|
<name>ruoyi</name>
|
||||||
<url>http://www.ruoyi.vip</url>
|
<url>http://www.ruoyi.vip</url>
|
||||||
<description>若依管理系统</description>
|
<description>若依管理系统</description>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<ruoyi.version>3.8.4</ruoyi.version>
|
<ruoyi.version>3.8.8</ruoyi.version>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||||
<java.version>1.8</java.version>
|
<java.version>1.8</java.version>
|
||||||
<maven-jar-plugin.version>3.1.1</maven-jar-plugin.version>
|
<maven-jar-plugin.version>3.1.1</maven-jar-plugin.version>
|
||||||
<druid.version>1.2.11</druid.version>
|
<spring-framework.version>5.3.33</spring-framework.version>
|
||||||
|
<spring-security.version>5.7.12</spring-security.version>
|
||||||
|
<druid.version>1.2.23</druid.version>
|
||||||
<bitwalker.version>1.21</bitwalker.version>
|
<bitwalker.version>1.21</bitwalker.version>
|
||||||
<swagger.version>3.0.0</swagger.version>
|
<swagger.version>3.0.0</swagger.version>
|
||||||
<kaptcha.version>2.3.2</kaptcha.version>
|
<kaptcha.version>2.3.3</kaptcha.version>
|
||||||
<mybatis-spring-boot.version>2.2.2</mybatis-spring-boot.version>
|
<pagehelper.boot.version>1.4.7</pagehelper.boot.version>
|
||||||
<pagehelper.boot.version>1.4.3</pagehelper.boot.version>
|
<fastjson.version>2.0.43</fastjson.version>
|
||||||
<fastjson.version>2.0.14</fastjson.version>
|
<oshi.version>6.6.1</oshi.version>
|
||||||
<oshi.version>6.2.2</oshi.version>
|
<commons.io.version>2.13.0</commons.io.version>
|
||||||
<commons.io.version>2.11.0</commons.io.version>
|
|
||||||
<commons.fileupload.version>1.4</commons.fileupload.version>
|
|
||||||
<commons.collections.version>3.2.2</commons.collections.version>
|
|
||||||
<poi.version>4.1.2</poi.version>
|
<poi.version>4.1.2</poi.version>
|
||||||
<velocity.version>2.3</velocity.version>
|
<velocity.version>2.3</velocity.version>
|
||||||
<jwt.version>0.9.1</jwt.version>
|
<jwt.version>0.9.1</jwt.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<!-- 依赖声明 -->
|
<!-- 依赖声明 -->
|
||||||
<dependencyManagement>
|
<dependencyManagement>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
||||||
|
<!-- SpringFramework的依赖配置-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-framework-bom</artifactId>
|
||||||
|
<version>${spring-framework.version}</version>
|
||||||
|
<type>pom</type>
|
||||||
|
<scope>import</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- SpringSecurity的依赖配置-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.security</groupId>
|
||||||
|
<artifactId>spring-security-bom</artifactId>
|
||||||
|
<version>${spring-security.version}</version>
|
||||||
|
<type>pom</type>
|
||||||
|
<scope>import</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!-- SpringBoot的依赖配置-->
|
<!-- SpringBoot的依赖配置-->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-dependencies</artifactId>
|
<artifactId>spring-boot-dependencies</artifactId>
|
||||||
<version>2.5.14</version>
|
<version>2.5.15</version>
|
||||||
<type>pom</type>
|
<type>pom</type>
|
||||||
<scope>import</scope>
|
<scope>import</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
@ -61,13 +78,6 @@
|
|||||||
<version>${bitwalker.version}</version>
|
<version>${bitwalker.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- SpringBoot集成mybatis框架 -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.mybatis.spring.boot</groupId>
|
|
||||||
<artifactId>mybatis-spring-boot-starter</artifactId>
|
|
||||||
<version>${mybatis-spring-boot.version}</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- pagehelper 分页插件 -->
|
<!-- pagehelper 分页插件 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.github.pagehelper</groupId>
|
<groupId>com.github.pagehelper</groupId>
|
||||||
@ -102,13 +112,6 @@
|
|||||||
<version>${commons.io.version}</version>
|
<version>${commons.io.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- 文件上传工具类 -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>commons-fileupload</groupId>
|
|
||||||
<artifactId>commons-fileupload</artifactId>
|
|
||||||
<version>${commons.fileupload.version}</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- excel工具 -->
|
<!-- excel工具 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.poi</groupId>
|
<groupId>org.apache.poi</groupId>
|
||||||
@ -123,13 +126,6 @@
|
|||||||
<version>${velocity.version}</version>
|
<version>${velocity.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- collections工具类 -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>commons-collections</groupId>
|
|
||||||
<artifactId>commons-collections</artifactId>
|
|
||||||
<version>${commons.collections.version}</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- 阿里JSON解析器 -->
|
<!-- 阿里JSON解析器 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.alibaba.fastjson2</groupId>
|
<groupId>com.alibaba.fastjson2</groupId>
|
||||||
@ -146,7 +142,7 @@
|
|||||||
|
|
||||||
<!-- 验证码 -->
|
<!-- 验证码 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.github.penggle</groupId>
|
<groupId>pro.fessional</groupId>
|
||||||
<artifactId>kaptcha</artifactId>
|
<artifactId>kaptcha</artifactId>
|
||||||
<version>${kaptcha.version}</version>
|
<version>${kaptcha.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
@ -199,11 +195,6 @@
|
|||||||
</modules>
|
</modules>
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
|
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
|
|
||||||
</dependencies>
|
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
<plugin>
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>ruoyi</artifactId>
|
<artifactId>ruoyi</artifactId>
|
||||||
<groupId>com.ruoyi</groupId>
|
<groupId>com.ruoyi</groupId>
|
||||||
<version>3.8.4</version>
|
<version>3.8.8</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
@ -68,7 +68,7 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
<version>2.1.1.RELEASE</version>
|
<version>2.5.15</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<fork>true</fork> <!-- 如果没有该配置,devtools不会生效 -->
|
<fork>true</fork> <!-- 如果没有该配置,devtools不会生效 -->
|
||||||
</configuration>
|
</configuration>
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.TreeSet;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.data.redis.core.RedisCallback;
|
import org.springframework.data.redis.core.RedisCallback;
|
||||||
import org.springframework.data.redis.core.RedisTemplate;
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
@ -80,7 +81,7 @@ public class CacheController
|
|||||||
public AjaxResult getCacheKeys(@PathVariable String cacheName)
|
public AjaxResult getCacheKeys(@PathVariable String cacheName)
|
||||||
{
|
{
|
||||||
Set<String> cacheKeys = redisTemplate.keys(cacheName + "*");
|
Set<String> cacheKeys = redisTemplate.keys(cacheName + "*");
|
||||||
return AjaxResult.success(cacheKeys);
|
return AjaxResult.success(new TreeSet<>(cacheKeys));
|
||||||
}
|
}
|
||||||
|
|
||||||
@PreAuthorize("@ss.hasPermi('monitor:cache:list')")
|
@PreAuthorize("@ss.hasPermi('monitor:cache:list')")
|
||||||
|
|||||||
@ -64,6 +64,6 @@ public class SysOperlogController extends BaseController
|
|||||||
public AjaxResult clean()
|
public AjaxResult clean()
|
||||||
{
|
{
|
||||||
operLogService.cleanOperLog();
|
operLogService.cleanOperLog();
|
||||||
return AjaxResult.success();
|
return success();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -49,24 +49,15 @@ public class SysUserOnlineController extends BaseController
|
|||||||
LoginUser user = redisCache.getCacheObject(key);
|
LoginUser user = redisCache.getCacheObject(key);
|
||||||
if (StringUtils.isNotEmpty(ipaddr) && StringUtils.isNotEmpty(userName))
|
if (StringUtils.isNotEmpty(ipaddr) && StringUtils.isNotEmpty(userName))
|
||||||
{
|
{
|
||||||
if (StringUtils.equals(ipaddr, user.getIpaddr()) && StringUtils.equals(userName, user.getUsername()))
|
userOnlineList.add(userOnlineService.selectOnlineByInfo(ipaddr, userName, user));
|
||||||
{
|
|
||||||
userOnlineList.add(userOnlineService.selectOnlineByInfo(ipaddr, userName, user));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (StringUtils.isNotEmpty(ipaddr))
|
else if (StringUtils.isNotEmpty(ipaddr))
|
||||||
{
|
{
|
||||||
if (StringUtils.equals(ipaddr, user.getIpaddr()))
|
userOnlineList.add(userOnlineService.selectOnlineByIpaddr(ipaddr, user));
|
||||||
{
|
|
||||||
userOnlineList.add(userOnlineService.selectOnlineByIpaddr(ipaddr, user));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (StringUtils.isNotEmpty(userName) && StringUtils.isNotNull(user.getUser()))
|
else if (StringUtils.isNotEmpty(userName) && StringUtils.isNotNull(user.getUser()))
|
||||||
{
|
{
|
||||||
if (StringUtils.equals(userName, user.getUsername()))
|
userOnlineList.add(userOnlineService.selectOnlineByUserName(userName, user));
|
||||||
{
|
|
||||||
userOnlineList.add(userOnlineService.selectOnlineByUserName(userName, user));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -87,6 +78,6 @@ public class SysUserOnlineController extends BaseController
|
|||||||
public AjaxResult forceLogout(@PathVariable String tokenId)
|
public AjaxResult forceLogout(@PathVariable String tokenId)
|
||||||
{
|
{
|
||||||
redisCache.deleteObject(CacheConstants.LOGIN_TOKEN_KEY + tokenId);
|
redisCache.deleteObject(CacheConstants.LOGIN_TOKEN_KEY + tokenId);
|
||||||
return AjaxResult.success();
|
return success();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,7 +14,6 @@ import org.springframework.web.bind.annotation.RequestBody;
|
|||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import com.ruoyi.common.annotation.Log;
|
import com.ruoyi.common.annotation.Log;
|
||||||
import com.ruoyi.common.constant.UserConstants;
|
|
||||||
import com.ruoyi.common.core.controller.BaseController;
|
import com.ruoyi.common.core.controller.BaseController;
|
||||||
import com.ruoyi.common.core.domain.AjaxResult;
|
import com.ruoyi.common.core.domain.AjaxResult;
|
||||||
import com.ruoyi.common.core.page.TableDataInfo;
|
import com.ruoyi.common.core.page.TableDataInfo;
|
||||||
@ -64,7 +63,7 @@ public class SysConfigController extends BaseController
|
|||||||
@GetMapping(value = "/{configId}")
|
@GetMapping(value = "/{configId}")
|
||||||
public AjaxResult getInfo(@PathVariable Long configId)
|
public AjaxResult getInfo(@PathVariable Long configId)
|
||||||
{
|
{
|
||||||
return AjaxResult.success(configService.selectConfigById(configId));
|
return success(configService.selectConfigById(configId));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -73,7 +72,7 @@ public class SysConfigController extends BaseController
|
|||||||
@GetMapping(value = "/configKey/{configKey}")
|
@GetMapping(value = "/configKey/{configKey}")
|
||||||
public AjaxResult getConfigKey(@PathVariable String configKey)
|
public AjaxResult getConfigKey(@PathVariable String configKey)
|
||||||
{
|
{
|
||||||
return AjaxResult.success(configService.selectConfigByKey(configKey));
|
return success(configService.selectConfigByKey(configKey));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -84,9 +83,9 @@ public class SysConfigController extends BaseController
|
|||||||
@PostMapping
|
@PostMapping
|
||||||
public AjaxResult add(@Validated @RequestBody SysConfig config)
|
public AjaxResult add(@Validated @RequestBody SysConfig config)
|
||||||
{
|
{
|
||||||
if (UserConstants.NOT_UNIQUE.equals(configService.checkConfigKeyUnique(config)))
|
if (!configService.checkConfigKeyUnique(config))
|
||||||
{
|
{
|
||||||
return AjaxResult.error("新增参数'" + config.getConfigName() + "'失败,参数键名已存在");
|
return error("新增参数'" + config.getConfigName() + "'失败,参数键名已存在");
|
||||||
}
|
}
|
||||||
config.setCreateBy(getUsername());
|
config.setCreateBy(getUsername());
|
||||||
return toAjax(configService.insertConfig(config));
|
return toAjax(configService.insertConfig(config));
|
||||||
@ -100,9 +99,9 @@ public class SysConfigController extends BaseController
|
|||||||
@PutMapping
|
@PutMapping
|
||||||
public AjaxResult edit(@Validated @RequestBody SysConfig config)
|
public AjaxResult edit(@Validated @RequestBody SysConfig config)
|
||||||
{
|
{
|
||||||
if (UserConstants.NOT_UNIQUE.equals(configService.checkConfigKeyUnique(config)))
|
if (!configService.checkConfigKeyUnique(config))
|
||||||
{
|
{
|
||||||
return AjaxResult.error("修改参数'" + config.getConfigName() + "'失败,参数键名已存在");
|
return error("修改参数'" + config.getConfigName() + "'失败,参数键名已存在");
|
||||||
}
|
}
|
||||||
config.setUpdateBy(getUsername());
|
config.setUpdateBy(getUsername());
|
||||||
return toAjax(configService.updateConfig(config));
|
return toAjax(configService.updateConfig(config));
|
||||||
@ -129,6 +128,6 @@ public class SysConfigController extends BaseController
|
|||||||
public AjaxResult refreshCache()
|
public AjaxResult refreshCache()
|
||||||
{
|
{
|
||||||
configService.resetConfigCache();
|
configService.resetConfigCache();
|
||||||
return AjaxResult.success();
|
return success();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -42,7 +42,7 @@ public class SysDeptController extends BaseController
|
|||||||
public AjaxResult list(SysDept dept)
|
public AjaxResult list(SysDept dept)
|
||||||
{
|
{
|
||||||
List<SysDept> depts = deptService.selectDeptList(dept);
|
List<SysDept> depts = deptService.selectDeptList(dept);
|
||||||
return AjaxResult.success(depts);
|
return success(depts);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -54,7 +54,7 @@ public class SysDeptController extends BaseController
|
|||||||
{
|
{
|
||||||
List<SysDept> depts = deptService.selectDeptList(new SysDept());
|
List<SysDept> depts = deptService.selectDeptList(new SysDept());
|
||||||
depts.removeIf(d -> d.getDeptId().intValue() == deptId || ArrayUtils.contains(StringUtils.split(d.getAncestors(), ","), deptId + ""));
|
depts.removeIf(d -> d.getDeptId().intValue() == deptId || ArrayUtils.contains(StringUtils.split(d.getAncestors(), ","), deptId + ""));
|
||||||
return AjaxResult.success(depts);
|
return success(depts);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -65,7 +65,7 @@ public class SysDeptController extends BaseController
|
|||||||
public AjaxResult getInfo(@PathVariable Long deptId)
|
public AjaxResult getInfo(@PathVariable Long deptId)
|
||||||
{
|
{
|
||||||
deptService.checkDeptDataScope(deptId);
|
deptService.checkDeptDataScope(deptId);
|
||||||
return AjaxResult.success(deptService.selectDeptById(deptId));
|
return success(deptService.selectDeptById(deptId));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -76,9 +76,9 @@ public class SysDeptController extends BaseController
|
|||||||
@PostMapping
|
@PostMapping
|
||||||
public AjaxResult add(@Validated @RequestBody SysDept dept)
|
public AjaxResult add(@Validated @RequestBody SysDept dept)
|
||||||
{
|
{
|
||||||
if (UserConstants.NOT_UNIQUE.equals(deptService.checkDeptNameUnique(dept)))
|
if (!deptService.checkDeptNameUnique(dept))
|
||||||
{
|
{
|
||||||
return AjaxResult.error("新增部门'" + dept.getDeptName() + "'失败,部门名称已存在");
|
return error("新增部门'" + dept.getDeptName() + "'失败,部门名称已存在");
|
||||||
}
|
}
|
||||||
dept.setCreateBy(getUsername());
|
dept.setCreateBy(getUsername());
|
||||||
return toAjax(deptService.insertDept(dept));
|
return toAjax(deptService.insertDept(dept));
|
||||||
@ -94,17 +94,17 @@ public class SysDeptController extends BaseController
|
|||||||
{
|
{
|
||||||
Long deptId = dept.getDeptId();
|
Long deptId = dept.getDeptId();
|
||||||
deptService.checkDeptDataScope(deptId);
|
deptService.checkDeptDataScope(deptId);
|
||||||
if (UserConstants.NOT_UNIQUE.equals(deptService.checkDeptNameUnique(dept)))
|
if (!deptService.checkDeptNameUnique(dept))
|
||||||
{
|
{
|
||||||
return AjaxResult.error("修改部门'" + dept.getDeptName() + "'失败,部门名称已存在");
|
return error("修改部门'" + dept.getDeptName() + "'失败,部门名称已存在");
|
||||||
}
|
}
|
||||||
else if (dept.getParentId().equals(deptId))
|
else if (dept.getParentId().equals(deptId))
|
||||||
{
|
{
|
||||||
return AjaxResult.error("修改部门'" + dept.getDeptName() + "'失败,上级部门不能是自己");
|
return error("修改部门'" + dept.getDeptName() + "'失败,上级部门不能是自己");
|
||||||
}
|
}
|
||||||
else if (StringUtils.equals(UserConstants.DEPT_DISABLE, dept.getStatus()) && deptService.selectNormalChildrenDeptById(deptId) > 0)
|
else if (StringUtils.equals(UserConstants.DEPT_DISABLE, dept.getStatus()) && deptService.selectNormalChildrenDeptById(deptId) > 0)
|
||||||
{
|
{
|
||||||
return AjaxResult.error("该部门包含未停用的子部门!");
|
return error("该部门包含未停用的子部门!");
|
||||||
}
|
}
|
||||||
dept.setUpdateBy(getUsername());
|
dept.setUpdateBy(getUsername());
|
||||||
return toAjax(deptService.updateDept(dept));
|
return toAjax(deptService.updateDept(dept));
|
||||||
@ -120,11 +120,11 @@ public class SysDeptController extends BaseController
|
|||||||
{
|
{
|
||||||
if (deptService.hasChildByDeptId(deptId))
|
if (deptService.hasChildByDeptId(deptId))
|
||||||
{
|
{
|
||||||
return AjaxResult.error("存在下级部门,不允许删除");
|
return warn("存在下级部门,不允许删除");
|
||||||
}
|
}
|
||||||
if (deptService.checkDeptExistUser(deptId))
|
if (deptService.checkDeptExistUser(deptId))
|
||||||
{
|
{
|
||||||
return AjaxResult.error("部门存在用户,不允许删除");
|
return warn("部门存在用户,不允许删除");
|
||||||
}
|
}
|
||||||
deptService.checkDeptDataScope(deptId);
|
deptService.checkDeptDataScope(deptId);
|
||||||
return toAjax(deptService.deleteDeptById(deptId));
|
return toAjax(deptService.deleteDeptById(deptId));
|
||||||
|
|||||||
@ -66,7 +66,7 @@ public class SysDictDataController extends BaseController
|
|||||||
@GetMapping(value = "/{dictCode}")
|
@GetMapping(value = "/{dictCode}")
|
||||||
public AjaxResult getInfo(@PathVariable Long dictCode)
|
public AjaxResult getInfo(@PathVariable Long dictCode)
|
||||||
{
|
{
|
||||||
return AjaxResult.success(dictDataService.selectDictDataById(dictCode));
|
return success(dictDataService.selectDictDataById(dictCode));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -80,7 +80,7 @@ public class SysDictDataController extends BaseController
|
|||||||
{
|
{
|
||||||
data = new ArrayList<SysDictData>();
|
data = new ArrayList<SysDictData>();
|
||||||
}
|
}
|
||||||
return AjaxResult.success(data);
|
return success(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -14,7 +14,6 @@ import org.springframework.web.bind.annotation.RequestBody;
|
|||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import com.ruoyi.common.annotation.Log;
|
import com.ruoyi.common.annotation.Log;
|
||||||
import com.ruoyi.common.constant.UserConstants;
|
|
||||||
import com.ruoyi.common.core.controller.BaseController;
|
import com.ruoyi.common.core.controller.BaseController;
|
||||||
import com.ruoyi.common.core.domain.AjaxResult;
|
import com.ruoyi.common.core.domain.AjaxResult;
|
||||||
import com.ruoyi.common.core.domain.entity.SysDictType;
|
import com.ruoyi.common.core.domain.entity.SysDictType;
|
||||||
@ -61,7 +60,7 @@ public class SysDictTypeController extends BaseController
|
|||||||
@GetMapping(value = "/{dictId}")
|
@GetMapping(value = "/{dictId}")
|
||||||
public AjaxResult getInfo(@PathVariable Long dictId)
|
public AjaxResult getInfo(@PathVariable Long dictId)
|
||||||
{
|
{
|
||||||
return AjaxResult.success(dictTypeService.selectDictTypeById(dictId));
|
return success(dictTypeService.selectDictTypeById(dictId));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -72,9 +71,9 @@ public class SysDictTypeController extends BaseController
|
|||||||
@PostMapping
|
@PostMapping
|
||||||
public AjaxResult add(@Validated @RequestBody SysDictType dict)
|
public AjaxResult add(@Validated @RequestBody SysDictType dict)
|
||||||
{
|
{
|
||||||
if (UserConstants.NOT_UNIQUE.equals(dictTypeService.checkDictTypeUnique(dict)))
|
if (!dictTypeService.checkDictTypeUnique(dict))
|
||||||
{
|
{
|
||||||
return AjaxResult.error("新增字典'" + dict.getDictName() + "'失败,字典类型已存在");
|
return error("新增字典'" + dict.getDictName() + "'失败,字典类型已存在");
|
||||||
}
|
}
|
||||||
dict.setCreateBy(getUsername());
|
dict.setCreateBy(getUsername());
|
||||||
return toAjax(dictTypeService.insertDictType(dict));
|
return toAjax(dictTypeService.insertDictType(dict));
|
||||||
@ -88,9 +87,9 @@ public class SysDictTypeController extends BaseController
|
|||||||
@PutMapping
|
@PutMapping
|
||||||
public AjaxResult edit(@Validated @RequestBody SysDictType dict)
|
public AjaxResult edit(@Validated @RequestBody SysDictType dict)
|
||||||
{
|
{
|
||||||
if (UserConstants.NOT_UNIQUE.equals(dictTypeService.checkDictTypeUnique(dict)))
|
if (!dictTypeService.checkDictTypeUnique(dict))
|
||||||
{
|
{
|
||||||
return AjaxResult.error("修改字典'" + dict.getDictName() + "'失败,字典类型已存在");
|
return error("修改字典'" + dict.getDictName() + "'失败,字典类型已存在");
|
||||||
}
|
}
|
||||||
dict.setUpdateBy(getUsername());
|
dict.setUpdateBy(getUsername());
|
||||||
return toAjax(dictTypeService.updateDictType(dict));
|
return toAjax(dictTypeService.updateDictType(dict));
|
||||||
@ -117,7 +116,7 @@ public class SysDictTypeController extends BaseController
|
|||||||
public AjaxResult refreshCache()
|
public AjaxResult refreshCache()
|
||||||
{
|
{
|
||||||
dictTypeService.resetDictCache();
|
dictTypeService.resetDictCache();
|
||||||
return AjaxResult.success();
|
return success();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -127,6 +126,6 @@ public class SysDictTypeController extends BaseController
|
|||||||
public AjaxResult optionselect()
|
public AjaxResult optionselect()
|
||||||
{
|
{
|
||||||
List<SysDictType> dictTypes = dictTypeService.selectDictTypeAll();
|
List<SysDictType> dictTypes = dictTypeService.selectDictTypeAll();
|
||||||
return AjaxResult.success(dictTypes);
|
return success(dictTypes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -41,7 +41,7 @@ public class SysMenuController extends BaseController
|
|||||||
public AjaxResult list(SysMenu menu)
|
public AjaxResult list(SysMenu menu)
|
||||||
{
|
{
|
||||||
List<SysMenu> menus = menuService.selectMenuList(menu, getUserId());
|
List<SysMenu> menus = menuService.selectMenuList(menu, getUserId());
|
||||||
return AjaxResult.success(menus);
|
return success(menus);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -51,7 +51,7 @@ public class SysMenuController extends BaseController
|
|||||||
@GetMapping(value = "/{menuId}")
|
@GetMapping(value = "/{menuId}")
|
||||||
public AjaxResult getInfo(@PathVariable Long menuId)
|
public AjaxResult getInfo(@PathVariable Long menuId)
|
||||||
{
|
{
|
||||||
return AjaxResult.success(menuService.selectMenuById(menuId));
|
return success(menuService.selectMenuById(menuId));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -61,7 +61,7 @@ public class SysMenuController extends BaseController
|
|||||||
public AjaxResult treeselect(SysMenu menu)
|
public AjaxResult treeselect(SysMenu menu)
|
||||||
{
|
{
|
||||||
List<SysMenu> menus = menuService.selectMenuList(menu, getUserId());
|
List<SysMenu> menus = menuService.selectMenuList(menu, getUserId());
|
||||||
return AjaxResult.success(menuService.buildMenuTreeSelect(menus));
|
return success(menuService.buildMenuTreeSelect(menus));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -85,13 +85,13 @@ public class SysMenuController extends BaseController
|
|||||||
@PostMapping
|
@PostMapping
|
||||||
public AjaxResult add(@Validated @RequestBody SysMenu menu)
|
public AjaxResult add(@Validated @RequestBody SysMenu menu)
|
||||||
{
|
{
|
||||||
if (UserConstants.NOT_UNIQUE.equals(menuService.checkMenuNameUnique(menu)))
|
if (!menuService.checkMenuNameUnique(menu))
|
||||||
{
|
{
|
||||||
return AjaxResult.error("新增菜单'" + menu.getMenuName() + "'失败,菜单名称已存在");
|
return error("新增菜单'" + menu.getMenuName() + "'失败,菜单名称已存在");
|
||||||
}
|
}
|
||||||
else if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath()))
|
else if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath()))
|
||||||
{
|
{
|
||||||
return AjaxResult.error("新增菜单'" + menu.getMenuName() + "'失败,地址必须以http(s)://开头");
|
return error("新增菜单'" + menu.getMenuName() + "'失败,地址必须以http(s)://开头");
|
||||||
}
|
}
|
||||||
menu.setCreateBy(getUsername());
|
menu.setCreateBy(getUsername());
|
||||||
return toAjax(menuService.insertMenu(menu));
|
return toAjax(menuService.insertMenu(menu));
|
||||||
@ -105,17 +105,17 @@ public class SysMenuController extends BaseController
|
|||||||
@PutMapping
|
@PutMapping
|
||||||
public AjaxResult edit(@Validated @RequestBody SysMenu menu)
|
public AjaxResult edit(@Validated @RequestBody SysMenu menu)
|
||||||
{
|
{
|
||||||
if (UserConstants.NOT_UNIQUE.equals(menuService.checkMenuNameUnique(menu)))
|
if (!menuService.checkMenuNameUnique(menu))
|
||||||
{
|
{
|
||||||
return AjaxResult.error("修改菜单'" + menu.getMenuName() + "'失败,菜单名称已存在");
|
return error("修改菜单'" + menu.getMenuName() + "'失败,菜单名称已存在");
|
||||||
}
|
}
|
||||||
else if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath()))
|
else if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath()))
|
||||||
{
|
{
|
||||||
return AjaxResult.error("修改菜单'" + menu.getMenuName() + "'失败,地址必须以http(s)://开头");
|
return error("修改菜单'" + menu.getMenuName() + "'失败,地址必须以http(s)://开头");
|
||||||
}
|
}
|
||||||
else if (menu.getMenuId().equals(menu.getParentId()))
|
else if (menu.getMenuId().equals(menu.getParentId()))
|
||||||
{
|
{
|
||||||
return AjaxResult.error("修改菜单'" + menu.getMenuName() + "'失败,上级菜单不能选择自己");
|
return error("修改菜单'" + menu.getMenuName() + "'失败,上级菜单不能选择自己");
|
||||||
}
|
}
|
||||||
menu.setUpdateBy(getUsername());
|
menu.setUpdateBy(getUsername());
|
||||||
return toAjax(menuService.updateMenu(menu));
|
return toAjax(menuService.updateMenu(menu));
|
||||||
@ -131,11 +131,11 @@ public class SysMenuController extends BaseController
|
|||||||
{
|
{
|
||||||
if (menuService.hasChildByMenuId(menuId))
|
if (menuService.hasChildByMenuId(menuId))
|
||||||
{
|
{
|
||||||
return AjaxResult.error("存在子菜单,不允许删除");
|
return warn("存在子菜单,不允许删除");
|
||||||
}
|
}
|
||||||
if (menuService.checkMenuExistRole(menuId))
|
if (menuService.checkMenuExistRole(menuId))
|
||||||
{
|
{
|
||||||
return AjaxResult.error("菜单已分配,不允许删除");
|
return warn("菜单已分配,不允许删除");
|
||||||
}
|
}
|
||||||
return toAjax(menuService.deleteMenuById(menuId));
|
return toAjax(menuService.deleteMenuById(menuId));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -51,7 +51,7 @@ public class SysNoticeController extends BaseController
|
|||||||
@GetMapping(value = "/{noticeId}")
|
@GetMapping(value = "/{noticeId}")
|
||||||
public AjaxResult getInfo(@PathVariable Long noticeId)
|
public AjaxResult getInfo(@PathVariable Long noticeId)
|
||||||
{
|
{
|
||||||
return AjaxResult.success(noticeService.selectNoticeById(noticeId));
|
return success(noticeService.selectNoticeById(noticeId));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -14,7 +14,6 @@ import org.springframework.web.bind.annotation.RequestBody;
|
|||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import com.ruoyi.common.annotation.Log;
|
import com.ruoyi.common.annotation.Log;
|
||||||
import com.ruoyi.common.constant.UserConstants;
|
|
||||||
import com.ruoyi.common.core.controller.BaseController;
|
import com.ruoyi.common.core.controller.BaseController;
|
||||||
import com.ruoyi.common.core.domain.AjaxResult;
|
import com.ruoyi.common.core.domain.AjaxResult;
|
||||||
import com.ruoyi.common.core.page.TableDataInfo;
|
import com.ruoyi.common.core.page.TableDataInfo;
|
||||||
@ -64,7 +63,7 @@ public class SysPostController extends BaseController
|
|||||||
@GetMapping(value = "/{postId}")
|
@GetMapping(value = "/{postId}")
|
||||||
public AjaxResult getInfo(@PathVariable Long postId)
|
public AjaxResult getInfo(@PathVariable Long postId)
|
||||||
{
|
{
|
||||||
return AjaxResult.success(postService.selectPostById(postId));
|
return success(postService.selectPostById(postId));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -75,13 +74,13 @@ public class SysPostController extends BaseController
|
|||||||
@PostMapping
|
@PostMapping
|
||||||
public AjaxResult add(@Validated @RequestBody SysPost post)
|
public AjaxResult add(@Validated @RequestBody SysPost post)
|
||||||
{
|
{
|
||||||
if (UserConstants.NOT_UNIQUE.equals(postService.checkPostNameUnique(post)))
|
if (!postService.checkPostNameUnique(post))
|
||||||
{
|
{
|
||||||
return AjaxResult.error("新增岗位'" + post.getPostName() + "'失败,岗位名称已存在");
|
return error("新增岗位'" + post.getPostName() + "'失败,岗位名称已存在");
|
||||||
}
|
}
|
||||||
else if (UserConstants.NOT_UNIQUE.equals(postService.checkPostCodeUnique(post)))
|
else if (!postService.checkPostCodeUnique(post))
|
||||||
{
|
{
|
||||||
return AjaxResult.error("新增岗位'" + post.getPostName() + "'失败,岗位编码已存在");
|
return error("新增岗位'" + post.getPostName() + "'失败,岗位编码已存在");
|
||||||
}
|
}
|
||||||
post.setCreateBy(getUsername());
|
post.setCreateBy(getUsername());
|
||||||
return toAjax(postService.insertPost(post));
|
return toAjax(postService.insertPost(post));
|
||||||
@ -95,13 +94,13 @@ public class SysPostController extends BaseController
|
|||||||
@PutMapping
|
@PutMapping
|
||||||
public AjaxResult edit(@Validated @RequestBody SysPost post)
|
public AjaxResult edit(@Validated @RequestBody SysPost post)
|
||||||
{
|
{
|
||||||
if (UserConstants.NOT_UNIQUE.equals(postService.checkPostNameUnique(post)))
|
if (!postService.checkPostNameUnique(post))
|
||||||
{
|
{
|
||||||
return AjaxResult.error("修改岗位'" + post.getPostName() + "'失败,岗位名称已存在");
|
return error("修改岗位'" + post.getPostName() + "'失败,岗位名称已存在");
|
||||||
}
|
}
|
||||||
else if (UserConstants.NOT_UNIQUE.equals(postService.checkPostCodeUnique(post)))
|
else if (!postService.checkPostCodeUnique(post))
|
||||||
{
|
{
|
||||||
return AjaxResult.error("修改岗位'" + post.getPostName() + "'失败,岗位编码已存在");
|
return error("修改岗位'" + post.getPostName() + "'失败,岗位编码已存在");
|
||||||
}
|
}
|
||||||
post.setUpdateBy(getUsername());
|
post.setUpdateBy(getUsername());
|
||||||
return toAjax(postService.updatePost(post));
|
return toAjax(postService.updatePost(post));
|
||||||
@ -125,6 +124,6 @@ public class SysPostController extends BaseController
|
|||||||
public AjaxResult optionselect()
|
public AjaxResult optionselect()
|
||||||
{
|
{
|
||||||
List<SysPost> posts = postService.selectPostAll();
|
List<SysPost> posts = postService.selectPostAll();
|
||||||
return AjaxResult.success(posts);
|
return success(posts);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,7 +11,6 @@ import org.springframework.web.bind.annotation.RestController;
|
|||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import com.ruoyi.common.annotation.Log;
|
import com.ruoyi.common.annotation.Log;
|
||||||
import com.ruoyi.common.config.RuoYiConfig;
|
import com.ruoyi.common.config.RuoYiConfig;
|
||||||
import com.ruoyi.common.constant.UserConstants;
|
|
||||||
import com.ruoyi.common.core.controller.BaseController;
|
import com.ruoyi.common.core.controller.BaseController;
|
||||||
import com.ruoyi.common.core.domain.AjaxResult;
|
import com.ruoyi.common.core.domain.AjaxResult;
|
||||||
import com.ruoyi.common.core.domain.entity.SysUser;
|
import com.ruoyi.common.core.domain.entity.SysUser;
|
||||||
@ -61,33 +60,26 @@ public class SysProfileController extends BaseController
|
|||||||
public AjaxResult updateProfile(@RequestBody SysUser user)
|
public AjaxResult updateProfile(@RequestBody SysUser user)
|
||||||
{
|
{
|
||||||
LoginUser loginUser = getLoginUser();
|
LoginUser loginUser = getLoginUser();
|
||||||
SysUser sysUser = loginUser.getUser();
|
SysUser currentUser = loginUser.getUser();
|
||||||
user.setUserName(sysUser.getUserName());
|
currentUser.setNickName(user.getNickName());
|
||||||
if (StringUtils.isNotEmpty(user.getPhonenumber())
|
currentUser.setEmail(user.getEmail());
|
||||||
&& UserConstants.NOT_UNIQUE.equals(userService.checkPhoneUnique(user)))
|
currentUser.setPhonenumber(user.getPhonenumber());
|
||||||
|
currentUser.setSex(user.getSex());
|
||||||
|
if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(currentUser))
|
||||||
{
|
{
|
||||||
return AjaxResult.error("修改用户'" + user.getUserName() + "'失败,手机号码已存在");
|
return error("修改用户'" + loginUser.getUsername() + "'失败,手机号码已存在");
|
||||||
}
|
}
|
||||||
if (StringUtils.isNotEmpty(user.getEmail())
|
if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(currentUser))
|
||||||
&& UserConstants.NOT_UNIQUE.equals(userService.checkEmailUnique(user)))
|
|
||||||
{
|
{
|
||||||
return AjaxResult.error("修改用户'" + user.getUserName() + "'失败,邮箱账号已存在");
|
return error("修改用户'" + loginUser.getUsername() + "'失败,邮箱账号已存在");
|
||||||
}
|
}
|
||||||
user.setUserId(sysUser.getUserId());
|
if (userService.updateUserProfile(currentUser) > 0)
|
||||||
user.setPassword(null);
|
|
||||||
user.setAvatar(null);
|
|
||||||
user.setDeptId(null);
|
|
||||||
if (userService.updateUserProfile(user) > 0)
|
|
||||||
{
|
{
|
||||||
// 更新缓存用户信息
|
// 更新缓存用户信息
|
||||||
sysUser.setNickName(user.getNickName());
|
|
||||||
sysUser.setPhonenumber(user.getPhonenumber());
|
|
||||||
sysUser.setEmail(user.getEmail());
|
|
||||||
sysUser.setSex(user.getSex());
|
|
||||||
tokenService.setLoginUser(loginUser);
|
tokenService.setLoginUser(loginUser);
|
||||||
return AjaxResult.success();
|
return success();
|
||||||
}
|
}
|
||||||
return AjaxResult.error("修改个人信息异常,请联系管理员");
|
return error("修改个人信息异常,请联系管理员");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -102,20 +94,21 @@ public class SysProfileController extends BaseController
|
|||||||
String password = loginUser.getPassword();
|
String password = loginUser.getPassword();
|
||||||
if (!SecurityUtils.matchesPassword(oldPassword, password))
|
if (!SecurityUtils.matchesPassword(oldPassword, password))
|
||||||
{
|
{
|
||||||
return AjaxResult.error("修改密码失败,旧密码错误");
|
return error("修改密码失败,旧密码错误");
|
||||||
}
|
}
|
||||||
if (SecurityUtils.matchesPassword(newPassword, password))
|
if (SecurityUtils.matchesPassword(newPassword, password))
|
||||||
{
|
{
|
||||||
return AjaxResult.error("新密码不能与旧密码相同");
|
return error("新密码不能与旧密码相同");
|
||||||
}
|
}
|
||||||
if (userService.resetUserPwd(userName, SecurityUtils.encryptPassword(newPassword)) > 0)
|
newPassword = SecurityUtils.encryptPassword(newPassword);
|
||||||
|
if (userService.resetUserPwd(userName, newPassword) > 0)
|
||||||
{
|
{
|
||||||
// 更新缓存用户密码
|
// 更新缓存用户密码
|
||||||
loginUser.getUser().setPassword(SecurityUtils.encryptPassword(newPassword));
|
loginUser.getUser().setPassword(newPassword);
|
||||||
tokenService.setLoginUser(loginUser);
|
tokenService.setLoginUser(loginUser);
|
||||||
return AjaxResult.success();
|
return success();
|
||||||
}
|
}
|
||||||
return AjaxResult.error("修改密码异常,请联系管理员");
|
return error("修改密码异常,请联系管理员");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -139,6 +132,6 @@ public class SysProfileController extends BaseController
|
|||||||
return ajax;
|
return ajax;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return AjaxResult.error("上传图片异常,请联系管理员");
|
return error("上传图片异常,请联系管理员");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,7 +14,6 @@ import org.springframework.web.bind.annotation.RequestBody;
|
|||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import com.ruoyi.common.annotation.Log;
|
import com.ruoyi.common.annotation.Log;
|
||||||
import com.ruoyi.common.constant.UserConstants;
|
|
||||||
import com.ruoyi.common.core.controller.BaseController;
|
import com.ruoyi.common.core.controller.BaseController;
|
||||||
import com.ruoyi.common.core.domain.AjaxResult;
|
import com.ruoyi.common.core.domain.AjaxResult;
|
||||||
import com.ruoyi.common.core.domain.entity.SysDept;
|
import com.ruoyi.common.core.domain.entity.SysDept;
|
||||||
@ -83,7 +82,7 @@ public class SysRoleController extends BaseController
|
|||||||
public AjaxResult getInfo(@PathVariable Long roleId)
|
public AjaxResult getInfo(@PathVariable Long roleId)
|
||||||
{
|
{
|
||||||
roleService.checkRoleDataScope(roleId);
|
roleService.checkRoleDataScope(roleId);
|
||||||
return AjaxResult.success(roleService.selectRoleById(roleId));
|
return success(roleService.selectRoleById(roleId));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -94,13 +93,13 @@ public class SysRoleController extends BaseController
|
|||||||
@PostMapping
|
@PostMapping
|
||||||
public AjaxResult add(@Validated @RequestBody SysRole role)
|
public AjaxResult add(@Validated @RequestBody SysRole role)
|
||||||
{
|
{
|
||||||
if (UserConstants.NOT_UNIQUE.equals(roleService.checkRoleNameUnique(role)))
|
if (!roleService.checkRoleNameUnique(role))
|
||||||
{
|
{
|
||||||
return AjaxResult.error("新增角色'" + role.getRoleName() + "'失败,角色名称已存在");
|
return error("新增角色'" + role.getRoleName() + "'失败,角色名称已存在");
|
||||||
}
|
}
|
||||||
else if (UserConstants.NOT_UNIQUE.equals(roleService.checkRoleKeyUnique(role)))
|
else if (!roleService.checkRoleKeyUnique(role))
|
||||||
{
|
{
|
||||||
return AjaxResult.error("新增角色'" + role.getRoleName() + "'失败,角色权限已存在");
|
return error("新增角色'" + role.getRoleName() + "'失败,角色权限已存在");
|
||||||
}
|
}
|
||||||
role.setCreateBy(getUsername());
|
role.setCreateBy(getUsername());
|
||||||
return toAjax(roleService.insertRole(role));
|
return toAjax(roleService.insertRole(role));
|
||||||
@ -117,13 +116,13 @@ public class SysRoleController extends BaseController
|
|||||||
{
|
{
|
||||||
roleService.checkRoleAllowed(role);
|
roleService.checkRoleAllowed(role);
|
||||||
roleService.checkRoleDataScope(role.getRoleId());
|
roleService.checkRoleDataScope(role.getRoleId());
|
||||||
if (UserConstants.NOT_UNIQUE.equals(roleService.checkRoleNameUnique(role)))
|
if (!roleService.checkRoleNameUnique(role))
|
||||||
{
|
{
|
||||||
return AjaxResult.error("修改角色'" + role.getRoleName() + "'失败,角色名称已存在");
|
return error("修改角色'" + role.getRoleName() + "'失败,角色名称已存在");
|
||||||
}
|
}
|
||||||
else if (UserConstants.NOT_UNIQUE.equals(roleService.checkRoleKeyUnique(role)))
|
else if (!roleService.checkRoleKeyUnique(role))
|
||||||
{
|
{
|
||||||
return AjaxResult.error("修改角色'" + role.getRoleName() + "'失败,角色权限已存在");
|
return error("修改角色'" + role.getRoleName() + "'失败,角色权限已存在");
|
||||||
}
|
}
|
||||||
role.setUpdateBy(getUsername());
|
role.setUpdateBy(getUsername());
|
||||||
|
|
||||||
@ -137,9 +136,9 @@ public class SysRoleController extends BaseController
|
|||||||
loginUser.setUser(userService.selectUserByUserName(loginUser.getUser().getUserName()));
|
loginUser.setUser(userService.selectUserByUserName(loginUser.getUser().getUserName()));
|
||||||
tokenService.setLoginUser(loginUser);
|
tokenService.setLoginUser(loginUser);
|
||||||
}
|
}
|
||||||
return AjaxResult.success();
|
return success();
|
||||||
}
|
}
|
||||||
return AjaxResult.error("修改角色'" + role.getRoleName() + "'失败,请联系管理员");
|
return error("修改角色'" + role.getRoleName() + "'失败,请联系管理员");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -187,7 +186,7 @@ public class SysRoleController extends BaseController
|
|||||||
@GetMapping("/optionselect")
|
@GetMapping("/optionselect")
|
||||||
public AjaxResult optionselect()
|
public AjaxResult optionselect()
|
||||||
{
|
{
|
||||||
return AjaxResult.success(roleService.selectRoleAll());
|
return success(roleService.selectRoleAll());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -17,7 +17,6 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
|||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import com.ruoyi.common.annotation.Log;
|
import com.ruoyi.common.annotation.Log;
|
||||||
import com.ruoyi.common.constant.UserConstants;
|
|
||||||
import com.ruoyi.common.core.controller.BaseController;
|
import com.ruoyi.common.core.controller.BaseController;
|
||||||
import com.ruoyi.common.core.domain.AjaxResult;
|
import com.ruoyi.common.core.domain.AjaxResult;
|
||||||
import com.ruoyi.common.core.domain.entity.SysDept;
|
import com.ruoyi.common.core.domain.entity.SysDept;
|
||||||
@ -85,7 +84,7 @@ public class SysUserController extends BaseController
|
|||||||
List<SysUser> userList = util.importExcel(file.getInputStream());
|
List<SysUser> userList = util.importExcel(file.getInputStream());
|
||||||
String operName = getUsername();
|
String operName = getUsername();
|
||||||
String message = userService.importUser(userList, updateSupport, operName);
|
String message = userService.importUser(userList, updateSupport, operName);
|
||||||
return AjaxResult.success(message);
|
return success(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/importTemplate")
|
@PostMapping("/importTemplate")
|
||||||
@ -125,19 +124,19 @@ public class SysUserController extends BaseController
|
|||||||
@PostMapping
|
@PostMapping
|
||||||
public AjaxResult add(@Validated @RequestBody SysUser user)
|
public AjaxResult add(@Validated @RequestBody SysUser user)
|
||||||
{
|
{
|
||||||
if (UserConstants.NOT_UNIQUE.equals(userService.checkUserNameUnique(user)))
|
deptService.checkDeptDataScope(user.getDeptId());
|
||||||
|
roleService.checkRoleDataScope(user.getRoleIds());
|
||||||
|
if (!userService.checkUserNameUnique(user))
|
||||||
{
|
{
|
||||||
return AjaxResult.error("新增用户'" + user.getUserName() + "'失败,登录账号已存在");
|
return error("新增用户'" + user.getUserName() + "'失败,登录账号已存在");
|
||||||
}
|
}
|
||||||
else if (StringUtils.isNotEmpty(user.getPhonenumber())
|
else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user))
|
||||||
&& UserConstants.NOT_UNIQUE.equals(userService.checkPhoneUnique(user)))
|
|
||||||
{
|
{
|
||||||
return AjaxResult.error("新增用户'" + user.getUserName() + "'失败,手机号码已存在");
|
return error("新增用户'" + user.getUserName() + "'失败,手机号码已存在");
|
||||||
}
|
}
|
||||||
else if (StringUtils.isNotEmpty(user.getEmail())
|
else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user))
|
||||||
&& UserConstants.NOT_UNIQUE.equals(userService.checkEmailUnique(user)))
|
|
||||||
{
|
{
|
||||||
return AjaxResult.error("新增用户'" + user.getUserName() + "'失败,邮箱账号已存在");
|
return error("新增用户'" + user.getUserName() + "'失败,邮箱账号已存在");
|
||||||
}
|
}
|
||||||
user.setCreateBy(getUsername());
|
user.setCreateBy(getUsername());
|
||||||
user.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
|
user.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
|
||||||
@ -154,19 +153,19 @@ public class SysUserController extends BaseController
|
|||||||
{
|
{
|
||||||
userService.checkUserAllowed(user);
|
userService.checkUserAllowed(user);
|
||||||
userService.checkUserDataScope(user.getUserId());
|
userService.checkUserDataScope(user.getUserId());
|
||||||
if (UserConstants.NOT_UNIQUE.equals(userService.checkUserNameUnique(user)))
|
deptService.checkDeptDataScope(user.getDeptId());
|
||||||
|
roleService.checkRoleDataScope(user.getRoleIds());
|
||||||
|
if (!userService.checkUserNameUnique(user))
|
||||||
{
|
{
|
||||||
return AjaxResult.error("修改用户'" + user.getUserName() + "'失败,登录账号已存在");
|
return error("修改用户'" + user.getUserName() + "'失败,登录账号已存在");
|
||||||
}
|
}
|
||||||
else if (StringUtils.isNotEmpty(user.getPhonenumber())
|
else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user))
|
||||||
&& UserConstants.NOT_UNIQUE.equals(userService.checkPhoneUnique(user)))
|
|
||||||
{
|
{
|
||||||
return AjaxResult.error("修改用户'" + user.getUserName() + "'失败,手机号码已存在");
|
return error("修改用户'" + user.getUserName() + "'失败,手机号码已存在");
|
||||||
}
|
}
|
||||||
else if (StringUtils.isNotEmpty(user.getEmail())
|
else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user))
|
||||||
&& UserConstants.NOT_UNIQUE.equals(userService.checkEmailUnique(user)))
|
|
||||||
{
|
{
|
||||||
return AjaxResult.error("修改用户'" + user.getUserName() + "'失败,邮箱账号已存在");
|
return error("修改用户'" + user.getUserName() + "'失败,邮箱账号已存在");
|
||||||
}
|
}
|
||||||
user.setUpdateBy(getUsername());
|
user.setUpdateBy(getUsername());
|
||||||
return toAjax(userService.updateUser(user));
|
return toAjax(userService.updateUser(user));
|
||||||
@ -240,6 +239,7 @@ public class SysUserController extends BaseController
|
|||||||
public AjaxResult insertAuthRole(Long userId, Long[] roleIds)
|
public AjaxResult insertAuthRole(Long userId, Long[] roleIds)
|
||||||
{
|
{
|
||||||
userService.checkUserDataScope(userId);
|
userService.checkUserDataScope(userId);
|
||||||
|
roleService.checkRoleDataScope(roleIds);
|
||||||
userService.insertUserAuth(userId, roleIds);
|
userService.insertUserAuth(userId, roleIds);
|
||||||
return success();
|
return success();
|
||||||
}
|
}
|
||||||
@ -251,6 +251,6 @@ public class SysUserController extends BaseController
|
|||||||
@GetMapping("/deptTree")
|
@GetMapping("/deptTree")
|
||||||
public AjaxResult deptTree(SysDept dept)
|
public AjaxResult deptTree(SysDept dept)
|
||||||
{
|
{
|
||||||
return AjaxResult.success(deptService.selectDeptTreeList(dept));
|
return success(deptService.selectDeptTreeList(dept));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,24 +0,0 @@
|
|||||||
package com.ruoyi.web.controller.tool;
|
|
||||||
|
|
||||||
import org.springframework.security.access.prepost.PreAuthorize;
|
|
||||||
import org.springframework.stereotype.Controller;
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import com.ruoyi.common.core.controller.BaseController;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* swagger 接口
|
|
||||||
*
|
|
||||||
* @author ruoyi
|
|
||||||
*/
|
|
||||||
@Controller
|
|
||||||
@RequestMapping("/tool/swagger")
|
|
||||||
public class SwaggerController extends BaseController
|
|
||||||
{
|
|
||||||
@PreAuthorize("@ss.hasPermi('tool:swagger:view')")
|
|
||||||
@GetMapping()
|
|
||||||
public String index()
|
|
||||||
{
|
|
||||||
return redirect("/swagger-ui.html");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1 +1 @@
|
|||||||
restart.include.json=/com.alibaba.fastjson.*.jar
|
restart.include.json=/com.alibaba.fastjson2.*.jar
|
||||||
@ -24,6 +24,10 @@ spring:
|
|||||||
maxActive: 20
|
maxActive: 20
|
||||||
# 配置获取连接等待超时的时间
|
# 配置获取连接等待超时的时间
|
||||||
maxWait: 60000
|
maxWait: 60000
|
||||||
|
# 配置连接超时时间
|
||||||
|
connectTimeout: 30000
|
||||||
|
# 配置网络超时时间
|
||||||
|
socketTimeout: 60000
|
||||||
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
|
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
|
||||||
timeBetweenEvictionRunsMillis: 60000
|
timeBetweenEvictionRunsMillis: 60000
|
||||||
# 配置一个连接在池中最小生存的时间,单位是毫秒
|
# 配置一个连接在池中最小生存的时间,单位是毫秒
|
||||||
|
|||||||
@ -3,16 +3,14 @@ ruoyi:
|
|||||||
# 名称
|
# 名称
|
||||||
name: RuoYi
|
name: RuoYi
|
||||||
# 版本
|
# 版本
|
||||||
version: 3.8.4
|
version: 3.8.8
|
||||||
# 版权年份
|
# 版权年份
|
||||||
copyrightYear: 2022
|
copyrightYear: 2024
|
||||||
# 实例演示开关
|
|
||||||
demoEnabled: true
|
|
||||||
# 文件路径 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)
|
# 文件路径 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)
|
||||||
profile: D:/ruoyi/uploadPath
|
profile: D:/ruoyi/uploadPath
|
||||||
# 获取ip地址开关
|
# 获取ip地址开关
|
||||||
addressEnabled: false
|
addressEnabled: false
|
||||||
# 验证码类型 math 数组计算 char 字符验证
|
# 验证码类型 math 数字计算 char 字符验证
|
||||||
captchaType: math
|
captchaType: math
|
||||||
|
|
||||||
# 开发环境配置
|
# 开发环境配置
|
||||||
@ -53,15 +51,15 @@ spring:
|
|||||||
messages:
|
messages:
|
||||||
# 国际化资源文件路径
|
# 国际化资源文件路径
|
||||||
basename: i18n/messages
|
basename: i18n/messages
|
||||||
profiles:
|
profiles:
|
||||||
active: druid
|
active: druid
|
||||||
# 文件上传
|
# 文件上传
|
||||||
servlet:
|
servlet:
|
||||||
multipart:
|
multipart:
|
||||||
# 单个文件大小
|
# 单个文件大小
|
||||||
max-file-size: 10MB
|
max-file-size: 10MB
|
||||||
# 设置总上传的文件大小
|
# 设置总上传的文件大小
|
||||||
max-request-size: 20MB
|
max-request-size: 20MB
|
||||||
# 服务模块
|
# 服务模块
|
||||||
devtools:
|
devtools:
|
||||||
restart:
|
restart:
|
||||||
@ -76,7 +74,7 @@ spring:
|
|||||||
# 数据库索引
|
# 数据库索引
|
||||||
database: 0
|
database: 0
|
||||||
# 密码
|
# 密码
|
||||||
password:
|
password:
|
||||||
# 连接超时时间
|
# 连接超时时间
|
||||||
timeout: 10s
|
timeout: 10s
|
||||||
lettuce:
|
lettuce:
|
||||||
@ -92,27 +90,27 @@ spring:
|
|||||||
|
|
||||||
# token配置
|
# token配置
|
||||||
token:
|
token:
|
||||||
# 令牌自定义标识
|
# 令牌自定义标识
|
||||||
header: Authorization
|
header: Authorization
|
||||||
# 令牌密钥
|
# 令牌密钥
|
||||||
secret: abcdefghijklmnopqrstuvwxyz
|
secret: abcdefghijklmnopqrstuvwxyz
|
||||||
# 令牌有效期(默认30分钟)
|
# 令牌有效期(默认30分钟)
|
||||||
expireTime: 30
|
expireTime: 30
|
||||||
|
|
||||||
# MyBatis配置
|
# MyBatis配置
|
||||||
mybatis:
|
mybatis:
|
||||||
# 搜索指定包别名
|
# 搜索指定包别名
|
||||||
typeAliasesPackage: com.ruoyi.**.domain
|
typeAliasesPackage: com.ruoyi.**.domain
|
||||||
# 配置mapper的扫描,找到所有的mapper.xml映射文件
|
# 配置mapper的扫描,找到所有的mapper.xml映射文件
|
||||||
mapperLocations: classpath*:mapper/**/*Mapper.xml
|
mapperLocations: classpath*:mapper/**/*Mapper.xml
|
||||||
# 加载全局的配置文件
|
# 加载全局的配置文件
|
||||||
configLocation: classpath:mybatis/mybatis-config.xml
|
configLocation: classpath:mybatis/mybatis-config.xml
|
||||||
|
|
||||||
# PageHelper分页插件
|
# PageHelper分页插件
|
||||||
pagehelper:
|
pagehelper:
|
||||||
helperDialect: mysql
|
helperDialect: mysql
|
||||||
supportMethodsArguments: true
|
supportMethodsArguments: true
|
||||||
params: count=countSql
|
params: count=countSql
|
||||||
|
|
||||||
# Swagger配置
|
# Swagger配置
|
||||||
swagger:
|
swagger:
|
||||||
@ -122,7 +120,7 @@ swagger:
|
|||||||
pathMapping: /dev-api
|
pathMapping: /dev-api
|
||||||
|
|
||||||
# 防止XSS攻击
|
# 防止XSS攻击
|
||||||
xss:
|
xss:
|
||||||
# 过滤开关
|
# 过滤开关
|
||||||
enabled: true
|
enabled: true
|
||||||
# 排除链接(多个用逗号分隔)
|
# 排除链接(多个用逗号分隔)
|
||||||
|
|||||||
@ -9,6 +9,7 @@ user.password.retry.limit.exceed=密码输入错误{0}次,帐户锁定{1}分
|
|||||||
user.password.delete=对不起,您的账号已被删除
|
user.password.delete=对不起,您的账号已被删除
|
||||||
user.blocked=用户已封禁,请联系管理员
|
user.blocked=用户已封禁,请联系管理员
|
||||||
role.blocked=角色已封禁,请联系管理员
|
role.blocked=角色已封禁,请联系管理员
|
||||||
|
login.blocked=很遗憾,访问IP已被列入系统黑名单
|
||||||
user.logout.success=退出成功
|
user.logout.success=退出成功
|
||||||
|
|
||||||
length.not.valid=长度必须在{min}到{max}个字符之间
|
length.not.valid=长度必须在{min}到{max}个字符之间
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>ruoyi</artifactId>
|
<artifactId>ruoyi</artifactId>
|
||||||
<groupId>com.ruoyi</groupId>
|
<groupId>com.ruoyi</groupId>
|
||||||
<version>3.8.4</version>
|
<version>3.8.8</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
@ -58,7 +58,7 @@
|
|||||||
<groupId>com.fasterxml.jackson.core</groupId>
|
<groupId>com.fasterxml.jackson.core</groupId>
|
||||||
<artifactId>jackson-databind</artifactId>
|
<artifactId>jackson-databind</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- 阿里JSON解析器 -->
|
<!-- 阿里JSON解析器 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.alibaba.fastjson2</groupId>
|
<groupId>com.alibaba.fastjson2</groupId>
|
||||||
@ -71,12 +71,6 @@
|
|||||||
<artifactId>commons-io</artifactId>
|
<artifactId>commons-io</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- 文件上传工具类 -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>commons-fileupload</groupId>
|
|
||||||
<artifactId>commons-fileupload</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- excel工具 -->
|
<!-- excel工具 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.poi</groupId>
|
<groupId>org.apache.poi</groupId>
|
||||||
|
|||||||
@ -59,12 +59,12 @@ public @interface Excel
|
|||||||
public int roundingMode() default BigDecimal.ROUND_HALF_EVEN;
|
public int roundingMode() default BigDecimal.ROUND_HALF_EVEN;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 导出时在excel中每个列的高度 单位为字符
|
* 导出时在excel中每个列的高度
|
||||||
*/
|
*/
|
||||||
public double height() default 14;
|
public double height() default 14;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 导出时在excel中每个列的宽 单位为字符
|
* 导出时在excel中每个列的宽度
|
||||||
*/
|
*/
|
||||||
public double width() default 16;
|
public double width() default 16;
|
||||||
|
|
||||||
@ -88,6 +88,11 @@ public @interface Excel
|
|||||||
*/
|
*/
|
||||||
public String[] combo() default {};
|
public String[] combo() default {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否从字典读数据到combo,默认不读取,如读取需要设置dictType注解.
|
||||||
|
*/
|
||||||
|
public boolean comboReadDict() default false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 是否需要纵向合并单元格,应对需求:含有list集合单元格)
|
* 是否需要纵向合并单元格,应对需求:含有list集合单元格)
|
||||||
*/
|
*/
|
||||||
@ -114,7 +119,7 @@ public @interface Excel
|
|||||||
public ColumnType cellType() default ColumnType.STRING;
|
public ColumnType cellType() default ColumnType.STRING;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 导出列头背景色
|
* 导出列头背景颜色
|
||||||
*/
|
*/
|
||||||
public IndexedColors headerBackgroundColor() default IndexedColors.GREY_50_PERCENT;
|
public IndexedColors headerBackgroundColor() default IndexedColors.GREY_50_PERCENT;
|
||||||
|
|
||||||
@ -124,7 +129,7 @@ public @interface Excel
|
|||||||
public IndexedColors headerColor() default IndexedColors.WHITE;
|
public IndexedColors headerColor() default IndexedColors.WHITE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 导出单元格背景色
|
* 导出单元格背景颜色
|
||||||
*/
|
*/
|
||||||
public IndexedColors backgroundColor() default IndexedColors.WHITE;
|
public IndexedColors backgroundColor() default IndexedColors.WHITE;
|
||||||
|
|
||||||
@ -171,7 +176,7 @@ public @interface Excel
|
|||||||
|
|
||||||
public enum ColumnType
|
public enum ColumnType
|
||||||
{
|
{
|
||||||
NUMERIC(0), STRING(1), IMAGE(2);
|
NUMERIC(0), STRING(1), IMAGE(2), TEXT(3);
|
||||||
private final int value;
|
private final int value;
|
||||||
|
|
||||||
ColumnType(int value)
|
ColumnType(int value)
|
||||||
|
|||||||
@ -20,7 +20,7 @@ import com.ruoyi.common.enums.OperatorType;
|
|||||||
public @interface Log
|
public @interface Log
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* 模块
|
* 模块
|
||||||
*/
|
*/
|
||||||
public String title() default "";
|
public String title() default "";
|
||||||
|
|
||||||
@ -43,4 +43,9 @@ public @interface Log
|
|||||||
* 是否保存响应的参数
|
* 是否保存响应的参数
|
||||||
*/
|
*/
|
||||||
public boolean isSaveResponseData() default true;
|
public boolean isSaveResponseData() default true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 排除指定的请求参数
|
||||||
|
*/
|
||||||
|
public String[] excludeParamNames() default {};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,24 @@
|
|||||||
|
package com.ruoyi.common.annotation;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
|
||||||
|
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||||
|
import com.ruoyi.common.config.serializer.SensitiveJsonSerializer;
|
||||||
|
import com.ruoyi.common.enums.DesensitizedType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据脱敏注解
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
*/
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target(ElementType.FIELD)
|
||||||
|
@JacksonAnnotationsInside
|
||||||
|
@JsonSerialize(using = SensitiveJsonSerializer.class)
|
||||||
|
public @interface Sensitive
|
||||||
|
{
|
||||||
|
DesensitizedType desensitizedType();
|
||||||
|
}
|
||||||
@ -21,9 +21,6 @@ public class RuoYiConfig
|
|||||||
/** 版权年份 */
|
/** 版权年份 */
|
||||||
private String copyrightYear;
|
private String copyrightYear;
|
||||||
|
|
||||||
/** 实例演示开关 */
|
|
||||||
private boolean demoEnabled;
|
|
||||||
|
|
||||||
/** 上传路径 */
|
/** 上传路径 */
|
||||||
private static String profile;
|
private static String profile;
|
||||||
|
|
||||||
@ -63,16 +60,6 @@ public class RuoYiConfig
|
|||||||
this.copyrightYear = copyrightYear;
|
this.copyrightYear = copyrightYear;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isDemoEnabled()
|
|
||||||
{
|
|
||||||
return demoEnabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDemoEnabled(boolean demoEnabled)
|
|
||||||
{
|
|
||||||
this.demoEnabled = demoEnabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getProfile()
|
public static String getProfile()
|
||||||
{
|
{
|
||||||
return profile;
|
return profile;
|
||||||
|
|||||||
@ -0,0 +1,67 @@
|
|||||||
|
package com.ruoyi.common.config.serializer;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Objects;
|
||||||
|
import com.fasterxml.jackson.core.JsonGenerator;
|
||||||
|
import com.fasterxml.jackson.databind.BeanProperty;
|
||||||
|
import com.fasterxml.jackson.databind.JsonMappingException;
|
||||||
|
import com.fasterxml.jackson.databind.JsonSerializer;
|
||||||
|
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||||
|
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
|
||||||
|
import com.ruoyi.common.annotation.Sensitive;
|
||||||
|
import com.ruoyi.common.core.domain.model.LoginUser;
|
||||||
|
import com.ruoyi.common.enums.DesensitizedType;
|
||||||
|
import com.ruoyi.common.utils.SecurityUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据脱敏序列化过滤
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
*/
|
||||||
|
public class SensitiveJsonSerializer extends JsonSerializer<String> implements ContextualSerializer
|
||||||
|
{
|
||||||
|
private DesensitizedType desensitizedType;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException
|
||||||
|
{
|
||||||
|
if (desensitization())
|
||||||
|
{
|
||||||
|
gen.writeString(desensitizedType.desensitizer().apply(value));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gen.writeString(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property)
|
||||||
|
throws JsonMappingException
|
||||||
|
{
|
||||||
|
Sensitive annotation = property.getAnnotation(Sensitive.class);
|
||||||
|
if (Objects.nonNull(annotation) && Objects.equals(String.class, property.getType().getRawClass()))
|
||||||
|
{
|
||||||
|
this.desensitizedType = annotation.desensitizedType();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
return prov.findValueSerializer(property.getType(), property);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否需要脱敏处理
|
||||||
|
*/
|
||||||
|
private boolean desensitization()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
LoginUser securityUser = SecurityUtils.getLoginUser();
|
||||||
|
// 管理员不脱敏
|
||||||
|
return !securityUser.getUser().isAdmin();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,5 +1,6 @@
|
|||||||
package com.ruoyi.common.constant;
|
package com.ruoyi.common.constant;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
import io.jsonwebtoken.Claims;
|
import io.jsonwebtoken.Claims;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -19,6 +20,11 @@ public class Constants
|
|||||||
*/
|
*/
|
||||||
public static final String GBK = "GBK";
|
public static final String GBK = "GBK";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 系统语言
|
||||||
|
*/
|
||||||
|
public static final Locale DEFAULT_LOCALE = Locale.SIMPLIFIED_CHINESE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* www主域
|
* www主域
|
||||||
*/
|
*/
|
||||||
@ -63,7 +69,27 @@ public class Constants
|
|||||||
* 登录失败
|
* 登录失败
|
||||||
*/
|
*/
|
||||||
public static final String LOGIN_FAIL = "Error";
|
public static final String LOGIN_FAIL = "Error";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 所有权限标识
|
||||||
|
*/
|
||||||
|
public static final String ALL_PERMISSION = "*:*:*";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 管理员角色权限标识
|
||||||
|
*/
|
||||||
|
public static final String SUPER_ADMIN = "admin";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 角色权限分隔符
|
||||||
|
*/
|
||||||
|
public static final String ROLE_DELIMETER = ",";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 权限标识分隔符
|
||||||
|
*/
|
||||||
|
public static final String PERMISSION_DELIMETER = ",";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 验证码有效期(分钟)
|
* 验证码有效期(分钟)
|
||||||
*/
|
*/
|
||||||
@ -129,14 +155,19 @@ public class Constants
|
|||||||
*/
|
*/
|
||||||
public static final String LOOKUP_LDAPS = "ldaps:";
|
public static final String LOOKUP_LDAPS = "ldaps:";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自动识别json对象白名单配置(仅允许解析的包名,范围越小越安全)
|
||||||
|
*/
|
||||||
|
public static final String[] JSON_WHITELIST_STR = { "org.springframework", "com.ruoyi" };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 定时任务白名单配置(仅允许访问的包名,如其他需要可以自行添加)
|
* 定时任务白名单配置(仅允许访问的包名,如其他需要可以自行添加)
|
||||||
*/
|
*/
|
||||||
public static final String[] JOB_WHITELIST_STR = { "com.ruoyi" };
|
public static final String[] JOB_WHITELIST_STR = { "com.ruoyi.quartz.task" };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 定时任务违规的字符
|
* 定时任务违规的字符
|
||||||
*/
|
*/
|
||||||
public static final String[] JOB_ERROR_STR = { "java.net.URL", "javax.naming.InitialContext", "org.yaml.snakeyaml",
|
public static final String[] JOB_ERROR_STR = { "java.net.URL", "javax.naming.InitialContext", "org.yaml.snakeyaml",
|
||||||
"org.springframework", "org.apache", "com.ruoyi.common.utils.file" };
|
"org.springframework", "org.apache", "com.ruoyi.common.utils.file", "com.ruoyi.common.config", "com.ruoyi.generator" };
|
||||||
}
|
}
|
||||||
|
|||||||
@ -86,4 +86,9 @@ public class HttpStatus
|
|||||||
* 接口未实现
|
* 接口未实现
|
||||||
*/
|
*/
|
||||||
public static final int NOT_IMPLEMENTED = 501;
|
public static final int NOT_IMPLEMENTED = 501;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 系统警告消息
|
||||||
|
*/
|
||||||
|
public static final int WARN = 601;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -60,9 +60,9 @@ public class UserConstants
|
|||||||
/** InnerLink组件标识 */
|
/** InnerLink组件标识 */
|
||||||
public final static String INNER_LINK = "InnerLink";
|
public final static String INNER_LINK = "InnerLink";
|
||||||
|
|
||||||
/** 校验返回结果码 */
|
/** 校验是否唯一的返回标识 */
|
||||||
public final static String UNIQUE = "0";
|
public final static boolean UNIQUE = true;
|
||||||
public final static String NOT_UNIQUE = "1";
|
public final static boolean NOT_UNIQUE = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用户名长度限制
|
* 用户名长度限制
|
||||||
|
|||||||
@ -113,6 +113,14 @@ public class BaseController
|
|||||||
{
|
{
|
||||||
return AjaxResult.success(message);
|
return AjaxResult.success(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回成功消息
|
||||||
|
*/
|
||||||
|
public AjaxResult success(Object data)
|
||||||
|
{
|
||||||
|
return AjaxResult.success(data);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 返回失败消息
|
* 返回失败消息
|
||||||
@ -122,6 +130,14 @@ public class BaseController
|
|||||||
return AjaxResult.error(message);
|
return AjaxResult.error(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回警告消息
|
||||||
|
*/
|
||||||
|
public AjaxResult warn(String message)
|
||||||
|
{
|
||||||
|
return AjaxResult.warn(message);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 响应返回结果
|
* 响应返回结果
|
||||||
*
|
*
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
package com.ruoyi.common.core.domain;
|
package com.ruoyi.common.core.domain;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.Objects;
|
||||||
import com.ruoyi.common.constant.HttpStatus;
|
import com.ruoyi.common.constant.HttpStatus;
|
||||||
import com.ruoyi.common.utils.StringUtils;
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
|
|
||||||
@ -101,10 +102,33 @@ public class AjaxResult extends HashMap<String, Object>
|
|||||||
return new AjaxResult(HttpStatus.SUCCESS, msg, data);
|
return new AjaxResult(HttpStatus.SUCCESS, msg, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回警告消息
|
||||||
|
*
|
||||||
|
* @param msg 返回内容
|
||||||
|
* @return 警告消息
|
||||||
|
*/
|
||||||
|
public static AjaxResult warn(String msg)
|
||||||
|
{
|
||||||
|
return AjaxResult.warn(msg, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回警告消息
|
||||||
|
*
|
||||||
|
* @param msg 返回内容
|
||||||
|
* @param data 数据对象
|
||||||
|
* @return 警告消息
|
||||||
|
*/
|
||||||
|
public static AjaxResult warn(String msg, Object data)
|
||||||
|
{
|
||||||
|
return new AjaxResult(HttpStatus.WARN, msg, data);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 返回错误消息
|
* 返回错误消息
|
||||||
*
|
*
|
||||||
* @return
|
* @return 错误消息
|
||||||
*/
|
*/
|
||||||
public static AjaxResult error()
|
public static AjaxResult error()
|
||||||
{
|
{
|
||||||
@ -115,7 +139,7 @@ public class AjaxResult extends HashMap<String, Object>
|
|||||||
* 返回错误消息
|
* 返回错误消息
|
||||||
*
|
*
|
||||||
* @param msg 返回内容
|
* @param msg 返回内容
|
||||||
* @return 警告消息
|
* @return 错误消息
|
||||||
*/
|
*/
|
||||||
public static AjaxResult error(String msg)
|
public static AjaxResult error(String msg)
|
||||||
{
|
{
|
||||||
@ -127,7 +151,7 @@ public class AjaxResult extends HashMap<String, Object>
|
|||||||
*
|
*
|
||||||
* @param msg 返回内容
|
* @param msg 返回内容
|
||||||
* @param data 数据对象
|
* @param data 数据对象
|
||||||
* @return 警告消息
|
* @return 错误消息
|
||||||
*/
|
*/
|
||||||
public static AjaxResult error(String msg, Object data)
|
public static AjaxResult error(String msg, Object data)
|
||||||
{
|
{
|
||||||
@ -139,13 +163,43 @@ public class AjaxResult extends HashMap<String, Object>
|
|||||||
*
|
*
|
||||||
* @param code 状态码
|
* @param code 状态码
|
||||||
* @param msg 返回内容
|
* @param msg 返回内容
|
||||||
* @return 警告消息
|
* @return 错误消息
|
||||||
*/
|
*/
|
||||||
public static AjaxResult error(int code, String msg)
|
public static AjaxResult error(int code, String msg)
|
||||||
{
|
{
|
||||||
return new AjaxResult(code, msg, null);
|
return new AjaxResult(code, msg, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否为成功消息
|
||||||
|
*
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public boolean isSuccess()
|
||||||
|
{
|
||||||
|
return Objects.equals(HttpStatus.SUCCESS, this.get(CODE_TAG));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否为警告消息
|
||||||
|
*
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public boolean isWarn()
|
||||||
|
{
|
||||||
|
return Objects.equals(HttpStatus.WARN, this.get(CODE_TAG));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否为错误消息
|
||||||
|
*
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public boolean isError()
|
||||||
|
{
|
||||||
|
return Objects.equals(HttpStatus.ERROR, this.get(CODE_TAG));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 方便链式调用
|
* 方便链式调用
|
||||||
*
|
*
|
||||||
|
|||||||
@ -5,6 +5,8 @@ import java.util.Date;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Entity基类
|
* Entity基类
|
||||||
@ -16,6 +18,7 @@ public class BaseEntity implements Serializable
|
|||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
/** 搜索值 */
|
/** 搜索值 */
|
||||||
|
@JsonIgnore
|
||||||
private String searchValue;
|
private String searchValue;
|
||||||
|
|
||||||
/** 创建者 */
|
/** 创建者 */
|
||||||
@ -36,6 +39,7 @@ public class BaseEntity implements Serializable
|
|||||||
private String remark;
|
private String remark;
|
||||||
|
|
||||||
/** 请求参数 */
|
/** 请求参数 */
|
||||||
|
@JsonInclude(JsonInclude.Include.NON_EMPTY)
|
||||||
private Map<String, Object> params;
|
private Map<String, Object> params;
|
||||||
|
|
||||||
public String getSearchValue()
|
public String getSearchValue()
|
||||||
|
|||||||
@ -103,13 +103,13 @@ public class R<T> implements Serializable
|
|||||||
this.data = data;
|
this.data = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Boolean isError()
|
public static <T> Boolean isError(R<T> ret)
|
||||||
{
|
{
|
||||||
return !isSuccess();
|
return !isSuccess(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Boolean isSuccess()
|
public static <T> Boolean isSuccess(R<T> ret)
|
||||||
{
|
{
|
||||||
return R.SUCCESS == getCode();
|
return R.SUCCESS == ret.getCode();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -42,6 +42,9 @@ public class SysMenu extends BaseEntity
|
|||||||
/** 路由参数 */
|
/** 路由参数 */
|
||||||
private String query;
|
private String query;
|
||||||
|
|
||||||
|
/** 路由名称,默认和路由地址相同的驼峰格式(注意:因为vue3版本的router会删除名称相同路由,为避免名字的冲突,特殊情况可以自定义) */
|
||||||
|
private String routeName;
|
||||||
|
|
||||||
/** 是否为外链(0是 1否) */
|
/** 是否为外链(0是 1否) */
|
||||||
private String isFrame;
|
private String isFrame;
|
||||||
|
|
||||||
@ -53,8 +56,8 @@ public class SysMenu extends BaseEntity
|
|||||||
|
|
||||||
/** 显示状态(0显示 1隐藏) */
|
/** 显示状态(0显示 1隐藏) */
|
||||||
private String visible;
|
private String visible;
|
||||||
|
|
||||||
/** 菜单状态(0显示 1隐藏) */
|
/** 菜单状态(0正常 1停用) */
|
||||||
private String status;
|
private String status;
|
||||||
|
|
||||||
/** 权限字符串 */
|
/** 权限字符串 */
|
||||||
@ -151,6 +154,16 @@ public class SysMenu extends BaseEntity
|
|||||||
this.query = query;
|
this.query = query;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getRouteName()
|
||||||
|
{
|
||||||
|
return routeName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRouteName(String routeName)
|
||||||
|
{
|
||||||
|
this.routeName = routeName;
|
||||||
|
}
|
||||||
|
|
||||||
public String getIsFrame()
|
public String getIsFrame()
|
||||||
{
|
{
|
||||||
return isFrame;
|
return isFrame;
|
||||||
@ -232,7 +245,7 @@ public class SysMenu extends BaseEntity
|
|||||||
{
|
{
|
||||||
this.children = children;
|
this.children = children;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
|
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
|
||||||
@ -242,6 +255,8 @@ public class SysMenu extends BaseEntity
|
|||||||
.append("orderNum", getOrderNum())
|
.append("orderNum", getOrderNum())
|
||||||
.append("path", getPath())
|
.append("path", getPath())
|
||||||
.append("component", getComponent())
|
.append("component", getComponent())
|
||||||
|
.append("query", getQuery())
|
||||||
|
.append("routeName", getRouteName())
|
||||||
.append("isFrame", getIsFrame())
|
.append("isFrame", getIsFrame())
|
||||||
.append("IsCache", getIsCache())
|
.append("IsCache", getIsCache())
|
||||||
.append("menuType", getMenuType())
|
.append("menuType", getMenuType())
|
||||||
|
|||||||
@ -2,6 +2,7 @@ package com.ruoyi.common.core.domain.entity;
|
|||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import javax.validation.constraints.NotBlank;
|
import javax.validation.constraints.NotBlank;
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
import javax.validation.constraints.Size;
|
import javax.validation.constraints.Size;
|
||||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||||
@ -32,7 +33,7 @@ public class SysRole extends BaseEntity
|
|||||||
|
|
||||||
/** 角色排序 */
|
/** 角色排序 */
|
||||||
@Excel(name = "角色排序")
|
@Excel(name = "角色排序")
|
||||||
private String roleSort;
|
private Integer roleSort;
|
||||||
|
|
||||||
/** 数据范围(1:所有数据权限;2:自定义数据权限;3:本部门数据权限;4:本部门及以下数据权限;5:仅本人数据权限) */
|
/** 数据范围(1:所有数据权限;2:自定义数据权限;3:本部门数据权限;4:本部门及以下数据权限;5:仅本人数据权限) */
|
||||||
@Excel(name = "数据范围", readConverterExp = "1=所有数据权限,2=自定义数据权限,3=本部门数据权限,4=本部门及以下数据权限,5=仅本人数据权限")
|
@Excel(name = "数据范围", readConverterExp = "1=所有数据权限,2=自定义数据权限,3=本部门数据权限,4=本部门及以下数据权限,5=仅本人数据权限")
|
||||||
@ -117,13 +118,13 @@ public class SysRole extends BaseEntity
|
|||||||
this.roleKey = roleKey;
|
this.roleKey = roleKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotBlank(message = "显示顺序不能为空")
|
@NotNull(message = "显示顺序不能为空")
|
||||||
public String getRoleSort()
|
public Integer getRoleSort()
|
||||||
{
|
{
|
||||||
return roleSort;
|
return roleSort;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRoleSort(String roleSort)
|
public void setRoleSort(Integer roleSort)
|
||||||
{
|
{
|
||||||
this.roleSort = roleSort;
|
this.roleSort = roleSort;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,7 +22,7 @@ public class SysUser extends BaseEntity
|
|||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
/** 用户ID */
|
/** 用户ID */
|
||||||
@Excel(name = "用户序号", cellType = ColumnType.NUMERIC, prompt = "用户编号")
|
@Excel(name = "用户序号", type = Type.EXPORT, cellType = ColumnType.NUMERIC, prompt = "用户编号")
|
||||||
private Long userId;
|
private Long userId;
|
||||||
|
|
||||||
/** 部门ID */
|
/** 部门ID */
|
||||||
@ -42,7 +42,7 @@ public class SysUser extends BaseEntity
|
|||||||
private String email;
|
private String email;
|
||||||
|
|
||||||
/** 手机号码 */
|
/** 手机号码 */
|
||||||
@Excel(name = "手机号码")
|
@Excel(name = "手机号码", cellType = ColumnType.TEXT)
|
||||||
private String phonenumber;
|
private String phonenumber;
|
||||||
|
|
||||||
/** 用户性别 */
|
/** 用户性别 */
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
package com.ruoyi.common.core.domain.model;
|
package com.ruoyi.common.core.domain.model;
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Set;
|
|
||||||
import org.springframework.security.core.GrantedAuthority;
|
|
||||||
import org.springframework.security.core.userdetails.UserDetails;
|
|
||||||
import com.alibaba.fastjson2.annotation.JSONField;
|
import com.alibaba.fastjson2.annotation.JSONField;
|
||||||
import com.ruoyi.common.core.domain.entity.SysUser;
|
import com.ruoyi.common.core.domain.entity.SysUser;
|
||||||
|
import org.springframework.security.core.GrantedAuthority;
|
||||||
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 登录用户身份权限
|
* 登录用户身份权限
|
||||||
@ -71,6 +71,24 @@ public class LoginUser implements UserDetails
|
|||||||
*/
|
*/
|
||||||
private SysUser user;
|
private SysUser user;
|
||||||
|
|
||||||
|
public LoginUser()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public LoginUser(SysUser user, Set<String> permissions)
|
||||||
|
{
|
||||||
|
this.user = user;
|
||||||
|
this.permissions = permissions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LoginUser(Long userId, Long deptId, SysUser user, Set<String> permissions)
|
||||||
|
{
|
||||||
|
this.userId = userId;
|
||||||
|
this.deptId = deptId;
|
||||||
|
this.user = user;
|
||||||
|
this.permissions = permissions;
|
||||||
|
}
|
||||||
|
|
||||||
public Long getUserId()
|
public Long getUserId()
|
||||||
{
|
{
|
||||||
return userId;
|
return userId;
|
||||||
@ -101,24 +119,6 @@ public class LoginUser implements UserDetails
|
|||||||
this.token = token;
|
this.token = token;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LoginUser()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public LoginUser(SysUser user, Set<String> permissions)
|
|
||||||
{
|
|
||||||
this.user = user;
|
|
||||||
this.permissions = permissions;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LoginUser(Long userId, Long deptId, SysUser user, Set<String> permissions)
|
|
||||||
{
|
|
||||||
this.userId = userId;
|
|
||||||
this.deptId = deptId;
|
|
||||||
this.user = user;
|
|
||||||
this.permissions = permissions;
|
|
||||||
}
|
|
||||||
|
|
||||||
@JSONField(serialize = false)
|
@JSONField(serialize = false)
|
||||||
@Override
|
@Override
|
||||||
public String getPassword()
|
public String getPassword()
|
||||||
|
|||||||
@ -2,6 +2,7 @@ package com.ruoyi.common.core.text;
|
|||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
|
import java.math.RoundingMode;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.text.NumberFormat;
|
import java.text.NumberFormat;
|
||||||
@ -364,6 +365,10 @@ public class Convert
|
|||||||
*/
|
*/
|
||||||
public static String[] toStrArray(String str)
|
public static String[] toStrArray(String str)
|
||||||
{
|
{
|
||||||
|
if (StringUtils.isEmpty(str))
|
||||||
|
{
|
||||||
|
return new String[] {};
|
||||||
|
}
|
||||||
return toStrArray(",", str);
|
return toStrArray(",", str);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -713,7 +718,7 @@ public class Convert
|
|||||||
}
|
}
|
||||||
if (value instanceof Double)
|
if (value instanceof Double)
|
||||||
{
|
{
|
||||||
return new BigDecimal((Double) value);
|
return BigDecimal.valueOf((Double) value);
|
||||||
}
|
}
|
||||||
if (value instanceof Integer)
|
if (value instanceof Integer)
|
||||||
{
|
{
|
||||||
@ -977,7 +982,12 @@ public class Convert
|
|||||||
String s = "";
|
String s = "";
|
||||||
for (int i = 0; i < fraction.length; i++)
|
for (int i = 0; i < fraction.length; i++)
|
||||||
{
|
{
|
||||||
s += (digit[(int) (Math.floor(n * 10 * Math.pow(10, i)) % 10)] + fraction[i]).replaceAll("(零.)+", "");
|
// 优化double计算精度丢失问题
|
||||||
|
BigDecimal nNum = new BigDecimal(n);
|
||||||
|
BigDecimal decimal = new BigDecimal(10);
|
||||||
|
BigDecimal scale = nNum.multiply(decimal).setScale(2, RoundingMode.HALF_EVEN);
|
||||||
|
double d = scale.doubleValue();
|
||||||
|
s += (digit[(int) (Math.floor(d * Math.pow(10, i)) % 10)] + fraction[i]).replaceAll("(零.)+", "");
|
||||||
}
|
}
|
||||||
if (s.length() < 1)
|
if (s.length() < 1)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -0,0 +1,59 @@
|
|||||||
|
package com.ruoyi.common.enums;
|
||||||
|
|
||||||
|
import java.util.function.Function;
|
||||||
|
import com.ruoyi.common.utils.DesensitizedUtil;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 脱敏类型
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
*/
|
||||||
|
public enum DesensitizedType
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 姓名,第2位星号替换
|
||||||
|
*/
|
||||||
|
USERNAME(s -> s.replaceAll("(\\S)\\S(\\S*)", "$1*$2")),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 密码,全部字符都用*代替
|
||||||
|
*/
|
||||||
|
PASSWORD(DesensitizedUtil::password),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 身份证,中间10位星号替换
|
||||||
|
*/
|
||||||
|
ID_CARD(s -> s.replaceAll("(\\d{4})\\d{10}(\\d{4})", "$1** **** ****$2")),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 手机号,中间4位星号替换
|
||||||
|
*/
|
||||||
|
PHONE(s -> s.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2")),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 电子邮箱,仅显示第一个字母和@后面的地址显示,其他星号替换
|
||||||
|
*/
|
||||||
|
EMAIL(s -> s.replaceAll("(^.)[^@]*(@.*$)", "$1****$2")),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 银行卡号,保留最后4位,其他星号替换
|
||||||
|
*/
|
||||||
|
BANK_CARD(s -> s.replaceAll("\\d{15}(\\d{3})", "**** **** **** **** $1")),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 车牌号码,包含普通车辆、新能源车辆
|
||||||
|
*/
|
||||||
|
CAR_LICENSE(DesensitizedUtil::carLicense);
|
||||||
|
|
||||||
|
private final Function<String, String> desensitizer;
|
||||||
|
|
||||||
|
DesensitizedType(Function<String, String> desensitizer)
|
||||||
|
{
|
||||||
|
this.desensitizer = desensitizer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Function<String, String> desensitizer()
|
||||||
|
{
|
||||||
|
return desensitizer;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,61 @@
|
|||||||
|
package com.ruoyi.common.exception.file;
|
||||||
|
|
||||||
|
import java.io.PrintStream;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件上传异常类
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
*/
|
||||||
|
public class FileUploadException extends Exception
|
||||||
|
{
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private final Throwable cause;
|
||||||
|
|
||||||
|
public FileUploadException()
|
||||||
|
{
|
||||||
|
this(null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public FileUploadException(final String msg)
|
||||||
|
{
|
||||||
|
this(msg, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public FileUploadException(String msg, Throwable cause)
|
||||||
|
{
|
||||||
|
super(msg);
|
||||||
|
this.cause = cause;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void printStackTrace(PrintStream stream)
|
||||||
|
{
|
||||||
|
super.printStackTrace(stream);
|
||||||
|
if (cause != null)
|
||||||
|
{
|
||||||
|
stream.println("Caused by:");
|
||||||
|
cause.printStackTrace(stream);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void printStackTrace(PrintWriter writer)
|
||||||
|
{
|
||||||
|
super.printStackTrace(writer);
|
||||||
|
if (cause != null)
|
||||||
|
{
|
||||||
|
writer.println("Caused by:");
|
||||||
|
cause.printStackTrace(writer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Throwable getCause()
|
||||||
|
{
|
||||||
|
return cause;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,7 +1,6 @@
|
|||||||
package com.ruoyi.common.exception.file;
|
package com.ruoyi.common.exception.file;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import org.apache.commons.fileupload.FileUploadException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 文件上传 误异常类
|
* 文件上传 误异常类
|
||||||
|
|||||||
@ -0,0 +1,16 @@
|
|||||||
|
package com.ruoyi.common.exception.user;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 黑名单IP异常类
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
*/
|
||||||
|
public class BlackListException extends UserException
|
||||||
|
{
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public BlackListException()
|
||||||
|
{
|
||||||
|
super("login.blocked", null);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,16 @@
|
|||||||
|
package com.ruoyi.common.exception.user;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户不存在异常类
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
*/
|
||||||
|
public class UserNotExistsException extends UserException
|
||||||
|
{
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public UserNotExistsException()
|
||||||
|
{
|
||||||
|
super("user.not.exists", null);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -32,10 +32,10 @@ public class XssFilter implements Filter
|
|||||||
String tempExcludes = filterConfig.getInitParameter("excludes");
|
String tempExcludes = filterConfig.getInitParameter("excludes");
|
||||||
if (StringUtils.isNotEmpty(tempExcludes))
|
if (StringUtils.isNotEmpty(tempExcludes))
|
||||||
{
|
{
|
||||||
String[] url = tempExcludes.split(",");
|
String[] urls = tempExcludes.split(",");
|
||||||
for (int i = 0; url != null && i < url.length; i++)
|
for (String url : urls)
|
||||||
{
|
{
|
||||||
excludes.add(url[i]);
|
excludes.add(url);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -34,13 +34,13 @@ public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper
|
|||||||
if (values != null)
|
if (values != null)
|
||||||
{
|
{
|
||||||
int length = values.length;
|
int length = values.length;
|
||||||
String[] escapseValues = new String[length];
|
String[] escapesValues = new String[length];
|
||||||
for (int i = 0; i < length; i++)
|
for (int i = 0; i < length; i++)
|
||||||
{
|
{
|
||||||
// 防xss攻击和过滤前后空格
|
// 防xss攻击和过滤前后空格
|
||||||
escapseValues[i] = EscapeUtil.clean(values[i]).trim();
|
escapesValues[i] = EscapeUtil.clean(values[i]).trim();
|
||||||
}
|
}
|
||||||
return escapseValues;
|
return escapesValues;
|
||||||
}
|
}
|
||||||
return super.getParameterValues(name);
|
return super.getParameterValues(name);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -145,16 +145,20 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 计算两个时间差
|
* 计算时间差
|
||||||
|
*
|
||||||
|
* @param endDate 最后时间
|
||||||
|
* @param startTime 开始时间
|
||||||
|
* @return 时间差(天/小时/分钟)
|
||||||
*/
|
*/
|
||||||
public static String getDatePoor(Date endDate, Date nowDate)
|
public static String timeDistance(Date endDate, Date startTime)
|
||||||
{
|
{
|
||||||
long nd = 1000 * 24 * 60 * 60;
|
long nd = 1000 * 24 * 60 * 60;
|
||||||
long nh = 1000 * 60 * 60;
|
long nh = 1000 * 60 * 60;
|
||||||
long nm = 1000 * 60;
|
long nm = 1000 * 60;
|
||||||
// long ns = 1000;
|
// long ns = 1000;
|
||||||
// 获得两个时间的毫秒时间差异
|
// 获得两个时间的毫秒时间差异
|
||||||
long diff = endDate.getTime() - nowDate.getTime();
|
long diff = endDate.getTime() - startTime.getTime();
|
||||||
// 计算差多少天
|
// 计算差多少天
|
||||||
long day = diff / nd;
|
long day = diff / nd;
|
||||||
// 计算差多少小时
|
// 计算差多少小时
|
||||||
|
|||||||
@ -0,0 +1,49 @@
|
|||||||
|
package com.ruoyi.common.utils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 脱敏工具类
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
*/
|
||||||
|
public class DesensitizedUtil
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 密码的全部字符都用*代替,比如:******
|
||||||
|
*
|
||||||
|
* @param password 密码
|
||||||
|
* @return 脱敏后的密码
|
||||||
|
*/
|
||||||
|
public static String password(String password)
|
||||||
|
{
|
||||||
|
if (StringUtils.isBlank(password))
|
||||||
|
{
|
||||||
|
return StringUtils.EMPTY;
|
||||||
|
}
|
||||||
|
return StringUtils.repeat('*', password.length());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 车牌中间用*代替,如果是错误的车牌,不处理
|
||||||
|
*
|
||||||
|
* @param carLicense 完整的车牌号
|
||||||
|
* @return 脱敏后的车牌
|
||||||
|
*/
|
||||||
|
public static String carLicense(String carLicense)
|
||||||
|
{
|
||||||
|
if (StringUtils.isBlank(carLicense))
|
||||||
|
{
|
||||||
|
return StringUtils.EMPTY;
|
||||||
|
}
|
||||||
|
// 普通车牌
|
||||||
|
if (carLicense.length() == 7)
|
||||||
|
{
|
||||||
|
carLicense = StringUtils.hide(carLicense, 3, 6);
|
||||||
|
}
|
||||||
|
else if (carLicense.length() == 8)
|
||||||
|
{
|
||||||
|
// 新能源车牌
|
||||||
|
carLicense = StringUtils.hide(carLicense, 3, 7);
|
||||||
|
}
|
||||||
|
return carLicense;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -56,6 +56,10 @@ public class DictUtils
|
|||||||
*/
|
*/
|
||||||
public static String getDictLabel(String dictType, String dictValue)
|
public static String getDictLabel(String dictType, String dictValue)
|
||||||
{
|
{
|
||||||
|
if (StringUtils.isEmpty(dictValue))
|
||||||
|
{
|
||||||
|
return StringUtils.EMPTY;
|
||||||
|
}
|
||||||
return getDictLabel(dictType, dictValue, SEPARATOR);
|
return getDictLabel(dictType, dictValue, SEPARATOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,6 +72,10 @@ public class DictUtils
|
|||||||
*/
|
*/
|
||||||
public static String getDictValue(String dictType, String dictLabel)
|
public static String getDictValue(String dictType, String dictLabel)
|
||||||
{
|
{
|
||||||
|
if (StringUtils.isEmpty(dictLabel))
|
||||||
|
{
|
||||||
|
return StringUtils.EMPTY;
|
||||||
|
}
|
||||||
return getDictValue(dictType, dictLabel, SEPARATOR);
|
return getDictValue(dictType, dictLabel, SEPARATOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,31 +91,31 @@ public class DictUtils
|
|||||||
{
|
{
|
||||||
StringBuilder propertyString = new StringBuilder();
|
StringBuilder propertyString = new StringBuilder();
|
||||||
List<SysDictData> datas = getDictCache(dictType);
|
List<SysDictData> datas = getDictCache(dictType);
|
||||||
|
if (StringUtils.isNull(datas))
|
||||||
if (StringUtils.isNotNull(datas))
|
|
||||||
{
|
{
|
||||||
if (StringUtils.containsAny(separator, dictValue))
|
return StringUtils.EMPTY;
|
||||||
|
}
|
||||||
|
if (StringUtils.containsAny(separator, dictValue))
|
||||||
|
{
|
||||||
|
for (SysDictData dict : datas)
|
||||||
{
|
{
|
||||||
for (SysDictData dict : datas)
|
for (String value : dictValue.split(separator))
|
||||||
{
|
{
|
||||||
for (String value : dictValue.split(separator))
|
if (value.equals(dict.getDictValue()))
|
||||||
{
|
{
|
||||||
if (value.equals(dict.getDictValue()))
|
propertyString.append(dict.getDictLabel()).append(separator);
|
||||||
{
|
break;
|
||||||
propertyString.append(dict.getDictLabel()).append(separator);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (SysDictData dict : datas)
|
||||||
{
|
{
|
||||||
for (SysDictData dict : datas)
|
if (dictValue.equals(dict.getDictValue()))
|
||||||
{
|
{
|
||||||
if (dictValue.equals(dict.getDictValue()))
|
return dict.getDictLabel();
|
||||||
{
|
|
||||||
return dict.getDictLabel();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -126,8 +134,11 @@ public class DictUtils
|
|||||||
{
|
{
|
||||||
StringBuilder propertyString = new StringBuilder();
|
StringBuilder propertyString = new StringBuilder();
|
||||||
List<SysDictData> datas = getDictCache(dictType);
|
List<SysDictData> datas = getDictCache(dictType);
|
||||||
|
if (StringUtils.isNull(datas))
|
||||||
if (StringUtils.containsAny(separator, dictLabel) && StringUtils.isNotEmpty(datas))
|
{
|
||||||
|
return StringUtils.EMPTY;
|
||||||
|
}
|
||||||
|
if (StringUtils.containsAny(separator, dictLabel))
|
||||||
{
|
{
|
||||||
for (SysDictData dict : datas)
|
for (SysDictData dict : datas)
|
||||||
{
|
{
|
||||||
@ -154,6 +165,48 @@ public class DictUtils
|
|||||||
return StringUtils.stripEnd(propertyString.toString(), separator);
|
return StringUtils.stripEnd(propertyString.toString(), separator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据字典类型获取字典所有值
|
||||||
|
*
|
||||||
|
* @param dictType 字典类型
|
||||||
|
* @return 字典值
|
||||||
|
*/
|
||||||
|
public static String getDictValues(String dictType)
|
||||||
|
{
|
||||||
|
StringBuilder propertyString = new StringBuilder();
|
||||||
|
List<SysDictData> datas = getDictCache(dictType);
|
||||||
|
if (StringUtils.isNull(datas))
|
||||||
|
{
|
||||||
|
return StringUtils.EMPTY;
|
||||||
|
}
|
||||||
|
for (SysDictData dict : datas)
|
||||||
|
{
|
||||||
|
propertyString.append(dict.getDictValue()).append(SEPARATOR);
|
||||||
|
}
|
||||||
|
return StringUtils.stripEnd(propertyString.toString(), SEPARATOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据字典类型获取字典所有标签
|
||||||
|
*
|
||||||
|
* @param dictType 字典类型
|
||||||
|
* @return 字典值
|
||||||
|
*/
|
||||||
|
public static String getDictLabels(String dictType)
|
||||||
|
{
|
||||||
|
StringBuilder propertyString = new StringBuilder();
|
||||||
|
List<SysDictData> datas = getDictCache(dictType);
|
||||||
|
if (StringUtils.isNull(datas))
|
||||||
|
{
|
||||||
|
return StringUtils.EMPTY;
|
||||||
|
}
|
||||||
|
for (SysDictData dict : datas)
|
||||||
|
{
|
||||||
|
propertyString.append(dict.getDictLabel()).append(SEPARATOR);
|
||||||
|
}
|
||||||
|
return StringUtils.stripEnd(propertyString.toString(), SEPARATOR);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除指定字典缓存
|
* 删除指定字典缓存
|
||||||
*
|
*
|
||||||
|
|||||||
@ -1,9 +1,15 @@
|
|||||||
package com.ruoyi.common.utils;
|
package com.ruoyi.common.utils;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
import org.springframework.security.core.context.SecurityContextHolder;
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||||
|
import org.springframework.util.PatternMatchUtils;
|
||||||
|
import com.ruoyi.common.constant.Constants;
|
||||||
import com.ruoyi.common.constant.HttpStatus;
|
import com.ruoyi.common.constant.HttpStatus;
|
||||||
|
import com.ruoyi.common.core.domain.entity.SysRole;
|
||||||
import com.ruoyi.common.core.domain.model.LoginUser;
|
import com.ruoyi.common.core.domain.model.LoginUser;
|
||||||
import com.ruoyi.common.exception.ServiceException;
|
import com.ruoyi.common.exception.ServiceException;
|
||||||
|
|
||||||
@ -14,6 +20,7 @@ import com.ruoyi.common.exception.ServiceException;
|
|||||||
*/
|
*/
|
||||||
public class SecurityUtils
|
public class SecurityUtils
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用户ID
|
* 用户ID
|
||||||
**/
|
**/
|
||||||
@ -43,7 +50,7 @@ public class SecurityUtils
|
|||||||
throw new ServiceException("获取部门ID异常", HttpStatus.UNAUTHORIZED);
|
throw new ServiceException("获取部门ID异常", HttpStatus.UNAUTHORIZED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取用户账户
|
* 获取用户账户
|
||||||
**/
|
**/
|
||||||
@ -117,4 +124,55 @@ public class SecurityUtils
|
|||||||
{
|
{
|
||||||
return userId != null && 1L == userId;
|
return userId != null && 1L == userId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证用户是否具备某权限
|
||||||
|
*
|
||||||
|
* @param permission 权限字符串
|
||||||
|
* @return 用户是否具备某权限
|
||||||
|
*/
|
||||||
|
public static boolean hasPermi(String permission)
|
||||||
|
{
|
||||||
|
return hasPermi(getLoginUser().getPermissions(), permission);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是否包含权限
|
||||||
|
*
|
||||||
|
* @param authorities 权限列表
|
||||||
|
* @param permission 权限字符串
|
||||||
|
* @return 用户是否具备某权限
|
||||||
|
*/
|
||||||
|
public static boolean hasPermi(Collection<String> authorities, String permission)
|
||||||
|
{
|
||||||
|
return authorities.stream().filter(StringUtils::hasText)
|
||||||
|
.anyMatch(x -> Constants.ALL_PERMISSION.equals(x) || PatternMatchUtils.simpleMatch(x, permission));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证用户是否拥有某个角色
|
||||||
|
*
|
||||||
|
* @param role 角色标识
|
||||||
|
* @return 用户是否具备某角色
|
||||||
|
*/
|
||||||
|
public static boolean hasRole(String role)
|
||||||
|
{
|
||||||
|
List<SysRole> roleList = getLoginUser().getUser().getRoles();
|
||||||
|
Collection<String> roles = roleList.stream().map(SysRole::getRoleKey).collect(Collectors.toSet());
|
||||||
|
return hasRole(roles, role);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是否包含角色
|
||||||
|
*
|
||||||
|
* @param roles 角色列表
|
||||||
|
* @param role 角色
|
||||||
|
* @return 用户是否具备某角色权限
|
||||||
|
*/
|
||||||
|
public static boolean hasRole(Collection<String> roles, String role)
|
||||||
|
{
|
||||||
|
return roles.stream().filter(StringUtils::hasText)
|
||||||
|
.anyMatch(x -> Constants.SUPER_ADMIN.equals(x) || PatternMatchUtils.simpleMatch(x, role));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,6 +4,10 @@ import java.io.IOException;
|
|||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.net.URLDecoder;
|
import java.net.URLDecoder;
|
||||||
import java.net.URLEncoder;
|
import java.net.URLEncoder;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import javax.servlet.ServletRequest;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import javax.servlet.http.HttpSession;
|
import javax.servlet.http.HttpSession;
|
||||||
@ -68,6 +72,34 @@ public class ServletUtils
|
|||||||
return Convert.toBool(getRequest().getParameter(name), defaultValue);
|
return Convert.toBool(getRequest().getParameter(name), defaultValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得所有请求参数
|
||||||
|
*
|
||||||
|
* @param request 请求对象{@link ServletRequest}
|
||||||
|
* @return Map
|
||||||
|
*/
|
||||||
|
public static Map<String, String[]> getParams(ServletRequest request)
|
||||||
|
{
|
||||||
|
final Map<String, String[]> map = request.getParameterMap();
|
||||||
|
return Collections.unmodifiableMap(map);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得所有请求参数
|
||||||
|
*
|
||||||
|
* @param request 请求对象{@link ServletRequest}
|
||||||
|
* @return Map
|
||||||
|
*/
|
||||||
|
public static Map<String, String> getParamMap(ServletRequest request)
|
||||||
|
{
|
||||||
|
Map<String, String> params = new HashMap<>();
|
||||||
|
for (Map.Entry<String, String[]> entry : getParams(request).entrySet())
|
||||||
|
{
|
||||||
|
params.put(entry.getKey(), StringUtils.join(entry.getValue(), ","));
|
||||||
|
}
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取request
|
* 获取request
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -23,6 +23,9 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils
|
|||||||
/** 下划线 */
|
/** 下划线 */
|
||||||
private static final char SEPARATOR = '_';
|
private static final char SEPARATOR = '_';
|
||||||
|
|
||||||
|
/** 星号 */
|
||||||
|
private static final char ASTERISK = '*';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取参数不为空值
|
* 获取参数不为空值
|
||||||
*
|
*
|
||||||
@ -163,6 +166,49 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils
|
|||||||
return (str == null ? "" : str.trim());
|
return (str == null ? "" : str.trim());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 替换指定字符串的指定区间内字符为"*"
|
||||||
|
*
|
||||||
|
* @param str 字符串
|
||||||
|
* @param startInclude 开始位置(包含)
|
||||||
|
* @param endExclude 结束位置(不包含)
|
||||||
|
* @return 替换后的字符串
|
||||||
|
*/
|
||||||
|
public static String hide(CharSequence str, int startInclude, int endExclude)
|
||||||
|
{
|
||||||
|
if (isEmpty(str))
|
||||||
|
{
|
||||||
|
return NULLSTR;
|
||||||
|
}
|
||||||
|
final int strLength = str.length();
|
||||||
|
if (startInclude > strLength)
|
||||||
|
{
|
||||||
|
return NULLSTR;
|
||||||
|
}
|
||||||
|
if (endExclude > strLength)
|
||||||
|
{
|
||||||
|
endExclude = strLength;
|
||||||
|
}
|
||||||
|
if (startInclude > endExclude)
|
||||||
|
{
|
||||||
|
// 如果起始位置大于结束位置,不替换
|
||||||
|
return NULLSTR;
|
||||||
|
}
|
||||||
|
final char[] chars = new char[strLength];
|
||||||
|
for (int i = 0; i < strLength; i++)
|
||||||
|
{
|
||||||
|
if (i >= startInclude && i < endExclude)
|
||||||
|
{
|
||||||
|
chars[i] = ASTERISK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
chars[i] = str.charAt(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new String(chars);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 截取字符串
|
* 截取字符串
|
||||||
*
|
*
|
||||||
@ -240,6 +286,30 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils
|
|||||||
return str.substring(start, end);
|
return str.substring(start, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是否为空,并且不是空白字符
|
||||||
|
*
|
||||||
|
* @param str 要判断的value
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public static boolean hasText(String str)
|
||||||
|
{
|
||||||
|
return (str != null && !str.isEmpty() && containsText(str));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean containsText(CharSequence str)
|
||||||
|
{
|
||||||
|
int strLen = str.length();
|
||||||
|
for (int i = 0; i < strLen; i++)
|
||||||
|
{
|
||||||
|
if (!Character.isWhitespace(str.charAt(i)))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 格式化文本, {} 表示占位符<br>
|
* 格式化文本, {} 表示占位符<br>
|
||||||
* 此方法只是简单将占位符 {} 按照顺序替换为参数<br>
|
* 此方法只是简单将占位符 {} 按照顺序替换为参数<br>
|
||||||
@ -325,9 +395,9 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 判断给定的set列表中是否包含数组array 判断给定的数组array中是否包含给定的元素value
|
* 判断给定的collection列表中是否包含数组array 判断给定的数组array中是否包含给定的元素value
|
||||||
*
|
*
|
||||||
* @param set 给定的集合
|
* @param collection 给定的集合
|
||||||
* @param array 给定的数组
|
* @param array 给定的数组
|
||||||
* @return boolean 结果
|
* @return boolean 结果
|
||||||
*/
|
*/
|
||||||
@ -481,7 +551,8 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 驼峰式命名法 例如:user_name->userName
|
* 驼峰式命名法
|
||||||
|
* 例如:user_name->userName
|
||||||
*/
|
*/
|
||||||
public static String toCamelCase(String s)
|
public static String toCamelCase(String s)
|
||||||
{
|
{
|
||||||
@ -489,6 +560,10 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils
|
|||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
if (s.indexOf(SEPARATOR) == -1)
|
||||||
|
{
|
||||||
|
return s;
|
||||||
|
}
|
||||||
s = s.toLowerCase();
|
s = s.toLowerCase();
|
||||||
StringBuilder sb = new StringBuilder(s.length());
|
StringBuilder sb = new StringBuilder(s.length());
|
||||||
boolean upperCase = false;
|
boolean upperCase = false;
|
||||||
|
|||||||
@ -25,7 +25,7 @@ public class FileUploadUtils
|
|||||||
/**
|
/**
|
||||||
* 默认大小 50M
|
* 默认大小 50M
|
||||||
*/
|
*/
|
||||||
public static final long DEFAULT_MAX_SIZE = 50 * 1024 * 1024;
|
public static final long DEFAULT_MAX_SIZE = 50 * 1024 * 1024L;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 默认的文件名最大长度 100
|
* 默认的文件名最大长度 100
|
||||||
|
|||||||
@ -116,8 +116,7 @@ public class FileUtils
|
|||||||
// 路径为文件且不为空则进行删除
|
// 路径为文件且不为空则进行删除
|
||||||
if (file.isFile() && file.exists())
|
if (file.isFile() && file.exists())
|
||||||
{
|
{
|
||||||
file.delete();
|
flag = file.delete();
|
||||||
flag = true;
|
|
||||||
}
|
}
|
||||||
return flag;
|
return flag;
|
||||||
}
|
}
|
||||||
@ -289,5 +288,4 @@ public class FileUtils
|
|||||||
String baseName = FilenameUtils.getBaseName(fileName);
|
String baseName = FilenameUtils.getBaseName(fileName);
|
||||||
return baseName;
|
return baseName;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -74,7 +74,7 @@ public class HttpUtils
|
|||||||
URLConnection connection = realUrl.openConnection();
|
URLConnection connection = realUrl.openConnection();
|
||||||
connection.setRequestProperty("accept", "*/*");
|
connection.setRequestProperty("accept", "*/*");
|
||||||
connection.setRequestProperty("connection", "Keep-Alive");
|
connection.setRequestProperty("connection", "Keep-Alive");
|
||||||
connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
|
connection.setRequestProperty("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64)");
|
||||||
connection.connect();
|
connection.connect();
|
||||||
in = new BufferedReader(new InputStreamReader(connection.getInputStream(), contentType));
|
in = new BufferedReader(new InputStreamReader(connection.getInputStream(), contentType));
|
||||||
String line;
|
String line;
|
||||||
@ -136,7 +136,7 @@ public class HttpUtils
|
|||||||
URLConnection conn = realUrl.openConnection();
|
URLConnection conn = realUrl.openConnection();
|
||||||
conn.setRequestProperty("accept", "*/*");
|
conn.setRequestProperty("accept", "*/*");
|
||||||
conn.setRequestProperty("connection", "Keep-Alive");
|
conn.setRequestProperty("connection", "Keep-Alive");
|
||||||
conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
|
conn.setRequestProperty("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64)");
|
||||||
conn.setRequestProperty("Accept-Charset", "utf-8");
|
conn.setRequestProperty("Accept-Charset", "utf-8");
|
||||||
conn.setRequestProperty("contentType", "utf-8");
|
conn.setRequestProperty("contentType", "utf-8");
|
||||||
conn.setDoOutput(true);
|
conn.setDoOutput(true);
|
||||||
@ -202,7 +202,7 @@ public class HttpUtils
|
|||||||
HttpsURLConnection conn = (HttpsURLConnection) console.openConnection();
|
HttpsURLConnection conn = (HttpsURLConnection) console.openConnection();
|
||||||
conn.setRequestProperty("accept", "*/*");
|
conn.setRequestProperty("accept", "*/*");
|
||||||
conn.setRequestProperty("connection", "Keep-Alive");
|
conn.setRequestProperty("connection", "Keep-Alive");
|
||||||
conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
|
conn.setRequestProperty("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64)");
|
||||||
conn.setRequestProperty("Accept-Charset", "utf-8");
|
conn.setRequestProperty("Accept-Charset", "utf-8");
|
||||||
conn.setRequestProperty("contentType", "utf-8");
|
conn.setRequestProperty("contentType", "utf-8");
|
||||||
conn.setDoOutput(true);
|
conn.setDoOutput(true);
|
||||||
|
|||||||
@ -3,6 +3,7 @@ package com.ruoyi.common.utils.ip;
|
|||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import com.ruoyi.common.utils.ServletUtils;
|
||||||
import com.ruoyi.common.utils.StringUtils;
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -12,6 +13,23 @@ import com.ruoyi.common.utils.StringUtils;
|
|||||||
*/
|
*/
|
||||||
public class IpUtils
|
public class IpUtils
|
||||||
{
|
{
|
||||||
|
public final static String REGX_0_255 = "(25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]\\d|\\d)";
|
||||||
|
// 匹配 ip
|
||||||
|
public final static String REGX_IP = "((" + REGX_0_255 + "\\.){3}" + REGX_0_255 + ")";
|
||||||
|
public final static String REGX_IP_WILDCARD = "(((\\*\\.){3}\\*)|(" + REGX_0_255 + "(\\.\\*){3})|(" + REGX_0_255 + "\\." + REGX_0_255 + ")(\\.\\*){2}" + "|((" + REGX_0_255 + "\\.){3}\\*))";
|
||||||
|
// 匹配网段
|
||||||
|
public final static String REGX_IP_SEG = "(" + REGX_IP + "\\-" + REGX_IP + ")";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取客户端IP
|
||||||
|
*
|
||||||
|
* @return IP地址
|
||||||
|
*/
|
||||||
|
public static String getIpAddr()
|
||||||
|
{
|
||||||
|
return getIpAddr(ServletUtils.getRequest());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取客户端IP
|
* 获取客户端IP
|
||||||
*
|
*
|
||||||
@ -248,7 +266,7 @@ public class IpUtils
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ip;
|
return StringUtils.substring(ip, 0, 255);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -261,4 +279,104 @@ public class IpUtils
|
|||||||
{
|
{
|
||||||
return StringUtils.isBlank(checkString) || "unknown".equalsIgnoreCase(checkString);
|
return StringUtils.isBlank(checkString) || "unknown".equalsIgnoreCase(checkString);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否为IP
|
||||||
|
*/
|
||||||
|
public static boolean isIP(String ip)
|
||||||
|
{
|
||||||
|
return StringUtils.isNotBlank(ip) && ip.matches(REGX_IP);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否为IP,或 *为间隔的通配符地址
|
||||||
|
*/
|
||||||
|
public static boolean isIpWildCard(String ip)
|
||||||
|
{
|
||||||
|
return StringUtils.isNotBlank(ip) && ip.matches(REGX_IP_WILDCARD);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检测参数是否在ip通配符里
|
||||||
|
*/
|
||||||
|
public static boolean ipIsInWildCardNoCheck(String ipWildCard, String ip)
|
||||||
|
{
|
||||||
|
String[] s1 = ipWildCard.split("\\.");
|
||||||
|
String[] s2 = ip.split("\\.");
|
||||||
|
boolean isMatchedSeg = true;
|
||||||
|
for (int i = 0; i < s1.length && !s1[i].equals("*"); i++)
|
||||||
|
{
|
||||||
|
if (!s1[i].equals(s2[i]))
|
||||||
|
{
|
||||||
|
isMatchedSeg = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return isMatchedSeg;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否为特定格式如:“10.10.10.1-10.10.10.99”的ip段字符串
|
||||||
|
*/
|
||||||
|
public static boolean isIPSegment(String ipSeg)
|
||||||
|
{
|
||||||
|
return StringUtils.isNotBlank(ipSeg) && ipSeg.matches(REGX_IP_SEG);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断ip是否在指定网段中
|
||||||
|
*/
|
||||||
|
public static boolean ipIsInNetNoCheck(String iparea, String ip)
|
||||||
|
{
|
||||||
|
int idx = iparea.indexOf('-');
|
||||||
|
String[] sips = iparea.substring(0, idx).split("\\.");
|
||||||
|
String[] sipe = iparea.substring(idx + 1).split("\\.");
|
||||||
|
String[] sipt = ip.split("\\.");
|
||||||
|
long ips = 0L, ipe = 0L, ipt = 0L;
|
||||||
|
for (int i = 0; i < 4; ++i)
|
||||||
|
{
|
||||||
|
ips = ips << 8 | Integer.parseInt(sips[i]);
|
||||||
|
ipe = ipe << 8 | Integer.parseInt(sipe[i]);
|
||||||
|
ipt = ipt << 8 | Integer.parseInt(sipt[i]);
|
||||||
|
}
|
||||||
|
if (ips > ipe)
|
||||||
|
{
|
||||||
|
long t = ips;
|
||||||
|
ips = ipe;
|
||||||
|
ipe = t;
|
||||||
|
}
|
||||||
|
return ips <= ipt && ipt <= ipe;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验ip是否符合过滤串规则
|
||||||
|
*
|
||||||
|
* @param filter 过滤IP列表,支持后缀'*'通配,支持网段如:`10.10.10.1-10.10.10.99`
|
||||||
|
* @param ip 校验IP地址
|
||||||
|
* @return boolean 结果
|
||||||
|
*/
|
||||||
|
public static boolean isMatchedIp(String filter, String ip)
|
||||||
|
{
|
||||||
|
if (StringUtils.isEmpty(filter) || StringUtils.isEmpty(ip))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
String[] ips = filter.split(";");
|
||||||
|
for (String iStr : ips)
|
||||||
|
{
|
||||||
|
if (isIP(iStr) && iStr.equals(ip))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (isIpWildCard(iStr) && ipIsInWildCardNoCheck(iStr, ip))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (isIPSegment(iStr) && ipIsInNetNoCheck(iStr, ip))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -1,5 +1,8 @@
|
|||||||
package com.ruoyi.common.utils.poi;
|
package com.ruoyi.common.utils.poi;
|
||||||
|
|
||||||
|
import org.apache.poi.ss.usermodel.Cell;
|
||||||
|
import org.apache.poi.ss.usermodel.Workbook;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Excel数据格式处理适配器
|
* Excel数据格式处理适配器
|
||||||
*
|
*
|
||||||
@ -12,8 +15,10 @@ public interface ExcelHandlerAdapter
|
|||||||
*
|
*
|
||||||
* @param value 单元格数据值
|
* @param value 单元格数据值
|
||||||
* @param args excel注解args参数组
|
* @param args excel注解args参数组
|
||||||
|
* @param cell 单元格对象
|
||||||
|
* @param wb 工作簿对象
|
||||||
*
|
*
|
||||||
* @return 处理后的值
|
* @return 处理后的值
|
||||||
*/
|
*/
|
||||||
Object format(Object value, String[] args);
|
Object format(Object value, String[] args, Cell cell, Workbook wb);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -39,6 +39,7 @@ import org.apache.poi.ss.usermodel.Cell;
|
|||||||
import org.apache.poi.ss.usermodel.CellStyle;
|
import org.apache.poi.ss.usermodel.CellStyle;
|
||||||
import org.apache.poi.ss.usermodel.CellType;
|
import org.apache.poi.ss.usermodel.CellType;
|
||||||
import org.apache.poi.ss.usermodel.ClientAnchor;
|
import org.apache.poi.ss.usermodel.ClientAnchor;
|
||||||
|
import org.apache.poi.ss.usermodel.DataFormat;
|
||||||
import org.apache.poi.ss.usermodel.DataValidation;
|
import org.apache.poi.ss.usermodel.DataValidation;
|
||||||
import org.apache.poi.ss.usermodel.DataValidationConstraint;
|
import org.apache.poi.ss.usermodel.DataValidationConstraint;
|
||||||
import org.apache.poi.ss.usermodel.DataValidationHelper;
|
import org.apache.poi.ss.usermodel.DataValidationHelper;
|
||||||
@ -48,6 +49,7 @@ import org.apache.poi.ss.usermodel.FillPatternType;
|
|||||||
import org.apache.poi.ss.usermodel.Font;
|
import org.apache.poi.ss.usermodel.Font;
|
||||||
import org.apache.poi.ss.usermodel.HorizontalAlignment;
|
import org.apache.poi.ss.usermodel.HorizontalAlignment;
|
||||||
import org.apache.poi.ss.usermodel.IndexedColors;
|
import org.apache.poi.ss.usermodel.IndexedColors;
|
||||||
|
import org.apache.poi.ss.usermodel.Name;
|
||||||
import org.apache.poi.ss.usermodel.PictureData;
|
import org.apache.poi.ss.usermodel.PictureData;
|
||||||
import org.apache.poi.ss.usermodel.Row;
|
import org.apache.poi.ss.usermodel.Row;
|
||||||
import org.apache.poi.ss.usermodel.Sheet;
|
import org.apache.poi.ss.usermodel.Sheet;
|
||||||
@ -97,6 +99,11 @@ public class ExcelUtil<T>
|
|||||||
|
|
||||||
public static final String[] FORMULA_STR = { "=", "-", "+", "@" };
|
public static final String[] FORMULA_STR = { "=", "-", "+", "@" };
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用于dictType属性数据存储,避免重复查缓存
|
||||||
|
*/
|
||||||
|
public Map<String, String> sysDictMap = new HashMap<String, String>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Excel sheet最大行数,默认65536
|
* Excel sheet最大行数,默认65536
|
||||||
*/
|
*/
|
||||||
@ -282,9 +289,23 @@ public class ExcelUtil<T>
|
|||||||
* @param is 输入流
|
* @param is 输入流
|
||||||
* @return 转换后集合
|
* @return 转换后集合
|
||||||
*/
|
*/
|
||||||
public List<T> importExcel(InputStream is) throws Exception
|
public List<T> importExcel(InputStream is)
|
||||||
{
|
{
|
||||||
return importExcel(is, 0);
|
List<T> list = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
list = importExcel(is, 0);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
log.error("导入Excel异常{}", e.getMessage());
|
||||||
|
throw new UtilException(e.getMessage());
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
IOUtils.closeQuietly(is);
|
||||||
|
}
|
||||||
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -330,7 +351,6 @@ public class ExcelUtil<T>
|
|||||||
}
|
}
|
||||||
// 获取最后一个非空行的行下标,比如总行数为n,则返回的为n-1
|
// 获取最后一个非空行的行下标,比如总行数为n,则返回的为n-1
|
||||||
int rows = sheet.getLastRowNum();
|
int rows = sheet.getLastRowNum();
|
||||||
|
|
||||||
if (rows > 0)
|
if (rows > 0)
|
||||||
{
|
{
|
||||||
// 定义一个map用于存放excel列的序号和field.
|
// 定义一个map用于存放excel列的序号和field.
|
||||||
@ -445,17 +465,22 @@ public class ExcelUtil<T>
|
|||||||
{
|
{
|
||||||
propertyName = field.getName() + "." + attr.targetAttr();
|
propertyName = field.getName() + "." + attr.targetAttr();
|
||||||
}
|
}
|
||||||
else if (StringUtils.isNotEmpty(attr.readConverterExp()))
|
if (StringUtils.isNotEmpty(attr.readConverterExp()))
|
||||||
{
|
{
|
||||||
val = reverseByExp(Convert.toStr(val), attr.readConverterExp(), attr.separator());
|
val = reverseByExp(Convert.toStr(val), attr.readConverterExp(), attr.separator());
|
||||||
}
|
}
|
||||||
else if (StringUtils.isNotEmpty(attr.dictType()))
|
else if (StringUtils.isNotEmpty(attr.dictType()))
|
||||||
{
|
{
|
||||||
val = reverseDictByExp(Convert.toStr(val), attr.dictType(), attr.separator());
|
if (!sysDictMap.containsKey(attr.dictType() + val))
|
||||||
|
{
|
||||||
|
String dictValue = reverseDictByExp(Convert.toStr(val), attr.dictType(), attr.separator());
|
||||||
|
sysDictMap.put(attr.dictType() + val, dictValue);
|
||||||
|
}
|
||||||
|
val = sysDictMap.get(attr.dictType() + val);
|
||||||
}
|
}
|
||||||
else if (!attr.handler().equals(ExcelHandlerAdapter.class))
|
else if (!attr.handler().equals(ExcelHandlerAdapter.class))
|
||||||
{
|
{
|
||||||
val = dataFormatHandlerAdapter(val, attr);
|
val = dataFormatHandlerAdapter(val, attr, null);
|
||||||
}
|
}
|
||||||
else if (ColumnType.IMAGE == attr.cellType() && StringUtils.isNotEmpty(pictures))
|
else if (ColumnType.IMAGE == attr.cellType() && StringUtils.isNotEmpty(pictures))
|
||||||
{
|
{
|
||||||
@ -689,17 +714,24 @@ public class ExcelUtil<T>
|
|||||||
int rowNo = (1 + rownum) - startNo;
|
int rowNo = (1 + rownum) - startNo;
|
||||||
for (int i = startNo; i < endNo; i++)
|
for (int i = startNo; i < endNo; i++)
|
||||||
{
|
{
|
||||||
rowNo = i > 1 ? rowNo + 1 : rowNo + i;
|
rowNo = isSubList() ? (i > 1 ? rowNo + 1 : rowNo + i) : i + 1 + rownum - startNo;
|
||||||
row = sheet.createRow(rowNo);
|
row = sheet.createRow(rowNo);
|
||||||
// 得到导出对象.
|
// 得到导出对象.
|
||||||
T vo = (T) list.get(i);
|
T vo = (T) list.get(i);
|
||||||
Collection<?> subList = null;
|
Collection<?> subList = null;
|
||||||
if (isSubListValue(vo))
|
if (isSubList())
|
||||||
{
|
{
|
||||||
subList = getListCellValue(vo);
|
if (isSubListValue(vo))
|
||||||
subMergedLastRowNum = subMergedLastRowNum + subList.size();
|
{
|
||||||
|
subList = getListCellValue(vo);
|
||||||
|
subMergedLastRowNum = subMergedLastRowNum + subList.size();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
subMergedFirstRowNum++;
|
||||||
|
subMergedLastRowNum++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int column = 0;
|
int column = 0;
|
||||||
for (Object[] os : fields)
|
for (Object[] os : fields)
|
||||||
{
|
{
|
||||||
@ -757,6 +789,8 @@ public class ExcelUtil<T>
|
|||||||
titleFont.setFontHeightInPoints((short) 16);
|
titleFont.setFontHeightInPoints((short) 16);
|
||||||
titleFont.setBold(true);
|
titleFont.setBold(true);
|
||||||
style.setFont(titleFont);
|
style.setFont(titleFont);
|
||||||
|
DataFormat dataFormat = wb.createDataFormat();
|
||||||
|
style.setDataFormat(dataFormat.getFormat("@"));
|
||||||
styles.put("title", style);
|
styles.put("title", style);
|
||||||
|
|
||||||
style = wb.createCellStyle();
|
style = wb.createCellStyle();
|
||||||
@ -819,6 +853,9 @@ public class ExcelUtil<T>
|
|||||||
headerFont.setBold(true);
|
headerFont.setBold(true);
|
||||||
headerFont.setColor(excel.headerColor().index);
|
headerFont.setColor(excel.headerColor().index);
|
||||||
style.setFont(headerFont);
|
style.setFont(headerFont);
|
||||||
|
// 设置表格头单元格文本形式
|
||||||
|
DataFormat dataFormat = wb.createDataFormat();
|
||||||
|
style.setDataFormat(dataFormat.getFormat("@"));
|
||||||
headerStyles.put(key, style);
|
headerStyles.put(key, style);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -836,34 +873,66 @@ public class ExcelUtil<T>
|
|||||||
Map<String, CellStyle> styles = new HashMap<String, CellStyle>();
|
Map<String, CellStyle> styles = new HashMap<String, CellStyle>();
|
||||||
for (Object[] os : fields)
|
for (Object[] os : fields)
|
||||||
{
|
{
|
||||||
|
Field field = (Field) os[0];
|
||||||
Excel excel = (Excel) os[1];
|
Excel excel = (Excel) os[1];
|
||||||
String key = StringUtils.format("data_{}_{}_{}", excel.align(), excel.color(), excel.backgroundColor());
|
if (Collection.class.isAssignableFrom(field.getType()))
|
||||||
if (!styles.containsKey(key))
|
|
||||||
{
|
{
|
||||||
CellStyle style = wb.createCellStyle();
|
ParameterizedType pt = (ParameterizedType) field.getGenericType();
|
||||||
style.setAlignment(excel.align());
|
Class<?> subClass = (Class<?>) pt.getActualTypeArguments()[0];
|
||||||
style.setVerticalAlignment(VerticalAlignment.CENTER);
|
List<Field> subFields = FieldUtils.getFieldsListWithAnnotation(subClass, Excel.class);
|
||||||
style.setBorderRight(BorderStyle.THIN);
|
for (Field subField : subFields)
|
||||||
style.setRightBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
|
{
|
||||||
style.setBorderLeft(BorderStyle.THIN);
|
Excel subExcel = subField.getAnnotation(Excel.class);
|
||||||
style.setLeftBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
|
annotationDataStyles(styles, subField, subExcel);
|
||||||
style.setBorderTop(BorderStyle.THIN);
|
}
|
||||||
style.setTopBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
|
}
|
||||||
style.setBorderBottom(BorderStyle.THIN);
|
else
|
||||||
style.setBottomBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
|
{
|
||||||
style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
|
annotationDataStyles(styles, field, excel);
|
||||||
style.setFillForegroundColor(excel.backgroundColor().getIndex());
|
|
||||||
Font dataFont = wb.createFont();
|
|
||||||
dataFont.setFontName("Arial");
|
|
||||||
dataFont.setFontHeightInPoints((short) 10);
|
|
||||||
dataFont.setColor(excel.color().index);
|
|
||||||
style.setFont(dataFont);
|
|
||||||
styles.put(key, style);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return styles;
|
return styles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据Excel注解创建表格列样式
|
||||||
|
*
|
||||||
|
* @param styles 自定义样式列表
|
||||||
|
* @param field 属性列信息
|
||||||
|
* @param excel 注解信息
|
||||||
|
*/
|
||||||
|
public void annotationDataStyles(Map<String, CellStyle> styles, Field field, Excel excel)
|
||||||
|
{
|
||||||
|
String key = StringUtils.format("data_{}_{}_{}_{}", excel.align(), excel.color(), excel.backgroundColor(), excel.cellType());
|
||||||
|
if (!styles.containsKey(key))
|
||||||
|
{
|
||||||
|
CellStyle style = wb.createCellStyle();
|
||||||
|
style.setAlignment(excel.align());
|
||||||
|
style.setVerticalAlignment(VerticalAlignment.CENTER);
|
||||||
|
style.setBorderRight(BorderStyle.THIN);
|
||||||
|
style.setRightBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
|
||||||
|
style.setBorderLeft(BorderStyle.THIN);
|
||||||
|
style.setLeftBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
|
||||||
|
style.setBorderTop(BorderStyle.THIN);
|
||||||
|
style.setTopBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
|
||||||
|
style.setBorderBottom(BorderStyle.THIN);
|
||||||
|
style.setBottomBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
|
||||||
|
style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
|
||||||
|
style.setFillForegroundColor(excel.backgroundColor().getIndex());
|
||||||
|
Font dataFont = wb.createFont();
|
||||||
|
dataFont.setFontName("Arial");
|
||||||
|
dataFont.setFontHeightInPoints((short) 10);
|
||||||
|
dataFont.setColor(excel.color().index);
|
||||||
|
style.setFont(dataFont);
|
||||||
|
if (ColumnType.TEXT == excel.cellType())
|
||||||
|
{
|
||||||
|
DataFormat dataFormat = wb.createDataFormat();
|
||||||
|
style.setDataFormat(dataFormat.getFormat("@"));
|
||||||
|
}
|
||||||
|
styles.put(key, style);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建单元格
|
* 创建单元格
|
||||||
*/
|
*/
|
||||||
@ -878,7 +947,7 @@ public class ExcelUtil<T>
|
|||||||
if (isSubList())
|
if (isSubList())
|
||||||
{
|
{
|
||||||
// 填充默认样式,防止合并单元格样式失效
|
// 填充默认样式,防止合并单元格样式失效
|
||||||
sheet.setDefaultColumnStyle(column, styles.get(StringUtils.format("data_{}_{}_{}", attr.align(), attr.color(), attr.backgroundColor())));
|
sheet.setDefaultColumnStyle(column, styles.get(StringUtils.format("data_{}_{}_{}_{}", attr.align(), attr.color(), attr.backgroundColor(), attr.cellType())));
|
||||||
if (attr.needMerge())
|
if (attr.needMerge())
|
||||||
{
|
{
|
||||||
sheet.addMergedRegion(new CellRangeAddress(rownum - 1, rownum, column, column));
|
sheet.addMergedRegion(new CellRangeAddress(rownum - 1, rownum, column, column));
|
||||||
@ -896,7 +965,7 @@ public class ExcelUtil<T>
|
|||||||
*/
|
*/
|
||||||
public void setCellVo(Object value, Excel attr, Cell cell)
|
public void setCellVo(Object value, Excel attr, Cell cell)
|
||||||
{
|
{
|
||||||
if (ColumnType.STRING == attr.cellType())
|
if (ColumnType.STRING == attr.cellType() || ColumnType.TEXT == attr.cellType())
|
||||||
{
|
{
|
||||||
String cellValue = Convert.toStr(value);
|
String cellValue = Convert.toStr(value);
|
||||||
// 对于任何以表达式触发字符 =-+@开头的单元格,直接使用tab字符作为前缀,防止CSV注入。
|
// 对于任何以表达式触发字符 =-+@开头的单元格,直接使用tab字符作为前缀,防止CSV注入。
|
||||||
@ -904,6 +973,10 @@ public class ExcelUtil<T>
|
|||||||
{
|
{
|
||||||
cellValue = RegExUtils.replaceFirst(cellValue, FORMULA_REGEX_STR, "\t$0");
|
cellValue = RegExUtils.replaceFirst(cellValue, FORMULA_REGEX_STR, "\t$0");
|
||||||
}
|
}
|
||||||
|
if (value instanceof Collection && StringUtils.equals("[]", cellValue))
|
||||||
|
{
|
||||||
|
cellValue = StringUtils.EMPTY;
|
||||||
|
}
|
||||||
cell.setCellValue(StringUtils.isNull(cellValue) ? attr.defaultValue() : cellValue + attr.suffix());
|
cell.setCellValue(StringUtils.isNull(cellValue) ? attr.defaultValue() : cellValue + attr.suffix());
|
||||||
}
|
}
|
||||||
else if (ColumnType.NUMERIC == attr.cellType())
|
else if (ColumnType.NUMERIC == attr.cellType())
|
||||||
@ -969,10 +1042,29 @@ public class ExcelUtil<T>
|
|||||||
// 设置列宽
|
// 设置列宽
|
||||||
sheet.setColumnWidth(column, (int) ((attr.width() + 0.72) * 256));
|
sheet.setColumnWidth(column, (int) ((attr.width() + 0.72) * 256));
|
||||||
}
|
}
|
||||||
if (StringUtils.isNotEmpty(attr.prompt()) || attr.combo().length > 0)
|
if (StringUtils.isNotEmpty(attr.prompt()) || attr.combo().length > 0 || attr.comboReadDict())
|
||||||
{
|
{
|
||||||
// 提示信息或只能选择不能输入的列内容.
|
String[] comboArray = attr.combo();
|
||||||
setPromptOrValidation(sheet, attr.combo(), attr.prompt(), 1, 100, column, column);
|
if (attr.comboReadDict())
|
||||||
|
{
|
||||||
|
if (!sysDictMap.containsKey("combo_" + attr.dictType()))
|
||||||
|
{
|
||||||
|
String labels = DictUtils.getDictLabels(attr.dictType());
|
||||||
|
sysDictMap.put("combo_" + attr.dictType(), labels);
|
||||||
|
}
|
||||||
|
String val = sysDictMap.get("combo_" + attr.dictType());
|
||||||
|
comboArray = StringUtils.split(val, DictUtils.SEPARATOR);
|
||||||
|
}
|
||||||
|
if (comboArray.length > 15 || StringUtils.join(comboArray).length() > 255)
|
||||||
|
{
|
||||||
|
// 如果下拉数大于15或字符串长度大于255,则使用一个新sheet存储,避免生成的模板下拉值获取不到
|
||||||
|
setXSSFValidationWithHidden(sheet, comboArray, attr.prompt(), 1, 100, column, column);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 提示信息或只能选择不能输入的列内容.
|
||||||
|
setPromptOrValidation(sheet, comboArray, attr.prompt(), 1, 100, column, column);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -996,7 +1088,7 @@ public class ExcelUtil<T>
|
|||||||
CellRangeAddress cellAddress = new CellRangeAddress(subMergedFirstRowNum, subMergedLastRowNum, column, column);
|
CellRangeAddress cellAddress = new CellRangeAddress(subMergedFirstRowNum, subMergedLastRowNum, column, column);
|
||||||
sheet.addMergedRegion(cellAddress);
|
sheet.addMergedRegion(cellAddress);
|
||||||
}
|
}
|
||||||
cell.setCellStyle(styles.get(StringUtils.format("data_{}_{}_{}", attr.align(), attr.color(), attr.backgroundColor())));
|
cell.setCellStyle(styles.get(StringUtils.format("data_{}_{}_{}_{}", attr.align(), attr.color(), attr.backgroundColor(), attr.cellType())));
|
||||||
|
|
||||||
// 用于读取对象中的属性
|
// 用于读取对象中的属性
|
||||||
Object value = getTargetValue(vo, field, attr);
|
Object value = getTargetValue(vo, field, attr);
|
||||||
@ -1014,7 +1106,12 @@ public class ExcelUtil<T>
|
|||||||
}
|
}
|
||||||
else if (StringUtils.isNotEmpty(dictType) && StringUtils.isNotNull(value))
|
else if (StringUtils.isNotEmpty(dictType) && StringUtils.isNotNull(value))
|
||||||
{
|
{
|
||||||
cell.setCellValue(convertDictByExp(Convert.toStr(value), dictType, separator));
|
if (!sysDictMap.containsKey(dictType + value))
|
||||||
|
{
|
||||||
|
String lable = convertDictByExp(Convert.toStr(value), dictType, separator);
|
||||||
|
sysDictMap.put(dictType + value, lable);
|
||||||
|
}
|
||||||
|
cell.setCellValue(sysDictMap.get(dictType + value));
|
||||||
}
|
}
|
||||||
else if (value instanceof BigDecimal && -1 != attr.scale())
|
else if (value instanceof BigDecimal && -1 != attr.scale())
|
||||||
{
|
{
|
||||||
@ -1022,7 +1119,7 @@ public class ExcelUtil<T>
|
|||||||
}
|
}
|
||||||
else if (!attr.handler().equals(ExcelHandlerAdapter.class))
|
else if (!attr.handler().equals(ExcelHandlerAdapter.class))
|
||||||
{
|
{
|
||||||
cell.setCellValue(dataFormatHandlerAdapter(value, attr));
|
cell.setCellValue(dataFormatHandlerAdapter(value, attr, cell));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1076,6 +1173,58 @@ public class ExcelUtil<T>
|
|||||||
sheet.addValidationData(dataValidation);
|
sheet.addValidationData(dataValidation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置某些列的值只能输入预制的数据,显示下拉框(兼容超出一定数量的下拉框).
|
||||||
|
*
|
||||||
|
* @param sheet 要设置的sheet.
|
||||||
|
* @param textlist 下拉框显示的内容
|
||||||
|
* @param promptContent 提示内容
|
||||||
|
* @param firstRow 开始行
|
||||||
|
* @param endRow 结束行
|
||||||
|
* @param firstCol 开始列
|
||||||
|
* @param endCol 结束列
|
||||||
|
*/
|
||||||
|
public void setXSSFValidationWithHidden(Sheet sheet, String[] textlist, String promptContent, int firstRow, int endRow, int firstCol, int endCol)
|
||||||
|
{
|
||||||
|
String hideSheetName = "combo_" + firstCol + "_" + endCol;
|
||||||
|
Sheet hideSheet = wb.createSheet(hideSheetName); // 用于存储 下拉菜单数据
|
||||||
|
for (int i = 0; i < textlist.length; i++)
|
||||||
|
{
|
||||||
|
hideSheet.createRow(i).createCell(0).setCellValue(textlist[i]);
|
||||||
|
}
|
||||||
|
// 创建名称,可被其他单元格引用
|
||||||
|
Name name = wb.createName();
|
||||||
|
name.setNameName(hideSheetName + "_data");
|
||||||
|
name.setRefersToFormula(hideSheetName + "!$A$1:$A$" + textlist.length);
|
||||||
|
DataValidationHelper helper = sheet.getDataValidationHelper();
|
||||||
|
// 加载下拉列表内容
|
||||||
|
DataValidationConstraint constraint = helper.createFormulaListConstraint(hideSheetName + "_data");
|
||||||
|
// 设置数据有效性加载在哪个单元格上,四个参数分别是:起始行、终止行、起始列、终止列
|
||||||
|
CellRangeAddressList regions = new CellRangeAddressList(firstRow, endRow, firstCol, endCol);
|
||||||
|
// 数据有效性对象
|
||||||
|
DataValidation dataValidation = helper.createValidation(constraint, regions);
|
||||||
|
if (StringUtils.isNotEmpty(promptContent))
|
||||||
|
{
|
||||||
|
// 如果设置了提示信息则鼠标放上去提示
|
||||||
|
dataValidation.createPromptBox("", promptContent);
|
||||||
|
dataValidation.setShowPromptBox(true);
|
||||||
|
}
|
||||||
|
// 处理Excel兼容性问题
|
||||||
|
if (dataValidation instanceof XSSFDataValidation)
|
||||||
|
{
|
||||||
|
dataValidation.setSuppressDropDownArrow(true);
|
||||||
|
dataValidation.setShowErrorBox(true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dataValidation.setSuppressDropDownArrow(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
sheet.addValidationData(dataValidation);
|
||||||
|
// 设置hiddenSheet隐藏
|
||||||
|
wb.setSheetHidden(wb.getSheetIndex(hideSheet), true);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 解析导出值 0=男,1=女,2=未知
|
* 解析导出值 0=男,1=女,2=未知
|
||||||
*
|
*
|
||||||
@ -1183,13 +1332,13 @@ public class ExcelUtil<T>
|
|||||||
* @param excel 数据注解
|
* @param excel 数据注解
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public String dataFormatHandlerAdapter(Object value, Excel excel)
|
public String dataFormatHandlerAdapter(Object value, Excel excel, Cell cell)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Object instance = excel.handler().newInstance();
|
Object instance = excel.handler().newInstance();
|
||||||
Method formatMethod = excel.handler().getMethod("format", new Class[] { Object.class, String[].class });
|
Method formatMethod = excel.handler().getMethod("format", new Class[] { Object.class, String[].class, Cell.class, Workbook.class });
|
||||||
value = formatMethod.invoke(instance, value, excel.args());
|
value = formatMethod.invoke(instance, value, excel.args(), cell, this.wb);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
@ -1249,7 +1398,7 @@ public class ExcelUtil<T>
|
|||||||
*/
|
*/
|
||||||
public String encodingFilename(String filename)
|
public String encodingFilename(String filename)
|
||||||
{
|
{
|
||||||
filename = UUID.randomUUID().toString() + "_" + filename + ".xlsx";
|
filename = UUID.randomUUID() + "_" + filename + ".xlsx";
|
||||||
return filename;
|
return filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1368,7 +1517,8 @@ public class ExcelUtil<T>
|
|||||||
Excel[] excels = attrs.value();
|
Excel[] excels = attrs.value();
|
||||||
for (Excel attr : excels)
|
for (Excel attr : excels)
|
||||||
{
|
{
|
||||||
if (attr != null && (attr.type() == Type.ALL || attr.type() == type))
|
if (!ArrayUtils.contains(this.excludeFields, field.getName() + "." + attr.targetAttr())
|
||||||
|
&& (attr != null && (attr.type() == Type.ALL || attr.type() == type)))
|
||||||
{
|
{
|
||||||
field.setAccessible(true);
|
field.setAccessible(true);
|
||||||
fields.add(new Object[] { field, attr });
|
fields.add(new Object[] { field, attr });
|
||||||
@ -1526,7 +1676,7 @@ public class ExcelUtil<T>
|
|||||||
HSSFPicture pic = (HSSFPicture) shape;
|
HSSFPicture pic = (HSSFPicture) shape;
|
||||||
int pictureIndex = pic.getPictureIndex() - 1;
|
int pictureIndex = pic.getPictureIndex() - 1;
|
||||||
HSSFPictureData picData = pictures.get(pictureIndex);
|
HSSFPictureData picData = pictures.get(pictureIndex);
|
||||||
String picIndex = String.valueOf(anchor.getRow1()) + "_" + String.valueOf(anchor.getCol1());
|
String picIndex = anchor.getRow1() + "_" + anchor.getCol1();
|
||||||
sheetIndexPicMap.put(picIndex, picData);
|
sheetIndexPicMap.put(picIndex, picData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,13 +13,18 @@ public class SqlUtil
|
|||||||
/**
|
/**
|
||||||
* 定义常用的 sql关键字
|
* 定义常用的 sql关键字
|
||||||
*/
|
*/
|
||||||
public static String SQL_REGEX = "select |insert |delete |update |drop |count |exec |chr |mid |master |truncate |char |and |declare ";
|
public static String SQL_REGEX = "and |extractvalue|updatexml|exec |insert |select |delete |update |drop |count |chr |mid |master |truncate |char |declare |or |+|user()";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 仅支持字母、数字、下划线、空格、逗号、小数点(支持多个字段排序)
|
* 仅支持字母、数字、下划线、空格、逗号、小数点(支持多个字段排序)
|
||||||
*/
|
*/
|
||||||
public static String SQL_PATTERN = "[a-zA-Z0-9_\\ \\,\\.]+";
|
public static String SQL_PATTERN = "[a-zA-Z0-9_\\ \\,\\.]+";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 限制orderBy最大长度
|
||||||
|
*/
|
||||||
|
private static final int ORDER_BY_MAX_LENGTH = 500;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 检查字符,防止注入绕过
|
* 检查字符,防止注入绕过
|
||||||
*/
|
*/
|
||||||
@ -29,6 +34,10 @@ public class SqlUtil
|
|||||||
{
|
{
|
||||||
throw new UtilException("参数不符合规范,不能进行查询");
|
throw new UtilException("参数不符合规范,不能进行查询");
|
||||||
}
|
}
|
||||||
|
if (StringUtils.length(value) > ORDER_BY_MAX_LENGTH)
|
||||||
|
{
|
||||||
|
throw new UtilException("参数已超过最大限制,不能进行查询");
|
||||||
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -22,7 +22,7 @@ public class Seq
|
|||||||
private static AtomicInteger uploadSeq = new AtomicInteger(1);
|
private static AtomicInteger uploadSeq = new AtomicInteger(1);
|
||||||
|
|
||||||
// 机器标识
|
// 机器标识
|
||||||
private static String machineCode = "A";
|
private static final String machineCode = "A";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取通用序列号
|
* 获取通用序列号
|
||||||
|
|||||||
@ -66,7 +66,7 @@ public final class UUID implements java.io.Serializable, Comparable<UUID>
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取类型 4(伪随机生成的)UUID 的静态工厂。 使用加密的本地线程伪随机数生成器生成该 UUID。
|
* 获取类型 4(伪随机生成的)UUID 的静态工厂。
|
||||||
*
|
*
|
||||||
* @return 随机生成的 {@code UUID}
|
* @return 随机生成的 {@code UUID}
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -27,8 +27,13 @@ public class XssValidator implements ConstraintValidator<Xss, String>
|
|||||||
|
|
||||||
public static boolean containsHtml(String value)
|
public static boolean containsHtml(String value)
|
||||||
{
|
{
|
||||||
|
StringBuilder sHtml = new StringBuilder();
|
||||||
Pattern pattern = Pattern.compile(HTML_PATTERN);
|
Pattern pattern = Pattern.compile(HTML_PATTERN);
|
||||||
Matcher matcher = pattern.matcher(value);
|
Matcher matcher = pattern.matcher(value);
|
||||||
return matcher.matches();
|
while (matcher.find())
|
||||||
|
{
|
||||||
|
sHtml.append(matcher.group());
|
||||||
|
}
|
||||||
|
return pattern.matcher(sHtml).matches();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>ruoyi</artifactId>
|
<artifactId>ruoyi</artifactId>
|
||||||
<groupId>com.ruoyi</groupId>
|
<groupId>com.ruoyi</groupId>
|
||||||
<version>3.8.4</version>
|
<version>3.8.8</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
@ -37,11 +37,11 @@
|
|||||||
|
|
||||||
<!-- 验证码 -->
|
<!-- 验证码 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.github.penggle</groupId>
|
<groupId>pro.fessional</groupId>
|
||||||
<artifactId>kaptcha</artifactId>
|
<artifactId>kaptcha</artifactId>
|
||||||
<exclusions>
|
<exclusions>
|
||||||
<exclusion>
|
<exclusion>
|
||||||
<artifactId>javax.servlet-api</artifactId>
|
<artifactId>servlet-api</artifactId>
|
||||||
<groupId>javax.servlet</groupId>
|
<groupId>javax.servlet</groupId>
|
||||||
</exclusion>
|
</exclusion>
|
||||||
</exclusions>
|
</exclusions>
|
||||||
|
|||||||
@ -92,29 +92,42 @@ public class DataScopeAspect
|
|||||||
{
|
{
|
||||||
StringBuilder sqlString = new StringBuilder();
|
StringBuilder sqlString = new StringBuilder();
|
||||||
List<String> conditions = new ArrayList<String>();
|
List<String> conditions = new ArrayList<String>();
|
||||||
|
List<String> scopeCustomIds = new ArrayList<String>();
|
||||||
|
user.getRoles().forEach(role -> {
|
||||||
|
if (DATA_SCOPE_CUSTOM.equals(role.getDataScope()) && StringUtils.containsAny(role.getPermissions(), Convert.toStrArray(permission)))
|
||||||
|
{
|
||||||
|
scopeCustomIds.add(Convert.toStr(role.getRoleId()));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
for (SysRole role : user.getRoles())
|
for (SysRole role : user.getRoles())
|
||||||
{
|
{
|
||||||
String dataScope = role.getDataScope();
|
String dataScope = role.getDataScope();
|
||||||
if (!DATA_SCOPE_CUSTOM.equals(dataScope) && conditions.contains(dataScope))
|
if (conditions.contains(dataScope))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (StringUtils.isNotEmpty(permission) && StringUtils.isNotEmpty(role.getPermissions())
|
if (!StringUtils.containsAny(role.getPermissions(), Convert.toStrArray(permission)))
|
||||||
&& !StringUtils.containsAny(role.getPermissions(), Convert.toStrArray(permission)))
|
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (DATA_SCOPE_ALL.equals(dataScope))
|
if (DATA_SCOPE_ALL.equals(dataScope))
|
||||||
{
|
{
|
||||||
sqlString = new StringBuilder();
|
sqlString = new StringBuilder();
|
||||||
|
conditions.add(dataScope);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (DATA_SCOPE_CUSTOM.equals(dataScope))
|
else if (DATA_SCOPE_CUSTOM.equals(dataScope))
|
||||||
{
|
{
|
||||||
sqlString.append(StringUtils.format(
|
if (scopeCustomIds.size() > 1)
|
||||||
" OR {}.dept_id IN ( SELECT dept_id FROM sys_role_dept WHERE role_id = {} ) ", deptAlias,
|
{
|
||||||
role.getRoleId()));
|
// 多个自定数据权限使用in查询,避免多次拼接。
|
||||||
|
sqlString.append(StringUtils.format(" OR {}.dept_id IN ( SELECT dept_id FROM sys_role_dept WHERE role_id in ({}) ) ", deptAlias, String.join(",", scopeCustomIds)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sqlString.append(StringUtils.format(" OR {}.dept_id IN ( SELECT dept_id FROM sys_role_dept WHERE role_id = {} ) ", deptAlias, role.getRoleId()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (DATA_SCOPE_DEPT.equals(dataScope))
|
else if (DATA_SCOPE_DEPT.equals(dataScope))
|
||||||
{
|
{
|
||||||
@ -122,9 +135,7 @@ public class DataScopeAspect
|
|||||||
}
|
}
|
||||||
else if (DATA_SCOPE_DEPT_AND_CHILD.equals(dataScope))
|
else if (DATA_SCOPE_DEPT_AND_CHILD.equals(dataScope))
|
||||||
{
|
{
|
||||||
sqlString.append(StringUtils.format(
|
sqlString.append(StringUtils.format(" OR {}.dept_id IN ( SELECT dept_id FROM sys_dept WHERE dept_id = {} or find_in_set( {} , ancestors ) )", deptAlias, user.getDeptId(), user.getDeptId()));
|
||||||
" OR {}.dept_id IN ( SELECT dept_id FROM sys_dept WHERE dept_id = {} or find_in_set( {} , ancestors ) )",
|
|
||||||
deptAlias, user.getDeptId(), user.getDeptId()));
|
|
||||||
}
|
}
|
||||||
else if (DATA_SCOPE_SELF.equals(dataScope))
|
else if (DATA_SCOPE_SELF.equals(dataScope))
|
||||||
{
|
{
|
||||||
@ -141,6 +152,12 @@ public class DataScopeAspect
|
|||||||
conditions.add(dataScope);
|
conditions.add(dataScope);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 角色都不包含传递过来的权限字符,这个时候sqlString也会为空,所以要限制一下,不查询任何数据
|
||||||
|
if (StringUtils.isEmpty(conditions))
|
||||||
|
{
|
||||||
|
sqlString.append(StringUtils.format(" OR {}.dept_id = 0 ", deptAlias));
|
||||||
|
}
|
||||||
|
|
||||||
if (StringUtils.isNotBlank(sqlString.toString()))
|
if (StringUtils.isNotBlank(sqlString.toString()))
|
||||||
{
|
{
|
||||||
Object params = joinPoint.getArgs()[0];
|
Object params = joinPoint.getArgs()[0];
|
||||||
|
|||||||
@ -4,18 +4,21 @@ import java.util.Collection;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import org.apache.commons.lang3.ArrayUtils;
|
||||||
import org.aspectj.lang.JoinPoint;
|
import org.aspectj.lang.JoinPoint;
|
||||||
import org.aspectj.lang.annotation.AfterReturning;
|
import org.aspectj.lang.annotation.AfterReturning;
|
||||||
import org.aspectj.lang.annotation.AfterThrowing;
|
import org.aspectj.lang.annotation.AfterThrowing;
|
||||||
import org.aspectj.lang.annotation.Aspect;
|
import org.aspectj.lang.annotation.Aspect;
|
||||||
|
import org.aspectj.lang.annotation.Before;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.core.NamedThreadLocal;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.validation.BindingResult;
|
import org.springframework.validation.BindingResult;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.servlet.HandlerMapping;
|
|
||||||
import com.alibaba.fastjson2.JSON;
|
import com.alibaba.fastjson2.JSON;
|
||||||
import com.ruoyi.common.annotation.Log;
|
import com.ruoyi.common.annotation.Log;
|
||||||
|
import com.ruoyi.common.core.domain.entity.SysUser;
|
||||||
import com.ruoyi.common.core.domain.model.LoginUser;
|
import com.ruoyi.common.core.domain.model.LoginUser;
|
||||||
import com.ruoyi.common.enums.BusinessStatus;
|
import com.ruoyi.common.enums.BusinessStatus;
|
||||||
import com.ruoyi.common.enums.HttpMethod;
|
import com.ruoyi.common.enums.HttpMethod;
|
||||||
@ -42,6 +45,18 @@ public class LogAspect
|
|||||||
/** 排除敏感属性字段 */
|
/** 排除敏感属性字段 */
|
||||||
public static final String[] EXCLUDE_PROPERTIES = { "password", "oldPassword", "newPassword", "confirmPassword" };
|
public static final String[] EXCLUDE_PROPERTIES = { "password", "oldPassword", "newPassword", "confirmPassword" };
|
||||||
|
|
||||||
|
/** 计算操作消耗时间 */
|
||||||
|
private static final ThreadLocal<Long> TIME_THREADLOCAL = new NamedThreadLocal<Long>("Cost Time");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理请求前执行
|
||||||
|
*/
|
||||||
|
@Before(value = "@annotation(controllerLog)")
|
||||||
|
public void boBefore(JoinPoint joinPoint, Log controllerLog)
|
||||||
|
{
|
||||||
|
TIME_THREADLOCAL.set(System.currentTimeMillis());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 处理完请求后执行
|
* 处理完请求后执行
|
||||||
*
|
*
|
||||||
@ -76,12 +91,17 @@ public class LogAspect
|
|||||||
SysOperLog operLog = new SysOperLog();
|
SysOperLog operLog = new SysOperLog();
|
||||||
operLog.setStatus(BusinessStatus.SUCCESS.ordinal());
|
operLog.setStatus(BusinessStatus.SUCCESS.ordinal());
|
||||||
// 请求的地址
|
// 请求的地址
|
||||||
String ip = IpUtils.getIpAddr(ServletUtils.getRequest());
|
String ip = IpUtils.getIpAddr();
|
||||||
operLog.setOperIp(ip);
|
operLog.setOperIp(ip);
|
||||||
operLog.setOperUrl(StringUtils.substring(ServletUtils.getRequest().getRequestURI(), 0, 255));
|
operLog.setOperUrl(StringUtils.substring(ServletUtils.getRequest().getRequestURI(), 0, 255));
|
||||||
if (loginUser != null)
|
if (loginUser != null)
|
||||||
{
|
{
|
||||||
operLog.setOperName(loginUser.getUsername());
|
operLog.setOperName(loginUser.getUsername());
|
||||||
|
SysUser currentUser = loginUser.getUser();
|
||||||
|
if (StringUtils.isNotNull(currentUser) && StringUtils.isNotNull(currentUser.getDept()))
|
||||||
|
{
|
||||||
|
operLog.setDeptName(currentUser.getDept().getDeptName());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e != null)
|
if (e != null)
|
||||||
@ -97,16 +117,21 @@ public class LogAspect
|
|||||||
operLog.setRequestMethod(ServletUtils.getRequest().getMethod());
|
operLog.setRequestMethod(ServletUtils.getRequest().getMethod());
|
||||||
// 处理设置注解上的参数
|
// 处理设置注解上的参数
|
||||||
getControllerMethodDescription(joinPoint, controllerLog, operLog, jsonResult);
|
getControllerMethodDescription(joinPoint, controllerLog, operLog, jsonResult);
|
||||||
|
// 设置消耗时间
|
||||||
|
operLog.setCostTime(System.currentTimeMillis() - TIME_THREADLOCAL.get());
|
||||||
// 保存数据库
|
// 保存数据库
|
||||||
AsyncManager.me().execute(AsyncFactory.recordOper(operLog));
|
AsyncManager.me().execute(AsyncFactory.recordOper(operLog));
|
||||||
}
|
}
|
||||||
catch (Exception exp)
|
catch (Exception exp)
|
||||||
{
|
{
|
||||||
// 记录本地异常日志
|
// 记录本地异常日志
|
||||||
log.error("==前置通知异常==");
|
|
||||||
log.error("异常信息:{}", exp.getMessage());
|
log.error("异常信息:{}", exp.getMessage());
|
||||||
exp.printStackTrace();
|
exp.printStackTrace();
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
TIME_THREADLOCAL.remove();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -128,7 +153,7 @@ public class LogAspect
|
|||||||
if (log.isSaveRequestData())
|
if (log.isSaveRequestData())
|
||||||
{
|
{
|
||||||
// 获取参数的信息,传入到数据库中。
|
// 获取参数的信息,传入到数据库中。
|
||||||
setRequestValue(joinPoint, operLog);
|
setRequestValue(joinPoint, operLog, log.excludeParamNames());
|
||||||
}
|
}
|
||||||
// 是否需要保存response,参数和值
|
// 是否需要保存response,参数和值
|
||||||
if (log.isSaveResponseData() && StringUtils.isNotNull(jsonResult))
|
if (log.isSaveResponseData() && StringUtils.isNotNull(jsonResult))
|
||||||
@ -143,25 +168,26 @@ public class LogAspect
|
|||||||
* @param operLog 操作日志
|
* @param operLog 操作日志
|
||||||
* @throws Exception 异常
|
* @throws Exception 异常
|
||||||
*/
|
*/
|
||||||
private void setRequestValue(JoinPoint joinPoint, SysOperLog operLog) throws Exception
|
private void setRequestValue(JoinPoint joinPoint, SysOperLog operLog, String[] excludeParamNames) throws Exception
|
||||||
{
|
{
|
||||||
|
Map<?, ?> paramsMap = ServletUtils.getParamMap(ServletUtils.getRequest());
|
||||||
String requestMethod = operLog.getRequestMethod();
|
String requestMethod = operLog.getRequestMethod();
|
||||||
if (HttpMethod.PUT.name().equals(requestMethod) || HttpMethod.POST.name().equals(requestMethod))
|
if (StringUtils.isEmpty(paramsMap)
|
||||||
|
&& (HttpMethod.PUT.name().equals(requestMethod) || HttpMethod.POST.name().equals(requestMethod)))
|
||||||
{
|
{
|
||||||
String params = argsArrayToString(joinPoint.getArgs());
|
String params = argsArrayToString(joinPoint.getArgs(), excludeParamNames);
|
||||||
operLog.setOperParam(StringUtils.substring(params, 0, 2000));
|
operLog.setOperParam(StringUtils.substring(params, 0, 2000));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Map<?, ?> paramsMap = (Map<?, ?>) ServletUtils.getRequest().getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);
|
operLog.setOperParam(StringUtils.substring(JSON.toJSONString(paramsMap, excludePropertyPreFilter(excludeParamNames)), 0, 2000));
|
||||||
operLog.setOperParam(StringUtils.substring(paramsMap.toString(), 0, 2000));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 参数拼装
|
* 参数拼装
|
||||||
*/
|
*/
|
||||||
private String argsArrayToString(Object[] paramsArray)
|
private String argsArrayToString(Object[] paramsArray, String[] excludeParamNames)
|
||||||
{
|
{
|
||||||
String params = "";
|
String params = "";
|
||||||
if (paramsArray != null && paramsArray.length > 0)
|
if (paramsArray != null && paramsArray.length > 0)
|
||||||
@ -172,7 +198,7 @@ public class LogAspect
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
String jsonObj = JSON.toJSONString(o, excludePropertyPreFilter());
|
String jsonObj = JSON.toJSONString(o, excludePropertyPreFilter(excludeParamNames));
|
||||||
params += jsonObj.toString() + " ";
|
params += jsonObj.toString() + " ";
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
@ -187,9 +213,9 @@ public class LogAspect
|
|||||||
/**
|
/**
|
||||||
* 忽略敏感属性
|
* 忽略敏感属性
|
||||||
*/
|
*/
|
||||||
public PropertyPreExcludeFilter excludePropertyPreFilter()
|
public PropertyPreExcludeFilter excludePropertyPreFilter(String[] excludeParamNames)
|
||||||
{
|
{
|
||||||
return new PropertyPreExcludeFilter().addExcludes(EXCLUDE_PROPERTIES);
|
return new PropertyPreExcludeFilter().addExcludes(ArrayUtils.addAll(EXCLUDE_PROPERTIES, excludeParamNames));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -16,7 +16,6 @@ import org.springframework.stereotype.Component;
|
|||||||
import com.ruoyi.common.annotation.RateLimiter;
|
import com.ruoyi.common.annotation.RateLimiter;
|
||||||
import com.ruoyi.common.enums.LimitType;
|
import com.ruoyi.common.enums.LimitType;
|
||||||
import com.ruoyi.common.exception.ServiceException;
|
import com.ruoyi.common.exception.ServiceException;
|
||||||
import com.ruoyi.common.utils.ServletUtils;
|
|
||||||
import com.ruoyi.common.utils.StringUtils;
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
import com.ruoyi.common.utils.ip.IpUtils;
|
import com.ruoyi.common.utils.ip.IpUtils;
|
||||||
|
|
||||||
@ -50,7 +49,6 @@ public class RateLimiterAspect
|
|||||||
@Before("@annotation(rateLimiter)")
|
@Before("@annotation(rateLimiter)")
|
||||||
public void doBefore(JoinPoint point, RateLimiter rateLimiter) throws Throwable
|
public void doBefore(JoinPoint point, RateLimiter rateLimiter) throws Throwable
|
||||||
{
|
{
|
||||||
String key = rateLimiter.key();
|
|
||||||
int time = rateLimiter.time();
|
int time = rateLimiter.time();
|
||||||
int count = rateLimiter.count();
|
int count = rateLimiter.count();
|
||||||
|
|
||||||
@ -63,7 +61,7 @@ public class RateLimiterAspect
|
|||||||
{
|
{
|
||||||
throw new ServiceException("访问过于频繁,请稍候再试");
|
throw new ServiceException("访问过于频繁,请稍候再试");
|
||||||
}
|
}
|
||||||
log.info("限制请求'{}',当前请求'{}',缓存key'{}'", count, number.intValue(), key);
|
log.info("限制请求'{}',当前请求'{}',缓存key'{}'", count, number.intValue(), combineKey);
|
||||||
}
|
}
|
||||||
catch (ServiceException e)
|
catch (ServiceException e)
|
||||||
{
|
{
|
||||||
@ -80,7 +78,7 @@ public class RateLimiterAspect
|
|||||||
StringBuffer stringBuffer = new StringBuffer(rateLimiter.key());
|
StringBuffer stringBuffer = new StringBuffer(rateLimiter.key());
|
||||||
if (rateLimiter.limitType() == LimitType.IP)
|
if (rateLimiter.limitType() == LimitType.IP)
|
||||||
{
|
{
|
||||||
stringBuffer.append(IpUtils.getIpAddr(ServletUtils.getRequest())).append("-");
|
stringBuffer.append(IpUtils.getIpAddr()).append("-");
|
||||||
}
|
}
|
||||||
MethodSignature signature = (MethodSignature) point.getSignature();
|
MethodSignature signature = (MethodSignature) point.getSignature();
|
||||||
Method method = signature.getMethod();
|
Method method = signature.getMethod();
|
||||||
|
|||||||
@ -6,6 +6,8 @@ import org.springframework.data.redis.serializer.SerializationException;
|
|||||||
import com.alibaba.fastjson2.JSON;
|
import com.alibaba.fastjson2.JSON;
|
||||||
import com.alibaba.fastjson2.JSONReader;
|
import com.alibaba.fastjson2.JSONReader;
|
||||||
import com.alibaba.fastjson2.JSONWriter;
|
import com.alibaba.fastjson2.JSONWriter;
|
||||||
|
import com.alibaba.fastjson2.filter.Filter;
|
||||||
|
import com.ruoyi.common.constant.Constants;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Redis使用FastJson序列化
|
* Redis使用FastJson序列化
|
||||||
@ -16,6 +18,8 @@ public class FastJson2JsonRedisSerializer<T> implements RedisSerializer<T>
|
|||||||
{
|
{
|
||||||
public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
|
public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
|
||||||
|
|
||||||
|
static final Filter AUTO_TYPE_FILTER = JSONReader.autoTypeFilter(Constants.JSON_WHITELIST_STR);
|
||||||
|
|
||||||
private Class<T> clazz;
|
private Class<T> clazz;
|
||||||
|
|
||||||
public FastJson2JsonRedisSerializer(Class<T> clazz)
|
public FastJson2JsonRedisSerializer(Class<T> clazz)
|
||||||
@ -43,6 +47,6 @@ public class FastJson2JsonRedisSerializer<T> implements RedisSerializer<T>
|
|||||||
}
|
}
|
||||||
String str = new String(bytes, DEFAULT_CHARSET);
|
String str = new String(bytes, DEFAULT_CHARSET);
|
||||||
|
|
||||||
return JSON.parseObject(str, clazz, JSONReader.Feature.SupportAutoType);
|
return JSON.parseObject(str, clazz, AUTO_TYPE_FILTER);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,43 @@
|
|||||||
|
package com.ruoyi.framework.config;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.web.servlet.LocaleResolver;
|
||||||
|
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||||
|
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||||
|
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
|
||||||
|
import org.springframework.web.servlet.i18n.SessionLocaleResolver;
|
||||||
|
import com.ruoyi.common.constant.Constants;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 资源文件配置加载
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
public class I18nConfig implements WebMvcConfigurer
|
||||||
|
{
|
||||||
|
@Bean
|
||||||
|
public LocaleResolver localeResolver()
|
||||||
|
{
|
||||||
|
SessionLocaleResolver slr = new SessionLocaleResolver();
|
||||||
|
// 默认语言
|
||||||
|
slr.setDefaultLocale(Constants.DEFAULT_LOCALE);
|
||||||
|
return slr;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public LocaleChangeInterceptor localeChangeInterceptor()
|
||||||
|
{
|
||||||
|
LocaleChangeInterceptor lci = new LocaleChangeInterceptor();
|
||||||
|
// 参数名
|
||||||
|
lci.setParamName("lang");
|
||||||
|
return lci;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addInterceptors(InterceptorRegistry registry)
|
||||||
|
{
|
||||||
|
registry.addInterceptor(localeChangeInterceptor());
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,8 +1,10 @@
|
|||||||
package com.ruoyi.framework.config;
|
package com.ruoyi.framework.config;
|
||||||
|
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.http.CacheControl;
|
||||||
import org.springframework.web.cors.CorsConfiguration;
|
import org.springframework.web.cors.CorsConfiguration;
|
||||||
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
|
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
|
||||||
import org.springframework.web.filter.CorsFilter;
|
import org.springframework.web.filter.CorsFilter;
|
||||||
@ -33,7 +35,8 @@ public class ResourcesConfig implements WebMvcConfigurer
|
|||||||
|
|
||||||
/** swagger配置 */
|
/** swagger配置 */
|
||||||
registry.addResourceHandler("/swagger-ui/**")
|
registry.addResourceHandler("/swagger-ui/**")
|
||||||
.addResourceLocations("classpath:/META-INF/resources/webjars/springfox-swagger-ui/");
|
.addResourceLocations("classpath:/META-INF/resources/webjars/springfox-swagger-ui/")
|
||||||
|
.setCacheControl(CacheControl.maxAge(5, TimeUnit.HOURS).cachePublic());;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -2,16 +2,17 @@ package com.ruoyi.framework.config;
|
|||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.http.HttpMethod;
|
import org.springframework.http.HttpMethod;
|
||||||
import org.springframework.security.authentication.AuthenticationManager;
|
import org.springframework.security.authentication.AuthenticationManager;
|
||||||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
import org.springframework.security.authentication.ProviderManager;
|
||||||
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
|
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
|
||||||
|
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
|
||||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
|
||||||
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
|
|
||||||
import org.springframework.security.config.http.SessionCreationPolicy;
|
import org.springframework.security.config.http.SessionCreationPolicy;
|
||||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||||
|
import org.springframework.security.web.SecurityFilterChain;
|
||||||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
||||||
import org.springframework.security.web.authentication.logout.LogoutFilter;
|
import org.springframework.security.web.authentication.logout.LogoutFilter;
|
||||||
import org.springframework.web.filter.CorsFilter;
|
import org.springframework.web.filter.CorsFilter;
|
||||||
@ -25,8 +26,9 @@ import com.ruoyi.framework.security.handle.LogoutSuccessHandlerImpl;
|
|||||||
*
|
*
|
||||||
* @author ruoyi
|
* @author ruoyi
|
||||||
*/
|
*/
|
||||||
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
|
@EnableMethodSecurity(prePostEnabled = true, securedEnabled = true)
|
||||||
public class SecurityConfig extends WebSecurityConfigurerAdapter
|
@Configuration
|
||||||
|
public class SecurityConfig
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* 自定义用户认证逻辑
|
* 自定义用户认证逻辑
|
||||||
@ -65,16 +67,15 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
|
|||||||
private PermitAllUrlProperties permitAllUrl;
|
private PermitAllUrlProperties permitAllUrl;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 解决 无法直接注入 AuthenticationManager
|
* 身份验证实现
|
||||||
*
|
|
||||||
* @return
|
|
||||||
* @throws Exception
|
|
||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
@Override
|
public AuthenticationManager authenticationManager()
|
||||||
public AuthenticationManager authenticationManagerBean() throws Exception
|
|
||||||
{
|
{
|
||||||
return super.authenticationManagerBean();
|
DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
|
||||||
|
daoAuthenticationProvider.setUserDetailsService(userDetailsService);
|
||||||
|
daoAuthenticationProvider.setPasswordEncoder(bCryptPasswordEncoder());
|
||||||
|
return new ProviderManager(daoAuthenticationProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -92,38 +93,39 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
|
|||||||
* rememberMe | 允许通过remember-me登录的用户访问
|
* rememberMe | 允许通过remember-me登录的用户访问
|
||||||
* authenticated | 用户登录后可访问
|
* authenticated | 用户登录后可访问
|
||||||
*/
|
*/
|
||||||
@Override
|
@Bean
|
||||||
protected void configure(HttpSecurity httpSecurity) throws Exception
|
protected SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception
|
||||||
{
|
{
|
||||||
// 注解标记允许匿名访问的url
|
return httpSecurity
|
||||||
ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry = httpSecurity.authorizeRequests();
|
// CSRF禁用,因为不使用session
|
||||||
permitAllUrl.getUrls().forEach(url -> registry.antMatchers(url).permitAll());
|
.csrf(csrf -> csrf.disable())
|
||||||
|
// 禁用HTTP响应标头
|
||||||
httpSecurity
|
.headers((headersCustomizer) -> {
|
||||||
// CSRF禁用,因为不使用session
|
headersCustomizer.cacheControl(cache -> cache.disable()).frameOptions(options -> options.sameOrigin());
|
||||||
.csrf().disable()
|
})
|
||||||
// 认证失败处理类
|
// 认证失败处理类
|
||||||
.exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
|
.exceptionHandling(exception -> exception.authenticationEntryPoint(unauthorizedHandler))
|
||||||
// 基于token,所以不需要session
|
// 基于token,所以不需要session
|
||||||
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
|
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
|
||||||
// 过滤请求
|
// 注解标记允许匿名访问的url
|
||||||
.authorizeRequests()
|
.authorizeHttpRequests((requests) -> {
|
||||||
|
permitAllUrl.getUrls().forEach(url -> requests.antMatchers(url).permitAll());
|
||||||
// 对于登录login 注册register 验证码captchaImage 允许匿名访问
|
// 对于登录login 注册register 验证码captchaImage 允许匿名访问
|
||||||
.antMatchers("/login", "/register", "/captchaImage").anonymous()
|
requests.antMatchers("/login", "/register", "/captchaImage").permitAll()
|
||||||
// 静态资源,可匿名访问
|
// 静态资源,可匿名访问
|
||||||
.antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll()
|
.antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll()
|
||||||
.antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll()
|
.antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll()
|
||||||
// 除上面外的所有请求全部需要鉴权认证
|
// 除上面外的所有请求全部需要鉴权认证
|
||||||
.anyRequest().authenticated()
|
.anyRequest().authenticated();
|
||||||
.and()
|
})
|
||||||
.headers().frameOptions().disable();
|
// 添加Logout filter
|
||||||
// 添加Logout filter
|
.logout(logout -> logout.logoutUrl("/logout").logoutSuccessHandler(logoutSuccessHandler))
|
||||||
httpSecurity.logout().logoutUrl("/logout").logoutSuccessHandler(logoutSuccessHandler);
|
// 添加JWT filter
|
||||||
// 添加JWT filter
|
.addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class)
|
||||||
httpSecurity.addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
|
// 添加CORS filter
|
||||||
// 添加CORS filter
|
.addFilterBefore(corsFilter, JwtAuthenticationTokenFilter.class)
|
||||||
httpSecurity.addFilterBefore(corsFilter, JwtAuthenticationTokenFilter.class);
|
.addFilterBefore(corsFilter, LogoutFilter.class)
|
||||||
httpSecurity.addFilterBefore(corsFilter, LogoutFilter.class);
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -134,13 +136,4 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
|
|||||||
{
|
{
|
||||||
return new BCryptPasswordEncoder();
|
return new BCryptPasswordEncoder();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 身份认证接口
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
protected void configure(AuthenticationManagerBuilder auth) throws Exception
|
|
||||||
{
|
|
||||||
auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -24,6 +24,12 @@ public class DruidProperties
|
|||||||
@Value("${spring.datasource.druid.maxWait}")
|
@Value("${spring.datasource.druid.maxWait}")
|
||||||
private int maxWait;
|
private int maxWait;
|
||||||
|
|
||||||
|
@Value("${spring.datasource.druid.connectTimeout}")
|
||||||
|
private int connectTimeout;
|
||||||
|
|
||||||
|
@Value("${spring.datasource.druid.socketTimeout}")
|
||||||
|
private int socketTimeout;
|
||||||
|
|
||||||
@Value("${spring.datasource.druid.timeBetweenEvictionRunsMillis}")
|
@Value("${spring.datasource.druid.timeBetweenEvictionRunsMillis}")
|
||||||
private int timeBetweenEvictionRunsMillis;
|
private int timeBetweenEvictionRunsMillis;
|
||||||
|
|
||||||
@ -54,6 +60,12 @@ public class DruidProperties
|
|||||||
|
|
||||||
/** 配置获取连接等待超时的时间 */
|
/** 配置获取连接等待超时的时间 */
|
||||||
datasource.setMaxWait(maxWait);
|
datasource.setMaxWait(maxWait);
|
||||||
|
|
||||||
|
/** 配置驱动连接超时时间,检测数据库建立连接的超时时间,单位是毫秒 */
|
||||||
|
datasource.setConnectTimeout(connectTimeout);
|
||||||
|
|
||||||
|
/** 配置网络超时时间,等待数据库操作完成的网络超时时间,单位是毫秒 */
|
||||||
|
datasource.setSocketTimeout(socketTimeout);
|
||||||
|
|
||||||
/** 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 */
|
/** 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 */
|
||||||
datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
|
datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
|
||||||
|
|||||||
@ -3,6 +3,7 @@ package com.ruoyi.framework.config.properties;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import org.apache.commons.lang3.RegExUtils;
|
import org.apache.commons.lang3.RegExUtils;
|
||||||
@ -44,12 +45,12 @@ public class PermitAllUrlProperties implements InitializingBean, ApplicationCont
|
|||||||
|
|
||||||
// 获取方法上边的注解 替代path variable 为 *
|
// 获取方法上边的注解 替代path variable 为 *
|
||||||
Anonymous method = AnnotationUtils.findAnnotation(handlerMethod.getMethod(), Anonymous.class);
|
Anonymous method = AnnotationUtils.findAnnotation(handlerMethod.getMethod(), Anonymous.class);
|
||||||
Optional.ofNullable(method).ifPresent(anonymous -> info.getPatternsCondition().getPatterns()
|
Optional.ofNullable(method).ifPresent(anonymous -> Objects.requireNonNull(info.getPatternsCondition().getPatterns())
|
||||||
.forEach(url -> urls.add(RegExUtils.replaceAll(url, PATTERN, ASTERISK))));
|
.forEach(url -> urls.add(RegExUtils.replaceAll(url, PATTERN, ASTERISK))));
|
||||||
|
|
||||||
// 获取类上边的注解, 替代path variable 为 *
|
// 获取类上边的注解, 替代path variable 为 *
|
||||||
Anonymous controller = AnnotationUtils.findAnnotation(handlerMethod.getBeanType(), Anonymous.class);
|
Anonymous controller = AnnotationUtils.findAnnotation(handlerMethod.getBeanType(), Anonymous.class);
|
||||||
Optional.ofNullable(controller).ifPresent(anonymous -> info.getPatternsCondition().getPatterns()
|
Optional.ofNullable(controller).ifPresent(anonymous -> Objects.requireNonNull(info.getPatternsCondition().getPatterns())
|
||||||
.forEach(url -> urls.add(RegExUtils.replaceAll(url, PATTERN, ASTERISK))));
|
.forEach(url -> urls.add(RegExUtils.replaceAll(url, PATTERN, ASTERISK))));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,7 +14,7 @@ public class DynamicDataSourceContextHolder
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 使用ThreadLocal维护变量,ThreadLocal为每个使用该变量的线程提供独立的变量副本,
|
* 使用ThreadLocal维护变量,ThreadLocal为每个使用该变量的线程提供独立的变量副本,
|
||||||
* 所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。
|
* 所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。
|
||||||
*/
|
*/
|
||||||
private static final ThreadLocal<String> CONTEXT_HOLDER = new ThreadLocal<>();
|
private static final ThreadLocal<String> CONTEXT_HOLDER = new ThreadLocal<>();
|
||||||
|
|
||||||
|
|||||||
@ -47,8 +47,9 @@ public abstract class RepeatSubmitInterceptor implements HandlerInterceptor
|
|||||||
/**
|
/**
|
||||||
* 验证是否重复提交由子类实现具体的防重复提交的规则
|
* 验证是否重复提交由子类实现具体的防重复提交的规则
|
||||||
*
|
*
|
||||||
* @param request
|
* @param request 请求信息
|
||||||
* @return
|
* @param annotation 防重复注解参数
|
||||||
|
* @return 结果
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public abstract boolean isRepeatSubmit(HttpServletRequest request, RepeatSubmit annotation);
|
public abstract boolean isRepeatSubmit(HttpServletRequest request, RepeatSubmit annotation);
|
||||||
|
|||||||
@ -38,7 +38,7 @@ public class AsyncFactory
|
|||||||
final Object... args)
|
final Object... args)
|
||||||
{
|
{
|
||||||
final UserAgent userAgent = UserAgent.parseUserAgentString(ServletUtils.getRequest().getHeader("User-Agent"));
|
final UserAgent userAgent = UserAgent.parseUserAgentString(ServletUtils.getRequest().getHeader("User-Agent"));
|
||||||
final String ip = IpUtils.getIpAddr(ServletUtils.getRequest());
|
final String ip = IpUtils.getIpAddr();
|
||||||
return new TimerTask()
|
return new TimerTask()
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@ -10,9 +10,9 @@ import org.springframework.security.core.Authentication;
|
|||||||
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
|
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
|
||||||
import com.alibaba.fastjson2.JSON;
|
import com.alibaba.fastjson2.JSON;
|
||||||
import com.ruoyi.common.constant.Constants;
|
import com.ruoyi.common.constant.Constants;
|
||||||
import com.ruoyi.common.constant.HttpStatus;
|
|
||||||
import com.ruoyi.common.core.domain.AjaxResult;
|
import com.ruoyi.common.core.domain.AjaxResult;
|
||||||
import com.ruoyi.common.core.domain.model.LoginUser;
|
import com.ruoyi.common.core.domain.model.LoginUser;
|
||||||
|
import com.ruoyi.common.utils.MessageUtils;
|
||||||
import com.ruoyi.common.utils.ServletUtils;
|
import com.ruoyi.common.utils.ServletUtils;
|
||||||
import com.ruoyi.common.utils.StringUtils;
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
import com.ruoyi.framework.manager.AsyncManager;
|
import com.ruoyi.framework.manager.AsyncManager;
|
||||||
@ -46,8 +46,8 @@ public class LogoutSuccessHandlerImpl implements LogoutSuccessHandler
|
|||||||
// 删除用户缓存记录
|
// 删除用户缓存记录
|
||||||
tokenService.delLoginUser(loginUser.getToken());
|
tokenService.delLoginUser(loginUser.getToken());
|
||||||
// 记录用户退出日志
|
// 记录用户退出日志
|
||||||
AsyncManager.me().execute(AsyncFactory.recordLogininfor(userName, Constants.LOGOUT, "退出成功"));
|
AsyncManager.me().execute(AsyncFactory.recordLogininfor(userName, Constants.LOGOUT, MessageUtils.message("user.logout.success")));
|
||||||
}
|
}
|
||||||
ServletUtils.renderString(response, JSON.toJSONString(AjaxResult.error(HttpStatus.SUCCESS, "退出成功")));
|
ServletUtils.renderString(response, JSON.toJSONString(AjaxResult.success(MessageUtils.message("user.logout.success"))));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -117,7 +117,7 @@ public class Jvm
|
|||||||
*/
|
*/
|
||||||
public String getRunTime()
|
public String getRunTime()
|
||||||
{
|
{
|
||||||
return DateUtils.getDatePoor(DateUtils.getNowDate(), DateUtils.getServerStartDate());
|
return DateUtils.timeDistance(DateUtils.getNowDate(), DateUtils.getServerStartDate());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -7,13 +7,17 @@ import org.springframework.security.access.AccessDeniedException;
|
|||||||
import org.springframework.validation.BindException;
|
import org.springframework.validation.BindException;
|
||||||
import org.springframework.web.HttpRequestMethodNotSupportedException;
|
import org.springframework.web.HttpRequestMethodNotSupportedException;
|
||||||
import org.springframework.web.bind.MethodArgumentNotValidException;
|
import org.springframework.web.bind.MethodArgumentNotValidException;
|
||||||
|
import org.springframework.web.bind.MissingPathVariableException;
|
||||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||||
|
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
|
||||||
import com.ruoyi.common.constant.HttpStatus;
|
import com.ruoyi.common.constant.HttpStatus;
|
||||||
import com.ruoyi.common.core.domain.AjaxResult;
|
import com.ruoyi.common.core.domain.AjaxResult;
|
||||||
|
import com.ruoyi.common.core.text.Convert;
|
||||||
import com.ruoyi.common.exception.DemoModeException;
|
import com.ruoyi.common.exception.DemoModeException;
|
||||||
import com.ruoyi.common.exception.ServiceException;
|
import com.ruoyi.common.exception.ServiceException;
|
||||||
import com.ruoyi.common.utils.StringUtils;
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
|
import com.ruoyi.common.utils.html.EscapeUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 全局异常处理器
|
* 全局异常处理器
|
||||||
@ -59,6 +63,33 @@ public class GlobalExceptionHandler
|
|||||||
return StringUtils.isNotNull(code) ? AjaxResult.error(code, e.getMessage()) : AjaxResult.error(e.getMessage());
|
return StringUtils.isNotNull(code) ? AjaxResult.error(code, e.getMessage()) : AjaxResult.error(e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 请求路径中缺少必需的路径变量
|
||||||
|
*/
|
||||||
|
@ExceptionHandler(MissingPathVariableException.class)
|
||||||
|
public AjaxResult handleMissingPathVariableException(MissingPathVariableException e, HttpServletRequest request)
|
||||||
|
{
|
||||||
|
String requestURI = request.getRequestURI();
|
||||||
|
log.error("请求路径中缺少必需的路径变量'{}',发生系统异常.", requestURI, e);
|
||||||
|
return AjaxResult.error(String.format("请求路径中缺少必需的路径变量[%s]", e.getVariableName()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 请求参数类型不匹配
|
||||||
|
*/
|
||||||
|
@ExceptionHandler(MethodArgumentTypeMismatchException.class)
|
||||||
|
public AjaxResult handleMethodArgumentTypeMismatchException(MethodArgumentTypeMismatchException e, HttpServletRequest request)
|
||||||
|
{
|
||||||
|
String requestURI = request.getRequestURI();
|
||||||
|
String value = Convert.toStr(e.getValue());
|
||||||
|
if (StringUtils.isNotEmpty(value))
|
||||||
|
{
|
||||||
|
value = EscapeUtil.clean(value);
|
||||||
|
}
|
||||||
|
log.error("请求参数类型不匹配'{}',发生系统异常.", requestURI, e);
|
||||||
|
return AjaxResult.error(String.format("请求参数类型不匹配,参数[%s]要求类型为:'%s',但输入值为:'%s'", e.getName(), e.getRequiredType().getName(), value));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 拦截未知的运行时异常
|
* 拦截未知的运行时异常
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -3,6 +3,7 @@ package com.ruoyi.framework.web.service;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
|
import com.ruoyi.common.constant.Constants;
|
||||||
import com.ruoyi.common.core.domain.entity.SysRole;
|
import com.ruoyi.common.core.domain.entity.SysRole;
|
||||||
import com.ruoyi.common.core.domain.model.LoginUser;
|
import com.ruoyi.common.core.domain.model.LoginUser;
|
||||||
import com.ruoyi.common.utils.SecurityUtils;
|
import com.ruoyi.common.utils.SecurityUtils;
|
||||||
@ -17,16 +18,6 @@ import com.ruoyi.framework.security.context.PermissionContextHolder;
|
|||||||
@Service("ss")
|
@Service("ss")
|
||||||
public class PermissionService
|
public class PermissionService
|
||||||
{
|
{
|
||||||
/** 所有权限标识 */
|
|
||||||
private static final String ALL_PERMISSION = "*:*:*";
|
|
||||||
|
|
||||||
/** 管理员角色权限标识 */
|
|
||||||
private static final String SUPER_ADMIN = "admin";
|
|
||||||
|
|
||||||
private static final String ROLE_DELIMETER = ",";
|
|
||||||
|
|
||||||
private static final String PERMISSION_DELIMETER = ",";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 验证用户是否具备某权限
|
* 验证用户是否具备某权限
|
||||||
*
|
*
|
||||||
@ -62,7 +53,7 @@ public class PermissionService
|
|||||||
/**
|
/**
|
||||||
* 验证用户是否具有以下任意一个权限
|
* 验证用户是否具有以下任意一个权限
|
||||||
*
|
*
|
||||||
* @param permissions 以 PERMISSION_NAMES_DELIMETER 为分隔符的权限列表
|
* @param permissions 以 PERMISSION_DELIMETER 为分隔符的权限列表
|
||||||
* @return 用户是否具有以下任意一个权限
|
* @return 用户是否具有以下任意一个权限
|
||||||
*/
|
*/
|
||||||
public boolean hasAnyPermi(String permissions)
|
public boolean hasAnyPermi(String permissions)
|
||||||
@ -78,7 +69,7 @@ public class PermissionService
|
|||||||
}
|
}
|
||||||
PermissionContextHolder.setContext(permissions);
|
PermissionContextHolder.setContext(permissions);
|
||||||
Set<String> authorities = loginUser.getPermissions();
|
Set<String> authorities = loginUser.getPermissions();
|
||||||
for (String permission : permissions.split(PERMISSION_DELIMETER))
|
for (String permission : permissions.split(Constants.PERMISSION_DELIMETER))
|
||||||
{
|
{
|
||||||
if (permission != null && hasPermissions(authorities, permission))
|
if (permission != null && hasPermissions(authorities, permission))
|
||||||
{
|
{
|
||||||
@ -108,7 +99,7 @@ public class PermissionService
|
|||||||
for (SysRole sysRole : loginUser.getUser().getRoles())
|
for (SysRole sysRole : loginUser.getUser().getRoles())
|
||||||
{
|
{
|
||||||
String roleKey = sysRole.getRoleKey();
|
String roleKey = sysRole.getRoleKey();
|
||||||
if (SUPER_ADMIN.equals(roleKey) || roleKey.equals(StringUtils.trim(role)))
|
if (Constants.SUPER_ADMIN.equals(roleKey) || roleKey.equals(StringUtils.trim(role)))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -144,7 +135,7 @@ public class PermissionService
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (String role : roles.split(ROLE_DELIMETER))
|
for (String role : roles.split(Constants.ROLE_DELIMETER))
|
||||||
{
|
{
|
||||||
if (hasRole(role))
|
if (hasRole(role))
|
||||||
{
|
{
|
||||||
@ -163,6 +154,6 @@ public class PermissionService
|
|||||||
*/
|
*/
|
||||||
private boolean hasPermissions(Set<String> permissions, String permission)
|
private boolean hasPermissions(Set<String> permissions, String permission)
|
||||||
{
|
{
|
||||||
return permissions.contains(ALL_PERMISSION) || permissions.contains(StringUtils.trim(permission));
|
return permissions.contains(Constants.ALL_PERMISSION) || permissions.contains(StringUtils.trim(permission));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,16 +9,18 @@ import org.springframework.security.core.Authentication;
|
|||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import com.ruoyi.common.constant.CacheConstants;
|
import com.ruoyi.common.constant.CacheConstants;
|
||||||
import com.ruoyi.common.constant.Constants;
|
import com.ruoyi.common.constant.Constants;
|
||||||
|
import com.ruoyi.common.constant.UserConstants;
|
||||||
import com.ruoyi.common.core.domain.entity.SysUser;
|
import com.ruoyi.common.core.domain.entity.SysUser;
|
||||||
import com.ruoyi.common.core.domain.model.LoginUser;
|
import com.ruoyi.common.core.domain.model.LoginUser;
|
||||||
import com.ruoyi.common.core.redis.RedisCache;
|
import com.ruoyi.common.core.redis.RedisCache;
|
||||||
import com.ruoyi.common.exception.ServiceException;
|
import com.ruoyi.common.exception.ServiceException;
|
||||||
|
import com.ruoyi.common.exception.user.BlackListException;
|
||||||
import com.ruoyi.common.exception.user.CaptchaException;
|
import com.ruoyi.common.exception.user.CaptchaException;
|
||||||
import com.ruoyi.common.exception.user.CaptchaExpireException;
|
import com.ruoyi.common.exception.user.CaptchaExpireException;
|
||||||
|
import com.ruoyi.common.exception.user.UserNotExistsException;
|
||||||
import com.ruoyi.common.exception.user.UserPasswordNotMatchException;
|
import com.ruoyi.common.exception.user.UserPasswordNotMatchException;
|
||||||
import com.ruoyi.common.utils.DateUtils;
|
import com.ruoyi.common.utils.DateUtils;
|
||||||
import com.ruoyi.common.utils.MessageUtils;
|
import com.ruoyi.common.utils.MessageUtils;
|
||||||
import com.ruoyi.common.utils.ServletUtils;
|
|
||||||
import com.ruoyi.common.utils.StringUtils;
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
import com.ruoyi.common.utils.ip.IpUtils;
|
import com.ruoyi.common.utils.ip.IpUtils;
|
||||||
import com.ruoyi.framework.manager.AsyncManager;
|
import com.ruoyi.framework.manager.AsyncManager;
|
||||||
@ -61,12 +63,10 @@ public class SysLoginService
|
|||||||
*/
|
*/
|
||||||
public String login(String username, String password, String code, String uuid)
|
public String login(String username, String password, String code, String uuid)
|
||||||
{
|
{
|
||||||
boolean captchaEnabled = configService.selectCaptchaEnabled();
|
// 验证码校验
|
||||||
// 验证码开关
|
validateCaptcha(username, code, uuid);
|
||||||
if (captchaEnabled)
|
// 登录前置校验
|
||||||
{
|
loginPreCheck(username, password);
|
||||||
validateCaptcha(username, code, uuid);
|
|
||||||
}
|
|
||||||
// 用户验证
|
// 用户验证
|
||||||
Authentication authentication = null;
|
Authentication authentication = null;
|
||||||
try
|
try
|
||||||
@ -110,18 +110,58 @@ public class SysLoginService
|
|||||||
*/
|
*/
|
||||||
public void validateCaptcha(String username, String code, String uuid)
|
public void validateCaptcha(String username, String code, String uuid)
|
||||||
{
|
{
|
||||||
String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + StringUtils.nvl(uuid, "");
|
boolean captchaEnabled = configService.selectCaptchaEnabled();
|
||||||
String captcha = redisCache.getCacheObject(verifyKey);
|
if (captchaEnabled)
|
||||||
redisCache.deleteObject(verifyKey);
|
|
||||||
if (captcha == null)
|
|
||||||
{
|
{
|
||||||
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire")));
|
String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + StringUtils.nvl(uuid, "");
|
||||||
throw new CaptchaExpireException();
|
String captcha = redisCache.getCacheObject(verifyKey);
|
||||||
|
if (captcha == null)
|
||||||
|
{
|
||||||
|
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire")));
|
||||||
|
throw new CaptchaExpireException();
|
||||||
|
}
|
||||||
|
redisCache.deleteObject(verifyKey);
|
||||||
|
if (!code.equalsIgnoreCase(captcha))
|
||||||
|
{
|
||||||
|
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error")));
|
||||||
|
throw new CaptchaException();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!code.equalsIgnoreCase(captcha))
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 登录前置校验
|
||||||
|
* @param username 用户名
|
||||||
|
* @param password 用户密码
|
||||||
|
*/
|
||||||
|
public void loginPreCheck(String username, String password)
|
||||||
|
{
|
||||||
|
// 用户名或密码为空 错误
|
||||||
|
if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password))
|
||||||
{
|
{
|
||||||
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error")));
|
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("not.null")));
|
||||||
throw new CaptchaException();
|
throw new UserNotExistsException();
|
||||||
|
}
|
||||||
|
// 密码如果不在指定范围内 错误
|
||||||
|
if (password.length() < UserConstants.PASSWORD_MIN_LENGTH
|
||||||
|
|| password.length() > UserConstants.PASSWORD_MAX_LENGTH)
|
||||||
|
{
|
||||||
|
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
|
||||||
|
throw new UserPasswordNotMatchException();
|
||||||
|
}
|
||||||
|
// 用户名不在指定范围内 错误
|
||||||
|
if (username.length() < UserConstants.USERNAME_MIN_LENGTH
|
||||||
|
|| username.length() > UserConstants.USERNAME_MAX_LENGTH)
|
||||||
|
{
|
||||||
|
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
|
||||||
|
throw new UserPasswordNotMatchException();
|
||||||
|
}
|
||||||
|
// IP黑名单校验
|
||||||
|
String blackStr = configService.selectConfigByKey("sys.login.blackIPList");
|
||||||
|
if (IpUtils.isMatchedIp(blackStr, IpUtils.getIpAddr()))
|
||||||
|
{
|
||||||
|
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("login.blocked")));
|
||||||
|
throw new BlackListException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,7 +174,7 @@ public class SysLoginService
|
|||||||
{
|
{
|
||||||
SysUser sysUser = new SysUser();
|
SysUser sysUser = new SysUser();
|
||||||
sysUser.setUserId(userId);
|
sysUser.setUserId(userId);
|
||||||
sysUser.setLoginIp(IpUtils.getIpAddr(ServletUtils.getRequest()));
|
sysUser.setLoginIp(IpUtils.getIpAddr());
|
||||||
sysUser.setLoginDate(DateUtils.getNowDate());
|
sysUser.setLoginDate(DateUtils.getNowDate());
|
||||||
userService.updateUserProfile(sysUser);
|
userService.updateUserProfile(sysUser);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,15 +6,11 @@ import org.springframework.beans.factory.annotation.Value;
|
|||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import com.ruoyi.common.constant.CacheConstants;
|
import com.ruoyi.common.constant.CacheConstants;
|
||||||
import com.ruoyi.common.constant.Constants;
|
|
||||||
import com.ruoyi.common.core.domain.entity.SysUser;
|
import com.ruoyi.common.core.domain.entity.SysUser;
|
||||||
import com.ruoyi.common.core.redis.RedisCache;
|
import com.ruoyi.common.core.redis.RedisCache;
|
||||||
import com.ruoyi.common.exception.user.UserPasswordNotMatchException;
|
import com.ruoyi.common.exception.user.UserPasswordNotMatchException;
|
||||||
import com.ruoyi.common.exception.user.UserPasswordRetryLimitExceedException;
|
import com.ruoyi.common.exception.user.UserPasswordRetryLimitExceedException;
|
||||||
import com.ruoyi.common.utils.MessageUtils;
|
|
||||||
import com.ruoyi.common.utils.SecurityUtils;
|
import com.ruoyi.common.utils.SecurityUtils;
|
||||||
import com.ruoyi.framework.manager.AsyncManager;
|
|
||||||
import com.ruoyi.framework.manager.factory.AsyncFactory;
|
|
||||||
import com.ruoyi.framework.security.context.AuthenticationContextHolder;
|
import com.ruoyi.framework.security.context.AuthenticationContextHolder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -60,16 +56,12 @@ public class SysPasswordService
|
|||||||
|
|
||||||
if (retryCount >= Integer.valueOf(maxRetryCount).intValue())
|
if (retryCount >= Integer.valueOf(maxRetryCount).intValue())
|
||||||
{
|
{
|
||||||
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL,
|
|
||||||
MessageUtils.message("user.password.retry.limit.exceed", maxRetryCount, lockTime)));
|
|
||||||
throw new UserPasswordRetryLimitExceedException(maxRetryCount, lockTime);
|
throw new UserPasswordRetryLimitExceedException(maxRetryCount, lockTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!matches(user, password))
|
if (!matches(user, password))
|
||||||
{
|
{
|
||||||
retryCount = retryCount + 1;
|
retryCount = retryCount + 1;
|
||||||
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL,
|
|
||||||
MessageUtils.message("user.password.retry.limit.count", retryCount)));
|
|
||||||
redisCache.setCacheObject(getCacheKey(username), retryCount, lockTime, TimeUnit.MINUTES);
|
redisCache.setCacheObject(getCacheKey(username), retryCount, lockTime, TimeUnit.MINUTES);
|
||||||
throw new UserPasswordNotMatchException();
|
throw new UserPasswordNotMatchException();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,6 +5,7 @@ import java.util.List;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
import com.ruoyi.common.core.domain.entity.SysRole;
|
import com.ruoyi.common.core.domain.entity.SysRole;
|
||||||
import com.ruoyi.common.core.domain.entity.SysUser;
|
import com.ruoyi.common.core.domain.entity.SysUser;
|
||||||
import com.ruoyi.system.service.ISysMenuService;
|
import com.ruoyi.system.service.ISysMenuService;
|
||||||
@ -62,7 +63,7 @@ public class SysPermissionService
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
List<SysRole> roles = user.getRoles();
|
List<SysRole> roles = user.getRoles();
|
||||||
if (!roles.isEmpty() && roles.size() > 1)
|
if (!CollectionUtils.isEmpty(roles))
|
||||||
{
|
{
|
||||||
// 多角色设置permissions属性,以便数据权限匹配权限
|
// 多角色设置permissions属性,以便数据权限匹配权限
|
||||||
for (SysRole role : roles)
|
for (SysRole role : roles)
|
||||||
|
|||||||
@ -69,7 +69,7 @@ public class SysRegisterService
|
|||||||
{
|
{
|
||||||
msg = "密码长度必须在5到20个字符之间";
|
msg = "密码长度必须在5到20个字符之间";
|
||||||
}
|
}
|
||||||
else if (UserConstants.NOT_UNIQUE.equals(userService.checkUserNameUnique(sysUser)))
|
else if (!userService.checkUserNameUnique(sysUser))
|
||||||
{
|
{
|
||||||
msg = "保存用户'" + username + "'失败,注册账号已存在";
|
msg = "保存用户'" + username + "'失败,注册账号已存在";
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,6 +4,8 @@ import java.util.HashMap;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
@ -29,6 +31,8 @@ import io.jsonwebtoken.SignatureAlgorithm;
|
|||||||
@Component
|
@Component
|
||||||
public class TokenService
|
public class TokenService
|
||||||
{
|
{
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(TokenService.class);
|
||||||
|
|
||||||
// 令牌自定义标识
|
// 令牌自定义标识
|
||||||
@Value("${token.header}")
|
@Value("${token.header}")
|
||||||
private String header;
|
private String header;
|
||||||
@ -72,6 +76,7 @@ public class TokenService
|
|||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
log.error("获取用户信息异常'{}'", e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
@ -156,7 +161,7 @@ public class TokenService
|
|||||||
public void setUserAgent(LoginUser loginUser)
|
public void setUserAgent(LoginUser loginUser)
|
||||||
{
|
{
|
||||||
UserAgent userAgent = UserAgent.parseUserAgentString(ServletUtils.getRequest().getHeader("User-Agent"));
|
UserAgent userAgent = UserAgent.parseUserAgentString(ServletUtils.getRequest().getHeader("User-Agent"));
|
||||||
String ip = IpUtils.getIpAddr(ServletUtils.getRequest());
|
String ip = IpUtils.getIpAddr();
|
||||||
loginUser.setIpaddr(ip);
|
loginUser.setIpaddr(ip);
|
||||||
loginUser.setLoginLocation(AddressUtils.getRealAddressByIP(ip));
|
loginUser.setLoginLocation(AddressUtils.getRealAddressByIP(ip));
|
||||||
loginUser.setBrowser(userAgent.getBrowser().getName());
|
loginUser.setBrowser(userAgent.getBrowser().getName());
|
||||||
|
|||||||
@ -11,6 +11,7 @@ import com.ruoyi.common.core.domain.entity.SysUser;
|
|||||||
import com.ruoyi.common.core.domain.model.LoginUser;
|
import com.ruoyi.common.core.domain.model.LoginUser;
|
||||||
import com.ruoyi.common.enums.UserStatus;
|
import com.ruoyi.common.enums.UserStatus;
|
||||||
import com.ruoyi.common.exception.ServiceException;
|
import com.ruoyi.common.exception.ServiceException;
|
||||||
|
import com.ruoyi.common.utils.MessageUtils;
|
||||||
import com.ruoyi.common.utils.StringUtils;
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
import com.ruoyi.system.service.ISysUserService;
|
import com.ruoyi.system.service.ISysUserService;
|
||||||
|
|
||||||
@ -40,17 +41,17 @@ public class UserDetailsServiceImpl implements UserDetailsService
|
|||||||
if (StringUtils.isNull(user))
|
if (StringUtils.isNull(user))
|
||||||
{
|
{
|
||||||
log.info("登录用户:{} 不存在.", username);
|
log.info("登录用户:{} 不存在.", username);
|
||||||
throw new ServiceException("登录用户:" + username + " 不存在");
|
throw new ServiceException(MessageUtils.message("user.not.exists"));
|
||||||
}
|
}
|
||||||
else if (UserStatus.DELETED.getCode().equals(user.getDelFlag()))
|
else if (UserStatus.DELETED.getCode().equals(user.getDelFlag()))
|
||||||
{
|
{
|
||||||
log.info("登录用户:{} 已被删除.", username);
|
log.info("登录用户:{} 已被删除.", username);
|
||||||
throw new ServiceException("对不起,您的账号:" + username + " 已被删除");
|
throw new ServiceException(MessageUtils.message("user.password.delete"));
|
||||||
}
|
}
|
||||||
else if (UserStatus.DISABLE.getCode().equals(user.getStatus()))
|
else if (UserStatus.DISABLE.getCode().equals(user.getStatus()))
|
||||||
{
|
{
|
||||||
log.info("登录用户:{} 已被停用.", username);
|
log.info("登录用户:{} 已被停用.", username);
|
||||||
throw new ServiceException("对不起,您的账号:" + username + " 已停用");
|
throw new ServiceException(MessageUtils.message("user.blocked"));
|
||||||
}
|
}
|
||||||
|
|
||||||
passwordService.validate(user);
|
passwordService.validate(user);
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>ruoyi</artifactId>
|
<artifactId>ruoyi</artifactId>
|
||||||
<groupId>com.ruoyi</groupId>
|
<groupId>com.ruoyi</groupId>
|
||||||
<version>3.8.4</version>
|
<version>3.8.8</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
@ -17,24 +17,24 @@
|
|||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
||||||
<!--velocity代码生成使用模板 -->
|
<!-- velocity代码生成使用模板 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.velocity</groupId>
|
<groupId>org.apache.velocity</groupId>
|
||||||
<artifactId>velocity-engine-core</artifactId>
|
<artifactId>velocity-engine-core</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- collections工具类 -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>commons-collections</groupId>
|
|
||||||
<artifactId>commons-collections</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- 通用工具-->
|
<!-- 通用工具-->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.ruoyi</groupId>
|
<groupId>com.ruoyi</groupId>
|
||||||
<artifactId>ruoyi-common</artifactId>
|
<artifactId>ruoyi-common</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- 阿里数据库连接池 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba</groupId>
|
||||||
|
<artifactId>druid-spring-boot-starter</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
@ -1,6 +1,7 @@
|
|||||||
package com.ruoyi.generator.controller;
|
package com.ruoyi.generator.controller;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -17,12 +18,18 @@ import org.springframework.web.bind.annotation.PutMapping;
|
|||||||
import org.springframework.web.bind.annotation.RequestBody;
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
import com.alibaba.druid.DbType;
|
||||||
|
import com.alibaba.druid.sql.SQLUtils;
|
||||||
|
import com.alibaba.druid.sql.ast.SQLStatement;
|
||||||
|
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCreateTableStatement;
|
||||||
import com.ruoyi.common.annotation.Log;
|
import com.ruoyi.common.annotation.Log;
|
||||||
import com.ruoyi.common.core.controller.BaseController;
|
import com.ruoyi.common.core.controller.BaseController;
|
||||||
import com.ruoyi.common.core.domain.AjaxResult;
|
import com.ruoyi.common.core.domain.AjaxResult;
|
||||||
import com.ruoyi.common.core.page.TableDataInfo;
|
import com.ruoyi.common.core.page.TableDataInfo;
|
||||||
import com.ruoyi.common.core.text.Convert;
|
import com.ruoyi.common.core.text.Convert;
|
||||||
import com.ruoyi.common.enums.BusinessType;
|
import com.ruoyi.common.enums.BusinessType;
|
||||||
|
import com.ruoyi.common.utils.SecurityUtils;
|
||||||
|
import com.ruoyi.common.utils.sql.SqlUtil;
|
||||||
import com.ruoyi.generator.domain.GenTable;
|
import com.ruoyi.generator.domain.GenTable;
|
||||||
import com.ruoyi.generator.domain.GenTableColumn;
|
import com.ruoyi.generator.domain.GenTableColumn;
|
||||||
import com.ruoyi.generator.service.IGenTableColumnService;
|
import com.ruoyi.generator.service.IGenTableColumnService;
|
||||||
@ -69,7 +76,7 @@ public class GenController extends BaseController
|
|||||||
map.put("info", table);
|
map.put("info", table);
|
||||||
map.put("rows", list);
|
map.put("rows", list);
|
||||||
map.put("tables", tables);
|
map.put("tables", tables);
|
||||||
return AjaxResult.success(map);
|
return success(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -109,8 +116,45 @@ public class GenController extends BaseController
|
|||||||
String[] tableNames = Convert.toStrArray(tables);
|
String[] tableNames = Convert.toStrArray(tables);
|
||||||
// 查询表信息
|
// 查询表信息
|
||||||
List<GenTable> tableList = genTableService.selectDbTableListByNames(tableNames);
|
List<GenTable> tableList = genTableService.selectDbTableListByNames(tableNames);
|
||||||
genTableService.importGenTable(tableList);
|
genTableService.importGenTable(tableList, SecurityUtils.getUsername());
|
||||||
return AjaxResult.success();
|
return success();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建表结构(保存)
|
||||||
|
*/
|
||||||
|
@PreAuthorize("@ss.hasRole('admin')")
|
||||||
|
@Log(title = "创建表", businessType = BusinessType.OTHER)
|
||||||
|
@PostMapping("/createTable")
|
||||||
|
public AjaxResult createTableSave(String sql)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
SqlUtil.filterKeyword(sql);
|
||||||
|
List<SQLStatement> sqlStatements = SQLUtils.parseStatements(sql, DbType.mysql);
|
||||||
|
List<String> tableNames = new ArrayList<>();
|
||||||
|
for (SQLStatement sqlStatement : sqlStatements)
|
||||||
|
{
|
||||||
|
if (sqlStatement instanceof MySqlCreateTableStatement)
|
||||||
|
{
|
||||||
|
MySqlCreateTableStatement createTableStatement = (MySqlCreateTableStatement) sqlStatement;
|
||||||
|
if (genTableService.createTable(createTableStatement.toString()))
|
||||||
|
{
|
||||||
|
String tableName = createTableStatement.getTableName().replaceAll("`", "");
|
||||||
|
tableNames.add(tableName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
List<GenTable> tableList = genTableService.selectDbTableListByNames(tableNames.toArray(new String[tableNames.size()]));
|
||||||
|
String operName = SecurityUtils.getUsername();
|
||||||
|
genTableService.importGenTable(tableList, operName);
|
||||||
|
return AjaxResult.success();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
logger.error(e.getMessage(), e);
|
||||||
|
return AjaxResult.error("创建表结构异常");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -123,7 +167,7 @@ public class GenController extends BaseController
|
|||||||
{
|
{
|
||||||
genTableService.validateEdit(genTable);
|
genTableService.validateEdit(genTable);
|
||||||
genTableService.updateGenTable(genTable);
|
genTableService.updateGenTable(genTable);
|
||||||
return AjaxResult.success();
|
return success();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -135,7 +179,7 @@ public class GenController extends BaseController
|
|||||||
public AjaxResult remove(@PathVariable Long[] tableIds)
|
public AjaxResult remove(@PathVariable Long[] tableIds)
|
||||||
{
|
{
|
||||||
genTableService.deleteGenTableByIds(tableIds);
|
genTableService.deleteGenTableByIds(tableIds);
|
||||||
return AjaxResult.success();
|
return success();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -146,7 +190,7 @@ public class GenController extends BaseController
|
|||||||
public AjaxResult preview(@PathVariable("tableId") Long tableId) throws IOException
|
public AjaxResult preview(@PathVariable("tableId") Long tableId) throws IOException
|
||||||
{
|
{
|
||||||
Map<String, String> dataMap = genTableService.previewCode(tableId);
|
Map<String, String> dataMap = genTableService.previewCode(tableId);
|
||||||
return AjaxResult.success(dataMap);
|
return success(dataMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -170,7 +214,7 @@ public class GenController extends BaseController
|
|||||||
public AjaxResult genCode(@PathVariable("tableName") String tableName)
|
public AjaxResult genCode(@PathVariable("tableName") String tableName)
|
||||||
{
|
{
|
||||||
genTableService.generatorCode(tableName);
|
genTableService.generatorCode(tableName);
|
||||||
return AjaxResult.success();
|
return success();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -182,7 +226,7 @@ public class GenController extends BaseController
|
|||||||
public AjaxResult synchDb(@PathVariable("tableName") String tableName)
|
public AjaxResult synchDb(@PathVariable("tableName") String tableName)
|
||||||
{
|
{
|
||||||
genTableService.synchDb(tableName);
|
genTableService.synchDb(tableName);
|
||||||
return AjaxResult.success();
|
return success();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -41,6 +41,9 @@ public class GenTable extends BaseEntity
|
|||||||
/** 使用的模板(crud单表操作 tree树表操作 sub主子表操作) */
|
/** 使用的模板(crud单表操作 tree树表操作 sub主子表操作) */
|
||||||
private String tplCategory;
|
private String tplCategory;
|
||||||
|
|
||||||
|
/** 前端类型(element-ui模版 element-plus模版) */
|
||||||
|
private String tplWebType;
|
||||||
|
|
||||||
/** 生成包路径 */
|
/** 生成包路径 */
|
||||||
@NotBlank(message = "生成包路径不能为空")
|
@NotBlank(message = "生成包路径不能为空")
|
||||||
private String packageName;
|
private String packageName;
|
||||||
@ -165,6 +168,16 @@ public class GenTable extends BaseEntity
|
|||||||
this.tplCategory = tplCategory;
|
this.tplCategory = tplCategory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getTplWebType()
|
||||||
|
{
|
||||||
|
return tplWebType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTplWebType(String tplWebType)
|
||||||
|
{
|
||||||
|
this.tplWebType = tplWebType;
|
||||||
|
}
|
||||||
|
|
||||||
public String getPackageName()
|
public String getPackageName()
|
||||||
{
|
{
|
||||||
return packageName;
|
return packageName;
|
||||||
|
|||||||
@ -80,4 +80,12 @@ public interface GenTableMapper
|
|||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
public int deleteGenTableByIds(Long[] ids);
|
public int deleteGenTableByIds(Long[] ids);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建表
|
||||||
|
*
|
||||||
|
* @param sql 表结构
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public int createTable(String sql);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -27,7 +27,6 @@ import com.ruoyi.common.constant.Constants;
|
|||||||
import com.ruoyi.common.constant.GenConstants;
|
import com.ruoyi.common.constant.GenConstants;
|
||||||
import com.ruoyi.common.core.text.CharsetKit;
|
import com.ruoyi.common.core.text.CharsetKit;
|
||||||
import com.ruoyi.common.exception.ServiceException;
|
import com.ruoyi.common.exception.ServiceException;
|
||||||
import com.ruoyi.common.utils.SecurityUtils;
|
|
||||||
import com.ruoyi.common.utils.StringUtils;
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
import com.ruoyi.generator.domain.GenTable;
|
import com.ruoyi.generator.domain.GenTable;
|
||||||
import com.ruoyi.generator.domain.GenTableColumn;
|
import com.ruoyi.generator.domain.GenTableColumn;
|
||||||
@ -150,6 +149,18 @@ public class GenTableServiceImpl implements IGenTableService
|
|||||||
genTableColumnMapper.deleteGenTableColumnByIds(tableIds);
|
genTableColumnMapper.deleteGenTableColumnByIds(tableIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建表
|
||||||
|
*
|
||||||
|
* @param sql 创建表语句
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean createTable(String sql)
|
||||||
|
{
|
||||||
|
return genTableMapper.createTable(sql) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 导入表结构
|
* 导入表结构
|
||||||
*
|
*
|
||||||
@ -157,9 +168,8 @@ public class GenTableServiceImpl implements IGenTableService
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
public void importGenTable(List<GenTable> tableList)
|
public void importGenTable(List<GenTable> tableList, String operName)
|
||||||
{
|
{
|
||||||
String operName = SecurityUtils.getUsername();
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
for (GenTable table : tableList)
|
for (GenTable table : tableList)
|
||||||
@ -206,7 +216,7 @@ public class GenTableServiceImpl implements IGenTableService
|
|||||||
VelocityContext context = VelocityUtils.prepareContext(table);
|
VelocityContext context = VelocityUtils.prepareContext(table);
|
||||||
|
|
||||||
// 获取模板列表
|
// 获取模板列表
|
||||||
List<String> templates = VelocityUtils.getTemplateList(table.getTplCategory());
|
List<String> templates = VelocityUtils.getTemplateList(table.getTplCategory(), table.getTplWebType());
|
||||||
for (String template : templates)
|
for (String template : templates)
|
||||||
{
|
{
|
||||||
// 渲染模板
|
// 渲染模板
|
||||||
@ -254,7 +264,7 @@ public class GenTableServiceImpl implements IGenTableService
|
|||||||
VelocityContext context = VelocityUtils.prepareContext(table);
|
VelocityContext context = VelocityUtils.prepareContext(table);
|
||||||
|
|
||||||
// 获取模板列表
|
// 获取模板列表
|
||||||
List<String> templates = VelocityUtils.getTemplateList(table.getTplCategory());
|
List<String> templates = VelocityUtils.getTemplateList(table.getTplCategory(), table.getTplWebType());
|
||||||
for (String template : templates)
|
for (String template : templates)
|
||||||
{
|
{
|
||||||
if (!StringUtils.containsAny(template, "sql.vm", "api.js.vm", "index.vue.vm", "index-tree.vue.vm"))
|
if (!StringUtils.containsAny(template, "sql.vm", "api.js.vm", "index.vue.vm", "index-tree.vue.vm"))
|
||||||
@ -367,7 +377,7 @@ public class GenTableServiceImpl implements IGenTableService
|
|||||||
VelocityContext context = VelocityUtils.prepareContext(table);
|
VelocityContext context = VelocityUtils.prepareContext(table);
|
||||||
|
|
||||||
// 获取模板列表
|
// 获取模板列表
|
||||||
List<String> templates = VelocityUtils.getTemplateList(table.getTplCategory());
|
List<String> templates = VelocityUtils.getTemplateList(table.getTplCategory(), table.getTplWebType());
|
||||||
for (String template : templates)
|
for (String template : templates)
|
||||||
{
|
{
|
||||||
// 渲染模板
|
// 渲染模板
|
||||||
|
|||||||
@ -67,11 +67,20 @@ public interface IGenTableService
|
|||||||
public void deleteGenTableByIds(Long[] tableIds);
|
public void deleteGenTableByIds(Long[] tableIds);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 导入表结构
|
* 创建表
|
||||||
*
|
*
|
||||||
* @param tableList 导入表列表
|
* @param sql 创建表语句
|
||||||
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
public void importGenTable(List<GenTable> tableList);
|
public boolean createTable(String sql);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导入表结构
|
||||||
|
*
|
||||||
|
* @param tableList 导入表列表
|
||||||
|
* @param operName 操作人员
|
||||||
|
*/
|
||||||
|
public void importGenTable(List<GenTable> tableList, String operName);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 预览代码
|
* 预览代码
|
||||||
|
|||||||
@ -123,11 +123,17 @@ public class VelocityUtils
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取模板信息
|
* 获取模板信息
|
||||||
*
|
* @param tplCategory 生成的模板
|
||||||
|
* @param tplWebType 前端类型
|
||||||
* @return 模板列表
|
* @return 模板列表
|
||||||
*/
|
*/
|
||||||
public static List<String> getTemplateList(String tplCategory)
|
public static List<String> getTemplateList(String tplCategory, String tplWebType)
|
||||||
{
|
{
|
||||||
|
String useWebType = "vm/vue";
|
||||||
|
if ("element-plus".equals(tplWebType))
|
||||||
|
{
|
||||||
|
useWebType = "vm/vue/v3";
|
||||||
|
}
|
||||||
List<String> templates = new ArrayList<String>();
|
List<String> templates = new ArrayList<String>();
|
||||||
templates.add("vm/java/domain.java.vm");
|
templates.add("vm/java/domain.java.vm");
|
||||||
templates.add("vm/java/mapper.java.vm");
|
templates.add("vm/java/mapper.java.vm");
|
||||||
@ -139,15 +145,15 @@ public class VelocityUtils
|
|||||||
templates.add("vm/js/api.js.vm");
|
templates.add("vm/js/api.js.vm");
|
||||||
if (GenConstants.TPL_CRUD.equals(tplCategory))
|
if (GenConstants.TPL_CRUD.equals(tplCategory))
|
||||||
{
|
{
|
||||||
templates.add("vm/vue/index.vue.vm");
|
templates.add(useWebType + "/index.vue.vm");
|
||||||
}
|
}
|
||||||
else if (GenConstants.TPL_TREE.equals(tplCategory))
|
else if (GenConstants.TPL_TREE.equals(tplCategory))
|
||||||
{
|
{
|
||||||
templates.add("vm/vue/index-tree.vue.vm");
|
templates.add(useWebType + "/index-tree.vue.vm");
|
||||||
}
|
}
|
||||||
else if (GenConstants.TPL_SUB.equals(tplCategory))
|
else if (GenConstants.TPL_SUB.equals(tplCategory))
|
||||||
{
|
{
|
||||||
templates.add("vm/vue/index.vue.vm");
|
templates.add(useWebType + "/index.vue.vm");
|
||||||
templates.add("vm/java/sub-domain.java.vm");
|
templates.add("vm/java/sub-domain.java.vm");
|
||||||
}
|
}
|
||||||
return templates;
|
return templates;
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
# 代码生成
|
# 代码生成
|
||||||
gen:
|
gen:
|
||||||
# 作者
|
# 作者
|
||||||
author: ruoyi
|
author: ruoyi
|
||||||
# 默认生成包路径 system 需改成自己的模块名称 如 system monitor tool
|
# 默认生成包路径 system 需改成自己的模块名称 如 system monitor tool
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
<mapper namespace="com.ruoyi.generator.mapper.GenTableColumnMapper">
|
<mapper namespace="com.ruoyi.generator.mapper.GenTableColumnMapper">
|
||||||
|
|
||||||
<resultMap type="GenTableColumn" id="GenTableColumnResult">
|
<resultMap type="GenTableColumn" id="GenTableColumnResult">
|
||||||
<id property="columnId" column="column_id" />
|
<id property="columnId" column="column_id" />
|
||||||
<result property="tableId" column="table_id" />
|
<result property="tableId" column="table_id" />
|
||||||
@ -28,23 +28,23 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
<result property="updateBy" column="update_by" />
|
<result property="updateBy" column="update_by" />
|
||||||
<result property="updateTime" column="update_time" />
|
<result property="updateTime" column="update_time" />
|
||||||
</resultMap>
|
</resultMap>
|
||||||
|
|
||||||
<sql id="selectGenTableColumnVo">
|
<sql id="selectGenTableColumnVo">
|
||||||
select column_id, table_id, column_name, column_comment, column_type, java_type, java_field, is_pk, is_increment, is_required, is_insert, is_edit, is_list, is_query, query_type, html_type, dict_type, sort, create_by, create_time, update_by, update_time from gen_table_column
|
select column_id, table_id, column_name, column_comment, column_type, java_type, java_field, is_pk, is_increment, is_required, is_insert, is_edit, is_list, is_query, query_type, html_type, dict_type, sort, create_by, create_time, update_by, update_time from gen_table_column
|
||||||
</sql>
|
</sql>
|
||||||
|
|
||||||
<select id="selectGenTableColumnListByTableId" parameterType="Long" resultMap="GenTableColumnResult">
|
<select id="selectGenTableColumnListByTableId" parameterType="Long" resultMap="GenTableColumnResult">
|
||||||
<include refid="selectGenTableColumnVo"/>
|
<include refid="selectGenTableColumnVo"/>
|
||||||
where table_id = #{tableId}
|
where table_id = #{tableId}
|
||||||
order by sort
|
order by sort
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<select id="selectDbTableColumnsByName" parameterType="String" resultMap="GenTableColumnResult">
|
<select id="selectDbTableColumnsByName" parameterType="String" resultMap="GenTableColumnResult">
|
||||||
select column_name, (case when (is_nullable = 'no' <![CDATA[ && ]]> column_key != 'PRI') then '1' else null end) as is_required, (case when column_key = 'PRI' then '1' else '0' end) as is_pk, ordinal_position as sort, column_comment, (case when extra = 'auto_increment' then '1' else '0' end) as is_increment, column_type
|
select column_name, (case when (is_nullable = 'no' <![CDATA[ && ]]> column_key != 'PRI') then '1' else '0' end) as is_required, (case when column_key = 'PRI' then '1' else '0' end) as is_pk, ordinal_position as sort, column_comment, (case when extra = 'auto_increment' then '1' else '0' end) as is_increment, column_type
|
||||||
from information_schema.columns where table_schema = (select database()) and table_name = (#{tableName})
|
from information_schema.columns where table_schema = (select database()) and table_name = (#{tableName})
|
||||||
order by ordinal_position
|
order by ordinal_position
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<insert id="insertGenTableColumn" parameterType="GenTableColumn" useGeneratedKeys="true" keyProperty="columnId">
|
<insert id="insertGenTableColumn" parameterType="GenTableColumn" useGeneratedKeys="true" keyProperty="columnId">
|
||||||
insert into gen_table_column (
|
insert into gen_table_column (
|
||||||
<if test="tableId != null and tableId != ''">table_id,</if>
|
<if test="tableId != null and tableId != ''">table_id,</if>
|
||||||
@ -88,7 +88,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
sysdate()
|
sysdate()
|
||||||
)
|
)
|
||||||
</insert>
|
</insert>
|
||||||
|
|
||||||
<update id="updateGenTableColumn" parameterType="GenTableColumn">
|
<update id="updateGenTableColumn" parameterType="GenTableColumn">
|
||||||
update gen_table_column
|
update gen_table_column
|
||||||
<set>
|
<set>
|
||||||
@ -111,14 +111,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
</update>
|
</update>
|
||||||
|
|
||||||
<delete id="deleteGenTableColumnByIds" parameterType="Long">
|
<delete id="deleteGenTableColumnByIds" parameterType="Long">
|
||||||
delete from gen_table_column where table_id in
|
delete from gen_table_column where table_id in
|
||||||
<foreach collection="array" item="tableId" open="(" separator="," close=")">
|
<foreach collection="array" item="tableId" open="(" separator="," close=")">
|
||||||
#{tableId}
|
#{tableId}
|
||||||
</foreach>
|
</foreach>
|
||||||
</delete>
|
</delete>
|
||||||
|
|
||||||
<delete id="deleteGenTableColumns">
|
<delete id="deleteGenTableColumns">
|
||||||
delete from gen_table_column where column_id in
|
delete from gen_table_column where column_id in
|
||||||
<foreach collection="list" item="item" open="(" separator="," close=")">
|
<foreach collection="list" item="item" open="(" separator="," close=")">
|
||||||
#{item.columnId}
|
#{item.columnId}
|
||||||
</foreach>
|
</foreach>
|
||||||
|
|||||||
@ -12,6 +12,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
<result property="subTableFkName" column="sub_table_fk_name" />
|
<result property="subTableFkName" column="sub_table_fk_name" />
|
||||||
<result property="className" column="class_name" />
|
<result property="className" column="class_name" />
|
||||||
<result property="tplCategory" column="tpl_category" />
|
<result property="tplCategory" column="tpl_category" />
|
||||||
|
<result property="tplWebType" column="tpl_web_type" />
|
||||||
<result property="packageName" column="package_name" />
|
<result property="packageName" column="package_name" />
|
||||||
<result property="moduleName" column="module_name" />
|
<result property="moduleName" column="module_name" />
|
||||||
<result property="businessName" column="business_name" />
|
<result property="businessName" column="business_name" />
|
||||||
@ -25,7 +26,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
<result property="updateBy" column="update_by" />
|
<result property="updateBy" column="update_by" />
|
||||||
<result property="updateTime" column="update_time" />
|
<result property="updateTime" column="update_time" />
|
||||||
<result property="remark" column="remark" />
|
<result property="remark" column="remark" />
|
||||||
<collection property="columns" javaType="java.util.List" resultMap="GenTableColumnResult" />
|
<collection property="columns" javaType="java.util.List" resultMap="GenTableColumnResult" />
|
||||||
</resultMap>
|
</resultMap>
|
||||||
|
|
||||||
<resultMap type="GenTableColumn" id="GenTableColumnResult">
|
<resultMap type="GenTableColumn" id="GenTableColumnResult">
|
||||||
@ -54,7 +55,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
</resultMap>
|
</resultMap>
|
||||||
|
|
||||||
<sql id="selectGenTableVo">
|
<sql id="selectGenTableVo">
|
||||||
select table_id, table_name, table_comment, sub_table_name, sub_table_fk_name, class_name, tpl_category, package_name, module_name, business_name, function_name, function_author, gen_type, gen_path, options, create_by, create_time, update_by, update_time, remark from gen_table
|
select table_id, table_name, table_comment, sub_table_name, sub_table_fk_name, class_name, tpl_category, tpl_web_type, package_name, module_name, business_name, function_name, function_author, gen_type, gen_path, options, create_by, create_time, update_by, update_time, remark from gen_table
|
||||||
</sql>
|
</sql>
|
||||||
|
|
||||||
<select id="selectGenTableList" parameterType="GenTable" resultMap="GenTableResult">
|
<select id="selectGenTableList" parameterType="GenTable" resultMap="GenTableResult">
|
||||||
@ -78,7 +79,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
<select id="selectDbTableList" parameterType="GenTable" resultMap="GenTableResult">
|
<select id="selectDbTableList" parameterType="GenTable" resultMap="GenTableResult">
|
||||||
select table_name, table_comment, create_time, update_time from information_schema.tables
|
select table_name, table_comment, create_time, update_time from information_schema.tables
|
||||||
where table_schema = (select database())
|
where table_schema = (select database())
|
||||||
AND table_name NOT LIKE 'qrtz_%' AND table_name NOT LIKE 'gen_%'
|
AND table_name NOT LIKE 'qrtz\_%' AND table_name NOT LIKE 'gen\_%'
|
||||||
AND table_name NOT IN (select table_name from gen_table)
|
AND table_name NOT IN (select table_name from gen_table)
|
||||||
<if test="tableName != null and tableName != ''">
|
<if test="tableName != null and tableName != ''">
|
||||||
AND lower(table_name) like lower(concat('%', #{tableName}, '%'))
|
AND lower(table_name) like lower(concat('%', #{tableName}, '%'))
|
||||||
@ -97,7 +98,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
|
|
||||||
<select id="selectDbTableListByNames" resultMap="GenTableResult">
|
<select id="selectDbTableListByNames" resultMap="GenTableResult">
|
||||||
select table_name, table_comment, create_time, update_time from information_schema.tables
|
select table_name, table_comment, create_time, update_time from information_schema.tables
|
||||||
where table_name NOT LIKE 'qrtz_%' and table_name NOT LIKE 'gen_%' and table_schema = (select database())
|
where table_name NOT LIKE 'qrtz\_%' and table_name NOT LIKE 'gen\_%' and table_schema = (select database())
|
||||||
and table_name in
|
and table_name in
|
||||||
<foreach collection="array" item="name" open="(" separator="," close=")">
|
<foreach collection="array" item="name" open="(" separator="," close=")">
|
||||||
#{name}
|
#{name}
|
||||||
@ -111,7 +112,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
</select>
|
</select>
|
||||||
|
|
||||||
<select id="selectGenTableById" parameterType="Long" resultMap="GenTableResult">
|
<select id="selectGenTableById" parameterType="Long" resultMap="GenTableResult">
|
||||||
SELECT t.table_id, t.table_name, t.table_comment, t.sub_table_name, t.sub_table_fk_name, t.class_name, t.tpl_category, t.package_name, t.module_name, t.business_name, t.function_name, t.function_author, t.gen_type, t.gen_path, t.options, t.remark,
|
SELECT t.table_id, t.table_name, t.table_comment, t.sub_table_name, t.sub_table_fk_name, t.class_name, t.tpl_category, t.tpl_web_type, t.package_name, t.module_name, t.business_name, t.function_name, t.function_author, t.gen_type, t.gen_path, t.options, t.remark,
|
||||||
c.column_id, c.column_name, c.column_comment, c.column_type, c.java_type, c.java_field, c.is_pk, c.is_increment, c.is_required, c.is_insert, c.is_edit, c.is_list, c.is_query, c.query_type, c.html_type, c.dict_type, c.sort
|
c.column_id, c.column_name, c.column_comment, c.column_type, c.java_type, c.java_field, c.is_pk, c.is_increment, c.is_required, c.is_insert, c.is_edit, c.is_list, c.is_query, c.query_type, c.html_type, c.dict_type, c.sort
|
||||||
FROM gen_table t
|
FROM gen_table t
|
||||||
LEFT JOIN gen_table_column c ON t.table_id = c.table_id
|
LEFT JOIN gen_table_column c ON t.table_id = c.table_id
|
||||||
@ -119,7 +120,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
</select>
|
</select>
|
||||||
|
|
||||||
<select id="selectGenTableByName" parameterType="String" resultMap="GenTableResult">
|
<select id="selectGenTableByName" parameterType="String" resultMap="GenTableResult">
|
||||||
SELECT t.table_id, t.table_name, t.table_comment, t.sub_table_name, t.sub_table_fk_name, t.class_name, t.tpl_category, t.package_name, t.module_name, t.business_name, t.function_name, t.function_author, t.gen_type, t.gen_path, t.options, t.remark,
|
SELECT t.table_id, t.table_name, t.table_comment, t.sub_table_name, t.sub_table_fk_name, t.class_name, t.tpl_category, t.tpl_web_type, t.package_name, t.module_name, t.business_name, t.function_name, t.function_author, t.gen_type, t.gen_path, t.options, t.remark,
|
||||||
c.column_id, c.column_name, c.column_comment, c.column_type, c.java_type, c.java_field, c.is_pk, c.is_increment, c.is_required, c.is_insert, c.is_edit, c.is_list, c.is_query, c.query_type, c.html_type, c.dict_type, c.sort
|
c.column_id, c.column_name, c.column_comment, c.column_type, c.java_type, c.java_field, c.is_pk, c.is_increment, c.is_required, c.is_insert, c.is_edit, c.is_list, c.is_query, c.query_type, c.html_type, c.dict_type, c.sort
|
||||||
FROM gen_table t
|
FROM gen_table t
|
||||||
LEFT JOIN gen_table_column c ON t.table_id = c.table_id
|
LEFT JOIN gen_table_column c ON t.table_id = c.table_id
|
||||||
@ -127,7 +128,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
</select>
|
</select>
|
||||||
|
|
||||||
<select id="selectGenTableAll" parameterType="String" resultMap="GenTableResult">
|
<select id="selectGenTableAll" parameterType="String" resultMap="GenTableResult">
|
||||||
SELECT t.table_id, t.table_name, t.table_comment, t.sub_table_name, t.sub_table_fk_name, t.class_name, t.tpl_category, t.package_name, t.module_name, t.business_name, t.function_name, t.function_author, t.options, t.remark,
|
SELECT t.table_id, t.table_name, t.table_comment, t.sub_table_name, t.sub_table_fk_name, t.class_name, t.tpl_category, t.tpl_web_type, t.package_name, t.module_name, t.business_name, t.function_name, t.function_author, t.options, t.remark,
|
||||||
c.column_id, c.column_name, c.column_comment, c.column_type, c.java_type, c.java_field, c.is_pk, c.is_increment, c.is_required, c.is_insert, c.is_edit, c.is_list, c.is_query, c.query_type, c.html_type, c.dict_type, c.sort
|
c.column_id, c.column_name, c.column_comment, c.column_type, c.java_type, c.java_field, c.is_pk, c.is_increment, c.is_required, c.is_insert, c.is_edit, c.is_list, c.is_query, c.query_type, c.html_type, c.dict_type, c.sort
|
||||||
FROM gen_table t
|
FROM gen_table t
|
||||||
LEFT JOIN gen_table_column c ON t.table_id = c.table_id
|
LEFT JOIN gen_table_column c ON t.table_id = c.table_id
|
||||||
@ -140,6 +141,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
<if test="tableComment != null and tableComment != ''">table_comment,</if>
|
<if test="tableComment != null and tableComment != ''">table_comment,</if>
|
||||||
<if test="className != null and className != ''">class_name,</if>
|
<if test="className != null and className != ''">class_name,</if>
|
||||||
<if test="tplCategory != null and tplCategory != ''">tpl_category,</if>
|
<if test="tplCategory != null and tplCategory != ''">tpl_category,</if>
|
||||||
|
<if test="tplWebType != null and tplWebType != ''">tpl_web_type,</if>
|
||||||
<if test="packageName != null and packageName != ''">package_name,</if>
|
<if test="packageName != null and packageName != ''">package_name,</if>
|
||||||
<if test="moduleName != null and moduleName != ''">module_name,</if>
|
<if test="moduleName != null and moduleName != ''">module_name,</if>
|
||||||
<if test="businessName != null and businessName != ''">business_name,</if>
|
<if test="businessName != null and businessName != ''">business_name,</if>
|
||||||
@ -155,6 +157,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
<if test="tableComment != null and tableComment != ''">#{tableComment},</if>
|
<if test="tableComment != null and tableComment != ''">#{tableComment},</if>
|
||||||
<if test="className != null and className != ''">#{className},</if>
|
<if test="className != null and className != ''">#{className},</if>
|
||||||
<if test="tplCategory != null and tplCategory != ''">#{tplCategory},</if>
|
<if test="tplCategory != null and tplCategory != ''">#{tplCategory},</if>
|
||||||
|
<if test="tplWebType != null and tplWebType != ''">#{tplWebType},</if>
|
||||||
<if test="packageName != null and packageName != ''">#{packageName},</if>
|
<if test="packageName != null and packageName != ''">#{packageName},</if>
|
||||||
<if test="moduleName != null and moduleName != ''">#{moduleName},</if>
|
<if test="moduleName != null and moduleName != ''">#{moduleName},</if>
|
||||||
<if test="businessName != null and businessName != ''">#{businessName},</if>
|
<if test="businessName != null and businessName != ''">#{businessName},</if>
|
||||||
@ -168,6 +171,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
)
|
)
|
||||||
</insert>
|
</insert>
|
||||||
|
|
||||||
|
<update id="createTable">
|
||||||
|
${sql}
|
||||||
|
</update>
|
||||||
|
|
||||||
<update id="updateGenTable" parameterType="GenTable">
|
<update id="updateGenTable" parameterType="GenTable">
|
||||||
update gen_table
|
update gen_table
|
||||||
<set>
|
<set>
|
||||||
@ -180,6 +187,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
<if test="genType != null and genType != ''">gen_type = #{genType},</if>
|
<if test="genType != null and genType != ''">gen_type = #{genType},</if>
|
||||||
<if test="genPath != null and genPath != ''">gen_path = #{genPath},</if>
|
<if test="genPath != null and genPath != ''">gen_path = #{genPath},</if>
|
||||||
<if test="tplCategory != null and tplCategory != ''">tpl_category = #{tplCategory},</if>
|
<if test="tplCategory != null and tplCategory != ''">tpl_category = #{tplCategory},</if>
|
||||||
|
<if test="tplWebType != null and tplWebType != ''">tpl_web_type = #{tplWebType},</if>
|
||||||
<if test="packageName != null and packageName != ''">package_name = #{packageName},</if>
|
<if test="packageName != null and packageName != ''">package_name = #{packageName},</if>
|
||||||
<if test="moduleName != null and moduleName != ''">module_name = #{moduleName},</if>
|
<if test="moduleName != null and moduleName != ''">module_name = #{moduleName},</if>
|
||||||
<if test="businessName != null and businessName != ''">business_name = #{businessName},</if>
|
<if test="businessName != null and businessName != ''">business_name = #{businessName},</if>
|
||||||
|
|||||||
@ -53,7 +53,7 @@ public class ${ClassName}Controller extends BaseController
|
|||||||
public AjaxResult list(${ClassName} ${className})
|
public AjaxResult list(${ClassName} ${className})
|
||||||
{
|
{
|
||||||
List<${ClassName}> list = ${className}Service.select${ClassName}List(${className});
|
List<${ClassName}> list = ${className}Service.select${ClassName}List(${className});
|
||||||
return AjaxResult.success(list);
|
return success(list);
|
||||||
}
|
}
|
||||||
#end
|
#end
|
||||||
|
|
||||||
@ -77,7 +77,7 @@ public class ${ClassName}Controller extends BaseController
|
|||||||
@GetMapping(value = "/{${pkColumn.javaField}}")
|
@GetMapping(value = "/{${pkColumn.javaField}}")
|
||||||
public AjaxResult getInfo(@PathVariable("${pkColumn.javaField}") ${pkColumn.javaType} ${pkColumn.javaField})
|
public AjaxResult getInfo(@PathVariable("${pkColumn.javaField}") ${pkColumn.javaType} ${pkColumn.javaField})
|
||||||
{
|
{
|
||||||
return AjaxResult.success(${className}Service.select${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaField}));
|
return success(${className}Service.select${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaField}));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -187,11 +187,11 @@
|
|||||||
<el-input v-model="form.${field}" placeholder="请输入${comment}" />
|
<el-input v-model="form.${field}" placeholder="请输入${comment}" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
#elseif($column.htmlType == "imageUpload")
|
#elseif($column.htmlType == "imageUpload")
|
||||||
<el-form-item label="${comment}">
|
<el-form-item label="${comment}" prop="${field}">
|
||||||
<image-upload v-model="form.${field}"/>
|
<image-upload v-model="form.${field}"/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
#elseif($column.htmlType == "fileUpload")
|
#elseif($column.htmlType == "fileUpload")
|
||||||
<el-form-item label="${comment}">
|
<el-form-item label="${comment}" prop="${field}">
|
||||||
<file-upload v-model="form.${field}"/>
|
<file-upload v-model="form.${field}"/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
#elseif($column.htmlType == "editor")
|
#elseif($column.htmlType == "editor")
|
||||||
@ -205,8 +205,11 @@
|
|||||||
v-for="dict in dict.type.${dictType}"
|
v-for="dict in dict.type.${dictType}"
|
||||||
:key="dict.value"
|
:key="dict.value"
|
||||||
:label="dict.label"
|
:label="dict.label"
|
||||||
#if($column.javaType == "Integer" || $column.javaType == "Long"):value="parseInt(dict.value)"#else:value="dict.value"#end
|
#if($column.javaType == "Integer" || $column.javaType == "Long")
|
||||||
|
:value="parseInt(dict.value)"
|
||||||
|
#else
|
||||||
|
:value="dict.value"
|
||||||
|
#end
|
||||||
></el-option>
|
></el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@ -217,7 +220,7 @@
|
|||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
#elseif($column.htmlType == "checkbox" && "" != $dictType)
|
#elseif($column.htmlType == "checkbox" && "" != $dictType)
|
||||||
<el-form-item label="${comment}">
|
<el-form-item label="${comment}" prop="${field}">
|
||||||
<el-checkbox-group v-model="form.${field}">
|
<el-checkbox-group v-model="form.${field}">
|
||||||
<el-checkbox
|
<el-checkbox
|
||||||
v-for="dict in dict.type.${dictType}"
|
v-for="dict in dict.type.${dictType}"
|
||||||
@ -228,24 +231,27 @@
|
|||||||
</el-checkbox-group>
|
</el-checkbox-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
#elseif($column.htmlType == "checkbox" && $dictType)
|
#elseif($column.htmlType == "checkbox" && $dictType)
|
||||||
<el-form-item label="${comment}">
|
<el-form-item label="${comment}" prop="${field}">
|
||||||
<el-checkbox-group v-model="form.${field}">
|
<el-checkbox-group v-model="form.${field}">
|
||||||
<el-checkbox>请选择字典生成</el-checkbox>
|
<el-checkbox>请选择字典生成</el-checkbox>
|
||||||
</el-checkbox-group>
|
</el-checkbox-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
#elseif($column.htmlType == "radio" && "" != $dictType)
|
#elseif($column.htmlType == "radio" && "" != $dictType)
|
||||||
<el-form-item label="${comment}">
|
<el-form-item label="${comment}" prop="${field}">
|
||||||
<el-radio-group v-model="form.${field}">
|
<el-radio-group v-model="form.${field}">
|
||||||
<el-radio
|
<el-radio
|
||||||
v-for="dict in dict.type.${dictType}"
|
v-for="dict in dict.type.${dictType}"
|
||||||
:key="dict.value"
|
:key="dict.value"
|
||||||
#if($column.javaType == "Integer" || $column.javaType == "Long"):label="parseInt(dict.value)"#else:label="dict.value"#end
|
#if($column.javaType == "Integer" || $column.javaType == "Long")
|
||||||
|
:label="parseInt(dict.value)"
|
||||||
|
#else
|
||||||
|
:label="dict.value"
|
||||||
|
#end
|
||||||
>{{dict.label}}</el-radio>
|
>{{dict.label}}</el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
#elseif($column.htmlType == "radio" && $dictType)
|
#elseif($column.htmlType == "radio" && $dictType)
|
||||||
<el-form-item label="${comment}">
|
<el-form-item label="${comment}" prop="${field}">
|
||||||
<el-radio-group v-model="form.${field}">
|
<el-radio-group v-model="form.${field}">
|
||||||
<el-radio label="1">请选择字典生成</el-radio>
|
<el-radio label="1">请选择字典生成</el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
@ -335,7 +341,7 @@ export default {
|
|||||||
#set($comment=$column.columnComment)
|
#set($comment=$column.columnComment)
|
||||||
#end
|
#end
|
||||||
$column.javaField: [
|
$column.javaField: [
|
||||||
{ required: true, message: "$comment不能为空", trigger: #if($column.htmlType == "select")"change"#else"blur"#end }
|
{ required: true, message: "$comment不能为空", trigger: #if($column.htmlType == "select" || $column.htmlType == "radio")"change"#else"blur"#end }
|
||||||
]#if($foreach.count != $columns.size()),#end
|
]#if($foreach.count != $columns.size()),#end
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
@ -398,10 +404,7 @@ export default {
|
|||||||
reset() {
|
reset() {
|
||||||
this.form = {
|
this.form = {
|
||||||
#foreach ($column in $columns)
|
#foreach ($column in $columns)
|
||||||
#if($column.htmlType == "radio")
|
#if($column.htmlType == "checkbox")
|
||||||
$column.javaField: #if($column.javaType == "Integer" || $column.javaType == "Long")0#else"0"#end#if($foreach.count != $columns.size()),#end
|
|
||||||
|
|
||||||
#elseif($column.htmlType == "checkbox")
|
|
||||||
$column.javaField: []#if($foreach.count != $columns.size()),#end
|
$column.javaField: []#if($foreach.count != $columns.size()),#end
|
||||||
#else
|
#else
|
||||||
$column.javaField: null#if($foreach.count != $columns.size()),#end
|
$column.javaField: null#if($foreach.count != $columns.size()),#end
|
||||||
@ -450,7 +453,7 @@ export default {
|
|||||||
this.reset();
|
this.reset();
|
||||||
this.getTreeselect();
|
this.getTreeselect();
|
||||||
if (row != null) {
|
if (row != null) {
|
||||||
this.form.${treeParentCode} = row.${treeCode};
|
this.form.${treeParentCode} = row.${treeParentCode};
|
||||||
}
|
}
|
||||||
get${BusinessName}(row.${pkColumn.javaField}).then(response => {
|
get${BusinessName}(row.${pkColumn.javaField}).then(response => {
|
||||||
this.form = response.data;
|
this.form = response.data;
|
||||||
|
|||||||
@ -198,11 +198,11 @@
|
|||||||
<el-input v-model="form.${field}" placeholder="请输入${comment}" />
|
<el-input v-model="form.${field}" placeholder="请输入${comment}" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
#elseif($column.htmlType == "imageUpload")
|
#elseif($column.htmlType == "imageUpload")
|
||||||
<el-form-item label="${comment}">
|
<el-form-item label="${comment}" prop="${field}">
|
||||||
<image-upload v-model="form.${field}"/>
|
<image-upload v-model="form.${field}"/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
#elseif($column.htmlType == "fileUpload")
|
#elseif($column.htmlType == "fileUpload")
|
||||||
<el-form-item label="${comment}">
|
<el-form-item label="${comment}" prop="${field}">
|
||||||
<file-upload v-model="form.${field}"/>
|
<file-upload v-model="form.${field}"/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
#elseif($column.htmlType == "editor")
|
#elseif($column.htmlType == "editor")
|
||||||
@ -216,8 +216,11 @@
|
|||||||
v-for="dict in dict.type.${dictType}"
|
v-for="dict in dict.type.${dictType}"
|
||||||
:key="dict.value"
|
:key="dict.value"
|
||||||
:label="dict.label"
|
:label="dict.label"
|
||||||
#if($column.javaType == "Integer" || $column.javaType == "Long"):value="parseInt(dict.value)"#else:value="dict.value"#end
|
#if($column.javaType == "Integer" || $column.javaType == "Long")
|
||||||
|
:value="parseInt(dict.value)"
|
||||||
|
#else
|
||||||
|
:value="dict.value"
|
||||||
|
#end
|
||||||
></el-option>
|
></el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@ -228,7 +231,7 @@
|
|||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
#elseif($column.htmlType == "checkbox" && "" != $dictType)
|
#elseif($column.htmlType == "checkbox" && "" != $dictType)
|
||||||
<el-form-item label="${comment}">
|
<el-form-item label="${comment}" prop="${field}">
|
||||||
<el-checkbox-group v-model="form.${field}">
|
<el-checkbox-group v-model="form.${field}">
|
||||||
<el-checkbox
|
<el-checkbox
|
||||||
v-for="dict in dict.type.${dictType}"
|
v-for="dict in dict.type.${dictType}"
|
||||||
@ -239,24 +242,27 @@
|
|||||||
</el-checkbox-group>
|
</el-checkbox-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
#elseif($column.htmlType == "checkbox" && $dictType)
|
#elseif($column.htmlType == "checkbox" && $dictType)
|
||||||
<el-form-item label="${comment}">
|
<el-form-item label="${comment}" prop="${field}">
|
||||||
<el-checkbox-group v-model="form.${field}">
|
<el-checkbox-group v-model="form.${field}">
|
||||||
<el-checkbox>请选择字典生成</el-checkbox>
|
<el-checkbox>请选择字典生成</el-checkbox>
|
||||||
</el-checkbox-group>
|
</el-checkbox-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
#elseif($column.htmlType == "radio" && "" != $dictType)
|
#elseif($column.htmlType == "radio" && "" != $dictType)
|
||||||
<el-form-item label="${comment}">
|
<el-form-item label="${comment}" prop="${field}">
|
||||||
<el-radio-group v-model="form.${field}">
|
<el-radio-group v-model="form.${field}">
|
||||||
<el-radio
|
<el-radio
|
||||||
v-for="dict in dict.type.${dictType}"
|
v-for="dict in dict.type.${dictType}"
|
||||||
:key="dict.value"
|
:key="dict.value"
|
||||||
#if($column.javaType == "Integer" || $column.javaType == "Long"):label="parseInt(dict.value)"#else:label="dict.value"#end
|
#if($column.javaType == "Integer" || $column.javaType == "Long")
|
||||||
|
:label="parseInt(dict.value)"
|
||||||
|
#else
|
||||||
|
:label="dict.value"
|
||||||
|
#end
|
||||||
>{{dict.label}}</el-radio>
|
>{{dict.label}}</el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
#elseif($column.htmlType == "radio" && $dictType)
|
#elseif($column.htmlType == "radio" && $dictType)
|
||||||
<el-form-item label="${comment}">
|
<el-form-item label="${comment}" prop="${field}">
|
||||||
<el-radio-group v-model="form.${field}">
|
<el-radio-group v-model="form.${field}">
|
||||||
<el-radio label="1">请选择字典生成</el-radio>
|
<el-radio label="1">请选择字典生成</el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
@ -412,7 +418,7 @@ export default {
|
|||||||
#set($comment=$column.columnComment)
|
#set($comment=$column.columnComment)
|
||||||
#end
|
#end
|
||||||
$column.javaField: [
|
$column.javaField: [
|
||||||
{ required: true, message: "$comment不能为空", trigger: #if($column.htmlType == "select")"change"#else"blur"#end }
|
{ required: true, message: "$comment不能为空", trigger: #if($column.htmlType == "select" || $column.htmlType == "radio")"change"#else"blur"#end }
|
||||||
]#if($foreach.count != $columns.size()),#end
|
]#if($foreach.count != $columns.size()),#end
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
@ -456,9 +462,7 @@ export default {
|
|||||||
reset() {
|
reset() {
|
||||||
this.form = {
|
this.form = {
|
||||||
#foreach ($column in $columns)
|
#foreach ($column in $columns)
|
||||||
#if($column.htmlType == "radio")
|
#if($column.htmlType == "checkbox")
|
||||||
$column.javaField: #if($column.javaType == "Integer" || $column.javaType == "Long")0#else"0"#end#if($foreach.count != $columns.size()),#end
|
|
||||||
#elseif($column.htmlType == "checkbox")
|
|
||||||
$column.javaField: []#if($foreach.count != $columns.size()),#end
|
$column.javaField: []#if($foreach.count != $columns.size()),#end
|
||||||
#else
|
#else
|
||||||
$column.javaField: null#if($foreach.count != $columns.size()),#end
|
$column.javaField: null#if($foreach.count != $columns.size()),#end
|
||||||
|
|||||||
@ -136,24 +136,9 @@
|
|||||||
#end
|
#end
|
||||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button
|
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['${moduleName}:${businessName}:edit']">修改</el-button>
|
||||||
type="text"
|
<el-button link type="primary" icon="Plus" @click="handleAdd(scope.row)" v-hasPermi="['${moduleName}:${businessName}:add']">新增</el-button>
|
||||||
icon="Edit"
|
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['${moduleName}:${businessName}:remove']">删除</el-button>
|
||||||
@click="handleUpdate(scope.row)"
|
|
||||||
v-hasPermi="['${moduleName}:${businessName}:edit']"
|
|
||||||
>修改</el-button>
|
|
||||||
<el-button
|
|
||||||
type="text"
|
|
||||||
icon="Plus"
|
|
||||||
@click="handleAdd(scope.row)"
|
|
||||||
v-hasPermi="['${moduleName}:${businessName}:add']"
|
|
||||||
>新增</el-button>
|
|
||||||
<el-button
|
|
||||||
type="text"
|
|
||||||
icon="Delete"
|
|
||||||
@click="handleDelete(scope.row)"
|
|
||||||
v-hasPermi="['${moduleName}:${businessName}:remove']"
|
|
||||||
>删除</el-button>
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
@ -188,11 +173,11 @@
|
|||||||
<el-input v-model="form.${field}" placeholder="请输入${comment}" />
|
<el-input v-model="form.${field}" placeholder="请输入${comment}" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
#elseif($column.htmlType == "imageUpload")
|
#elseif($column.htmlType == "imageUpload")
|
||||||
<el-form-item label="${comment}">
|
<el-form-item label="${comment}" prop="${field}">
|
||||||
<image-upload v-model="form.${field}"/>
|
<image-upload v-model="form.${field}"/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
#elseif($column.htmlType == "fileUpload")
|
#elseif($column.htmlType == "fileUpload")
|
||||||
<el-form-item label="${comment}">
|
<el-form-item label="${comment}" prop="${field}">
|
||||||
<file-upload v-model="form.${field}"/>
|
<file-upload v-model="form.${field}"/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
#elseif($column.htmlType == "editor")
|
#elseif($column.htmlType == "editor")
|
||||||
@ -206,8 +191,11 @@
|
|||||||
v-for="dict in ${dictType}"
|
v-for="dict in ${dictType}"
|
||||||
:key="dict.value"
|
:key="dict.value"
|
||||||
:label="dict.label"
|
:label="dict.label"
|
||||||
#if($column.javaType == "Integer" || $column.javaType == "Long"):value="parseInt(dict.value)"#else:value="dict.value"#end
|
#if($column.javaType == "Integer" || $column.javaType == "Long")
|
||||||
|
:value="parseInt(dict.value)"
|
||||||
|
#else
|
||||||
|
:value="dict.value"
|
||||||
|
#end
|
||||||
></el-option>
|
></el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@ -218,7 +206,7 @@
|
|||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
#elseif($column.htmlType == "checkbox" && "" != $dictType)
|
#elseif($column.htmlType == "checkbox" && "" != $dictType)
|
||||||
<el-form-item label="${comment}">
|
<el-form-item label="${comment}" prop="${field}">
|
||||||
<el-checkbox-group v-model="form.${field}">
|
<el-checkbox-group v-model="form.${field}">
|
||||||
<el-checkbox
|
<el-checkbox
|
||||||
v-for="dict in ${dictType}"
|
v-for="dict in ${dictType}"
|
||||||
@ -229,24 +217,27 @@
|
|||||||
</el-checkbox-group>
|
</el-checkbox-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
#elseif($column.htmlType == "checkbox" && $dictType)
|
#elseif($column.htmlType == "checkbox" && $dictType)
|
||||||
<el-form-item label="${comment}">
|
<el-form-item label="${comment}" prop="${field}">
|
||||||
<el-checkbox-group v-model="form.${field}">
|
<el-checkbox-group v-model="form.${field}">
|
||||||
<el-checkbox>请选择字典生成</el-checkbox>
|
<el-checkbox>请选择字典生成</el-checkbox>
|
||||||
</el-checkbox-group>
|
</el-checkbox-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
#elseif($column.htmlType == "radio" && "" != $dictType)
|
#elseif($column.htmlType == "radio" && "" != $dictType)
|
||||||
<el-form-item label="${comment}">
|
<el-form-item label="${comment}" prop="${field}">
|
||||||
<el-radio-group v-model="form.${field}">
|
<el-radio-group v-model="form.${field}">
|
||||||
<el-radio
|
<el-radio
|
||||||
v-for="dict in ${dictType}"
|
v-for="dict in ${dictType}"
|
||||||
:key="dict.value"
|
:key="dict.value"
|
||||||
#if($column.javaType == "Integer" || $column.javaType == "Long"):label="parseInt(dict.value)"#else:label="dict.value"#end
|
#if($column.javaType == "Integer" || $column.javaType == "Long")
|
||||||
|
:label="parseInt(dict.value)"
|
||||||
|
#else
|
||||||
|
:label="dict.value"
|
||||||
|
#end
|
||||||
>{{dict.label}}</el-radio>
|
>{{dict.label}}</el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
#elseif($column.htmlType == "radio" && $dictType)
|
#elseif($column.htmlType == "radio" && $dictType)
|
||||||
<el-form-item label="${comment}">
|
<el-form-item label="${comment}" prop="${field}">
|
||||||
<el-radio-group v-model="form.${field}">
|
<el-radio-group v-model="form.${field}">
|
||||||
<el-radio label="1">请选择字典生成</el-radio>
|
<el-radio label="1">请选择字典生成</el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
@ -322,7 +313,7 @@ const data = reactive({
|
|||||||
#set($comment=$column.columnComment)
|
#set($comment=$column.columnComment)
|
||||||
#end
|
#end
|
||||||
$column.javaField: [
|
$column.javaField: [
|
||||||
{ required: true, message: "$comment不能为空", trigger: #if($column.htmlType == "select")"change"#else"blur"#end }
|
{ required: true, message: "$comment不能为空", trigger: #if($column.htmlType == "select" || $column.htmlType == "radio")"change"#else"blur"#end }
|
||||||
]#if($foreach.count != $columns.size()),#end
|
]#if($foreach.count != $columns.size()),#end
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
@ -375,10 +366,7 @@ function cancel() {
|
|||||||
function reset() {
|
function reset() {
|
||||||
form.value = {
|
form.value = {
|
||||||
#foreach ($column in $columns)
|
#foreach ($column in $columns)
|
||||||
#if($column.htmlType == "radio")
|
#if($column.htmlType == "checkbox")
|
||||||
$column.javaField: #if($column.javaType == "Integer" || $column.javaType == "Long")0#else"0"#end#if($foreach.count != $columns.size()),#end
|
|
||||||
|
|
||||||
#elseif($column.htmlType == "checkbox")
|
|
||||||
$column.javaField: []#if($foreach.count != $columns.size()),#end
|
$column.javaField: []#if($foreach.count != $columns.size()),#end
|
||||||
#else
|
#else
|
||||||
$column.javaField: null#if($foreach.count != $columns.size()),#end
|
$column.javaField: null#if($foreach.count != $columns.size()),#end
|
||||||
@ -432,7 +420,7 @@ async function handleUpdate(row) {
|
|||||||
reset();
|
reset();
|
||||||
await getTreeselect();
|
await getTreeselect();
|
||||||
if (row != null) {
|
if (row != null) {
|
||||||
form.value.${treeParentCode} = row.${treeCode};
|
form.value.${treeParentCode} = row.${treeParentCode};
|
||||||
}
|
}
|
||||||
get${BusinessName}(row.${pkColumn.javaField}).then(response => {
|
get${BusinessName}(row.${pkColumn.javaField}).then(response => {
|
||||||
form.value = response.data;
|
form.value = response.data;
|
||||||
|
|||||||
@ -148,18 +148,8 @@
|
|||||||
#end
|
#end
|
||||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button
|
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['${moduleName}:${businessName}:edit']">修改</el-button>
|
||||||
type="text"
|
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['${moduleName}:${businessName}:remove']">删除</el-button>
|
||||||
icon="Edit"
|
|
||||||
@click="handleUpdate(scope.row)"
|
|
||||||
v-hasPermi="['${moduleName}:${businessName}:edit']"
|
|
||||||
>修改</el-button>
|
|
||||||
<el-button
|
|
||||||
type="text"
|
|
||||||
icon="Delete"
|
|
||||||
@click="handleDelete(scope.row)"
|
|
||||||
v-hasPermi="['${moduleName}:${businessName}:remove']"
|
|
||||||
>删除</el-button>
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
@ -191,11 +181,11 @@
|
|||||||
<el-input v-model="form.${field}" placeholder="请输入${comment}" />
|
<el-input v-model="form.${field}" placeholder="请输入${comment}" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
#elseif($column.htmlType == "imageUpload")
|
#elseif($column.htmlType == "imageUpload")
|
||||||
<el-form-item label="${comment}">
|
<el-form-item label="${comment}" prop="${field}">
|
||||||
<image-upload v-model="form.${field}"/>
|
<image-upload v-model="form.${field}"/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
#elseif($column.htmlType == "fileUpload")
|
#elseif($column.htmlType == "fileUpload")
|
||||||
<el-form-item label="${comment}">
|
<el-form-item label="${comment}" prop="${field}">
|
||||||
<file-upload v-model="form.${field}"/>
|
<file-upload v-model="form.${field}"/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
#elseif($column.htmlType == "editor")
|
#elseif($column.htmlType == "editor")
|
||||||
@ -209,8 +199,11 @@
|
|||||||
v-for="dict in ${dictType}"
|
v-for="dict in ${dictType}"
|
||||||
:key="dict.value"
|
:key="dict.value"
|
||||||
:label="dict.label"
|
:label="dict.label"
|
||||||
#if($column.javaType == "Integer" || $column.javaType == "Long"):value="parseInt(dict.value)"#else:value="dict.value"#end
|
#if($column.javaType == "Integer" || $column.javaType == "Long")
|
||||||
|
:value="parseInt(dict.value)"
|
||||||
|
#else
|
||||||
|
:value="dict.value"
|
||||||
|
#end
|
||||||
></el-option>
|
></el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@ -221,7 +214,7 @@
|
|||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
#elseif($column.htmlType == "checkbox" && "" != $dictType)
|
#elseif($column.htmlType == "checkbox" && "" != $dictType)
|
||||||
<el-form-item label="${comment}">
|
<el-form-item label="${comment}" prop="${field}">
|
||||||
<el-checkbox-group v-model="form.${field}">
|
<el-checkbox-group v-model="form.${field}">
|
||||||
<el-checkbox
|
<el-checkbox
|
||||||
v-for="dict in ${dictType}"
|
v-for="dict in ${dictType}"
|
||||||
@ -232,24 +225,27 @@
|
|||||||
</el-checkbox-group>
|
</el-checkbox-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
#elseif($column.htmlType == "checkbox" && $dictType)
|
#elseif($column.htmlType == "checkbox" && $dictType)
|
||||||
<el-form-item label="${comment}">
|
<el-form-item label="${comment}" prop="${field}">
|
||||||
<el-checkbox-group v-model="form.${field}">
|
<el-checkbox-group v-model="form.${field}">
|
||||||
<el-checkbox>请选择字典生成</el-checkbox>
|
<el-checkbox>请选择字典生成</el-checkbox>
|
||||||
</el-checkbox-group>
|
</el-checkbox-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
#elseif($column.htmlType == "radio" && "" != $dictType)
|
#elseif($column.htmlType == "radio" && "" != $dictType)
|
||||||
<el-form-item label="${comment}">
|
<el-form-item label="${comment}" prop="${field}">
|
||||||
<el-radio-group v-model="form.${field}">
|
<el-radio-group v-model="form.${field}">
|
||||||
<el-radio
|
<el-radio
|
||||||
v-for="dict in ${dictType}"
|
v-for="dict in ${dictType}"
|
||||||
:key="dict.value"
|
:key="dict.value"
|
||||||
#if($column.javaType == "Integer" || $column.javaType == "Long"):label="parseInt(dict.value)"#else:label="dict.value"#end
|
#if($column.javaType == "Integer" || $column.javaType == "Long")
|
||||||
|
:label="parseInt(dict.value)"
|
||||||
|
#else
|
||||||
|
:label="dict.value"
|
||||||
|
#end
|
||||||
>{{dict.label}}</el-radio>
|
>{{dict.label}}</el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
#elseif($column.htmlType == "radio" && $dictType)
|
#elseif($column.htmlType == "radio" && $dictType)
|
||||||
<el-form-item label="${comment}">
|
<el-form-item label="${comment}" prop="${field}">
|
||||||
<el-radio-group v-model="form.${field}">
|
<el-radio-group v-model="form.${field}">
|
||||||
<el-radio label="1">请选择字典生成</el-radio>
|
<el-radio label="1">请选择字典生成</el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
@ -398,7 +394,7 @@ const data = reactive({
|
|||||||
#set($comment=$column.columnComment)
|
#set($comment=$column.columnComment)
|
||||||
#end
|
#end
|
||||||
$column.javaField: [
|
$column.javaField: [
|
||||||
{ required: true, message: "$comment不能为空", trigger: #if($column.htmlType == "select")"change"#else"blur"#end }
|
{ required: true, message: "$comment不能为空", trigger: #if($column.htmlType == "select" || $column.htmlType == "radio")"change"#else"blur"#end }
|
||||||
]#if($foreach.count != $columns.size()),#end
|
]#if($foreach.count != $columns.size()),#end
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
@ -442,9 +438,7 @@ function cancel() {
|
|||||||
function reset() {
|
function reset() {
|
||||||
form.value = {
|
form.value = {
|
||||||
#foreach ($column in $columns)
|
#foreach ($column in $columns)
|
||||||
#if($column.htmlType == "radio")
|
#if($column.htmlType == "checkbox")
|
||||||
$column.javaField: #if($column.javaType == "Integer" || $column.javaType == "Long")0#else"0"#end#if($foreach.count != $columns.size()),#end
|
|
||||||
#elseif($column.htmlType == "checkbox")
|
|
||||||
$column.javaField: []#if($foreach.count != $columns.size()),#end
|
$column.javaField: []#if($foreach.count != $columns.size()),#end
|
||||||
#else
|
#else
|
||||||
$column.javaField: null#if($foreach.count != $columns.size()),#end
|
$column.javaField: null#if($foreach.count != $columns.size()),#end
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user