Compare commits
No commits in common. "master" and "v2026.03(jdk8/11)" have entirely different histories.
master
...
v2026.03(j
|
|
@ -1,18 +1,11 @@
|
||||||
######################################################################
|
|
||||||
# Build Tools
|
|
||||||
|
|
||||||
.gradle
|
# 查看更多 .gitignore 配置 -> https://help.github.com/articles/ignoring-files/
|
||||||
/build/
|
|
||||||
!gradle/wrapper/gradle-wrapper.jar
|
|
||||||
|
|
||||||
target/
|
target/
|
||||||
!.mvn/wrapper/maven-wrapper.jar
|
!.mvn/wrapper/maven-wrapper.jar
|
||||||
|
|
||||||
.flattened-pom.xml
|
.flattened-pom.xml
|
||||||
|
|
||||||
######################################################################
|
|
||||||
# IDE
|
|
||||||
|
|
||||||
### STS ###
|
### STS ###
|
||||||
.apt_generated
|
.apt_generated
|
||||||
.classpath
|
.classpath
|
||||||
|
|
@ -20,36 +13,63 @@ target/
|
||||||
.project
|
.project
|
||||||
.settings
|
.settings
|
||||||
.springBeans
|
.springBeans
|
||||||
|
.sts4-cache
|
||||||
|
|
||||||
### IntelliJ IDEA ###
|
### IntelliJ IDEA ###
|
||||||
.idea
|
.idea
|
||||||
*.iws
|
*.iws
|
||||||
*.iml
|
*.iml
|
||||||
*.ipr
|
*.ipr
|
||||||
|
*.class
|
||||||
|
target/*
|
||||||
|
|
||||||
### NetBeans ###
|
### NetBeans ###
|
||||||
nbproject/private/
|
/nbproject/private/
|
||||||
build/*
|
/nbbuild/
|
||||||
nbbuild/
|
/dist/
|
||||||
dist/
|
/nbdist/
|
||||||
nbdist/
|
/.nb-gradle/
|
||||||
.nb-gradle/
|
/build/
|
||||||
|
|
||||||
######################################################################
|
|
||||||
# Others
|
|
||||||
*.log
|
|
||||||
*.xml.versionsBackup
|
|
||||||
*.swp
|
|
||||||
|
|
||||||
!*/build/*.java
|
|
||||||
!*/build/*.html
|
|
||||||
!*/build/*.xml
|
|
||||||
|
|
||||||
### JRebel ###
|
### admin-web ###
|
||||||
rebel.xml
|
|
||||||
|
|
||||||
application-my.yaml
|
# dependencies
|
||||||
|
**/node_modules
|
||||||
|
|
||||||
/yudao-ui-app/unpackage/
|
# roadhog-api-doc ignore
|
||||||
|
/src/utils/request-temp.js
|
||||||
|
_roadhog-api-doc
|
||||||
|
|
||||||
|
# production
|
||||||
|
/dist
|
||||||
|
/.vscode
|
||||||
|
|
||||||
|
# misc
|
||||||
.DS_Store
|
.DS_Store
|
||||||
**/.DS_Store
|
npm-debug.log*
|
||||||
|
yarn-error.log
|
||||||
|
|
||||||
|
/coverage
|
||||||
|
.idea
|
||||||
|
yarn.lock
|
||||||
|
package-lock.json
|
||||||
|
*bak
|
||||||
|
.vscode
|
||||||
|
|
||||||
|
# visual studio code
|
||||||
|
.history
|
||||||
|
*.log
|
||||||
|
|
||||||
|
functions/mock
|
||||||
|
.temp/**
|
||||||
|
|
||||||
|
# umi
|
||||||
|
.umi
|
||||||
|
.umi-production
|
||||||
|
|
||||||
|
# screenshot
|
||||||
|
screenshot
|
||||||
|
.firebase
|
||||||
|
sessionStore
|
||||||
|
|
|
||||||
|
Before Width: | Height: | Size: 169 KiB |
|
Before Width: | Height: | Size: 72 KiB |
|
Before Width: | Height: | Size: 62 KiB |
|
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 64 KiB |
|
Before Width: | Height: | Size: 216 KiB |
|
Before Width: | Height: | Size: 54 KiB |
77
README.md
|
|
@ -1,5 +1,5 @@
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<img src="https://img.shields.io/badge/Spring%20Cloud-2021.0.9-blue.svg" alt="Coverage Status">
|
<img src="https://img.shields.io/badge/Spring%20Cloud-2021-blue.svg" alt="Coverage Status">
|
||||||
<img src="https://img.shields.io/badge/Spring%20Boot-2.7.18-blue.svg" alt="Downloads">
|
<img src="https://img.shields.io/badge/Spring%20Boot-2.7.18-blue.svg" alt="Downloads">
|
||||||
<img src="https://img.shields.io/badge/Vue-3.2-blue.svg" alt="Downloads">
|
<img src="https://img.shields.io/badge/Vue-3.2-blue.svg" alt="Downloads">
|
||||||
<img src="https://img.shields.io/github/license/YunaiV/yudao-cloud" alt="Downloads" />
|
<img src="https://img.shields.io/github/license/YunaiV/yudao-cloud" alt="Downloads" />
|
||||||
|
|
@ -26,13 +26,13 @@
|
||||||
|
|
||||||
## 🐰 版本说明
|
## 🐰 版本说明
|
||||||
|
|
||||||
| 版本 | JDK 8 + Spring Boot 2.7 | JDK 17/21 + Spring Boot 3.5 | JDK 25 + Spring Boot 4.x |
|
| 版本 | JDK 8 + Spring Boot 2.7 | JDK 17/21 + Spring Boot 3.2 |
|
||||||
|-----------------------------------------------------------------------|--------------------------------------------------------------------------|--------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------|
|
|-----------------------------------------------------------------------|--------------------------------------------------------------------------|--------------------------------------------------------------------------------------|
|
||||||
| 【完整版】[yudao-cloud](https://gitee.com/zhijiantianya/yudao-cloud) | [`master`](https://gitee.com/zhijiantianya/yudao-cloud/tree/master/) 分支 | [`master-jdk17`](https://gitee.com/zhijiantianya/yudao-cloud/tree/master-jdk17/) 分支 | [`master-jdk25`](https://gitee.com/zhijiantianya/yudao-cloud/tree/master-jdk25/) 分支 |
|
| 【完整版】[yudao-cloud](https://gitee.com/zhijiantianya/yudao-cloud) | [`master`](https://gitee.com/zhijiantianya/yudao-cloud/tree/master/) 分支 | [`master-jdk17`](https://gitee.com/zhijiantianya/yudao-cloud/tree/master-jdk17/) 分支 |
|
||||||
| 【精简版】[yudao-cloud-mini](https://gitee.com/yudaocode/yudao-cloud-mini) | [`master`](https://gitee.com/yudaocode/yudao-cloud-mini/tree/master/) 分支 | [`master-jdk17`](https://gitee.com/yudaocode/yudao-cloud-mini/tree/master-jdk17/) 分支 | [`master-jdk25`](https://gitee.com/yudaocode/yudao-cloud-mini/tree/master-jdk25/) 分支 |
|
| 【精简版】[yudao-cloud-mini](https://gitee.com/yudaocode/yudao-cloud-mini) | [`master`](https://gitee.com/yudaocode/yudao-cloud-mini/tree/master/) 分支 | [`master-jdk17`](https://gitee.com/yudaocode/yudao-cloud-mini/tree/master-jdk17/) 分支 |
|
||||||
|
|
||||||
* 【完整版】:包括系统功能、基础设施、会员中心、数据报表、工作流程、商城系统、微信公众号、CRM、ERP、WMS、MES、IM 即时通讯、AI 大模型、IoT 物联网等功能
|
* 【完整版】:包括系统功能、基础设施、会员中心、数据报表、工作流程、商城系统、微信公众号、CRM、ERP、MES、AI 大模型、IoT 物联网 等功能
|
||||||
* 【精简版】:只包括系统功能、基础设施功能,不包括会员中心、数据报表、工作流程、商城系统、微信公众号、CRM、ERP、WMS、MES、IM 即时通讯、AI 大模型、IoT 物联网等功能
|
* 【精简版】:只包括系统功能、基础设施功能,不包括会员中心、数据报表、工作流程、商城系统、微信公众号、CRM、ERP、MES、AI 大模型、IoT 物联网 等功能
|
||||||
|
|
||||||
可参考 [《迁移文档》](https://cloud.iocoder.cn/migrate-module/) ,只需要 5-10 分钟,即可将【完整版】按需迁移到【精简版】
|
可参考 [《迁移文档》](https://cloud.iocoder.cn/migrate-module/) ,只需要 5-10 分钟,即可将【完整版】按需迁移到【精简版】
|
||||||
|
|
||||||
|
|
@ -46,7 +46,7 @@
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
* Java 后端:`master` 分支为 JDK 8 + Spring Boot 2.7,`master-jdk17` 分支为 JDK 17/21 + Spring Boot 3.5,`master-jdk25` 分支为 JDK 25 + Spring Boot 4.x
|
* Java 后端:`master` 分支为 JDK 8 + Spring Boot 2.7,`master-jdk17` 分支为 JDK 17/21 + Spring Boot 3.2
|
||||||
* 管理后台的电脑端:Vue3 提供 [element-plus](https://gitee.com/yudaocode/yudao-ui-admin-vue3)、[vben(ant-design-vue)](https://gitee.com/yudaocode/yudao-ui-admin-vben) 两个版本,Vue2 提供 [element-ui](https://gitee.com/zhijiantianya/ruoyi-vue-pro/tree/master/yudao-ui-admin) 版本
|
* 管理后台的电脑端:Vue3 提供 [element-plus](https://gitee.com/yudaocode/yudao-ui-admin-vue3)、[vben(ant-design-vue)](https://gitee.com/yudaocode/yudao-ui-admin-vben) 两个版本,Vue2 提供 [element-ui](https://gitee.com/zhijiantianya/ruoyi-vue-pro/tree/master/yudao-ui-admin) 版本
|
||||||
* 管理后台的移动端:采用 [uni-app](https://github.com/dcloudio/uni-app) 方案,一份代码多终端适配,同时支持 APP、小程序、H5!
|
* 管理后台的移动端:采用 [uni-app](https://github.com/dcloudio/uni-app) 方案,一份代码多终端适配,同时支持 APP、小程序、H5!
|
||||||
* 后端采用 Spring Cloud Alibaba 微服务架构,注册中心 + 配置中心 Nacos,定时任务 XXL-Job,服务保障 Sentinel,服务网关 Gateway,分布式事务 Seata
|
* 后端采用 Spring Cloud Alibaba 微服务架构,注册中心 + 配置中心 Nacos,定时任务 XXL-Job,服务保障 Sentinel,服务网关 Gateway,分布式事务 Seata
|
||||||
|
|
@ -105,7 +105,7 @@
|
||||||
|
|
||||||
团队包含专业的项目经理、架构师、前端工程师、后端工程师、测试工程师、运维工程师,可以提供全流程的外包服务。
|
团队包含专业的项目经理、架构师、前端工程师、后端工程师、测试工程师、运维工程师,可以提供全流程的外包服务。
|
||||||
|
|
||||||
项目可以是商城、SCRM 系统、OA 系统、物流系统、ERP 系统、CMS 系统、HIS 系统、支付系统、IM 即时通讯、微信公众号、微信小程序等等。
|
项目可以是商城、SCRM 系统、OA 系统、物流系统、ERP 系统、CMS 系统、HIS 系统、支付系统、IM 聊天、微信公众号、微信小程序等等。
|
||||||
|
|
||||||
## 🐼 内置功能
|
## 🐼 内置功能
|
||||||
|
|
||||||
|
|
@ -115,7 +115,7 @@
|
||||||
|
|
||||||
* 通用模块(必选):系统功能、基础设施
|
* 通用模块(必选):系统功能、基础设施
|
||||||
* 通用模块(可选):工作流程、支付系统、数据报表、会员中心
|
* 通用模块(可选):工作流程、支付系统、数据报表、会员中心
|
||||||
* 业务系统(按需):Mall 电子商城、OA 办公自动化、ERP 企业资源计划系统、WMS 仓库管理系统、CRM 客户关系管理、CMS 内容管理系统、MES 执行制造系统、AI 大模型平台、IoT 物联网系统、IM 即时通讯系统、Mobile 手机移动端、Report 数据大屏
|
* 业务系统(按需):ERP 系统、CRM 系统、MES 系统、商城系统、微信公众号、AI 大模型、IoT 物联网
|
||||||
|
|
||||||
> 友情提示:本项目基于 RuoYi-Vue 修改,**重构优化**后端的代码,**美化**前端的界面。
|
> 友情提示:本项目基于 RuoYi-Vue 修改,**重构优化**后端的代码,**美化**前端的界面。
|
||||||
>
|
>
|
||||||
|
|
@ -273,14 +273,6 @@
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
### WMS 系统
|
|
||||||
|
|
||||||
演示地址:<https://cloud.iocoder.cn/wms-preview/>
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
### CRM 系统
|
### CRM 系统
|
||||||
|
|
||||||
演示地址:<https://cloud.iocoder.cn/crm-preview/>
|
演示地址:<https://cloud.iocoder.cn/crm-preview/>
|
||||||
|
|
@ -311,19 +303,6 @@
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
### IM 即时通讯
|
|
||||||
|
|
||||||
演示地址(Cloud):<https://cloud.iocoder.cn/im-preview/>
|
|
||||||
|
|
||||||
演示地址(Vue3 + Element Plus):<http://dashboard-vue3.yudao.iocoder.cn>
|
|
||||||
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
| 聊天界面 | 聊天管理 |
|
|
||||||
| --- | --- |
|
|
||||||
|  |  |
|
|
||||||
|
|
||||||
## 🐨 技术栈
|
## 🐨 技术栈
|
||||||
|
|
||||||
### 微服务
|
### 微服务
|
||||||
|
|
@ -342,8 +321,6 @@
|
||||||
| `yudao-module-erp` | ERP 系统的 Module 模块 |
|
| `yudao-module-erp` | ERP 系统的 Module 模块 |
|
||||||
| `yudao-module-crm` | CRM 系统的 Module 模块 |
|
| `yudao-module-crm` | CRM 系统的 Module 模块 |
|
||||||
| `yudao-module-mes` | MES 系统的 Module 模块 |
|
| `yudao-module-mes` | MES 系统的 Module 模块 |
|
||||||
| `yudao-module-wms` | WMS 系统的 Module 模块 |
|
|
||||||
| `yudao-module-im` | IM 即时通讯的 Module 模块 |
|
|
||||||
| `yudao-module-ai` | AI 大模型的 Module 模块 |
|
| `yudao-module-ai` | AI 大模型的 Module 模块 |
|
||||||
| `yudao-module-iot` | IoT 物联网的 Module 模块 |
|
| `yudao-module-iot` | IoT 物联网的 Module 模块 |
|
||||||
| `yudao-module-mp` | 微信公众号的 Module 模块 |
|
| `yudao-module-mp` | 微信公众号的 Module 模块 |
|
||||||
|
|
@ -352,32 +329,32 @@
|
||||||
### 框架
|
### 框架
|
||||||
|
|
||||||
| 框架 | 说明 | 版本 | 学习指南 |
|
| 框架 | 说明 | 版本 | 学习指南 |
|
||||||
|---------------------------------------------------------------------------------------------|------------------|----------------|---------------------------------------------------------------------|
|
|---------------------------------------------------------------------------------------------|------------------|------------|---------------------------------------------------------------------|
|
||||||
| [Spring Cloud Alibaba](https://github.com/alibaba/spring-cloud-alibaba) | 微服务框架 | 2021.0.6.2 | [文档](https://github.com/YunaiV/SpringBoot-Labs) |
|
| [Spring Cloud Alibaba](https://github.com/alibaba/spring-cloud-alibaba) | 微服务框架 | 2021.0.4.0 | [文档](https://github.com/YunaiV/SpringBoot-Labs) |
|
||||||
| [Nacos](https://github.com/alibaba/nacos) | 配置中心 & 注册中心 | 2.2.0 | [文档](https://www.iocoder.cn/categories/Nacos/?yudao) |
|
| [Nacos](https://github.com/alibaba/nacos) | 配置中心 & 注册中心 | 2.3.2 | [文档](https://www.iocoder.cn/categories/Nacos/?yudao) |
|
||||||
| [RocketMQ](https://github.com/apache/rocketmq) | 消息队列 | 5.2.0 | [文档](https://www.iocoder.cn/categories/RocketMQ/?yudao) |
|
| [RocketMQ](https://github.com/apache/rocketmq) | 消息队列 | 5.2.0 | [文档](https://www.iocoder.cn/categories/RocketMQ/?yudao) |
|
||||||
| [Sentinel](https://github.com/alibaba/sentinel) | 服务保障 | 1.8.6 | [文档](https://www.iocoder.cn/categories/Sentinel/?yudao) |
|
| [Sentinel](https://github.com/alibaba/sentinel) | 服务保障 | 1.8.6 | [文档](https://www.iocoder.cn/categories/Sentinel/?yudao) |
|
||||||
| [XXL Job](https://github.com/xuxueli/xxl-job) | 定时任务 | 2.4.0 | [文档](https://www.iocoder.cn/XXL-JOB/good-collection/?yudao) |
|
| [XXL Job](https://github.com/xuxueli/xxl-job) | 定时任务 | 2.3.1 | [文档](https://www.iocoder.cn/XXL-JOB/good-collection/?yudao) |
|
||||||
| [Spring Cloud Gateway](https://github.com/spring-cloud/spring-cloud-gateway) | 服务网关 | 3.1.9 | [文档](https://www.iocoder.cn/categories/Spring-Cloud-Gateway/?yudao) |
|
| [Spring Cloud Gateway](https://github.com/spring-cloud/spring-cloud-gateway) | 服务网关 | 3.4.1 | [文档](https://www.iocoder.cn/categories/Spring-Cloud-Gateway/?yudao) |
|
||||||
| [Seata](https://github.com/seata/seata) | 分布式事务 | 1.6.1 | [文档](https://www.iocoder.cn/categories/Seata/?yudao) |
|
| [Seata](https://github.com/seata/seata) | 分布式事务 | 1.6.1 | [文档](https://www.iocoder.cn/categories/Seata/?yudao) |
|
||||||
| [MySQL](https://www.mysql.com/cn/) | 数据库服务器 | 5.7 / 8.0+ | |
|
| [MySQL](https://www.mysql.com/cn/) | 数据库服务器 | 5.7 / 8.0+ | |
|
||||||
| [Druid](https://github.com/alibaba/druid) | JDBC 连接池、监控组件 | 1.2.28 | [文档](http://www.iocoder.cn/Spring-Boot/datasource-pool/?yudao) |
|
| [Druid](https://github.com/alibaba/druid) | JDBC 连接池、监控组件 | 1.2.23 | [文档](http://www.iocoder.cn/Spring-Boot/datasource-pool/?yudao) |
|
||||||
| [MyBatis Plus](https://mp.baomidou.com/) | MyBatis 增强工具包 | 3.5.16 | [文档](http://www.iocoder.cn/Spring-Boot/MyBatis/?yudao) |
|
| [MyBatis Plus](https://mp.baomidou.com/) | MyBatis 增强工具包 | 3.5.7 | [文档](http://www.iocoder.cn/Spring-Boot/MyBatis/?yudao) |
|
||||||
| [Dynamic Datasource](https://dynamic-datasource.com/) | 动态数据源 | 4.5.0 | [文档](http://www.iocoder.cn/Spring-Boot/datasource-pool/?yudao) |
|
| [Dynamic Datasource](https://dynamic-datasource.com/) | 动态数据源 | 4.3.1 | [文档](http://www.iocoder.cn/Spring-Boot/datasource-pool/?yudao) |
|
||||||
| [Redis](https://redis.io/) | key-value 数据库 | 5.0 / 6.0 /7.0 | |
|
| [Redis](https://redis.io/) | key-value 数据库 | 5.0 / 6.0 | |
|
||||||
| [Redisson](https://github.com/redisson/redisson) | Redis 客户端 | 4.6.1 | [文档](http://www.iocoder.cn/Spring-Boot/Redis/?yudao) |
|
| [Redisson](https://github.com/redisson/redisson) | Redis 客户端 | 3.32.0 | [文档](http://www.iocoder.cn/Spring-Boot/Redis/?yudao) |
|
||||||
| [Spring MVC](https://github.com/spring-projects/spring-framework/tree/master/spring-webmvc) | MVC 框架 | 5.3.39 | [文档](http://www.iocoder.cn/SpringMVC/MVC/?yudao) |
|
| [Spring MVC](https://github.com/spring-projects/spring-framework/tree/master/spring-webmvc) | MVC 框架 | 5.3.24 | [文档](http://www.iocoder.cn/SpringMVC/MVC/?yudao) |
|
||||||
| [Spring Security](https://github.com/spring-projects/spring-security) | Spring 安全框架 | 5.8.16 | [文档](http://www.iocoder.cn/Spring-Boot/Spring-Security/?yudao) |
|
| [Spring Security](https://github.com/spring-projects/spring-security) | Spring 安全框架 | 5.7.5 | [文档](http://www.iocoder.cn/Spring-Boot/Spring-Security/?yudao) |
|
||||||
| [Hibernate Validator](https://github.com/hibernate/hibernate-validator) | 参数校验组件 | 6.2.5 | [文档](http://www.iocoder.cn/Spring-Boot/Validation/?yudao) |
|
| [Hibernate Validator](https://github.com/hibernate/hibernate-validator) | 参数校验组件 | 6.2.5 | [文档](http://www.iocoder.cn/Spring-Boot/Validation/?yudao) |
|
||||||
| [Flowable](https://github.com/flowable/flowable-engine) | 工作流引擎 | 6.8.1 | [文档](https://doc.iocoder.cn/bpm/) |
|
| [Flowable](https://github.com/flowable/flowable-engine) | 工作流引擎 | 6.8.0 | [文档](https://doc.iocoder.cn/bpm/) |
|
||||||
| [Knife4j](https://gitee.com/xiaoym/knife4j) | Swagger 增强 UI 实现 | 4.5.0 | [文档](http://www.iocoder.cn/Spring-Boot/Swagger/?yudao) |
|
| [Knife4j](https://gitee.com/xiaoym/knife4j) | Swagger 增强 UI 实现 | 4.5.0 | [文档](http://www.iocoder.cn/Spring-Boot/Swagger/?yudao) |
|
||||||
| [SkyWalking](https://skywalking.apache.org/) | 分布式应用追踪系统 | 8.12.0 | [文档](http://www.iocoder.cn/Spring-Boot/SkyWalking/?yudao) |
|
| [SkyWalking](https://skywalking.apache.org/) | 分布式应用追踪系统 | 8.12.0 | [文档](http://www.iocoder.cn/Spring-Boot/SkyWalking/?yudao) |
|
||||||
| [Spring Boot Admin](https://github.com/codecentric/spring-boot-admin) | Spring Boot 监控平台 | 2.7.15 | [文档](http://www.iocoder.cn/Spring-Boot/Admin/?yudao) |
|
| [Spring Boot Admin](https://github.com/codecentric/spring-boot-admin) | Spring Boot 监控平台 | 2.7.10 | [文档](http://www.iocoder.cn/Spring-Boot/Admin/?yudao) |
|
||||||
| [Jackson](https://github.com/FasterXML/jackson) | JSON 工具库 | 2.13.5 | |
|
| [Jackson](https://github.com/FasterXML/jackson) | JSON 工具库 | 2.13.3 | |
|
||||||
| [MapStruct](https://mapstruct.org/) | Java Bean 转换 | 1.6.3 | [文档](http://www.iocoder.cn/Spring-Boot/MapStruct/?yudao) |
|
| [MapStruct](https://mapstruct.org/) | Java Bean 转换 | 1.6.3 | [文档](http://www.iocoder.cn/Spring-Boot/MapStruct/?yudao) |
|
||||||
| [Lombok](https://projectlombok.org/) | 消除冗长的 Java 代码 | 1.18.46 | [文档](http://www.iocoder.cn/Spring-Boot/Lombok/?yudao) |
|
| [Lombok](https://projectlombok.org/) | 消除冗长的 Java 代码 | 1.18.34 | [文档](http://www.iocoder.cn/Spring-Boot/Lombok/?yudao) |
|
||||||
| [JUnit](https://junit.org/junit5/) | Java 单元测试框架 | 5.8.2 | - |
|
| [JUnit](https://junit.org/junit5/) | Java 单元测试框架 | 5.8.2 | - |
|
||||||
| [Mockito](https://github.com/mockito/mockito) | Java Mock 框架 | 4.11.0 | - |
|
| [Mockito](https://github.com/mockito/mockito) | Java Mock 框架 | 4.8.0 | - |
|
||||||
|
|
||||||
## 🐷 演示图
|
## 🐷 演示图
|
||||||
|
|
||||||
|
|
|
||||||
6
pom.xml
|
|
@ -26,8 +26,6 @@
|
||||||
<module>yudao-module-crm</module>
|
<module>yudao-module-crm</module>
|
||||||
<module>yudao-module-iot</module>
|
<module>yudao-module-iot</module>
|
||||||
<module>yudao-module-mes</module>
|
<module>yudao-module-mes</module>
|
||||||
<module>yudao-module-wms</module>
|
|
||||||
<module>yudao-module-im</module>
|
|
||||||
<!-- 友情提示:基于 Spring AI 实现 LLM 大模型的接入,需要使用 JDK17 版本,详细可见 https://doc.iocoder.cn/ai/build/ -->
|
<!-- 友情提示:基于 Spring AI 实现 LLM 大模型的接入,需要使用 JDK17 版本,详细可见 https://doc.iocoder.cn/ai/build/ -->
|
||||||
<!-- <module>yudao-module-ai</module>-->
|
<!-- <module>yudao-module-ai</module>-->
|
||||||
</modules>
|
</modules>
|
||||||
|
|
@ -37,7 +35,7 @@
|
||||||
<url>https://github.com/YunaiV/ruoyi-vue-pro</url>
|
<url>https://github.com/YunaiV/ruoyi-vue-pro</url>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<revision>2026.05-jdk8-SNAPSHOT</revision>
|
<revision>2026.03-jdk8-SNAPSHOT</revision>
|
||||||
<!-- Maven 相关 -->
|
<!-- Maven 相关 -->
|
||||||
<java.version>1.8</java.version>
|
<java.version>1.8</java.version>
|
||||||
<maven.compiler.source>${java.version}</maven.compiler.source>
|
<maven.compiler.source>${java.version}</maven.compiler.source>
|
||||||
|
|
@ -46,7 +44,7 @@
|
||||||
<maven-compiler-plugin.version>3.14.0</maven-compiler-plugin.version>
|
<maven-compiler-plugin.version>3.14.0</maven-compiler-plugin.version>
|
||||||
<flatten-maven-plugin.version>1.7.2</flatten-maven-plugin.version>
|
<flatten-maven-plugin.version>1.7.2</flatten-maven-plugin.version>
|
||||||
<!-- maven-surefire-plugin 暂时无法通过 bom 的依赖读取(兼容老版本 IDEA 2024 及以前版本) -->
|
<!-- maven-surefire-plugin 暂时无法通过 bom 的依赖读取(兼容老版本 IDEA 2024 及以前版本) -->
|
||||||
<lombok.version>1.18.46</lombok.version>
|
<lombok.version>1.18.42</lombok.version>
|
||||||
<spring.boot.version>2.7.18</spring.boot.version>
|
<spring.boot.version>2.7.18</spring.boot.version>
|
||||||
<mapstruct.version>1.6.3</mapstruct.version>
|
<mapstruct.version>1.6.3</mapstruct.version>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
|
|
||||||
|
|
@ -1,208 +0,0 @@
|
||||||
-- https://github.com/quartz-scheduler/quartz/blob/main/quartz/src/main/resources/org/quartz/impl/jdbcjobstore/tables_postgres.sql
|
|
||||||
-- Thanks to Patrick Lightbody for submitting this...
|
|
||||||
--
|
|
||||||
-- In your Quartz properties file, you'll need to set
|
|
||||||
-- org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.PostgreSQLDelegate
|
|
||||||
|
|
||||||
DROP TABLE IF EXISTS QRTZ_FIRED_TRIGGERS;
|
|
||||||
DROP TABLE IF EXISTS QRTZ_PAUSED_TRIGGER_GRPS;
|
|
||||||
DROP TABLE IF EXISTS QRTZ_SCHEDULER_STATE;
|
|
||||||
DROP TABLE IF EXISTS QRTZ_LOCKS;
|
|
||||||
DROP TABLE IF EXISTS QRTZ_SIMPLE_TRIGGERS;
|
|
||||||
DROP TABLE IF EXISTS QRTZ_CRON_TRIGGERS;
|
|
||||||
DROP TABLE IF EXISTS QRTZ_SIMPROP_TRIGGERS;
|
|
||||||
DROP TABLE IF EXISTS QRTZ_BLOB_TRIGGERS;
|
|
||||||
DROP TABLE IF EXISTS QRTZ_TRIGGERS;
|
|
||||||
DROP TABLE IF EXISTS QRTZ_JOB_DETAILS;
|
|
||||||
DROP TABLE IF EXISTS QRTZ_CALENDARS;
|
|
||||||
|
|
||||||
CREATE TABLE QRTZ_JOB_DETAILS
|
|
||||||
(
|
|
||||||
SCHED_NAME VARCHAR(120) NOT NULL,
|
|
||||||
JOB_NAME VARCHAR(200) NOT NULL,
|
|
||||||
JOB_GROUP VARCHAR(200) NOT NULL,
|
|
||||||
DESCRIPTION VARCHAR(250) NULL,
|
|
||||||
JOB_CLASS_NAME VARCHAR(250) NOT NULL,
|
|
||||||
IS_DURABLE BOOL NOT NULL,
|
|
||||||
IS_NONCONCURRENT BOOL NOT NULL,
|
|
||||||
IS_UPDATE_DATA BOOL NOT NULL,
|
|
||||||
REQUESTS_RECOVERY BOOL NOT NULL,
|
|
||||||
JOB_DATA BYTEA NULL,
|
|
||||||
PRIMARY KEY (SCHED_NAME, JOB_NAME, JOB_GROUP)
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE QRTZ_TRIGGERS
|
|
||||||
(
|
|
||||||
SCHED_NAME VARCHAR(120) NOT NULL,
|
|
||||||
TRIGGER_NAME VARCHAR(200) NOT NULL,
|
|
||||||
TRIGGER_GROUP VARCHAR(200) NOT NULL,
|
|
||||||
JOB_NAME VARCHAR(200) NOT NULL,
|
|
||||||
JOB_GROUP VARCHAR(200) NOT NULL,
|
|
||||||
DESCRIPTION VARCHAR(250) NULL,
|
|
||||||
NEXT_FIRE_TIME BIGINT NULL,
|
|
||||||
PREV_FIRE_TIME BIGINT NULL,
|
|
||||||
PRIORITY INTEGER NULL,
|
|
||||||
TRIGGER_STATE VARCHAR(16) NOT NULL,
|
|
||||||
TRIGGER_TYPE VARCHAR(8) NOT NULL,
|
|
||||||
START_TIME BIGINT NOT NULL,
|
|
||||||
END_TIME BIGINT NULL,
|
|
||||||
CALENDAR_NAME VARCHAR(200) NULL,
|
|
||||||
MISFIRE_INSTR SMALLINT NULL,
|
|
||||||
JOB_DATA BYTEA NULL,
|
|
||||||
PRIMARY KEY (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP),
|
|
||||||
FOREIGN KEY (SCHED_NAME, JOB_NAME, JOB_GROUP)
|
|
||||||
REFERENCES QRTZ_JOB_DETAILS (SCHED_NAME, JOB_NAME, JOB_GROUP)
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE QRTZ_SIMPLE_TRIGGERS
|
|
||||||
(
|
|
||||||
SCHED_NAME VARCHAR(120) NOT NULL,
|
|
||||||
TRIGGER_NAME VARCHAR(200) NOT NULL,
|
|
||||||
TRIGGER_GROUP VARCHAR(200) NOT NULL,
|
|
||||||
REPEAT_COUNT BIGINT NOT NULL,
|
|
||||||
REPEAT_INTERVAL BIGINT NOT NULL,
|
|
||||||
TIMES_TRIGGERED BIGINT NOT NULL,
|
|
||||||
PRIMARY KEY (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP),
|
|
||||||
FOREIGN KEY (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP)
|
|
||||||
REFERENCES QRTZ_TRIGGERS (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP)
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE QRTZ_CRON_TRIGGERS
|
|
||||||
(
|
|
||||||
SCHED_NAME VARCHAR(120) NOT NULL,
|
|
||||||
TRIGGER_NAME VARCHAR(200) NOT NULL,
|
|
||||||
TRIGGER_GROUP VARCHAR(200) NOT NULL,
|
|
||||||
CRON_EXPRESSION VARCHAR(120) NOT NULL,
|
|
||||||
TIME_ZONE_ID VARCHAR(80),
|
|
||||||
PRIMARY KEY (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP),
|
|
||||||
FOREIGN KEY (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP)
|
|
||||||
REFERENCES QRTZ_TRIGGERS (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP)
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE QRTZ_SIMPROP_TRIGGERS
|
|
||||||
(
|
|
||||||
SCHED_NAME VARCHAR(120) NOT NULL,
|
|
||||||
TRIGGER_NAME VARCHAR(200) NOT NULL,
|
|
||||||
TRIGGER_GROUP VARCHAR(200) NOT NULL,
|
|
||||||
STR_PROP_1 VARCHAR(512) NULL,
|
|
||||||
STR_PROP_2 VARCHAR(512) NULL,
|
|
||||||
STR_PROP_3 VARCHAR(512) NULL,
|
|
||||||
INT_PROP_1 INT NULL,
|
|
||||||
INT_PROP_2 INT NULL,
|
|
||||||
LONG_PROP_1 BIGINT NULL,
|
|
||||||
LONG_PROP_2 BIGINT NULL,
|
|
||||||
DEC_PROP_1 NUMERIC(13, 4) NULL,
|
|
||||||
DEC_PROP_2 NUMERIC(13, 4) NULL,
|
|
||||||
BOOL_PROP_1 BOOL NULL,
|
|
||||||
BOOL_PROP_2 BOOL NULL,
|
|
||||||
PRIMARY KEY (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP),
|
|
||||||
FOREIGN KEY (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP)
|
|
||||||
REFERENCES QRTZ_TRIGGERS (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP)
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE QRTZ_BLOB_TRIGGERS
|
|
||||||
(
|
|
||||||
SCHED_NAME VARCHAR(120) NOT NULL,
|
|
||||||
TRIGGER_NAME VARCHAR(200) NOT NULL,
|
|
||||||
TRIGGER_GROUP VARCHAR(200) NOT NULL,
|
|
||||||
BLOB_DATA BYTEA NULL,
|
|
||||||
PRIMARY KEY (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP),
|
|
||||||
FOREIGN KEY (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP)
|
|
||||||
REFERENCES QRTZ_TRIGGERS (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP)
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE QRTZ_CALENDARS
|
|
||||||
(
|
|
||||||
SCHED_NAME VARCHAR(120) NOT NULL,
|
|
||||||
CALENDAR_NAME VARCHAR(200) NOT NULL,
|
|
||||||
CALENDAR BYTEA NOT NULL,
|
|
||||||
PRIMARY KEY (SCHED_NAME, CALENDAR_NAME)
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS
|
|
||||||
(
|
|
||||||
SCHED_NAME VARCHAR(120) NOT NULL,
|
|
||||||
TRIGGER_GROUP VARCHAR(200) NOT NULL,
|
|
||||||
PRIMARY KEY (SCHED_NAME, TRIGGER_GROUP)
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE QRTZ_FIRED_TRIGGERS
|
|
||||||
(
|
|
||||||
SCHED_NAME VARCHAR(120) NOT NULL,
|
|
||||||
ENTRY_ID VARCHAR(95) NOT NULL,
|
|
||||||
TRIGGER_NAME VARCHAR(200) NOT NULL,
|
|
||||||
TRIGGER_GROUP VARCHAR(200) NOT NULL,
|
|
||||||
INSTANCE_NAME VARCHAR(200) NOT NULL,
|
|
||||||
FIRED_TIME BIGINT NOT NULL,
|
|
||||||
SCHED_TIME BIGINT NOT NULL,
|
|
||||||
PRIORITY INTEGER NOT NULL,
|
|
||||||
STATE VARCHAR(16) NOT NULL,
|
|
||||||
JOB_NAME VARCHAR(200) NULL,
|
|
||||||
JOB_GROUP VARCHAR(200) NULL,
|
|
||||||
IS_NONCONCURRENT BOOL NULL,
|
|
||||||
REQUESTS_RECOVERY BOOL NULL,
|
|
||||||
PRIMARY KEY (SCHED_NAME, ENTRY_ID)
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE QRTZ_SCHEDULER_STATE
|
|
||||||
(
|
|
||||||
SCHED_NAME VARCHAR(120) NOT NULL,
|
|
||||||
INSTANCE_NAME VARCHAR(200) NOT NULL,
|
|
||||||
LAST_CHECKIN_TIME BIGINT NOT NULL,
|
|
||||||
CHECKIN_INTERVAL BIGINT NOT NULL,
|
|
||||||
PRIMARY KEY (SCHED_NAME, INSTANCE_NAME)
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE QRTZ_LOCKS
|
|
||||||
(
|
|
||||||
SCHED_NAME VARCHAR(120) NOT NULL,
|
|
||||||
LOCK_NAME VARCHAR(40) NOT NULL,
|
|
||||||
PRIMARY KEY (SCHED_NAME, LOCK_NAME)
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE INDEX IDX_QRTZ_J_REQ_RECOVERY
|
|
||||||
ON QRTZ_JOB_DETAILS (SCHED_NAME, REQUESTS_RECOVERY);
|
|
||||||
CREATE INDEX IDX_QRTZ_J_GRP
|
|
||||||
ON QRTZ_JOB_DETAILS (SCHED_NAME, JOB_GROUP);
|
|
||||||
|
|
||||||
CREATE INDEX IDX_QRTZ_T_J
|
|
||||||
ON QRTZ_TRIGGERS (SCHED_NAME, JOB_NAME, JOB_GROUP);
|
|
||||||
CREATE INDEX IDX_QRTZ_T_JG
|
|
||||||
ON QRTZ_TRIGGERS (SCHED_NAME, JOB_GROUP);
|
|
||||||
CREATE INDEX IDX_QRTZ_T_C
|
|
||||||
ON QRTZ_TRIGGERS (SCHED_NAME, CALENDAR_NAME);
|
|
||||||
CREATE INDEX IDX_QRTZ_T_G
|
|
||||||
ON QRTZ_TRIGGERS (SCHED_NAME, TRIGGER_GROUP);
|
|
||||||
CREATE INDEX IDX_QRTZ_T_STATE
|
|
||||||
ON QRTZ_TRIGGERS (SCHED_NAME, TRIGGER_STATE);
|
|
||||||
CREATE INDEX IDX_QRTZ_T_N_STATE
|
|
||||||
ON QRTZ_TRIGGERS (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP, TRIGGER_STATE);
|
|
||||||
CREATE INDEX IDX_QRTZ_T_N_G_STATE
|
|
||||||
ON QRTZ_TRIGGERS (SCHED_NAME, TRIGGER_GROUP, TRIGGER_STATE);
|
|
||||||
CREATE INDEX IDX_QRTZ_T_NEXT_FIRE_TIME
|
|
||||||
ON QRTZ_TRIGGERS (SCHED_NAME, NEXT_FIRE_TIME);
|
|
||||||
CREATE INDEX IDX_QRTZ_T_NFT_ST
|
|
||||||
ON QRTZ_TRIGGERS (SCHED_NAME, TRIGGER_STATE, NEXT_FIRE_TIME);
|
|
||||||
CREATE INDEX IDX_QRTZ_T_NFT_MISFIRE
|
|
||||||
ON QRTZ_TRIGGERS (SCHED_NAME, MISFIRE_INSTR, NEXT_FIRE_TIME);
|
|
||||||
CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE
|
|
||||||
ON QRTZ_TRIGGERS (SCHED_NAME, MISFIRE_INSTR, NEXT_FIRE_TIME, TRIGGER_STATE);
|
|
||||||
CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE_GRP
|
|
||||||
ON QRTZ_TRIGGERS (SCHED_NAME, MISFIRE_INSTR, NEXT_FIRE_TIME, TRIGGER_GROUP, TRIGGER_STATE);
|
|
||||||
|
|
||||||
CREATE INDEX IDX_QRTZ_FT_TRIG_INST_NAME
|
|
||||||
ON QRTZ_FIRED_TRIGGERS (SCHED_NAME, INSTANCE_NAME);
|
|
||||||
CREATE INDEX IDX_QRTZ_FT_INST_JOB_REQ_RCVRY
|
|
||||||
ON QRTZ_FIRED_TRIGGERS (SCHED_NAME, INSTANCE_NAME, REQUESTS_RECOVERY);
|
|
||||||
CREATE INDEX IDX_QRTZ_FT_J_G
|
|
||||||
ON QRTZ_FIRED_TRIGGERS (SCHED_NAME, JOB_NAME, JOB_GROUP);
|
|
||||||
CREATE INDEX IDX_QRTZ_FT_JG
|
|
||||||
ON QRTZ_FIRED_TRIGGERS (SCHED_NAME, JOB_GROUP);
|
|
||||||
CREATE INDEX IDX_QRTZ_FT_T_G
|
|
||||||
ON QRTZ_FIRED_TRIGGERS (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP);
|
|
||||||
CREATE INDEX IDX_QRTZ_FT_TG
|
|
||||||
ON QRTZ_FIRED_TRIGGERS (SCHED_NAME, TRIGGER_GROUP);
|
|
||||||
|
|
||||||
|
|
||||||
COMMIT;
|
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
Target Server Version : 80200 (8.2.0)
|
Target Server Version : 80200 (8.2.0)
|
||||||
File Encoding : 65001
|
File Encoding : 65001
|
||||||
|
|
||||||
Date: 31/05/2026 22:29:18
|
Date: 18/04/2026 11:02:29
|
||||||
*/
|
*/
|
||||||
|
|
||||||
SET NAMES utf8mb4;
|
SET NAMES utf8mb4;
|
||||||
|
|
@ -49,7 +49,7 @@ CREATE TABLE `infra_api_access_log` (
|
||||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
||||||
PRIMARY KEY (`id`) USING BTREE,
|
PRIMARY KEY (`id`) USING BTREE,
|
||||||
INDEX `idx_create_time`(`create_time` ASC) USING BTREE
|
INDEX `idx_create_time`(`create_time` ASC) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 36301 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'API 访问日志表';
|
) ENGINE = InnoDB AUTO_INCREMENT = 36233 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'API 访问日志表';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of infra_api_access_log
|
-- Records of infra_api_access_log
|
||||||
|
|
@ -92,7 +92,7 @@ CREATE TABLE `infra_api_error_log` (
|
||||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
||||||
PRIMARY KEY (`id`) USING BTREE,
|
PRIMARY KEY (`id`) USING BTREE,
|
||||||
INDEX `idx_create_time`(`create_time` ASC) USING BTREE
|
INDEX `idx_create_time`(`create_time` ASC) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 23958 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '系统异常日志';
|
) ENGINE = InnoDB AUTO_INCREMENT = 23726 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '系统异常日志';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of infra_api_error_log
|
-- Records of infra_api_error_log
|
||||||
|
|
@ -253,7 +253,7 @@ CREATE TABLE `infra_file` (
|
||||||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||||
PRIMARY KEY (`id`) USING BTREE
|
PRIMARY KEY (`id`) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 2233 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '文件表';
|
) ENGINE = InnoDB AUTO_INCREMENT = 2167 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '文件表';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of infra_file
|
-- Records of infra_file
|
||||||
|
|
@ -284,17 +284,17 @@ CREATE TABLE `infra_file_config` (
|
||||||
-- Records of infra_file_config
|
-- Records of infra_file_config
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
BEGIN;
|
BEGIN;
|
||||||
INSERT INTO `infra_file_config` (`id`, `name`, `storage`, `remark`, `master`, `config`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (4, '数据库(示例)', 1, '我是数据库', b'0', '{\"@class\":\"cn.iocoder.yudao.module.infra.framework.file.core.client.db.DBFileClientConfig\",\"domain\":\"http://127.0.0.1:48080\"}', '1', '2022-03-15 23:56:24', '1', '2026-05-17 14:05:15', b'0');
|
INSERT INTO `infra_file_config` (`id`, `name`, `storage`, `remark`, `master`, `config`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (4, '数据库(示例)', 1, '我是数据库', b'0', '{\"@class\":\"cn.iocoder.yudao.module.infra.framework.file.core.client.db.DBFileClientConfig\",\"domain\":\"http://127.0.0.1:48080\"}', '1', '2022-03-15 23:56:24', '1', '2025-11-24 20:57:14', b'0');
|
||||||
INSERT INTO `infra_file_config` (`id`, `name`, `storage`, `remark`, `master`, `config`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (22, '七牛存储器(示例)', 20, '请换成你自己的密钥!!!', b'1', '{\"@class\":\"cn.iocoder.yudao.module.infra.framework.file.core.client.s3.S3FileClientConfig\",\"endpoint\":\"s3.cn-south-1.qiniucs.com\",\"domain\":\"http://test.yudao.iocoder.cn\",\"bucket\":\"ruoyi-vue-pro\",\"accessKey\":\"3TvrJ70gl2Gt6IBe7_IZT1F6i_k0iMuRtyEv4EyS\",\"accessSecret\":\"wd0tbVBYlp0S-ihA8Qg2hPLncoP83wyrIq24OZuY\",\"enablePathStyleAccess\":false,\"enablePublicAccess\":true}', '1', '2024-01-13 22:11:12', '1', '2026-05-17 14:05:15', b'0');
|
INSERT INTO `infra_file_config` (`id`, `name`, `storage`, `remark`, `master`, `config`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (22, '七牛存储器(示例)', 20, '请换成你自己的密钥!!!', b'1', '{\"@class\":\"cn.iocoder.yudao.module.infra.framework.file.core.client.s3.S3FileClientConfig\",\"endpoint\":\"s3.cn-south-1.qiniucs.com\",\"domain\":\"http://test.yudao.iocoder.cn\",\"bucket\":\"ruoyi-vue-pro\",\"accessKey\":\"3TvrJ70gl2Gt6IBe7_IZT1F6i_k0iMuRtyEv4EyS\",\"accessSecret\":\"wd0tbVBYlp0S-ihA8Qg2hPLncoP83wyrIq24OZuY\",\"enablePathStyleAccess\":false,\"enablePublicAccess\":true}', '1', '2024-01-13 22:11:12', '1', '2025-11-24 20:57:14', b'0');
|
||||||
INSERT INTO `infra_file_config` (`id`, `name`, `storage`, `remark`, `master`, `config`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (24, '腾讯云存储(示例)', 20, '请换成你的密钥!!!', b'0', '{\"@class\":\"cn.iocoder.yudao.module.infra.framework.file.core.client.s3.S3FileClientConfig\",\"endpoint\":\"https://cos.ap-shanghai.myqcloud.com\",\"domain\":\"http://tengxun-oss.iocoder.cn\",\"bucket\":\"aoteman-1255880240\",\"accessKey\":\"AKIDAF6WSh1uiIjwqtrOsGSN3WryqTM6cTMt\",\"accessSecret\":\"X\",\"enablePathStyleAccess\":false,\"enablePublicAccess\":true}', '1', '2024-11-09 16:03:22', '1', '2026-05-17 14:05:15', b'0');
|
INSERT INTO `infra_file_config` (`id`, `name`, `storage`, `remark`, `master`, `config`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (24, '腾讯云存储(示例)', 20, '请换成你的密钥!!!', b'0', '{\"@class\":\"cn.iocoder.yudao.module.infra.framework.file.core.client.s3.S3FileClientConfig\",\"endpoint\":\"https://cos.ap-shanghai.myqcloud.com\",\"domain\":\"http://tengxun-oss.iocoder.cn\",\"bucket\":\"aoteman-1255880240\",\"accessKey\":\"AKIDAF6WSh1uiIjwqtrOsGSN3WryqTM6cTMt\",\"accessSecret\":\"X\",\"enablePathStyleAccess\":false,\"enablePublicAccess\":true}', '1', '2024-11-09 16:03:22', '1', '2025-11-24 20:57:14', b'0');
|
||||||
INSERT INTO `infra_file_config` (`id`, `name`, `storage`, `remark`, `master`, `config`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (25, '阿里云存储(示例)', 20, '', b'0', '{\"@class\":\"cn.iocoder.yudao.module.infra.framework.file.core.client.s3.S3FileClientConfig\",\"endpoint\":\"oss-cn-beijing.aliyuncs.com\",\"domain\":\"http://ali-oss.iocoder.cn\",\"bucket\":\"yunai-aoteman\",\"accessKey\":\"LTAI5tEQLgnDyjh3WpNcdMKA\",\"accessSecret\":\"X\",\"enablePathStyleAccess\":false,\"enablePublicAccess\":true}', '1', '2024-11-09 16:47:08', '1', '2026-05-17 14:05:15', b'0');
|
INSERT INTO `infra_file_config` (`id`, `name`, `storage`, `remark`, `master`, `config`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (25, '阿里云存储(示例)', 20, '', b'0', '{\"@class\":\"cn.iocoder.yudao.module.infra.framework.file.core.client.s3.S3FileClientConfig\",\"endpoint\":\"oss-cn-beijing.aliyuncs.com\",\"domain\":\"http://ali-oss.iocoder.cn\",\"bucket\":\"yunai-aoteman\",\"accessKey\":\"LTAI5tEQLgnDyjh3WpNcdMKA\",\"accessSecret\":\"X\",\"enablePathStyleAccess\":false,\"enablePublicAccess\":true}', '1', '2024-11-09 16:47:08', '1', '2025-11-24 20:57:14', b'0');
|
||||||
INSERT INTO `infra_file_config` (`id`, `name`, `storage`, `remark`, `master`, `config`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (26, '火山云存储(示例)', 20, '', b'0', '{\"@class\":\"cn.iocoder.yudao.module.infra.framework.file.core.client.s3.S3FileClientConfig\",\"endpoint\":\"tos-s3-cn-beijing.volces.com\",\"domain\":null,\"bucket\":\"yunai\",\"accessKey\":\"AKLTZjc3Zjc4MzZmMjU3NDk0ZTgxYmIyMmFkNTIwMDI1ZGE\",\"accessSecret\":\"X==\",\"enablePathStyleAccess\":false,\"enablePublicAccess\":true}', '1', '2024-11-09 16:56:42', '1', '2026-05-17 14:05:15', b'0');
|
INSERT INTO `infra_file_config` (`id`, `name`, `storage`, `remark`, `master`, `config`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (26, '火山云存储(示例)', 20, '', b'0', '{\"@class\":\"cn.iocoder.yudao.module.infra.framework.file.core.client.s3.S3FileClientConfig\",\"endpoint\":\"tos-s3-cn-beijing.volces.com\",\"domain\":null,\"bucket\":\"yunai\",\"accessKey\":\"AKLTZjc3Zjc4MzZmMjU3NDk0ZTgxYmIyMmFkNTIwMDI1ZGE\",\"accessSecret\":\"X==\",\"enablePathStyleAccess\":false,\"enablePublicAccess\":true}', '1', '2024-11-09 16:56:42', '1', '2025-11-24 20:57:14', b'0');
|
||||||
INSERT INTO `infra_file_config` (`id`, `name`, `storage`, `remark`, `master`, `config`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (27, '华为云存储(示例)', 20, '', b'0', '{\"@class\":\"cn.iocoder.yudao.module.infra.framework.file.core.client.s3.S3FileClientConfig\",\"endpoint\":\"obs.cn-east-3.myhuaweicloud.com\",\"domain\":\"\",\"bucket\":\"yudao\",\"accessKey\":\"PVDONDEIOTW88LF8DC4U\",\"accessSecret\":\"X\",\"enablePathStyleAccess\":false,\"enablePublicAccess\":true}', '1', '2024-11-09 17:18:41', '1', '2026-05-17 14:05:15', b'0');
|
INSERT INTO `infra_file_config` (`id`, `name`, `storage`, `remark`, `master`, `config`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (27, '华为云存储(示例)', 20, '', b'0', '{\"@class\":\"cn.iocoder.yudao.module.infra.framework.file.core.client.s3.S3FileClientConfig\",\"endpoint\":\"obs.cn-east-3.myhuaweicloud.com\",\"domain\":\"\",\"bucket\":\"yudao\",\"accessKey\":\"PVDONDEIOTW88LF8DC4U\",\"accessSecret\":\"X\",\"enablePathStyleAccess\":false,\"enablePublicAccess\":true}', '1', '2024-11-09 17:18:41', '1', '2025-11-24 20:57:14', b'0');
|
||||||
INSERT INTO `infra_file_config` (`id`, `name`, `storage`, `remark`, `master`, `config`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (28, 'MinIO 存储(示例)', 20, '', b'0', '{\"@class\":\"cn.iocoder.yudao.module.infra.framework.file.core.client.s3.S3FileClientConfig\",\"endpoint\":\"http://127.0.0.1:9000\",\"domain\":\"http://127.0.0.1:9000/yudao\",\"bucket\":\"yudao\",\"accessKey\":\"admin\",\"accessSecret\":\"password\",\"enablePathStyleAccess\":false,\"enablePublicAccess\":true}', '1', '2024-11-09 17:43:10', '1', '2026-05-17 14:05:15', b'0');
|
INSERT INTO `infra_file_config` (`id`, `name`, `storage`, `remark`, `master`, `config`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (28, 'MinIO 存储(示例)', 20, '', b'0', '{\"@class\":\"cn.iocoder.yudao.module.infra.framework.file.core.client.s3.S3FileClientConfig\",\"endpoint\":\"http://127.0.0.1:9000\",\"domain\":\"http://127.0.0.1:9000/yudao\",\"bucket\":\"yudao\",\"accessKey\":\"admin\",\"accessSecret\":\"password\",\"enablePathStyleAccess\":false,\"enablePublicAccess\":true}', '1', '2024-11-09 17:43:10', '1', '2025-11-24 20:57:14', b'0');
|
||||||
INSERT INTO `infra_file_config` (`id`, `name`, `storage`, `remark`, `master`, `config`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (29, '本地存储(示例)', 10, 'mac/linux 使用 /,windows 使用 \\', b'0', '{\"@class\":\"cn.iocoder.yudao.module.infra.framework.file.core.client.local.LocalFileClientConfig\",\"basePath\":\"/Users/yunai/tmp/file\",\"domain\":\"http://127.0.0.1:48080\"}', '1', '2025-05-02 11:25:45', '1', '2026-05-17 14:05:15', b'0');
|
INSERT INTO `infra_file_config` (`id`, `name`, `storage`, `remark`, `master`, `config`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (29, '本地存储(示例)', 10, 'mac/linux 使用 /,windows 使用 \\', b'0', '{\"@class\":\"cn.iocoder.yudao.module.infra.framework.file.core.client.local.LocalFileClientConfig\",\"basePath\":\"/Users/yunai/tmp/file\",\"domain\":\"http://127.0.0.1:48080\"}', '1', '2025-05-02 11:25:45', '1', '2025-11-24 20:57:14', b'0');
|
||||||
INSERT INTO `infra_file_config` (`id`, `name`, `storage`, `remark`, `master`, `config`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (30, 'SFTP 存储(示例)', 12, '', b'0', '{\"@class\":\"cn.iocoder.yudao.module.infra.framework.file.core.client.sftp.SftpFileClientConfig\",\"basePath\":\"/upload\",\"domain\":\"http://127.0.0.1:48080\",\"host\":\"127.0.0.1\",\"port\":2222,\"username\":\"foo\",\"password\":\"pass\"}', '1', '2025-05-02 16:34:10', '1', '2026-05-17 14:05:15', b'0');
|
INSERT INTO `infra_file_config` (`id`, `name`, `storage`, `remark`, `master`, `config`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (30, 'SFTP 存储(示例)', 12, '', b'0', '{\"@class\":\"cn.iocoder.yudao.module.infra.framework.file.core.client.sftp.SftpFileClientConfig\",\"basePath\":\"/upload\",\"domain\":\"http://127.0.0.1:48080\",\"host\":\"127.0.0.1\",\"port\":2222,\"username\":\"foo\",\"password\":\"pass\"}', '1', '2025-05-02 16:34:10', '1', '2025-11-24 20:57:14', b'0');
|
||||||
INSERT INTO `infra_file_config` (`id`, `name`, `storage`, `remark`, `master`, `config`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (34, '七牛云存储【私有】(示例)', 20, '请换成你自己的密钥!!!', b'0', '{\"@class\":\"cn.iocoder.yudao.module.infra.framework.file.core.client.s3.S3FileClientConfig\",\"endpoint\":\"s3.cn-south-1.qiniucs.com\",\"domain\":\"http://t151glocd.hn-bkt.clouddn.com\",\"bucket\":\"ruoyi-vue-pro-private\",\"accessKey\":\"3TvrJ70gl2Gt6IBe7_IZT1F6i_k0iMuRtyEv4EyS\",\"accessSecret\":\"wd0tbVBYlp0S-ihA8Qg2hPLncoP83wyrIq24OZuY\",\"enablePathStyleAccess\":false,\"enablePublicAccess\":false}', '1', '2025-08-17 21:22:00', '1', '2026-05-17 14:05:15', b'0');
|
INSERT INTO `infra_file_config` (`id`, `name`, `storage`, `remark`, `master`, `config`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (34, '七牛云存储【私有】(示例)', 20, '请换成你自己的密钥!!!', b'0', '{\"@class\":\"cn.iocoder.yudao.module.infra.framework.file.core.client.s3.S3FileClientConfig\",\"endpoint\":\"s3.cn-south-1.qiniucs.com\",\"domain\":\"http://t151glocd.hn-bkt.clouddn.com\",\"bucket\":\"ruoyi-vue-pro-private\",\"accessKey\":\"3TvrJ70gl2Gt6IBe7_IZT1F6i_k0iMuRtyEv4EyS\",\"accessSecret\":\"wd0tbVBYlp0S-ihA8Qg2hPLncoP83wyrIq24OZuY\",\"enablePathStyleAccess\":false,\"enablePublicAccess\":false}', '1', '2025-08-17 21:22:00', '1', '2025-11-24 20:57:14', b'0');
|
||||||
INSERT INTO `infra_file_config` (`id`, `name`, `storage`, `remark`, `master`, `config`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (35, '1', 20, '1', b'0', '{\"@class\":\"cn.iocoder.yudao.module.infra.framework.file.core.client.s3.S3FileClientConfig\",\"endpoint\":\"http://www.baidu.com\",\"domain\":\"http://www.xxx.com\",\"bucket\":\"1\",\"accessKey\":\"2\",\"accessSecret\":\"3\",\"enablePathStyleAccess\":false,\"enablePublicAccess\":false,\"region\":\"1\"}', '1', '2025-10-02 14:32:12', '1', '2026-05-17 14:05:15', b'0');
|
INSERT INTO `infra_file_config` (`id`, `name`, `storage`, `remark`, `master`, `config`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (35, '1', 20, '1', b'0', '{\"@class\":\"cn.iocoder.yudao.module.infra.framework.file.core.client.s3.S3FileClientConfig\",\"endpoint\":\"http://www.baidu.com\",\"domain\":\"http://www.xxx.com\",\"bucket\":\"1\",\"accessKey\":\"2\",\"accessSecret\":\"3\",\"enablePathStyleAccess\":false,\"enablePublicAccess\":false,\"region\":\"1\"}', '1', '2025-10-02 14:32:12', '1', '2025-11-29 15:59:39', b'0');
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
|
|
@ -313,7 +313,7 @@ CREATE TABLE `infra_file_content` (
|
||||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||||
PRIMARY KEY (`id`) USING BTREE,
|
PRIMARY KEY (`id`) USING BTREE,
|
||||||
INDEX `idx_config_id_path`(`config_id` ASC, `path` ASC) USING BTREE
|
INDEX `idx_config_id_path`(`config_id` ASC, `path` ASC) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 288 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '文件表';
|
) ENGINE = InnoDB AUTO_INCREMENT = 286 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '文件表';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of infra_file_content
|
-- Records of infra_file_content
|
||||||
|
|
@ -462,7 +462,7 @@ CREATE TABLE `system_dict_data` (
|
||||||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||||
PRIMARY KEY (`id`) USING BTREE
|
PRIMARY KEY (`id`) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 1061122 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '字典数据表';
|
) ENGINE = InnoDB AUTO_INCREMENT = 3449 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '字典数据表';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of system_dict_data
|
-- Records of system_dict_data
|
||||||
|
|
@ -1095,8 +1095,6 @@ INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `st
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3034, 1, 'ttt', 'tt', 'iot_ota_task_record_status', 0, 'success', '', NULL, '1', '2025-09-06 00:02:21', '1', '2025-09-06 00:02:31', b'0');
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3034, 1, 'ttt', 'tt', 'iot_ota_task_record_status', 0, 'success', '', NULL, '1', '2025-09-06 00:02:21', '1', '2025-09-06 00:02:31', b'0');
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3035, 40, '支付宝小程序', '40', 'system_social_type', 0, '', '', '', '1', '2023-11-04 13:05:38', '1', '2023-11-04 13:07:16', b'0');
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3035, 40, '支付宝小程序', '40', 'system_social_type', 0, '', '', '', '1', '2023-11-04 13:05:38', '1', '2023-11-04 13:07:16', b'0');
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3036, 60, 'Admin Uniapp 移动端', '60', 'infra_codegen_front_type', 0, '', '', NULL, '1', '2025-12-16 19:25:51', '1', '2025-12-17 09:46:15', b'0');
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3036, 60, 'Admin Uniapp 移动端', '60', 'infra_codegen_front_type', 0, '', '', NULL, '1', '2025-12-16 19:25:51', '1', '2025-12-17 09:46:15', b'0');
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3037, 42, 'Vben5.0 Antdv Next Schema 模版', '42', 'infra_codegen_front_type', 0, '', '', '', '1', '2026-05-23 13:52:25', '1', '2026-05-23 13:52:25', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3038, 43, 'Vben5.0 Antdv Next 标准模版', '43', 'infra_codegen_front_type', 0, '', '', '', '1', '2026-05-23 13:52:25', '1', '2026-05-23 13:52:25', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3040, 1, 'UDP', 'udp', 'iot_protocol_type', 0, '', '', 'UDP 协议', '1', '2026-02-04 00:32:47', '1', '2026-02-04 00:32:47', b'0');
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3040, 1, 'UDP', 'udp', 'iot_protocol_type', 0, '', '', 'UDP 协议', '1', '2026-02-04 00:32:47', '1', '2026-02-04 00:32:47', b'0');
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3041, 2, 'WebSocket', 'websocket', 'iot_protocol_type', 0, '', '', 'WebSocket 协议', '1', '2026-02-04 00:32:55', '1', '2026-02-04 00:32:55', b'0');
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3041, 2, 'WebSocket', 'websocket', 'iot_protocol_type', 0, '', '', 'WebSocket 协议', '1', '2026-02-04 00:32:55', '1', '2026-02-04 00:32:55', b'0');
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3042, 3, 'HTTP', 'http', 'iot_protocol_type', 0, '', '', 'HTTP 协议', '1', '2026-02-04 00:32:55', '1', '2026-02-04 00:32:55', b'0');
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3042, 3, 'HTTP', 'http', 'iot_protocol_type', 0, '', '', 'HTTP 协议', '1', '2026-02-04 00:32:55', '1', '2026-02-04 00:32:55', b'0');
|
||||||
|
|
@ -1369,116 +1367,19 @@ INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `st
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3426, 3, '待上架', '3', 'mes_wm_return_sales_status', 0, 'primary', '', '', '1', '2026-04-03 17:20:25', '1', '2026-04-03 17:20:25', b'0');
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3426, 3, '待上架', '3', 'mes_wm_return_sales_status', 0, 'primary', '', '', '1', '2026-04-03 17:20:25', '1', '2026-04-03 17:20:25', b'0');
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3427, 4, '已完成', '4', 'mes_wm_return_sales_status', 0, 'success', '', '', '1', '2026-04-03 17:20:25', '1', '2026-04-03 17:20:25', b'0');
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3427, 4, '已完成', '4', 'mes_wm_return_sales_status', 0, 'success', '', '', '1', '2026-04-03 17:20:25', '1', '2026-04-03 17:20:25', b'0');
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3428, 5, '已取消', '5', 'mes_wm_return_sales_status', 0, 'danger', '', '', '1', '2026-04-03 17:20:25', '1', '2026-04-03 17:20:25', b'0');
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3428, 5, '已取消', '5', 'mes_wm_return_sales_status', 0, 'danger', '', '', '1', '2026-04-03 17:20:25', '1', '2026-04-03 17:20:25', b'0');
|
||||||
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3429, 1, '尺寸', '1', 'mes_defect_type', 0, '', '', '', '1', '2026-04-04 12:49:51', '1', '2026-04-09 15:03:20', b'0');
|
||||||
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3430, 2, '外观', '2', 'mes_defect_type', 0, '', '', '', '1', '2026-04-04 12:49:51', '1', '2026-04-09 15:03:20', b'0');
|
||||||
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3431, 3, '重量', '3', 'mes_defect_type', 0, '', '', '', '1', '2026-04-04 12:49:51', '1', '2026-04-09 15:03:20', b'0');
|
||||||
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3432, 4, '性能', '4', 'mes_defect_type', 0, '', '', '', '1', '2026-04-04 12:49:51', '1', '2026-04-09 15:03:20', b'0');
|
||||||
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3433, 5, '成分', '5', 'mes_defect_type', 0, '', '', '', '1', '2026-04-04 12:49:51', '1', '2026-04-09 15:03:20', b'0');
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3436, 1, '上工', '1', 'mes_pro_work_record_type', 0, 'success', '', '', '1', '2026-04-05 14:07:27', '1', '2026-04-05 14:07:27', b'0');
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3436, 1, '上工', '1', 'mes_pro_work_record_type', 0, 'success', '', '', '1', '2026-04-05 14:07:27', '1', '2026-04-05 14:07:27', b'0');
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3437, 2, '下工', '2', 'mes_pro_work_record_type', 0, 'danger', '', '', '1', '2026-04-05 14:07:27', '1', '2026-04-05 14:07:27', b'0');
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3437, 2, '下工', '2', 'mes_pro_work_record_type', 0, 'danger', '', '', '1', '2026-04-05 14:07:27', '1', '2026-04-05 14:07:27', b'0');
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3443, 1, '草稿', '0', 'mes_wm_product_produce_status', 0, 'info', '', '草稿状态', '1', '2026-04-05 15:53:46', '1', '2026-04-05 15:53:46', b'0');
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3443, 1, '草稿', '0', 'mes_wm_product_produce_status', 0, 'info', '', '草稿状态', '1', '2026-04-05 15:53:46', '1', '2026-04-05 15:53:46', b'0');
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3444, 2, '已完成', '4', 'mes_wm_product_produce_status', 0, 'success', '', '已完成状态', '1', '2026-04-05 15:53:46', '1', '2026-04-05 15:53:46', b'0');
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3444, 2, '已完成', '4', 'mes_wm_product_produce_status', 0, 'success', '', '已完成状态', '1', '2026-04-05 15:53:46', '1', '2026-04-05 15:53:46', b'0');
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3445, 3, '已取消', '5', 'mes_wm_product_produce_status', 0, 'danger', '', '已取消状态', '1', '2026-04-05 15:53:46', '1', '2026-04-05 15:53:46', b'0');
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3445, 3, '已取消', '5', 'mes_wm_product_produce_status', 0, 'danger', '', '已取消状态', '1', '2026-04-05 15:53:46', '1', '2026-04-05 15:53:46', b'0');
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3446, 0, '草稿', '0', 'mes_pro_task_status', 0, '', '', NULL, '1', '2026-04-16 09:47:00', '1', '2026-04-16 09:47:00', b'0');
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3446, 0, 'è‰ç¨¿', '0', 'mes_pro_task_status', 0, '', '', NULL, '1', '2026-04-16 09:47:00', '1', '2026-04-16 09:47:00', b'0');
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3447, 1, '已完成', '4', 'mes_pro_task_status', 0, '', '', NULL, '1', '2026-04-16 09:47:00', '1', '2026-04-16 09:47:00', b'0');
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3447, 1, '已完æˆ', '4', 'mes_pro_task_status', 0, '', '', NULL, '1', '2026-04-16 09:47:00', '1', '2026-04-16 09:47:00', b'0');
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3448, 2, '已取消', '5', 'mes_pro_task_status', 0, '', '', NULL, '1', '2026-04-16 09:47:00', '1', '2026-04-16 09:47:00', b'0');
|
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3448, 2, '已喿¶ˆ', '5', 'mes_pro_task_status', 0, '', '', NULL, '1', '2026-04-16 09:47:00', '1', '2026-04-16 09:47:00', b'0');
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3525, 1, '正常', '0', 'im_message_status', 0, 'success', '', '正常(初始状态)', 'admin', '2026-04-30 15:14:36', 'admin', '2026-04-30 15:14:36', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3526, 2, '已撤回', '2', 'im_message_status', 0, 'danger', '', '已撤回', 'admin', '2026-04-30 15:14:36', 'admin', '2026-04-30 15:14:36', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3530, 1, '不需要回执', '0', 'im_message_receipt_status', 0, 'info', '', 'NO_RECEIPT', 'admin', '2026-04-30 11:35:07', 'admin', '2026-04-30 11:35:07', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3531, 2, '待完成', '1', 'im_message_receipt_status', 0, 'warning', '', 'PENDING', 'admin', '2026-04-30 11:35:07', 'admin', '2026-04-30 11:35:07', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3532, 3, '已完成', '2', 'im_message_receipt_status', 0, 'success', '', 'DONE', 'admin', '2026-04-30 11:35:07', 'admin', '2026-04-30 11:35:07', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3540, 1, '正常', '0', 'im_friend_status', 0, 'success', '', '正常好友关系', 'admin', '2026-04-30 11:35:07', 'admin', '2026-04-30 11:35:07', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3541, 2, '已删除', '1', 'im_friend_status', 0, 'danger', '', '已删除好友关系', 'admin', '2026-04-30 11:35:07', 'admin', '2026-04-30 11:35:07', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3550, 1, '正常', '0', 'im_group_status', 0, 'success', '', '群正常', 'admin', '2026-04-30 11:35:07', 'admin', '2026-04-30 11:35:07', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3551, 2, '已解散', '1', 'im_group_status', 0, 'info', '', '群已解散', 'admin', '2026-04-30 11:35:07', 'admin', '2026-04-30 11:35:07', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3552, 1, '群主', '1', 'im_group_member_role', 0, 'primary', '', NULL, '1', '2026-05-02 02:14:12', '1', '2026-05-02 02:14:12', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3553, 2, '管理员', '2', 'im_group_member_role', 0, 'warning', '', NULL, '1', '2026-05-02 02:14:12', '1', '2026-05-02 02:14:12', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3554, 3, '普通成员', '3', 'im_group_member_role', 0, 'info', '', NULL, '1', '2026-05-02 02:14:12', '1', '2026-05-02 02:14:12', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3555, 1, '搜索', '1', 'im_friend_add_source', 0, 'default', '', NULL, '1', '2026-05-04 02:43:41', '1', '2026-05-05 11:46:57', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3556, 2, '群聊', '2', 'im_friend_add_source', 0, 'default', '', NULL, '1', '2026-05-04 02:43:41', '1', '2026-05-05 11:46:53', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3557, 3, '扫码', '3', 'im_friend_add_source', 0, 'default', '', NULL, '1', '2026-05-04 02:43:41', '1', '2026-05-05 11:46:50', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3558, 4, '名片', '4', 'im_friend_add_source', 0, 'default', '', NULL, '1', '2026-05-04 02:43:41', '1', '2026-05-05 11:46:48', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3559, 1, '等待验证', '0', 'im_friend_request_handle_result', 0, 'warning', '', NULL, '1', '2026-05-04 02:43:41', '1', '2026-05-04 02:43:41', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3560, 2, '已添加', '1', 'im_friend_request_handle_result', 0, 'success', '', NULL, '1', '2026-05-04 02:43:41', '1', '2026-05-04 02:43:41', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3561, 3, '已拒绝', '2', 'im_friend_request_handle_result', 0, 'info', '', NULL, '1', '2026-05-04 02:43:41', '1', '2026-05-04 02:43:41', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3562, 101, '文本', '101', 'im_content_type', 0, '', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3563, 102, '图片', '102', 'im_content_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3564, 103, '语音', '103', 'im_content_type', 0, 'warning', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3565, 104, '视频', '104', 'im_content_type', 0, 'warning', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3566, 105, '文件', '105', 'im_content_type', 0, 'info', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3568, 2101, '撤回', '2101', 'im_content_type', 0, 'danger', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3569, 2200, '回执', '2200', 'im_content_type', 0, 'warning', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3570, 2201, '已读', '2201', 'im_content_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3571, 1501, '群创建', '1501', 'im_content_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3572, 1502, '群信息变更', '1502', 'im_content_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3573, 1503, '入群申请', '1503', 'im_content_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3574, 1504, '成员退群', '1504', 'im_content_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3575, 1505, '入群申请通过', '1505', 'im_content_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3576, 1506, '入群申请拒绝', '1506', 'im_content_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3577, 1507, '群主转让', '1507', 'im_content_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3578, 1508, '成员被移出', '1508', 'im_content_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3579, 1509, '成员加入', '1509', 'im_content_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3580, 1510, '自由进群', '1510', 'im_content_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3581, 1511, '群解散', '1511', 'im_content_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3582, 1512, '成员禁言', '1512', 'im_content_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3583, 1513, '成员取消禁言', '1513', 'im_content_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3584, 1514, '全群禁言', '1514', 'im_content_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3585, 1515, '全群取消禁言', '1515', 'im_content_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3586, 1516, '成员昵称变更', '1516', 'im_content_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3587, 1517, '添加管理员', '1517', 'im_content_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3588, 1518, '撤销管理员', '1518', 'im_content_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3589, 1519, '群公告变更', '1519', 'im_content_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3590, 1520, '群名变更', '1520', 'im_content_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3591, 1531, '群消息置顶', '1531', 'im_content_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3592, 1532, '群消息取消置顶', '1532', 'im_content_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3593, 1533, '群封禁变更', '1533', 'im_content_type', 0, 'success', '', NULL, 'admin', '2026-05-05 11:52:30', 'admin', '2026-05-05 11:52:30', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3594, 1204, '新增好友', '1204', 'im_content_type', 0, 'success', '', NULL, 'admin', '2026-05-05 13:26:53', 'admin', '2026-05-05 13:26:53', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3595, 1205, '好友被删除', '1205', 'im_content_type', 0, 'warning', '', NULL, 'admin', '2026-05-05 13:26:53', 'admin', '2026-05-05 13:26:53', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3596, 1, '搜索', '1', 'im_group_add_source', 0, '', '', NULL, '', '2026-05-06 09:26:36', '', '2026-05-06 09:26:36', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3597, 2, '邀请', '2', 'im_group_add_source', 0, '', '', NULL, '', '2026-05-06 09:26:36', '', '2026-05-06 09:26:36', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3598, 3, '扫码', '3', 'im_group_add_source', 0, '', '', NULL, '', '2026-05-06 09:26:36', '', '2026-05-06 09:26:36', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3599, 4, '分享链接', '4', 'im_group_add_source', 0, '', '', NULL, '', '2026-05-06 09:26:36', '', '2026-05-06 09:26:36', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3600, 1, '未处理', '0', 'im_group_request_handle_result', 0, '', '', NULL, '', '2026-05-06 09:26:36', '', '2026-05-06 09:26:36', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3601, 2, '同意', '1', 'im_group_request_handle_result', 0, '', '', NULL, '', '2026-05-06 09:26:36', '', '2026-05-06 09:26:36', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3602, 3, '拒绝', '2', 'im_group_request_handle_result', 0, '', '', NULL, '', '2026-05-06 09:26:36', '', '2026-05-06 09:26:36', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1061051, 1, '客户', '1', 'merchant_type', 0, 'primary', '', '客户', '1', '2026-05-10 15:26:09', '1', '2026-05-10 15:26:09', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1061052, 2, '供应商', '2', 'merchant_type', 0, 'success', '', '供应商', '1', '2026-05-10 15:26:09', '1', '2026-05-10 15:26:09', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1061053, 3, '客户/供应商', '3', 'merchant_type', 0, 'warning', '', '客户/供应商', '1', '2026-05-10 15:26:09', '1', '2026-05-10 15:26:09', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1061061, 1, '入库单', '1', 'wms_order_type', 0, 'success', '', '', '1', '2026-05-10 17:51:46', '1', '2026-05-14 08:14:09', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1061062, 2, '出库单', '2', 'wms_order_type', 0, 'danger', '', '', '1', '2026-05-10 17:51:46', '1', '2026-05-14 08:14:09', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1061063, 3, '移库单', '3', 'wms_order_type', 0, 'primary', '', '', '1', '2026-05-10 17:51:46', '1', '2026-05-14 08:14:09', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1061064, 4, '盘库单', '4', 'wms_order_type', 0, 'warning', '', '', '1', '2026-05-10 17:51:46', '1', '2026-05-14 08:14:09', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1061071, 1, '草稿', '0', 'wms_order_status', 0, 'info', '', '草稿', '1', '2026-05-12 13:40:29', '1', '2026-05-12 13:40:29', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1061072, 2, '已完成', '4', 'wms_order_status', 0, 'success', '', '已完成', '1', '2026-05-12 13:40:29', '1', '2026-05-12 13:40:29', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1061073, 3, '已作废', '5', 'wms_order_status', 0, 'danger', '', '已作废', '1', '2026-05-12 13:40:29', '1', '2026-05-12 13:40:29', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1061081, 1, '生产入库', '100', 'wms_receipt_order_type', 0, 'success', '', '', '1', '2026-05-11 11:21:49', '1', '2026-05-14 02:21:20', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1061082, 2, '采购入库', '101', 'wms_receipt_order_type', 0, 'primary', '', '', '1', '2026-05-11 11:21:49', '1', '2026-05-14 02:21:20', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1061083, 3, '退货入库', '102', 'wms_receipt_order_type', 0, 'warning', '', '', '1', '2026-05-11 11:21:49', '1', '2026-05-14 02:21:20', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1061084, 4, '归还入库', '103', 'wms_receipt_order_type', 0, 'info', '', '', '1', '2026-05-13 16:02:33', '1', '2026-05-14 02:21:20', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1061091, 1, '退货出库', '200', 'wms_shipment_order_type', 0, 'warning', '', '退货出库', '1', '2026-05-12 17:48:35', '1', '2026-05-12 17:48:35', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1061092, 2, '销售出库', '201', 'wms_shipment_order_type', 0, 'primary', '', '销售出库', '1', '2026-05-12 17:48:35', '1', '2026-05-12 17:48:35', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1061093, 3, '生产出库', '202', 'wms_shipment_order_type', 0, 'success', '', '生产出库', '1', '2026-05-12 17:48:35', '1', '2026-05-12 17:48:35', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1061096, 1, '语音', '1', 'im_rtc_call_media_type', 0, '', '', '语音通话', 'admin', '2026-05-16 11:34:50', 'admin', '2026-05-16 11:34:50', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1061097, 2, '视频', '2', 'im_rtc_call_media_type', 0, '', '', '视频通话', 'admin', '2026-05-16 11:34:50', 'admin', '2026-05-16 11:34:50', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1061098, 1, '私聊', '1', 'im_rtc_call_conversation_type', 0, 'primary', '', '一对一私聊通话', 'admin', '2026-05-18 03:36:12', 'admin', '2026-05-18 03:36:12', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1061099, 2, '群聊', '2', 'im_rtc_call_conversation_type', 0, 'success', '', '群内多人通话', 'admin', '2026-05-18 03:36:12', 'admin', '2026-05-18 03:36:12', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1061100, 1, '创建', '10', 'im_rtc_call_status', 0, 'info', '', '通话已创建,等待接通', 'admin', '2026-05-18 03:36:12', 'admin', '2026-05-18 03:36:12', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1061101, 2, '进行中', '20', 'im_rtc_call_status', 0, 'primary', '', '已有人接通,通话中', 'admin', '2026-05-18 03:36:12', 'admin', '2026-05-18 03:36:12', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1061102, 3, '已结束', '30', 'im_rtc_call_status', 0, 'success', '', '通话结束', 'admin', '2026-05-18 03:36:12', 'admin', '2026-05-18 03:36:12', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1061103, 1, '通话结束', '1', 'im_rtc_call_end_reason', 0, 'success', '', '接通后任一方主动挂断', 'admin', '2026-05-18 03:36:12', 'admin', '2026-05-18 03:36:12', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1061104, 2, '已拒绝', '2', 'im_rtc_call_end_reason', 0, 'warning', '', '被叫接通前点拒接', 'admin', '2026-05-18 03:36:12', 'admin', '2026-05-18 03:36:12', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1061105, 3, '已取消', '3', 'im_rtc_call_end_reason', 0, 'info', '', '主叫接通前主动取消', 'admin', '2026-05-18 03:36:12', 'admin', '2026-05-18 03:36:12', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1061106, 4, '无人接听', '4', 'im_rtc_call_end_reason', 0, 'info', '', '振铃超时未接通', 'admin', '2026-05-18 03:36:12', 'admin', '2026-05-18 03:36:12', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1061107, 5, '对方正忙', '5', 'im_rtc_call_end_reason', 0, 'warning', '', '对方在另一通话中', 'admin', '2026-05-18 03:36:12', 'admin', '2026-05-18 03:36:12', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1061108, 6, '通话异常', '9', 'im_rtc_call_end_reason', 0, 'danger', '', '网络中断、设备失败等', 'admin', '2026-05-18 03:36:12', 'admin', '2026-05-18 03:36:12', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1061109, 1, '发起人', '1', 'im_rtc_participant_role', 0, 'primary', '', '通话发起者', 'admin', '2026-05-18 03:36:12', 'admin', '2026-05-18 03:36:12', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1061110, 2, '被邀请者', '2', 'im_rtc_participant_role', 0, 'info', '', '被邀请加入', 'admin', '2026-05-18 03:36:12', 'admin', '2026-05-18 03:36:12', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1061111, 3, '主动加入者', '3', 'im_rtc_participant_role', 0, 'success', '', '群通话场景,旁观者主动加入', 'admin', '2026-05-18 03:36:12', 'admin', '2026-05-18 03:36:12', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1061112, 1, '邀请中', '10', 'im_rtc_participant_status', 0, 'info', '', '已发出 invite,等待响应', 'admin', '2026-05-18 03:36:12', 'admin', '2026-05-18 03:36:12', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1061113, 2, '已加入', '20', 'im_rtc_participant_status', 0, 'primary', '', '已接通并进入房间', 'admin', '2026-05-18 03:36:12', 'admin', '2026-05-18 03:36:12', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1061114, 3, '已拒绝', '30', 'im_rtc_participant_status', 0, 'warning', '', '接通前点拒接', 'admin', '2026-05-18 03:36:12', 'admin', '2026-05-18 03:36:12', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1061115, 4, '未应答', '40', 'im_rtc_participant_status', 0, 'info', '', '通话已结束仍未应答', 'admin', '2026-05-18 03:36:12', 'admin', '2026-05-18 03:36:12', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1061116, 5, '已离开', '50', 'im_rtc_participant_status', 0, 'success', '', '接通后挂断 / 离开', 'admin', '2026-05-18 03:36:12', 'admin', '2026-05-18 03:36:12', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1061117, 1610, '通话开始', '1610', 'im_content_type', 0, 'info', '', '入消息流;私聊定向通知,群聊全员广播', 'admin', '2026-05-18 03:36:12', 'admin', '2026-05-18 03:36:12', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1061118, 1611, '通话结束', '1611', 'im_content_type', 0, 'info', '', '入消息流;私聊准气泡,群聊系统 tip', 'admin', '2026-05-18 03:36:12', 'admin', '2026-05-18 03:36:12', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1061119, 125, '素材', '125', 'im_content_type', 0, 'success', '', '频道运营推送的图文卡片消息', '1', '2026-05-18 13:14:34', '1', '2026-05-18 13:14:34', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1061120, 1, '富文本', '1', 'im_channel_material_type', 0, 'primary', '', '', '1', '2026-05-19 14:09:25', '1', '2026-05-19 14:09:25', b'0');
|
|
||||||
INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1061121, 2, '外链', '2', 'im_channel_material_type', 0, 'info', '', '', '1', '2026-05-19 14:09:25', '1', '2026-05-19 14:09:25', b'0');
|
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
|
|
@ -1498,7 +1399,7 @@ CREATE TABLE `system_dict_type` (
|
||||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||||
`deleted_time` datetime NULL DEFAULT NULL COMMENT '删除时间',
|
`deleted_time` datetime NULL DEFAULT NULL COMMENT '删除时间',
|
||||||
PRIMARY KEY (`id`) USING BTREE
|
PRIMARY KEY (`id`) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 1061099 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '字典类型表';
|
) ENGINE = InnoDB AUTO_INCREMENT = 2139 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '字典类型表';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of system_dict_type
|
-- Records of system_dict_type
|
||||||
|
|
@ -1687,30 +1588,9 @@ INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creat
|
||||||
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (2131, 'MES 发货通知单状态', 'mes_wm_sales_notice_status', 0, 'MES 发货通知单状态', '1', '2026-03-30 08:54:30', '1', '2026-04-05 15:53:46', b'0', NULL);
|
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (2131, 'MES 发货通知单状态', 'mes_wm_sales_notice_status', 0, 'MES 发货通知单状态', '1', '2026-03-30 08:54:30', '1', '2026-04-05 15:53:46', b'0', NULL);
|
||||||
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (2132, 'MES 杂项出库单状态', 'mes_wm_misc_issue_status', 0, '杂项出库单状态', '1', '2026-03-30 15:00:18', '1', '2026-04-05 15:05:41', b'0', NULL);
|
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (2132, 'MES 杂项出库单状态', 'mes_wm_misc_issue_status', 0, '杂项出库单状态', '1', '2026-03-30 15:00:18', '1', '2026-04-05 15:05:41', b'0', NULL);
|
||||||
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (2133, 'MES 销售退货单状态', 'mes_wm_return_sales_status', 0, 'MES 销售退货单状态枚举', '1', '2026-04-03 17:20:25', '1', '2026-04-05 15:05:39', b'0', NULL);
|
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (2133, 'MES 销售退货单状态', 'mes_wm_return_sales_status', 0, 'MES 销售退货单状态枚举', '1', '2026-04-03 17:20:25', '1', '2026-04-05 15:05:39', b'0', NULL);
|
||||||
|
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (2134, 'MES 缺陷检测项类型', 'mes_defect_type', 0, '缺陷模块的检测项类型字典', '1', '2026-04-04 12:49:51', '1', '2026-04-04 12:49:51', b'0', NULL);
|
||||||
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (2135, 'MES 上下工状态类型', 'mes_pro_work_record_type', 0, 'MES 上下工状态类型', '1', '2026-04-05 14:07:27', '1', '2026-04-05 14:07:27', b'0', NULL);
|
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (2135, 'MES 上下工状态类型', 'mes_pro_work_record_type', 0, 'MES 上下工状态类型', '1', '2026-04-05 14:07:27', '1', '2026-04-05 14:07:27', b'0', NULL);
|
||||||
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (2138, 'MES 生产入库单状态', 'mes_wm_product_produce_status', 0, 'MES 生产入库单状态', '1', '2026-04-05 15:53:46', '1', '2026-04-05 15:53:46', b'0', '1970-01-01 00:00:00');
|
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (2138, 'MES 生产入库单状态', 'mes_wm_product_produce_status', 0, 'MES 生产入库单状态', '1', '2026-04-05 15:53:46', '1', '2026-04-05 15:53:46', b'0', '1970-01-01 00:00:00');
|
||||||
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (2200, 'IM 内容类型', 'im_content_type', 0, '对应 ImContentTypeEnum', 'admin', '2026-04-30 11:35:07', 'admin', '2026-04-30 11:35:07', b'0', NULL);
|
|
||||||
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (2202, 'IM 消息回执状态', 'im_message_receipt_status', 0, '对应 ImMessageReceiptStatusEnum', 'admin', '2026-04-30 11:35:07', 'admin', '2026-04-30 11:35:07', b'0', NULL);
|
|
||||||
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (2203, 'IM 好友状态', 'im_friend_status', 0, '0=正常 / 1=已删除', 'admin', '2026-04-30 11:35:07', 'admin', '2026-04-30 11:35:07', b'0', NULL);
|
|
||||||
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (2204, 'IM 群状态', 'im_group_status', 0, '0=正常 / 1=已解散', 'admin', '2026-04-30 11:35:07', 'admin', '2026-04-30 11:35:07', b'0', NULL);
|
|
||||||
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (2205, 'IM 消息状态', 'im_message_status', 0, '对应 ImMessageStatusEnum;0=正常 / 2=已撤回(私聊 / 群聊共用)', 'admin', '2026-04-30 15:14:36', 'admin', '2026-04-30 15:14:36', b'0', NULL);
|
|
||||||
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (2206, 'IM 群成员角色', 'im_group_member_role', 0, NULL, '1', '2026-05-02 02:14:12', '1', '2026-05-02 02:14:12', b'0', NULL);
|
|
||||||
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (2207, 'IM 好友添加来源', 'im_friend_add_source', 0, NULL, '1', '2026-05-04 02:43:41', '1', '2026-05-04 02:43:41', b'0', NULL);
|
|
||||||
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (2208, 'IM 好友申请处理结果', 'im_friend_request_handle_result', 0, NULL, '1', '2026-05-04 02:43:41', '1', '2026-05-04 02:43:41', b'0', NULL);
|
|
||||||
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (2209, 'IM 加群来源', 'im_group_add_source', 0, NULL, '', '2026-05-06 09:26:36', '', '2026-05-06 09:26:36', b'0', NULL);
|
|
||||||
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (2210, 'IM 加群申请处理结果', 'im_group_request_handle_result', 0, NULL, '', '2026-05-06 09:26:36', '', '2026-05-06 09:26:36', b'0', NULL);
|
|
||||||
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (1061050, '往来企业类型', 'merchant_type', 0, 'WMS 往来企业类型', '1', '2026-05-10 15:26:09', '1', '2026-05-10 15:26:09', b'0', NULL);
|
|
||||||
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (1061060, 'WMS 单据类型', 'wms_order_type', 0, 'WMS 单据类型', '1', '2026-05-10 17:51:46', '1', '2026-05-14 08:14:09', b'0', NULL);
|
|
||||||
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (1061070, 'WMS 单据状态', 'wms_order_status', 0, 'WMS 单据状态', '1', '2026-05-12 13:40:29', '1', '2026-05-12 13:40:29', b'0', NULL);
|
|
||||||
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (1061080, '入库单类型', 'wms_receipt_order_type', 0, 'WMS 入库单类型', '1', '2026-05-11 11:21:49', '1', '2026-05-12 13:40:29', b'0', NULL);
|
|
||||||
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (1061090, '出库单类型', 'wms_shipment_order_type', 0, 'WMS 出库单类型', '1', '2026-05-12 17:48:35', '1', '2026-05-12 17:48:35', b'0', NULL);
|
|
||||||
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (1061092, 'IM 通话媒体类型', 'im_rtc_call_media_type', 0, NULL, 'admin', '2026-05-16 11:34:50', 'admin', '2026-05-16 11:34:50', b'0', NULL);
|
|
||||||
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (1061093, 'IM 通话会话类型', 'im_rtc_call_conversation_type', 0, '1=私聊;2=群聊', 'admin', '2026-05-18 03:36:12', 'admin', '2026-05-18 03:36:12', b'0', NULL);
|
|
||||||
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (1061094, 'IM 通话状态', 'im_rtc_call_status', 0, '10=创建;20=进行中;30=已结束', 'admin', '2026-05-18 03:36:12', 'admin', '2026-05-18 03:36:12', b'0', NULL);
|
|
||||||
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (1061095, 'IM 通话结束原因', 'im_rtc_call_end_reason', 0, '1=通话结束;2=已拒绝;3=已取消;4=无人接听;5=对方正忙;9=通话异常', 'admin', '2026-05-18 03:36:12', 'admin', '2026-05-18 03:36:12', b'0', NULL);
|
|
||||||
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (1061096, 'IM 通话参与角色', 'im_rtc_participant_role', 0, '1=发起人;2=被邀请者;3=主动加入者', 'admin', '2026-05-18 03:36:12', 'admin', '2026-05-18 03:36:12', b'0', NULL);
|
|
||||||
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (1061097, 'IM 通话参与状态', 'im_rtc_participant_status', 0, '10=邀请中;20=已加入;30=已拒绝;40=未应答;50=已离开', 'admin', '2026-05-18 03:36:12', 'admin', '2026-05-18 03:36:12', b'0', NULL);
|
|
||||||
INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (1061098, 'IM 频道素材内容类型', 'im_channel_material_type', 0, '1=站内富文本 / 2=外链', '1', '2026-05-19 14:09:25', '1', '2026-05-19 14:09:25', b'0', NULL);
|
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
|
|
@ -1736,7 +1616,7 @@ CREATE TABLE `system_login_log` (
|
||||||
PRIMARY KEY (`id`) USING BTREE,
|
PRIMARY KEY (`id`) USING BTREE,
|
||||||
INDEX `idx_username`(`username` ASC) USING BTREE,
|
INDEX `idx_username`(`username` ASC) USING BTREE,
|
||||||
INDEX `idx_create_time`(`create_time` ASC) USING BTREE
|
INDEX `idx_create_time`(`create_time` ASC) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 4697 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '系统访问记录';
|
) ENGINE = InnoDB AUTO_INCREMENT = 4512 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '系统访问记录';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of system_login_log
|
-- Records of system_login_log
|
||||||
|
|
@ -1869,7 +1749,7 @@ CREATE TABLE `system_menu` (
|
||||||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||||
PRIMARY KEY (`id`) USING BTREE
|
PRIMARY KEY (`id`) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 6735 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '菜单权限表';
|
) ENGINE = InnoDB AUTO_INCREMENT = 5986 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '菜单权限表';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of system_menu
|
-- Records of system_menu
|
||||||
|
|
@ -2801,7 +2681,7 @@ INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_i
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (5034, 'OTA 固件创建', 'iot:ota-firmware:create', 3, 2, 5032, '', '', '', '', 0, b'1', b'1', b'1', '', '2025-06-30 07:50:29', '\"1\"', '2025-06-30 17:38:21', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (5034, 'OTA 固件创建', 'iot:ota-firmware:create', 3, 2, 5032, '', '', '', '', 0, b'1', b'1', b'1', '', '2025-06-30 07:50:29', '\"1\"', '2025-06-30 17:38:21', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (5035, 'OTA 固件更新', 'iot:ota-firmware:update', 3, 3, 5032, '', '', '', '', 0, b'1', b'1', b'1', '', '2025-06-30 07:50:29', '\"1\"', '2025-06-30 17:38:29', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (5035, 'OTA 固件更新', 'iot:ota-firmware:update', 3, 3, 5032, '', '', '', '', 0, b'1', b'1', b'1', '', '2025-06-30 07:50:29', '\"1\"', '2025-06-30 17:38:29', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (5036, 'OTA 固件删除', 'iot:ota-firmware:delete', 3, 4, 5032, '', '', '', '', 0, b'1', b'1', b'1', '', '2025-06-30 07:50:29', '\"1\"', '2025-06-30 17:38:37', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (5036, 'OTA 固件删除', 'iot:ota-firmware:delete', 3, 4, 5032, '', '', '', '', 0, b'1', b'1', b'1', '', '2025-06-30 07:50:29', '\"1\"', '2025-06-30 17:38:37', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (5037, 'OTA 升级任务查询', 'iot:ota-task:query', 3, 11, 5032, '', '', '', '', 0, b'1', b'1', b'1', '1', '2025-07-02 23:56:56', '1', '2026-05-19 08:48:53', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (5037, 'OTA 升级任务查询', 'iot:ota-task:create', 3, 11, 5032, '', '', '', '', 0, b'1', b'1', b'1', '1', '2025-07-02 23:56:56', '1', '2025-07-02 23:56:56', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (5038, 'OTA 升级任务取消', 'iot:ota-task:cancel', 3, 13, 5032, '', '', '', '', 0, b'1', b'1', b'1', '1', '2025-07-02 23:57:26', '1', '2025-07-02 23:57:26', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (5038, 'OTA 升级任务取消', 'iot:ota-task:cancel', 3, 13, 5032, '', '', '', '', 0, b'1', b'1', b'1', '1', '2025-07-02 23:57:26', '1', '2025-07-02 23:57:26', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (5039, 'OTA 升级任务创建', 'iot:ota-task:create', 3, 12, 5032, '', '', '', '', 0, b'1', b'1', b'1', '1', '2025-07-02 23:57:52', '1', '2025-07-02 23:57:52', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (5039, 'OTA 升级任务创建', 'iot:ota-task:create', 3, 12, 5032, '', '', '', '', 0, b'1', b'1', b'1', '1', '2025-07-02 23:57:52', '1', '2025-07-02 23:57:52', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (5040, 'OTA 升级记录查询', 'iot:ota-task-record:query', 3, 21, 5032, '', '', '', '', 0, b'1', b'1', b'1', '1', '2025-07-02 23:58:30', '1', '2025-07-02 23:58:30', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (5040, 'OTA 升级记录查询', 'iot:ota-task-record:query', 3, 21, 5032, '', '', '', '', 0, b'1', b'1', b'1', '1', '2025-07-02 23:58:30', '1', '2025-07-02 23:58:30', b'0');
|
||||||
|
|
@ -2811,7 +2691,7 @@ INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_i
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (5044, '删除模版消息', 'mp:message-template:delete', 3, 2, 5042, '', '', '', '', 0, b'1', b'1', b'1', '1', '2025-11-26 17:00:31', '1', '2025-11-26 18:45:05', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (5044, '删除模版消息', 'mp:message-template:delete', 3, 2, 5042, '', '', '', '', 0, b'1', b'1', b'1', '1', '2025-11-26 17:00:31', '1', '2025-11-26 18:45:05', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (5045, '同步公众号模板', 'mp:message-template:sync', 3, 3, 5042, '', '', '', '', 0, b'1', b'1', b'1', '1', '2025-11-26 17:00:55', '1', '2025-11-26 17:00:55', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (5045, '同步公众号模板', 'mp:message-template:sync', 3, 3, 5042, '', '', '', '', 0, b'1', b'1', b'1', '1', '2025-11-26 17:00:55', '1', '2025-11-26 17:00:55', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (5046, '给粉丝发送模版消息', 'mp:message-template:send', 3, 4, 5042, '', '', '', '', 0, b'1', b'1', b'1', '1', '2025-11-26 17:01:11', '1', '2025-11-26 17:01:11', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (5046, '给粉丝发送模版消息', 'mp:message-template:send', 3, 4, 5042, '', '', '', '', 0, b'1', b'1', b'1', '1', '2025-11-26 17:01:11', '1', '2025-11-26 17:01:11', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (5100, 'MES 系统', '', 1, 320, 0, '/mes', 'ep:cpu', '', '', 0, b'1', b'1', b'1', '1', '2026-02-15 00:39:57', '1', '2026-05-09 16:19:51', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (5100, 'MES 系统', '', 1, 500, 0, '/mes', 'ep:cpu', '', '', 0, b'1', b'1', b'1', '1', '2026-02-15 00:39:57', '1', '2026-04-05 23:22:56', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (5101, '基础数据', '', 1, 10, 5100, 'md', 'ep:data-analysis', '', '', 0, b'1', b'1', b'1', '1', '2026-02-15 00:40:13', '1', '2026-02-15 00:40:13', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (5101, '基础数据', '', 1, 10, 5100, 'md', 'ep:data-analysis', '', '', 0, b'1', b'1', b'1', '1', '2026-02-15 00:40:13', '1', '2026-02-15 00:40:13', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (5110, '物料产品分类', '', 2, 2, 5101, 'item-type', 'ep:files', 'mes/md/item/type/index', 'MesMdItemType', 0, b'1', b'1', b'1', '1', '2026-02-15 00:40:13', '1', '2026-02-15 13:58:29', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (5110, '物料产品分类', '', 2, 2, 5101, 'item-type', 'ep:files', 'mes/md/item/type/index', 'MesMdItemType', 0, b'1', b'1', b'1', '1', '2026-02-15 00:40:13', '1', '2026-02-15 13:58:29', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (5111, '分类查询', 'mes:md-item-type:query', 3, 1, 5110, '', '', '', '', 0, b'1', b'1', b'1', '1', '2026-02-15 00:40:13', '1', '2026-02-15 00:40:13', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (5111, '分类查询', 'mes:md-item-type:query', 3, 1, 5110, '', '', '', '', 0, b'1', b'1', b'1', '1', '2026-02-15 00:40:13', '1', '2026-02-15 00:40:13', b'0');
|
||||||
|
|
@ -3196,126 +3076,6 @@ INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_i
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (5983, '工作记录导出', 'mes:pro-workrecord:export', 3, 2, 5981, '', '', '', '', 0, b'1', b'1', b'1', '1', '2026-04-05 14:08:44', '1', '2026-04-05 14:08:44', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (5983, '工作记录导出', 'mes:pro-workrecord:export', 3, 2, 5981, '', '', '', '', 0, b'1', b'1', b'1', '1', '2026-04-05 14:08:44', '1', '2026-04-05 14:08:44', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (5984, '上工下工', 'mes:pro-workrecord:clock', 3, 3, 5981, '', '', '', '', 0, b'1', b'1', b'1', '1', '2026-04-05 14:08:44', '1', '2026-04-05 14:08:44', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (5984, '上工下工', 'mes:pro-workrecord:clock', 3, 3, 5981, '', '', '', '', 0, b'1', b'1', b'1', '1', '2026-04-05 14:08:44', '1', '2026-04-05 14:08:44', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (5985, 'MES 首页', 'mes:home:query', 2, 0, 5100, 'mes/home/index', 'ep:home-filled', 'mes/home/index', 'MesHome', 0, b'1', b'1', b'1', '1', '2026-04-05 23:24:03', '1', '2026-04-06 01:20:52', b'0');
|
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (5985, 'MES 首页', 'mes:home:query', 2, 0, 5100, 'mes/home/index', 'ep:home-filled', 'mes/home/index', 'MesHome', 0, b'1', b'1', b'1', '1', '2026-04-05 23:24:03', '1', '2026-04-06 01:20:52', b'0');
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6400, 'WMS 系统', '', 1, 310, 0, '/wms', 'ep:box', '', '', 0, b'1', b'1', b'1', '1', '2026-05-09 16:11:01', '1', '2026-05-09 16:11:01', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6401, '基础数据', '', 1, 6, 6400, 'md', 'ep:files', '', '', 0, b'1', b'1', b'1', '1', '2026-05-09 16:11:01', '1', '2026-05-12 17:48:35', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6402, '仓库管理', '', 2, 1, 6401, 'warehouse', 'ep:office-building', 'wms/md/warehouse/index', 'WmsWarehouse', 0, b'1', b'1', b'1', '1', '2026-05-09 16:11:01', '1', '2026-05-10 00:54:16', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6403, '仓库查询', 'wms:warehouse:query', 3, 1, 6402, '', '', '', '', 0, b'1', b'1', b'1', '1', '2026-05-09 16:11:01', '1', '2026-05-09 16:11:01', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6404, '仓库创建', 'wms:warehouse:create', 3, 2, 6402, '', '', '', '', 0, b'1', b'1', b'1', '1', '2026-05-09 16:11:01', '1', '2026-05-09 16:11:01', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6405, '仓库更新', 'wms:warehouse:update', 3, 3, 6402, '', '', '', '', 0, b'1', b'1', b'1', '1', '2026-05-09 16:11:01', '1', '2026-05-09 16:11:01', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6406, '仓库删除', 'wms:warehouse:delete', 3, 4, 6402, '', '', '', '', 0, b'1', b'1', b'1', '1', '2026-05-09 16:11:01', '1', '2026-05-09 16:11:01', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6411, '商品品牌', '', 2, 3, 6401, 'item/brand', 'ep:price-tag', 'wms/md/item/brand/index', 'WmsItemBrand', 0, b'1', b'1', b'1', '1', '2026-05-10 01:43:12', '1', '2026-05-10 02:12:51', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6412, '品牌查询', 'wms:item-brand:query', 3, 1, 6411, '', '', '', '', 0, b'1', b'1', b'1', '1', '2026-05-10 01:43:12', '1', '2026-05-10 01:43:12', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6413, '品牌创建', 'wms:item-brand:create', 3, 2, 6411, '', '', '', '', 0, b'1', b'1', b'1', '1', '2026-05-10 01:43:12', '1', '2026-05-10 01:43:12', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6414, '品牌更新', 'wms:item-brand:update', 3, 3, 6411, '', '', '', '', 0, b'1', b'1', b'1', '1', '2026-05-10 01:43:12', '1', '2026-05-10 01:43:12', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6415, '品牌删除', 'wms:item-brand:delete', 3, 4, 6411, '', '', '', '', 0, b'1', b'1', b'1', '1', '2026-05-10 01:43:12', '1', '2026-05-10 01:43:12', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6416, '品牌导出', 'wms:item-brand:export', 3, 5, 6411, '', '', '', '', 0, b'1', b'1', b'1', '1', '2026-05-10 01:43:12', '1', '2026-05-10 01:43:12', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6417, '仓库导出', 'wms:warehouse:export', 3, 5, 6402, '', '', '', '', 0, b'1', b'1', b'1', '1', '2026-05-10 02:42:47', '1', '2026-05-10 02:42:47', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6419, '商品分类', '', 2, 2, 6401, 'item/category', 'ep:folder', 'wms/md/item/category/index', 'WmsItemCategory', 0, b'1', b'1', b'1', '1', '2026-05-10 07:14:18', '1', '2026-05-10 07:14:18', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6420, '分类查询', 'wms:item-category:query', 3, 1, 6419, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2026-05-10 07:14:18', '1', '2026-05-10 07:14:18', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6421, '分类创建', 'wms:item-category:create', 3, 2, 6419, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2026-05-10 07:14:18', '1', '2026-05-10 07:14:18', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6422, '分类更新', 'wms:item-category:update', 3, 3, 6419, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2026-05-10 07:14:18', '1', '2026-05-10 07:14:18', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6423, '分类删除', 'wms:item-category:delete', 3, 4, 6419, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2026-05-10 07:14:18', '1', '2026-05-10 07:14:18', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6424, '商品管理', '', 2, 4, 6401, 'item', 'ep:goods', 'wms/md/item/index', 'WmsItem', 0, b'1', b'1', b'1', '1', '2026-05-10 09:15:34', '1', '2026-05-10 09:15:34', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6425, '商品查询', 'wms:item:query', 3, 1, 6424, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2026-05-10 09:15:34', '1', '2026-05-10 09:15:34', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6426, '商品创建', 'wms:item:create', 3, 2, 6424, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2026-05-10 09:15:34', '1', '2026-05-10 09:15:34', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6427, '商品更新', 'wms:item:update', 3, 3, 6424, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2026-05-10 09:15:34', '1', '2026-05-10 09:15:34', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6428, '商品删除', 'wms:item:delete', 3, 4, 6424, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2026-05-10 09:15:34', '1', '2026-05-10 09:15:34', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6429, '商品导出', 'wms:item:export', 3, 5, 6424, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2026-05-10 09:15:34', '1', '2026-05-10 09:15:34', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6430, '往来企业', '', 2, 5, 6401, 'merchant', 'ep:office-building', 'wms/md/merchant/index', 'WmsMerchant', 0, b'1', b'1', b'1', '1', '2026-05-10 15:26:09', '1', '2026-05-10 15:48:07', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6431, '往来企业查询', 'wms:merchant:query', 3, 1, 6430, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2026-05-10 15:26:09', '1', '2026-05-10 15:26:09', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6432, '往来企业创建', 'wms:merchant:create', 3, 2, 6430, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2026-05-10 15:26:09', '1', '2026-05-10 15:26:09', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6433, '往来企业更新', 'wms:merchant:update', 3, 3, 6430, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2026-05-10 15:26:09', '1', '2026-05-10 15:26:09', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6434, '往来企业删除', 'wms:merchant:delete', 3, 4, 6430, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2026-05-10 15:26:09', '1', '2026-05-10 15:26:09', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6435, '往来企业导出', 'wms:merchant:export', 3, 5, 6430, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2026-05-10 15:26:09', '1', '2026-05-10 15:26:09', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6440, '库存管理', '', 1, 5, 6400, 'inventory', 'ep:box', '', '', 0, b'1', b'1', b'1', '1', '2026-05-10 17:51:46', '1', '2026-05-13 01:23:11', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6441, '库存统计', '', 2, 1, 6440, 'index', 'ep:data-board', 'wms/inventory/index/index', 'WmsInventory', 0, b'1', b'1', b'1', '1', '2026-05-10 17:51:46', '1', '2026-05-11 02:08:28', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6442, '库存统计查询', 'wms:inventory:query', 3, 1, 6441, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2026-05-10 17:51:46', '1', '2026-05-11 00:30:41', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6445, '库存流水', '', 2, 2, 6440, 'history', 'ep:document', 'wms/inventory/history/index', 'WmsInventoryHistory', 0, b'1', b'1', b'1', '1', '2026-05-10 17:51:46', '1', '2026-05-14 07:59:15', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6446, '库存流水查询', 'wms:inventory-history:query', 3, 1, 6445, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2026-05-10 17:51:46', '1', '2026-05-11 00:29:15', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6451, '入库管理', '', 2, 1, 6400, 'receipt', 'ep:download', 'wms/order/receipt/index', 'WmsReceiptOrder', 0, b'1', b'1', b'1', '1', '2026-05-11 11:58:58', '1', '2026-05-11 16:58:02', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6452, '入库单查询', 'wms:receipt-order:query', 3, 1, 6451, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2026-05-11 11:58:58', '1', '2026-05-11 16:58:02', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6453, '入库单创建', 'wms:receipt-order:create', 3, 2, 6451, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2026-05-11 11:58:58', '1', '2026-05-11 16:58:02', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6454, '入库单更新', 'wms:receipt-order:update', 3, 3, 6451, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2026-05-11 11:58:58', '1', '2026-05-11 16:58:02', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6455, '入库单删除', 'wms:receipt-order:delete', 3, 4, 6451, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2026-05-11 11:58:58', '1', '2026-05-11 16:58:02', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6456, '入库单完成入库', 'wms:receipt-order:complete', 3, 5, 6451, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2026-05-11 11:58:58', '1', '2026-05-11 16:58:02', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6457, '入库单作废', 'wms:receipt-order:cancel', 3, 6, 6451, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2026-05-11 11:58:58', '1', '2026-05-12 16:27:16', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6458, '入库单导出', 'wms:receipt-order:export', 3, 7, 6451, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2026-05-11 16:58:02', '1', '2026-05-12 16:27:16', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6461, '出库管理', '', 2, 2, 6400, 'shipment', 'ep:upload', 'wms/order/shipment/index', 'WmsShipmentOrder', 0, b'1', b'1', b'1', '1', '2026-05-12 17:48:35', '1', '2026-05-12 17:48:35', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6462, '出库单查询', 'wms:shipment-order:query', 3, 1, 6461, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2026-05-12 17:48:35', '1', '2026-05-12 17:48:35', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6463, '出库单创建', 'wms:shipment-order:create', 3, 2, 6461, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2026-05-12 17:48:35', '1', '2026-05-12 17:48:35', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6464, '出库单更新', 'wms:shipment-order:update', 3, 3, 6461, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2026-05-12 17:48:35', '1', '2026-05-12 17:48:35', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6465, '出库单删除', 'wms:shipment-order:delete', 3, 4, 6461, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2026-05-12 17:48:35', '1', '2026-05-12 17:48:35', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6466, '出库单完成出库', 'wms:shipment-order:complete', 3, 5, 6461, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2026-05-12 17:48:35', '1', '2026-05-12 17:48:35', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6467, '出库单作废', 'wms:shipment-order:cancel', 3, 6, 6461, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2026-05-12 17:48:35', '1', '2026-05-12 17:48:35', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6468, '出库单导出', 'wms:shipment-order:export', 3, 7, 6461, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2026-05-12 17:48:35', '1', '2026-05-12 17:48:35', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6470, '移库管理', '', 2, 3, 6400, 'movement', 'ep:sort', 'wms/order/movement/index', 'WmsMovementOrder', 0, b'1', b'1', b'1', '1', '2026-05-13 01:23:11', '1', '2026-05-14 02:21:20', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6471, '移库单查询', 'wms:movement-order:query', 3, 1, 6470, '', '#', NULL, NULL, 0, b'1', b'1', b'1', '1', '2026-05-13 01:23:11', '1', '2026-05-14 02:21:20', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6472, '移库单创建', 'wms:movement-order:create', 3, 2, 6470, '', '#', NULL, NULL, 0, b'1', b'1', b'1', '1', '2026-05-13 01:23:11', '1', '2026-05-14 02:21:20', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6473, '移库单更新', 'wms:movement-order:update', 3, 3, 6470, '', '#', NULL, NULL, 0, b'1', b'1', b'1', '1', '2026-05-13 01:23:11', '1', '2026-05-14 02:21:20', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6474, '移库单删除', 'wms:movement-order:delete', 3, 4, 6470, '', '#', NULL, NULL, 0, b'1', b'1', b'1', '1', '2026-05-13 01:23:11', '1', '2026-05-14 02:21:20', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6475, '移库单完成移库', 'wms:movement-order:complete', 3, 5, 6470, '', '#', NULL, NULL, 0, b'1', b'1', b'1', '1', '2026-05-13 01:23:11', '1', '2026-05-14 02:21:20', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6476, '移库单作废', 'wms:movement-order:cancel', 3, 6, 6470, '', '#', NULL, NULL, 0, b'1', b'1', b'1', '1', '2026-05-13 01:23:11', '1', '2026-05-14 02:21:20', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6477, '移库单导出', 'wms:movement-order:export', 3, 7, 6470, '', '#', NULL, NULL, 0, b'1', b'1', b'1', '1', '2026-05-13 01:23:11', '1', '2026-05-14 02:21:20', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6480, '盘库管理', '', 2, 4, 6400, 'check', 'ep:circle-check-filled', 'wms/order/check/index', 'WmsCheckOrder', 0, b'1', b'1', b'1', '1', '2026-05-13 01:23:11', '1', '2026-05-14 02:21:20', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6481, '盘库单查询', 'wms:check-order:query', 3, 1, 6480, '', '#', NULL, NULL, 0, b'1', b'1', b'1', '1', '2026-05-13 01:23:11', '1', '2026-05-14 02:21:20', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6482, '盘库单创建', 'wms:check-order:create', 3, 2, 6480, '', '#', NULL, NULL, 0, b'1', b'1', b'1', '1', '2026-05-13 01:23:11', '1', '2026-05-14 02:21:20', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6483, '盘库单更新', 'wms:check-order:update', 3, 3, 6480, '', '#', NULL, NULL, 0, b'1', b'1', b'1', '1', '2026-05-13 01:23:11', '1', '2026-05-14 02:21:20', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6484, '盘库单删除', 'wms:check-order:delete', 3, 4, 6480, '', '#', NULL, NULL, 0, b'1', b'1', b'1', '1', '2026-05-13 01:23:11', '1', '2026-05-14 02:21:20', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6485, '盘库单完成盘库', 'wms:check-order:complete', 3, 5, 6480, '', '#', NULL, NULL, 0, b'1', b'1', b'1', '1', '2026-05-13 01:23:11', '1', '2026-05-14 02:21:20', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6486, '盘库单作废', 'wms:check-order:cancel', 3, 6, 6480, '', '#', NULL, NULL, 0, b'1', b'1', b'1', '1', '2026-05-13 01:23:11', '1', '2026-05-14 02:21:20', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6487, '盘库单导出', 'wms:check-order:export', 3, 7, 6480, '', '#', NULL, NULL, 0, b'1', b'1', b'1', '1', '2026-05-13 01:23:11', '1', '2026-05-14 02:21:20', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6490, 'WMS 首页', 'wms:home:query', 2, 0, 6400, 'home', 'ep:home-filled', 'wms/home/index', 'WmsHome', 0, b'1', b'1', b'1', '1', '2026-05-14 09:34:27', '1', '2026-05-14 10:05:06', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6500, 'IM 即时通讯', '', 1, 501, 0, '/im', 'ep:chat-dot-round', NULL, NULL, 0, b'1', b'1', b'1', 'admin', '2026-04-30 09:11:20', '1', '2026-05-09 16:19:34', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6510, '数据统计', 'im:manager:statistics:query', 2, 10, 6500, 'statistics', 'ep:trend-charts', 'im/manager/statistics/index', 'ImStatistics', 0, b'1', b'1', b'1', 'admin', '2026-04-30 09:11:20', '1', '2026-04-30 19:35:54', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6515, '好友申请', 'im:manager:friend-request:query', 2, 20, 6600, 'friend-request', 'ep:document', 'im/manager/friend/request/index', 'ImFriendRequest', 0, b'1', b'1', b'1', '1', '2026-05-05 11:15:48', '1', '2026-05-07 00:40:35', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6520, '好友列表', 'im:manager:friend:list', 2, 10, 6600, 'friend', 'ep:user', 'im/manager/friend/index', 'ImFriend', 0, b'1', b'1', b'1', 'admin', '2026-04-30 09:11:20', '1', '2026-05-07 00:40:35', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6521, '好友查询', 'im:manager:friend:query', 3, 10, 6520, '', '', NULL, NULL, 0, b'1', b'1', b'1', 'admin', '2026-04-30 09:11:20', 'admin', '2026-04-30 09:11:20', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6530, '好友消息', 'im:manager:message:private:list', 2, 30, 6600, 'message', 'ep:chat-dot-square', 'im/manager/message/private/index', 'ImPrivateMessage', 0, b'1', b'1', b'1', 'admin', '2026-04-30 09:11:20', '1', '2026-05-07 00:40:35', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6531, '私聊消息查询', 'im:manager:message:query', 3, 10, 6530, '', '', NULL, NULL, 0, b'1', b'1', b'1', 'admin', '2026-04-30 09:11:20', 'admin', '2026-04-30 09:11:20', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6540, '群聊列表', 'im:manager:group:list', 2, 10, 6610, 'list', 'ep:user-filled', 'im/manager/group/index', 'ImGroup', 0, b'1', b'1', b'1', 'admin', '2026-04-30 09:11:20', '1', '2026-05-07 00:40:35', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6541, '群组查询', 'im:manager:group:query', 3, 10, 6540, '', '', NULL, NULL, 0, b'1', b'1', b'1', 'admin', '2026-04-30 09:11:20', 'admin', '2026-04-30 09:11:20', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6542, '群组封禁/解封', 'im:manager:group:ban', 3, 20, 6540, '', '', NULL, NULL, 0, b'1', b'1', b'1', 'admin', '2026-04-30 09:11:20', 'admin', '2026-04-30 09:11:20', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6545, '群聊申请', 'im:manager:group-request:query', 2, 20, 6610, 'request', 'ep:document', 'im/manager/group/request/index', 'ImGroupRequest', 0, b'1', b'1', b'1', '1', '2026-05-07 00:31:35', '1', '2026-05-07 00:40:35', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6550, '群聊消息', 'im:manager:message:group:list', 2, 30, 6610, 'message', 'ep:chat-line-round', 'im/manager/message/group/index', 'ImGroupMessage', 0, b'1', b'1', b'1', 'admin', '2026-04-30 09:11:20', '1', '2026-05-07 00:40:35', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6551, '群聊消息查询', 'im:manager:message:query', 3, 10, 6550, '', '', NULL, NULL, 0, b'1', b'1', b'1', 'admin', '2026-04-30 09:11:20', 'admin', '2026-04-30 09:11:20', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6560, '敏感词管理', 'im:manager:sensitive-word:list', 2, 60, 6500, 'sensitive-word', 'ep:warning', 'im/manager/sensitiveword/index', 'ImSensitiveWord', 0, b'1', b'1', b'1', 'admin', '2026-04-30 09:11:20', '1', '2026-04-30 22:25:48', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6561, '敏感词查询', 'im:manager:sensitive-word:query', 3, 10, 6560, '', '', NULL, NULL, 0, b'1', b'1', b'1', 'admin', '2026-04-30 09:11:20', 'admin', '2026-04-30 09:11:20', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6562, '敏感词新增', 'im:manager:sensitive-word:create', 3, 20, 6560, '', '', NULL, NULL, 0, b'1', b'1', b'1', 'admin', '2026-04-30 09:11:20', 'admin', '2026-04-30 09:11:20', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6563, '敏感词修改', 'im:manager:sensitive-word:update', 3, 30, 6560, '', '', NULL, NULL, 0, b'1', b'1', b'1', 'admin', '2026-04-30 09:11:20', 'admin', '2026-04-30 09:11:20', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6564, '敏感词删除', 'im:manager:sensitive-word:delete', 3, 40, 6560, '', '', NULL, NULL, 0, b'1', b'1', b'1', 'admin', '2026-04-30 09:11:20', 'admin', '2026-04-30 09:11:20', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6570, '表情管理', '', 1, 70, 6500, 'face', 'ep:magic-stick', NULL, NULL, 0, b'1', b'1', b'1', '', '2026-05-06 13:56:08', '', '2026-05-06 13:56:08', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6571, '系统表情', 'im:manager:face-pack:list', 2, 10, 6570, 'pack', 'ep:picture', 'im/manager/face/pack/index', 'ImManagerFacePack', 0, b'1', b'1', b'1', '', '2026-05-06 13:56:08', '', '2026-05-06 13:56:08', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6572, '表情包查询', 'im:manager:face-pack:query', 3, 10, 6571, '', '', '', '', 0, b'1', b'1', b'1', '', '2026-05-06 13:56:08', '', '2026-05-06 13:56:08', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6573, '表情包创建', 'im:manager:face-pack:create', 3, 20, 6571, '', '', '', '', 0, b'1', b'1', b'1', '', '2026-05-06 13:56:08', '', '2026-05-06 13:56:08', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6574, '表情包修改', 'im:manager:face-pack:update', 3, 30, 6571, '', '', '', '', 0, b'1', b'1', b'1', '', '2026-05-06 13:56:08', '', '2026-05-06 13:56:08', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6575, '表情包删除', 'im:manager:face-pack:delete', 3, 40, 6571, '', '', '', '', 0, b'1', b'1', b'1', '', '2026-05-06 13:56:08', '', '2026-05-06 13:56:08', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6576, '表情图查询', 'im:manager:face-pack-item:query', 3, 50, 6571, '', '', '', '', 0, b'1', b'1', b'1', '', '2026-05-06 13:56:08', '', '2026-05-06 13:56:08', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6577, '表情图创建', 'im:manager:face-pack-item:create', 3, 60, 6571, '', '', '', '', 0, b'1', b'1', b'1', '', '2026-05-06 13:56:08', '', '2026-05-06 13:56:08', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6578, '表情图修改', 'im:manager:face-pack-item:update', 3, 70, 6571, '', '', '', '', 0, b'1', b'1', b'1', '', '2026-05-06 13:56:08', '', '2026-05-06 13:56:08', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6579, '表情图删除', 'im:manager:face-pack-item:delete', 3, 80, 6571, '', '', '', '', 0, b'1', b'1', b'1', '', '2026-05-06 13:56:08', '', '2026-05-06 13:56:08', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6580, '用户表情', 'im:manager:face-user-item:list', 2, 20, 6570, 'user-item', 'ep:user', 'im/manager/face/userItem/index', 'ImManagerFaceUserItem', 0, b'1', b'1', b'1', '', '2026-05-06 13:56:08', '', '2026-05-06 14:24:20', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6581, '用户表情查询', 'im:manager:face-user-item:query', 3, 10, 6580, '', '', '', '', 0, b'1', b'1', b'1', '', '2026-05-06 13:56:08', '', '2026-05-06 13:56:08', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6582, '用户表情删除', 'im:manager:face-user-item:delete', 3, 20, 6580, '', '', '', '', 0, b'1', b'1', b'1', '', '2026-05-06 13:56:08', '', '2026-05-06 13:56:08', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6600, '私聊管理', '', 1, 20, 6500, 'private', 'ep:chat-round', NULL, NULL, 0, b'1', b'1', b'1', '1', '2026-05-07 00:40:35', '1', '2026-05-07 00:40:35', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6610, '群聊管理', '', 1, 30, 6500, 'group', 'ep:chat-line-round', NULL, NULL, 0, b'1', b'1', b'1', '1', '2026-05-07 00:40:35', '1', '2026-05-07 00:40:35', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6611, '通话记录', '', 2, 40, 6500, 'rtc', 'ep:phone', 'im/manager/rtc/index', 'ImRtcCall', 0, b'1', b'1', b'1', 'admin', '2026-05-18 03:36:12', 'admin', '2026-05-18 03:36:12', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6612, '通话记录查询', 'im:manager:rtc:query', 3, 1, 6611, '', '', NULL, NULL, 0, b'1', b'1', b'1', 'admin', '2026-05-18 03:36:12', 'admin', '2026-05-18 03:36:12', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6700, '频道管理', '', 1, 90, 6500, 'channel', 'ep:promotion', NULL, NULL, 0, b'1', b'1', b'1', '1', '2026-05-18 13:14:34', '1', '2026-05-18 13:14:34', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6710, '频道列表', '', 2, 1, 6700, 'list', 'ep:promotion', 'im/manager/channel/list/index', 'ImChannel', 0, b'1', b'1', b'1', '1', '2026-05-18 13:14:34', '1', '2026-05-19 09:44:34', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6711, '频道查询', 'im:manager:channel:query', 3, 1, 6710, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2026-05-18 13:14:34', '1', '2026-05-18 13:14:34', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6712, '频道创建', 'im:manager:channel:create', 3, 2, 6710, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2026-05-18 13:14:34', '1', '2026-05-18 13:14:34', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6713, '频道修改', 'im:manager:channel:update', 3, 3, 6710, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2026-05-18 13:14:34', '1', '2026-05-18 13:14:34', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6714, '频道删除', 'im:manager:channel:delete', 3, 4, 6710, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2026-05-18 13:14:34', '1', '2026-05-18 13:14:34', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6720, '频道素材', '', 2, 2, 6700, 'material', 'ep:document', 'im/manager/channel/material/index', 'ImChannelMaterial', 0, b'1', b'1', b'1', '1', '2026-05-18 13:14:34', '1', '2026-05-19 09:44:34', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6721, '素材查询', 'im:manager:channel-material:query', 3, 1, 6720, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2026-05-18 13:14:34', '1', '2026-05-18 13:14:34', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6722, '素材创建', 'im:manager:channel-material:create', 3, 2, 6720, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2026-05-18 13:14:34', '1', '2026-05-18 13:14:34', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6723, '素材修改', 'im:manager:channel-material:update', 3, 3, 6720, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2026-05-18 13:14:34', '1', '2026-05-18 13:14:34', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6724, '素材删除', 'im:manager:channel-material:delete', 3, 4, 6720, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2026-05-18 13:14:34', '1', '2026-05-18 13:14:34', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6730, '频道消息', '', 2, 3, 6700, 'message', 'ep:message', 'im/manager/channel/message/index', 'ImChannelMessage', 0, b'1', b'1', b'1', '1', '2026-05-18 13:14:34', '1', '2026-05-19 09:44:34', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6731, '消息查询', 'im:manager:channel-message:query', 3, 1, 6730, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2026-05-18 13:14:34', '1', '2026-05-18 13:14:34', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6732, '立即推送', 'im:manager:channel-message:send', 3, 2, 6730, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2026-05-18 13:14:34', '1', '2026-05-18 13:14:34', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6733, '消息删除', 'im:manager:channel-message:delete', 3, 3, 6730, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2026-05-18 13:14:34', '1', '2026-05-18 13:14:34', b'0');
|
|
||||||
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (6734, '解散群', 'im:manager:group:dissolve', 3, 21, 6540, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2026-05-24 12:02:38', '1', '2026-05-24 12:02:38', b'0');
|
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
|
|
@ -3342,7 +3102,7 @@ CREATE TABLE `system_notice` (
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
BEGIN;
|
BEGIN;
|
||||||
INSERT INTO `system_notice` (`id`, `title`, `content`, `type`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1, '芋道的公众', '<p>新版本内容133222</p>', 1, 0, 'admin', '2021-01-05 17:03:48', '\"1\"', '2025-08-31 09:38:22', b'0', 1);
|
INSERT INTO `system_notice` (`id`, `title`, `content`, `type`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1, '芋道的公众', '<p>新版本内容133222</p>', 1, 0, 'admin', '2021-01-05 17:03:48', '\"1\"', '2025-08-31 09:38:22', b'0', 1);
|
||||||
INSERT INTO `system_notice` (`id`, `title`, `content`, `type`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2, '维护通知:2018-07-01 系统凌晨维护', '<p><img src=\"http://test.yudao.iocoder.cn/b7cb3cf49b4b3258bf7309a09dd2f4e5.jpg\" alt=\"\" data-href=\"\">11112222<img src=\"http://test.yudao.iocoder.cn/fe44fc7bdb82ca421184b2eebbaee9e2148d4a1827479a4eb4521e11d2a062ba.png\" alt=\"image\" data-href=\"http://test.yudao.iocoder.cn/fe44fc7bdb82ca421184b2eebbaee9e2148d4a1827479a4eb4521e11d2a062ba.png\">3333</p>\n<p><img src=\"http://test.yudao.iocoder.cn/20260503/备份.jpg\" alt=\"\" width=\"258\" height=\"258\"><img src=\"http://test.yudao.iocoder.cn/20260503/萌萌的皮卡丘.png\"></p>', 2, 1, 'admin', '2021-01-05 17:03:48', '1', '2026-05-03 23:07:48', b'0', 1);
|
INSERT INTO `system_notice` (`id`, `title`, `content`, `type`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (2, '维护通知:2018-07-01 系统凌晨维护', '<p><img src=\"http://test.yudao.iocoder.cn/b7cb3cf49b4b3258bf7309a09dd2f4e5.jpg\" alt=\"\" data-href=\"\">11112222<img src=\"http://test.yudao.iocoder.cn/fe44fc7bdb82ca421184b2eebbaee9e2148d4a1827479a4eb4521e11d2a062ba.png\" alt=\"image\" data-href=\"http://test.yudao.iocoder.cn/fe44fc7bdb82ca421184b2eebbaee9e2148d4a1827479a4eb4521e11d2a062ba.png\">3333</p>', 2, 1, 'admin', '2021-01-05 17:03:48', '1', '2025-04-18 23:56:40', b'0', 1);
|
||||||
INSERT INTO `system_notice` (`id`, `title`, `content`, `type`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4, '我是测试标题', '<p>哈哈哈哈123</p>', 1, 0, '110', '2022-02-22 01:01:25', '110', '2022-02-22 01:01:46', b'0', 121);
|
INSERT INTO `system_notice` (`id`, `title`, `content`, `type`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (4, '我是测试标题', '<p>哈哈哈哈123</p>', 1, 0, '110', '2022-02-22 01:01:25', '110', '2022-02-22 01:01:46', b'0', 121);
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
|
|
@ -3438,7 +3198,7 @@ CREATE TABLE `system_oauth2_access_token` (
|
||||||
PRIMARY KEY (`id`) USING BTREE,
|
PRIMARY KEY (`id`) USING BTREE,
|
||||||
INDEX `idx_access_token`(`access_token` ASC) USING BTREE,
|
INDEX `idx_access_token`(`access_token` ASC) USING BTREE,
|
||||||
INDEX `idx_refresh_token`(`refresh_token` ASC) USING BTREE
|
INDEX `idx_refresh_token`(`refresh_token` ASC) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 57395 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'OAuth2 访问令牌';
|
) ENGINE = InnoDB AUTO_INCREMENT = 51247 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'OAuth2 访问令牌';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of system_oauth2_access_token
|
-- Records of system_oauth2_access_token
|
||||||
|
|
@ -3564,7 +3324,7 @@ CREATE TABLE `system_oauth2_refresh_token` (
|
||||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
||||||
PRIMARY KEY (`id`) USING BTREE,
|
PRIMARY KEY (`id`) USING BTREE,
|
||||||
INDEX `idx_refresh_token`(`refresh_token` ASC) USING BTREE
|
INDEX `idx_refresh_token`(`refresh_token` ASC) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 2728 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'OAuth2 刷新令牌';
|
) ENGINE = InnoDB AUTO_INCREMENT = 2553 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'OAuth2 刷新令牌';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of system_oauth2_refresh_token
|
-- Records of system_oauth2_refresh_token
|
||||||
|
|
@ -3600,7 +3360,7 @@ CREATE TABLE `system_operate_log` (
|
||||||
PRIMARY KEY (`id`) USING BTREE,
|
PRIMARY KEY (`id`) USING BTREE,
|
||||||
INDEX `idx_user_id`(`user_id` ASC) USING BTREE,
|
INDEX `idx_user_id`(`user_id` ASC) USING BTREE,
|
||||||
INDEX `idx_create_time`(`create_time` ASC) USING BTREE
|
INDEX `idx_create_time`(`create_time` ASC) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 9195 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '操作日志记录 V2 版本';
|
) ENGINE = InnoDB AUTO_INCREMENT = 9193 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '操作日志记录 V2 版本';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of system_operate_log
|
-- Records of system_operate_log
|
||||||
|
|
@ -3689,7 +3449,7 @@ CREATE TABLE `system_role_menu` (
|
||||||
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
|
||||||
PRIMARY KEY (`id`) USING BTREE,
|
PRIMARY KEY (`id`) USING BTREE,
|
||||||
INDEX `idx_role_id`(`role_id` ASC) USING BTREE
|
INDEX `idx_role_id`(`role_id` ASC) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 6381 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '角色和菜单关联表';
|
) ENGINE = InnoDB AUTO_INCREMENT = 6365 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '角色和菜单关联表';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of system_role_menu
|
-- Records of system_role_menu
|
||||||
|
|
@ -4581,14 +4341,6 @@ INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_t
|
||||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6362, 109, 5811, '', '2026-03-30 03:13:05', '', '2026-03-30 03:13:05', b'0', 121);
|
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6362, 109, 5811, '', '2026-03-30 03:13:05', '', '2026-03-30 03:13:05', b'0', 121);
|
||||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6363, 111, 5811, '', '2026-03-30 03:13:05', '', '2026-03-30 03:13:05', b'0', 122);
|
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6363, 111, 5811, '', '2026-03-30 03:13:05', '', '2026-03-30 03:13:05', b'0', 122);
|
||||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6364, 155, 5811, '', '2026-03-30 03:13:05', '', '2026-03-30 03:13:05', b'0', 1);
|
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6364, 155, 5811, '', '2026-03-30 03:13:05', '', '2026-03-30 03:13:05', b'0', 1);
|
||||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6365, 2, 6400, '1', '2026-05-09 16:11:01', '1', '2026-05-09 16:11:01', b'0', 1);
|
|
||||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6366, 2, 6401, '1', '2026-05-09 16:11:01', '1', '2026-05-09 16:11:01', b'0', 1);
|
|
||||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6367, 2, 6402, '1', '2026-05-09 16:11:01', '1', '2026-05-09 16:11:01', b'0', 1);
|
|
||||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6368, 2, 6403, '1', '2026-05-09 16:11:01', '1', '2026-05-09 16:11:01', b'0', 1);
|
|
||||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6369, 2, 6404, '1', '2026-05-09 16:11:01', '1', '2026-05-09 16:11:01', b'0', 1);
|
|
||||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6370, 2, 6405, '1', '2026-05-09 16:11:01', '1', '2026-05-09 16:11:01', b'0', 1);
|
|
||||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6371, 2, 6406, '1', '2026-05-09 16:11:01', '1', '2026-05-09 16:11:01', b'0', 1);
|
|
||||||
INSERT INTO `system_role_menu` (`id`, `role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6380, 2, 6490, '1', '2026-05-14 09:36:12', '1', '2026-05-14 09:36:12', b'0', 1);
|
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
|
|
@ -4684,7 +4436,7 @@ CREATE TABLE `system_sms_log` (
|
||||||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||||
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
|
||||||
PRIMARY KEY (`id`) USING BTREE
|
PRIMARY KEY (`id`) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 1553 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '短信日志';
|
) ENGINE = InnoDB AUTO_INCREMENT = 1549 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '短信日志';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of system_sms_log
|
-- Records of system_sms_log
|
||||||
|
|
@ -4998,16 +4750,16 @@ CREATE TABLE `system_users` (
|
||||||
INDEX `idx_mobile`(`mobile` ASC) USING BTREE,
|
INDEX `idx_mobile`(`mobile` ASC) USING BTREE,
|
||||||
INDEX `idx_email`(`email` ASC) USING BTREE,
|
INDEX `idx_email`(`email` ASC) USING BTREE,
|
||||||
INDEX `idx_dept_id`(`dept_id` ASC) USING BTREE
|
INDEX `idx_dept_id`(`dept_id` ASC) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 225 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '用户信息表';
|
) ENGINE = InnoDB AUTO_INCREMENT = 145 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '用户信息表';
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of system_users
|
-- Records of system_users
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
BEGIN;
|
BEGIN;
|
||||||
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1, 'admin', '$2a$04$.vd8nPeLwxt6hnSzmAoAyul8BOLX7Cib6QhcxRe30rfvrIPQHH1OG', '芋道源码', '管理员', 103, '[1,2]', '13aoteman@126.com', '18818260272', 1, 'http://test.yudao.iocoder.cn/20260517/blob_1778998103688.png', 0, '0:0:0:0:0:0:0:1', '2026-05-31 21:54:49', 'admin', '2021-01-05 17:03:47', NULL, '2026-05-31 21:54:49', b'0', 1);
|
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1, 'admin', '$2a$04$.vd8nPeLwxt6hnSzmAoAyul8BOLX7Cib6QhcxRe30rfvrIPQHH1OG', '芋道源码', '管理员', 103, '[1,2]', '13aoteman@126.com', '18818260272', 1, 'http://test.yudao.iocoder.cn/user/avatar/20251220/blob_1766215463801.jpg', 0, '0:0:0:0:0:0:0:1', '2026-04-17 08:47:40', 'admin', '2021-01-05 17:03:47', NULL, '2026-04-17 08:47:40', b'0', 1);
|
||||||
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (100, 'yudao', '$2a$04$.vd8nPeLwxt6hnSzmAoAyul8BOLX7Cib6QhcxRe30rfvrIPQHH1OG', '芋道', '不要吓我', 104, '[1]', 'yudao@iocoder.cn', '15601691300', 1, NULL, 0, '0:0:0:0:0:0:0:1', '2026-04-19 17:40:55', '', '2021-01-07 09:07:17', NULL, '2026-04-19 17:40:55', b'0', 1);
|
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (100, 'yudao', '$2a$04$h.aaPKgO.odHepnk5PCsWeEwKdojFWdTItxGKfx1r0e1CSeBzsTJ6', '芋道', '不要吓我', 104, '[1]', 'yudao@iocoder.cn', '15601691300', 1, NULL, 0, '0:0:0:0:0:0:0:1', '2025-12-15 21:47:26', '', '2021-01-07 09:07:17', NULL, '2025-12-15 21:47:26', b'0', 1);
|
||||||
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (103, 'yuanma', '$2a$04$k/d6mc0nySN0i2udwcI8Ee8V5aM5OHixBRbQfXmPuFTUl3Zf/DBs.', '源码', NULL, 106, NULL, 'yuanma@iocoder.cn', '15601701300', 0, NULL, 0, '0:0:0:0:0:0:0:1', '2026-04-27 13:19:27', '', '2021-01-13 23:50:35', NULL, '2026-04-27 13:19:27', b'0', 1);
|
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (103, 'yuanma', '$2a$04$fUBSmjKCPYAUmnMzOb6qE.eZCGPhHi1JmAKclODbfS/O7fHOl2bH6', '源码', NULL, 106, NULL, 'yuanma@iocoder.cn', '15601701300', 0, NULL, 0, '0:0:0:0:0:0:0:1', '2024-08-11 17:48:12', '', '2021-01-13 23:50:35', '1', '2025-07-09 23:41:58', b'0', 1);
|
||||||
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (104, 'test', '$2a$04$BrwaYn303hjA/6TnXqdGoOLhyHOAA0bVrAFu6.1dJKycqKUnIoRz2', '测试号', NULL, 107, '[1,2]', '111@qq.com', '15601691200', 1, NULL, 0, '0:0:0:0:0:0:0:1', '2026-05-20 23:37:11', '', '2021-01-21 02:13:53', NULL, '2026-05-20 23:37:11', b'0', 1);
|
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (104, 'test', '$2a$04$BrwaYn303hjA/6TnXqdGoOLhyHOAA0bVrAFu6.1dJKycqKUnIoRz2', '测试号', NULL, 107, '[1,2]', '111@qq.com', '15601691200', 1, NULL, 0, '0:0:0:0:0:0:0:1', '2026-01-04 18:09:54', '', '2021-01-21 02:13:53', NULL, '2026-01-04 18:09:54', b'0', 1);
|
||||||
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (107, 'admin107', '$2a$10$dYOOBKMO93v/.ReCqzyFg.o67Tqk.bbc2bhrpyBGkIw9aypCtr2pm', '芋艿', NULL, NULL, NULL, '', '15601691300', 0, NULL, 0, '', NULL, '1', '2022-02-20 22:59:33', '1', '2025-04-21 14:23:08', b'0', 118);
|
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (107, 'admin107', '$2a$10$dYOOBKMO93v/.ReCqzyFg.o67Tqk.bbc2bhrpyBGkIw9aypCtr2pm', '芋艿', NULL, NULL, NULL, '', '15601691300', 0, NULL, 0, '', NULL, '1', '2022-02-20 22:59:33', '1', '2025-04-21 14:23:08', b'0', 118);
|
||||||
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (108, 'admin108', '$2a$10$y6mfvKoNYL1GXWak8nYwVOH.kCWqjactkzdoIDgiKl93WN3Ejg.Lu', '芋艿', NULL, NULL, NULL, '', '15601691300', 0, NULL, 0, '', NULL, '1', '2022-02-20 23:00:50', '1', '2025-04-21 14:23:08', b'0', 119);
|
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (108, 'admin108', '$2a$10$y6mfvKoNYL1GXWak8nYwVOH.kCWqjactkzdoIDgiKl93WN3Ejg.Lu', '芋艿', NULL, NULL, NULL, '', '15601691300', 0, NULL, 0, '', NULL, '1', '2022-02-20 23:00:50', '1', '2025-04-21 14:23:08', b'0', 119);
|
||||||
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (109, 'admin109', '$2a$10$JAqvH0tEc0I7dfDVBI7zyuB4E3j.uH6daIjV53.vUS6PknFkDJkuK', '芋艿', NULL, NULL, NULL, '', '15601691300', 0, NULL, 0, '', NULL, '1', '2022-02-20 23:11:50', '1', '2025-04-21 14:23:08', b'0', 120);
|
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (109, 'admin109', '$2a$10$JAqvH0tEc0I7dfDVBI7zyuB4E3j.uH6daIjV53.vUS6PknFkDJkuK', '芋艿', NULL, NULL, NULL, '', '15601691300', 0, NULL, 0, '', NULL, '1', '2022-02-20 23:11:50', '1', '2025-04-21 14:23:08', b'0', 120);
|
||||||
|
|
@ -5023,7 +4775,7 @@ INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`,
|
||||||
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (141, 'admin1', '$2a$04$oj6F6d7HrZ70kYVD3TNzEu.m3TPUzajOVuC66zdKna8KRerK1FmVa', '新用户', NULL, NULL, NULL, '', '', 0, '', 0, '0:0:0:0:0:0:0:1', '2025-04-08 13:09:07', '1', '2025-04-08 13:09:07', '1', '2025-05-14 19:11:48', b'0', 1);
|
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (141, 'admin1', '$2a$04$oj6F6d7HrZ70kYVD3TNzEu.m3TPUzajOVuC66zdKna8KRerK1FmVa', '新用户', NULL, NULL, NULL, '', '', 0, '', 0, '0:0:0:0:0:0:0:1', '2025-04-08 13:09:07', '1', '2025-04-08 13:09:07', '1', '2025-05-14 19:11:48', b'0', 1);
|
||||||
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (142, 'test01', '$2a$04$4bCYWZkjxxOC4QE0LY2M9uEEKWeJbLfs489NFtQoyidL5I0FndRaO', 'test01', '', NULL, '[]', '', '19021719925', 1, '', 0, '0:0:0:0:0:0:0:1', '2025-07-29 19:47:17', '1', '2025-07-09 21:07:10', NULL, '2025-12-02 13:23:11', b'0', 1);
|
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (142, 'test01', '$2a$04$4bCYWZkjxxOC4QE0LY2M9uEEKWeJbLfs489NFtQoyidL5I0FndRaO', 'test01', '', NULL, '[]', '', '19021719925', 1, '', 0, '0:0:0:0:0:0:0:1', '2025-07-29 19:47:17', '1', '2025-07-09 21:07:10', NULL, '2025-12-02 13:23:11', b'0', 1);
|
||||||
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (143, 'a00001', '$2a$04$GhVHFviOw/SsTmiQtifHJesDYFlHMeGK7OWh7aGCCjGGVCmbHVAwa', 'a00001', NULL, 104, NULL, '', '', 0, '', 0, '0:0:0:0:0:0:0:1', '2025-12-01 16:10:13', NULL, '2025-12-01 16:10:13', '1', '2025-12-05 21:34:05', b'0', 1);
|
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (143, 'a00001', '$2a$04$GhVHFviOw/SsTmiQtifHJesDYFlHMeGK7OWh7aGCCjGGVCmbHVAwa', 'a00001', NULL, 104, NULL, '', '', 0, '', 0, '0:0:0:0:0:0:0:1', '2025-12-01 16:10:13', NULL, '2025-12-01 16:10:13', '1', '2025-12-05 21:34:05', b'0', 1);
|
||||||
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (144, 'aoteman001', '$2a$04$omQOmhz8OyUFBKw77nr8KOtMp6xdvoQ1gWStjk9r8.OYT3Bv6oEYe', 'aoteman001', NULL, 104, NULL, '', '', 0, '', 1, '0:0:0:0:0:0:0:1', '2025-12-01 17:05:27', '1', '2025-12-01 17:05:27', '1', '2026-05-31 21:52:48', b'0', 1);
|
INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (144, 'aoteman001', '$2a$04$omQOmhz8OyUFBKw77nr8KOtMp6xdvoQ1gWStjk9r8.OYT3Bv6oEYe', 'aoteman001', NULL, 116, NULL, '', '', 0, '', 1, '0:0:0:0:0:0:0:1', '2025-12-01 17:05:27', '1', '2025-12-01 17:05:27', '1', '2025-12-15 15:55:54', b'0', 1);
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
|
|
|
||||||
|
|
@ -57,12 +57,10 @@ docker load -i dm8_20240715_x86_rh6_rq_single.tar
|
||||||
```Bash
|
```Bash
|
||||||
docker compose up -d dm8
|
docker compose up -d dm8
|
||||||
# 注意:启动完 dm 后,需要手动再执行如下命令,因为 dm 不支持初始化脚本
|
# 注意:启动完 dm 后,需要手动再执行如下命令,因为 dm 不支持初始化脚本
|
||||||
docker compose exec dm8 bash -c 'printf "SET DEFINE OFF;\n" > /tmp/schema-with-define-off.sql && cat /tmp/schema.sql >> /tmp/schema-with-define-off.sql && /opt/dmdbms/bin/disql SYSDBA/SYSDBA001 \`/tmp/schema-with-define-off.sql'
|
docker compose exec dm8 bash -c '/opt/dmdbms/bin/disql SYSDBA/SYSDBA001 \`/tmp/schema.sql'
|
||||||
exit
|
exit
|
||||||
```
|
```
|
||||||
|
|
||||||
> 注意:项目 DM8 脚本使用 `varchar(n char)` 保持和 MySQL `varchar(n)` 一致的字符长度语义,建议初始化 DM8 时使用 `PAGE_SIZE=16`、`UNICODE_FLAG=1`。`sql/tools/docker-compose.yaml` 已按该配置提供示例。使用 `disql` 导入时需要先执行 `SET DEFINE OFF;`,避免数据里的 `&` 被当作变量替换。
|
|
||||||
|
|
||||||
### 1.6 KingbaseES 人大金仓
|
### 1.6 KingbaseES 人大金仓
|
||||||
|
|
||||||
① 下载人大金仓 Docker 镜像:
|
① 下载人大金仓 Docker 镜像:
|
||||||
|
|
@ -92,25 +90,6 @@ docker compose up -d opengauss
|
||||||
docker compose exec opengauss bash -c '/usr/local/opengauss/bin/gsql -U $GS_USERNAME -W $GS_PASSWORD -d postgres -f /tmp/schema.sql'
|
docker compose exec opengauss bash -c '/usr/local/opengauss/bin/gsql -U $GS_USERNAME -W $GS_PASSWORD -d postgres -f /tmp/schema.sql'
|
||||||
```
|
```
|
||||||
|
|
||||||
### 1.8 HighGo 瀚高数据库
|
|
||||||
|
|
||||||
① 下载瀚高官方 Docker 镜像,并加载镜像文件。加载后,将镜像打成本地标签:
|
|
||||||
|
|
||||||
```Bash
|
|
||||||
docker load -i <highgo-image>.tar
|
|
||||||
docker tag <image>:<tag> highgo:local
|
|
||||||
```
|
|
||||||
|
|
||||||
② 在项目 `sql/tools` 目录下运行:
|
|
||||||
|
|
||||||
```Bash
|
|
||||||
docker compose up -d highgo
|
|
||||||
```
|
|
||||||
|
|
||||||
> 注意:不同瀚高镜像的数据目录可能不同,如果容器无法启动,请按镜像实际 `PGDATA` 修改 `docker-compose.yaml` 中的 `highgo` 数据卷挂载目录。
|
|
||||||
|
|
||||||
③ 启动完成后,需要手动导入 Quartz 和项目 SQL。瀚高兼容 PostgreSQL,具体客户端命令以当前镜像为准,可使用 `psql` 或瀚高镜像内置的兼容客户端执行 `/tmp/quartz.sql`、`/tmp/schema.sql`。
|
|
||||||
|
|
||||||
## 1.X 容器的销毁重建
|
## 1.X 容器的销毁重建
|
||||||
|
|
||||||
开发测试过程中,有时候需要创建全新干净的数据库。由于测试数据 Docker 容器采用数据卷 Volume 挂载数据库实例的数据目录,因此销毁数据需要停止容器后,删除数据卷,然后再重新创建容器。
|
开发测试过程中,有时候需要创建全新干净的数据库。由于测试数据 Docker 容器采用数据卷 Volume 挂载数据库实例的数据目录,因此销毁数据需要停止容器后,删除数据卷,然后再重新创建容器。
|
||||||
|
|
@ -124,7 +103,7 @@ docker volume rm ruoyi-vue-pro_postgres
|
||||||
|
|
||||||
## 2. MySQL 转换其它数据库
|
## 2. MySQL 转换其它数据库
|
||||||
|
|
||||||
项目提供了 `sql/tools/convertor.py` 脚本,支持将 MySQL 转换为 Oracle、PostgreSQL、SQL Server、达梦、人大金仓、OpenGauss、瀚高等数据库的脚本。
|
项目提供了 `sql/tools/convertor.py` 脚本,支持将 MySQL 转换为 Oracle、PostgreSQL、SQL Server、达梦、人大金仓、OpenGauss 等数据库的脚本。
|
||||||
|
|
||||||
### 2.1 实现原理
|
### 2.1 实现原理
|
||||||
|
|
||||||
|
|
@ -139,12 +118,11 @@ pip install simple-ddl-parser
|
||||||
# pip3 install simple-ddl-parser
|
# pip3 install simple-ddl-parser
|
||||||
```
|
```
|
||||||
|
|
||||||
② 在 `sql/tools/` 目录下,执行如下命令打印生成 postgres 的脚本内容,其他可选参数有:`oracle`、`sqlserver`、`dm8`、`kingbase`、`opengauss`、`highgo`:
|
② 在 `sql/tools/` 目录下,执行如下命令打印生成 postgres 的脚本内容,其他可选参数有:`oracle`、`sqlserver`、`dm8`、`kingbase`、`opengauss`:
|
||||||
|
|
||||||
```Bash
|
```Bash
|
||||||
python3 convertor.py postgres
|
python3 convertor.py postgres
|
||||||
# python3 convertor.py postgres > tmp.sql
|
# python3 convertor.py postgres > tmp.sql
|
||||||
# python3 convertor.py highgo ../mysql/ruoyi-vue-pro.sql > ../highgo/ruoyi-vue-pro.sql
|
|
||||||
```
|
```
|
||||||
|
|
||||||
程序将 SQL 脚本打印到终端,可以重定向到临时文件 `tmp.sql`。
|
程序将 SQL 脚本打印到终端,可以重定向到临时文件 `tmp.sql`。
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,6 @@ uv run --with simple-ddl-parser convertor.py postgres ../mysql/ruoyi-vue-pro.sql
|
||||||
uv run --with simple-ddl-parser convertor.py sqlserver ../mysql/ruoyi-vue-pro.sql > ../sqlserver/ruoyi-vue-pro.sql
|
uv run --with simple-ddl-parser convertor.py sqlserver ../mysql/ruoyi-vue-pro.sql > ../sqlserver/ruoyi-vue-pro.sql
|
||||||
uv run --with simple-ddl-parser convertor.py kingbase ../mysql/ruoyi-vue-pro.sql > ../kingbase/ruoyi-vue-pro.sql
|
uv run --with simple-ddl-parser convertor.py kingbase ../mysql/ruoyi-vue-pro.sql > ../kingbase/ruoyi-vue-pro.sql
|
||||||
uv run --with simple-ddl-parser convertor.py opengauss ../mysql/ruoyi-vue-pro.sql > ../opengauss/ruoyi-vue-pro.sql
|
uv run --with simple-ddl-parser convertor.py opengauss ../mysql/ruoyi-vue-pro.sql > ../opengauss/ruoyi-vue-pro.sql
|
||||||
uv run --with simple-ddl-parser convertor.py highgo ../mysql/ruoyi-vue-pro.sql > ../highgo/ruoyi-vue-pro.sql
|
|
||||||
uv run --with simple-ddl-parser convertor.py oracle ../mysql/ruoyi-vue-pro.sql > ../oracle/ruoyi-vue-pro.sql
|
uv run --with simple-ddl-parser convertor.py oracle ../mysql/ruoyi-vue-pro.sql > ../oracle/ruoyi-vue-pro.sql
|
||||||
uv run --with simple-ddl-parser convertor.py dm8 ../mysql/ruoyi-vue-pro.sql > ../dm/ruoyi-vue-pro-dm8.sql
|
uv run --with simple-ddl-parser convertor.py dm8 ../mysql/ruoyi-vue-pro.sql > ../dm/ruoyi-vue-pro-dm8.sql
|
||||||
"""
|
"""
|
||||||
|
|
@ -63,10 +62,6 @@ def load_and_clean(sql_file: str) -> str:
|
||||||
content = open(sql_file, encoding="utf-8").read()
|
content = open(sql_file, encoding="utf-8").read()
|
||||||
for replace_pair in REPLACE_PAIR_LIST:
|
for replace_pair in REPLACE_PAIR_LIST:
|
||||||
content = content.replace(*replace_pair)
|
content = content.replace(*replace_pair)
|
||||||
# 移除所有 CHARACTER SET / COLLATE 变体 (utf8mb3、utf8 等)
|
|
||||||
content = re.sub(r" CHARACTER SET \w+ COLLATE \w+", "", content)
|
|
||||||
content = re.sub(r" CHARACTER SET \w+", "", content)
|
|
||||||
content = re.sub(r" COLLATE \w+", "", content)
|
|
||||||
# 移除索引字段的前缀长度定义,例如: `name`(32) -> `name`
|
# 移除索引字段的前缀长度定义,例如: `name`(32) -> `name`
|
||||||
# 移除索引定义上的 USING BTREE COMMENT 部分
|
# 移除索引定义上的 USING BTREE COMMENT 部分
|
||||||
# 相关 issue:https://t.zsxq.com/96IFc 、https://t.zsxq.com/rC3A3
|
# 相关 issue:https://t.zsxq.com/96IFc 、https://t.zsxq.com/rC3A3
|
||||||
|
|
@ -78,18 +73,11 @@ def load_and_clean(sql_file: str) -> str:
|
||||||
|
|
||||||
|
|
||||||
class Convertor(ABC):
|
class Convertor(ABC):
|
||||||
# 不同数据库的关键字不完全一致;子类按需声明需要转义的列名。
|
|
||||||
reserved_column_names = set()
|
|
||||||
|
|
||||||
def __init__(self, src: str, db_type) -> None:
|
def __init__(self, src: str, db_type) -> None:
|
||||||
self.src = src
|
self.src = src
|
||||||
self.db_type = db_type
|
self.db_type = db_type
|
||||||
self.content = load_and_clean(self.src)
|
self.content = load_and_clean(self.src)
|
||||||
# original_content 保留原始 COMMENT 信息,用于注释提取
|
self.table_script_list = re.findall(r"CREATE TABLE [^;]*;", self.content)
|
||||||
self.original_content = open(src, encoding="utf-8").read()
|
|
||||||
# 剥离列级 COMMENT 以避免 COMMENT 值内的分号截断 CREATE TABLE 正则
|
|
||||||
content_no_comment = re.sub(r" COMMENT '(?:[^'\\]|\\.)*'", "", self.content)
|
|
||||||
self.table_script_list = re.findall(r"CREATE TABLE [^;]*;", content_no_comment)
|
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def translate_type(self, type: str, size: Optional[Union[int, Tuple[int]]]) -> str:
|
def translate_type(self, type: str, size: Optional[Union[int, Tuple[int]]]) -> str:
|
||||||
|
|
@ -183,31 +171,6 @@ class Convertor(ABC):
|
||||||
"""
|
"""
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
def escape_column_name(self, name: str) -> str:
|
|
||||||
"""转义目标库保留字列名,例如 Oracle / Kingbase 的 level。"""
|
|
||||||
|
|
||||||
column_name = name.lower()
|
|
||||||
if column_name in self.reserved_column_names:
|
|
||||||
return f'"{column_name}"'
|
|
||||||
return column_name
|
|
||||||
|
|
||||||
def escape_insert_columns(self, insert_script: str) -> str:
|
|
||||||
"""INSERT 显式列清单需要和 CREATE / COMMENT 使用同一套列名转义。"""
|
|
||||||
|
|
||||||
match = re.match(
|
|
||||||
r"(INSERT INTO\s+\S+\s*\()([^)]+)(\)\s+VALUES\s+[\s\S]*)",
|
|
||||||
insert_script,
|
|
||||||
flags=re.IGNORECASE,
|
|
||||||
)
|
|
||||||
if not match:
|
|
||||||
return insert_script
|
|
||||||
|
|
||||||
columns = [
|
|
||||||
self.escape_column_name(column.strip())
|
|
||||||
for column in match.group(2).split(",")
|
|
||||||
]
|
|
||||||
return f"{match.group(1)}{', '.join(columns)}{match.group(3)}"
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def inserts(table_name: str, script_content: str) -> Generator:
|
def inserts(table_name: str, script_content: str) -> Generator:
|
||||||
PREFIX = f"INSERT INTO `{table_name}`"
|
PREFIX = f"INSERT INTO `{table_name}`"
|
||||||
|
|
@ -219,8 +182,7 @@ class Convertor(ABC):
|
||||||
head = head.strip().replace("`", "").lower()
|
head = head.strip().replace("`", "").lower()
|
||||||
tail = tail.strip().replace(r"\"", '"')
|
tail = tail.strip().replace(r"\"", '"')
|
||||||
# tail = tail.replace("b'0'", "'0'").replace("b'1'", "'1'")
|
# tail = tail.replace("b'0'", "'0'").replace("b'1'", "'1'")
|
||||||
col_part = f" {head}" if head else ""
|
yield f"INSERT INTO {table_name.lower()} {head} VALUES {tail}"
|
||||||
yield f"INSERT INTO {table_name.lower()}{col_part} VALUES {tail}"
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def index(ddl: Dict) -> Generator:
|
def index(ddl: Dict) -> Generator:
|
||||||
|
|
@ -233,55 +195,18 @@ class Convertor(ABC):
|
||||||
Generator[str]: create index 语句
|
Generator[str]: create index 语句
|
||||||
"""
|
"""
|
||||||
|
|
||||||
for no, index in enumerate(ddl.get("index", []), 1):
|
def generate_columns(columns):
|
||||||
columns = ", ".join(Convertor.index_columns(index.get("columns", [])))
|
keys = [
|
||||||
if not columns:
|
f"{col['name'].lower()}{' ' + col['order'].lower() if col['order'] != 'ASC' else ''}"
|
||||||
continue
|
for col in columns[0]
|
||||||
|
]
|
||||||
|
return ", ".join(keys)
|
||||||
|
|
||||||
|
for no, index in enumerate(ddl["index"], 1):
|
||||||
|
columns = generate_columns(index["columns"])
|
||||||
table_name = ddl["table_name"].lower()
|
table_name = ddl["table_name"].lower()
|
||||||
yield f"CREATE INDEX idx_{table_name}_{no:02d} ON {table_name} ({columns})"
|
yield f"CREATE INDEX idx_{table_name}_{no:02d} ON {table_name} ({columns})"
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def index_columns(columns) -> list:
|
|
||||||
"""兼容 simple-ddl-parser 不同版本的索引列结构。"""
|
|
||||||
|
|
||||||
keys = []
|
|
||||||
|
|
||||||
def append(name, order="ASC"):
|
|
||||||
if not name:
|
|
||||||
return
|
|
||||||
column_name = str(name).strip("`").lower()
|
|
||||||
column_order = str(order or "ASC").upper()
|
|
||||||
if column_order == "DESC":
|
|
||||||
keys.append(f"{column_name} desc")
|
|
||||||
else:
|
|
||||||
keys.append(column_name)
|
|
||||||
|
|
||||||
def visit(value):
|
|
||||||
# 普通索引常见结构:[[{'name': 'user_id', 'order': 'ASC'}]]
|
|
||||||
if isinstance(value, (list, tuple)):
|
|
||||||
for item in value:
|
|
||||||
visit(item)
|
|
||||||
return
|
|
||||||
if isinstance(value, dict):
|
|
||||||
name = value.get("name")
|
|
||||||
if isinstance(name, (dict, list, tuple)):
|
|
||||||
visit(name)
|
|
||||||
return
|
|
||||||
append(name, value.get("order", "ASC"))
|
|
||||||
return
|
|
||||||
# 唯一索引在部分版本中会被解析成 ['mobile', 'ASC', 'tenant_id', 'ASC']。
|
|
||||||
if isinstance(value, str):
|
|
||||||
token = value.strip("`")
|
|
||||||
order = token.upper()
|
|
||||||
if order in ("ASC", "DESC"):
|
|
||||||
if order == "DESC" and keys and not keys[-1].endswith(" desc"):
|
|
||||||
keys[-1] = f"{keys[-1]} desc"
|
|
||||||
return
|
|
||||||
append(token)
|
|
||||||
|
|
||||||
visit(columns)
|
|
||||||
return keys
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def unique_index(ddl: Dict) -> Generator:
|
def unique_index(ddl: Dict) -> Generator:
|
||||||
if "constraints" in ddl and "uniques" in ddl["constraints"]:
|
if "constraints" in ddl and "uniques" in ddl["constraints"]:
|
||||||
|
|
@ -289,9 +214,7 @@ class Convertor(ABC):
|
||||||
for uk in uk_list:
|
for uk in uk_list:
|
||||||
table_name = ddl["table_name"]
|
table_name = ddl["table_name"]
|
||||||
uk_name = uk["constraint_name"]
|
uk_name = uk["constraint_name"]
|
||||||
uk_columns = Convertor.index_columns(uk["columns"])
|
uk_columns = uk["columns"]
|
||||||
if not uk_columns:
|
|
||||||
continue
|
|
||||||
yield table_name, uk_name, uk_columns
|
yield table_name, uk_name, uk_columns
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
|
@ -304,8 +227,7 @@ class Convertor(ABC):
|
||||||
yield field, comment_string
|
yield field, comment_string
|
||||||
|
|
||||||
def table_comment(self, table_sql: str) -> str:
|
def table_comment(self, table_sql: str) -> str:
|
||||||
# 兼容 COMMENT='xxx' / COMMENT = 'xxx' 等等号两侧空格变体;允许 COMMENT 内含转义单引号
|
match = re.search(r"COMMENT \='([^']+)';", table_sql)
|
||||||
match = re.search(r"COMMENT\s*=\s*'((?:[^'\\]|\\.)*)'", table_sql)
|
|
||||||
return match.group(1) if match else None
|
return match.group(1) if match else None
|
||||||
|
|
||||||
def print(self):
|
def print(self):
|
||||||
|
|
@ -329,9 +251,7 @@ class Convertor(ABC):
|
||||||
|
|
||||||
error_scripts = []
|
error_scripts = []
|
||||||
for table_sql in self.table_script_list:
|
for table_sql in self.table_script_list:
|
||||||
# 剥离 COMMENT 子句避免 DDLParser 无法处理中文等特殊字符
|
ddl = DDLParser(table_sql.replace("`", "")).run()
|
||||||
table_sql_for_parse = re.sub(r"\s+COMMENT\s+'[^']*'", "", table_sql)
|
|
||||||
ddl = DDLParser(table_sql_for_parse.replace("`", "")).run()
|
|
||||||
|
|
||||||
# 如果parse失败, 需要跟进
|
# 如果parse失败, 需要跟进
|
||||||
if len(ddl) == 0:
|
if len(ddl) == 0:
|
||||||
|
|
@ -346,23 +266,17 @@ class Convertor(ABC):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# 解析注释
|
# 解析注释
|
||||||
# 从原始 SQL 提取注释(支持中文等 DDLParser 不能处理的内容)
|
|
||||||
# 按表名定位完整建表段(以「换行 + )」起始的 ENGINE 行作为终止),避免被列 COMMENT 内的分号截断
|
|
||||||
orig_match = re.search(
|
|
||||||
rf"CREATE TABLE\s+`{re.escape(table_name)}`[\s\S]*?\n\)[^;]*;",
|
|
||||||
self.original_content,
|
|
||||||
flags=re.IGNORECASE,
|
|
||||||
)
|
|
||||||
orig_table_sql = orig_match.group() if orig_match else table_sql
|
|
||||||
comments_dict = dict(Convertor.filed_comments(orig_table_sql))
|
|
||||||
for column in table_ddl["columns"]:
|
for column in table_ddl["columns"]:
|
||||||
column["comment"] = comments_dict.get(column["name"], "")
|
column["comment"] = bytes(column["comment"], "utf-8").decode(
|
||||||
table_ddl["comment"] = self.table_comment(orig_table_sql) or ""
|
r"unicode_escape"
|
||||||
|
)[1:-1]
|
||||||
|
table_ddl["comment"] = bytes(table_ddl["comment"], "utf-8").decode(
|
||||||
|
r"unicode_escape"
|
||||||
|
)[1:-1]
|
||||||
|
|
||||||
# 为每个表生成个6个基本部分
|
# 为每个表生成个6个基本部分
|
||||||
create = self.gen_create(table_ddl)
|
create = self.gen_create(table_ddl)
|
||||||
has_id = any(col["name"].lower() == "id" for col in table_ddl["columns"])
|
pk = self.gen_pk(table_name)
|
||||||
pk = self.gen_pk(table_name) if has_id else ""
|
|
||||||
uk = self.gen_uk(table_ddl)
|
uk = self.gen_uk(table_ddl)
|
||||||
index = self.gen_index(table_ddl)
|
index = self.gen_index(table_ddl)
|
||||||
comment = self.gen_comment(table_ddl)
|
comment = self.gen_comment(table_ddl)
|
||||||
|
|
@ -406,31 +320,25 @@ class PostgreSQLConvertor(Convertor):
|
||||||
|
|
||||||
if type == "varchar":
|
if type == "varchar":
|
||||||
return f"varchar({size})"
|
return f"varchar({size})"
|
||||||
if type in ("int", "int unsigned", "int unsigned zerofill"):
|
if type in ("int", "int unsigned"):
|
||||||
return "int4"
|
return "int4"
|
||||||
if type in ("bigint", "bigint unsigned"):
|
if type in ("bigint", "bigint unsigned"):
|
||||||
return "int8"
|
return "int8"
|
||||||
if type in ("tinyint", "smallint", "tinyint unsigned"):
|
if type == "datetime":
|
||||||
return "int2"
|
|
||||||
if type in ("datetime", "timestamp null"):
|
|
||||||
return "timestamp"
|
return "timestamp"
|
||||||
if type == "date":
|
|
||||||
return "date"
|
|
||||||
if type == "json":
|
|
||||||
return "jsonb"
|
|
||||||
if type == "double":
|
|
||||||
return "double precision"
|
|
||||||
if type == "timestamp":
|
if type == "timestamp":
|
||||||
return f"timestamp({size})" if size else "timestamp"
|
return f"timestamp({size})"
|
||||||
if type == "bit":
|
if type == "bit":
|
||||||
return "bool"
|
return "bool"
|
||||||
|
if type in ("tinyint", "smallint"):
|
||||||
|
return "int2"
|
||||||
if type in ("text", "longtext"):
|
if type in ("text", "longtext"):
|
||||||
return "text"
|
return "text"
|
||||||
if type in ("blob", "mediumblob", "longblob"):
|
if type in ("blob", "mediumblob"):
|
||||||
return "bytea"
|
return "bytea"
|
||||||
if type == "decimal":
|
if type == "decimal":
|
||||||
return (
|
return (
|
||||||
f"numeric({','.join(str(s) for s in size)})" if size and len(size) else "numeric"
|
f"numeric({','.join(str(s) for s in size)})" if len(size) else "numeric"
|
||||||
)
|
)
|
||||||
|
|
||||||
def gen_create(self, ddl: Dict) -> str:
|
def gen_create(self, ddl: Dict) -> str:
|
||||||
|
|
@ -443,13 +351,9 @@ class PostgreSQLConvertor(Convertor):
|
||||||
|
|
||||||
type = col["type"].lower()
|
type = col["type"].lower()
|
||||||
full_type = self.translate_type(type, col["size"])
|
full_type = self.translate_type(type, col["size"])
|
||||||
if full_type is None:
|
|
||||||
raise NotImplementedError(
|
|
||||||
f"未支持的类型: '{col['type']}' (列: {name}, 表: {ddl['table_name']})"
|
|
||||||
)
|
|
||||||
nullable = "NULL" if col["nullable"] else "NOT NULL"
|
nullable = "NULL" if col["nullable"] else "NOT NULL"
|
||||||
default = f"DEFAULT {col['default']}" if col["default"] is not None else ""
|
default = f"DEFAULT {col['default']}" if col["default"] is not None else ""
|
||||||
return f"{self.escape_column_name(name)} {full_type} {nullable} {default}"
|
return f"{name} {full_type} {nullable} {default}"
|
||||||
|
|
||||||
table_name = ddl["table_name"].lower()
|
table_name = ddl["table_name"].lower()
|
||||||
columns = [f"{_generate_column(col).strip()}" for col in ddl["columns"]]
|
columns = [f"{_generate_column(col).strip()}" for col in ddl["columns"]]
|
||||||
|
|
@ -474,7 +378,7 @@ CREATE TABLE {table_name} (
|
||||||
for column in table_ddl["columns"]:
|
for column in table_ddl["columns"]:
|
||||||
table_comment = column["comment"]
|
table_comment = column["comment"]
|
||||||
script += (
|
script += (
|
||||||
f"COMMENT ON COLUMN {table_ddl['table_name']}.{self.escape_column_name(column['name'])} IS '{table_comment}';"
|
f"COMMENT ON COLUMN {table_ddl['table_name']}.{column['name']} IS '{table_comment}';"
|
||||||
+ "\n"
|
+ "\n"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -503,9 +407,6 @@ CREATE TABLE {table_name} (
|
||||||
"""生成 insert 语句,以及根据最后的 insert id+1 生成 Sequence"""
|
"""生成 insert 语句,以及根据最后的 insert id+1 生成 Sequence"""
|
||||||
|
|
||||||
inserts = list(Convertor.inserts(table_name, self.content))
|
inserts = list(Convertor.inserts(table_name, self.content))
|
||||||
inserts = [self.escape_insert_columns(s) for s in inserts]
|
|
||||||
# 转换 MySQL 字符串转义为 PostgreSQL 格式:\\ -> \,\' -> ''
|
|
||||||
inserts = [re.sub(r"\\\\|\\'", lambda m: "\\" if m.group() == "\\\\" else "''", s) for s in inserts]
|
|
||||||
## 生成 insert 脚本
|
## 生成 insert 脚本
|
||||||
script = ""
|
script = ""
|
||||||
last_id = 0
|
last_id = 0
|
||||||
|
|
@ -551,8 +452,6 @@ INSERT INTO dual VALUES (1);
|
||||||
|
|
||||||
|
|
||||||
class OracleConvertor(Convertor):
|
class OracleConvertor(Convertor):
|
||||||
reserved_column_names = {"level", "size"}
|
|
||||||
|
|
||||||
def __init__(self, src):
|
def __init__(self, src):
|
||||||
super().__init__(src, "Oracle")
|
super().__init__(src, "Oracle")
|
||||||
|
|
||||||
|
|
@ -597,8 +496,10 @@ class OracleConvertor(Convertor):
|
||||||
# Oracle的 INSERT '' 不能通过NOT NULL校验,因此对文字类型字段覆写为 NULL
|
# Oracle的 INSERT '' 不能通过NOT NULL校验,因此对文字类型字段覆写为 NULL
|
||||||
nullable = "NULL" if type in ("varchar", "text", "longtext") else nullable
|
nullable = "NULL" if type in ("varchar", "text", "longtext") else nullable
|
||||||
default = f"DEFAULT {col['default']}" if col["default"] is not None else ""
|
default = f"DEFAULT {col['default']}" if col["default"] is not None else ""
|
||||||
|
# Oracle 中 size 不能作为字段名
|
||||||
|
field_name = '"size"' if name == "size" else name
|
||||||
# Oracle DEFAULT 定义在 NULLABLE 之前
|
# Oracle DEFAULT 定义在 NULLABLE 之前
|
||||||
return f"{self.escape_column_name(name)} {full_type} {default} {nullable}"
|
return f"{field_name} {full_type} {default} {nullable}"
|
||||||
|
|
||||||
table_name = ddl["table_name"].lower()
|
table_name = ddl["table_name"].lower()
|
||||||
columns = [f"{generate_column(col).strip()}" for col in ddl["columns"]]
|
columns = [f"{generate_column(col).strip()}" for col in ddl["columns"]]
|
||||||
|
|
@ -623,7 +524,7 @@ CREATE TABLE {table_name} (
|
||||||
for column in table_ddl["columns"]:
|
for column in table_ddl["columns"]:
|
||||||
table_comment = column["comment"]
|
table_comment = column["comment"]
|
||||||
script += (
|
script += (
|
||||||
f"COMMENT ON COLUMN {table_ddl['table_name']}.{self.escape_column_name(column['name'])} IS '{table_comment}';"
|
f"COMMENT ON COLUMN {table_ddl['table_name']}.{column['name']} IS '{table_comment}';"
|
||||||
+ "\n"
|
+ "\n"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -655,7 +556,6 @@ CREATE TABLE {table_name} (
|
||||||
"""拷贝 INSERT 语句"""
|
"""拷贝 INSERT 语句"""
|
||||||
inserts = []
|
inserts = []
|
||||||
for insert_script in Convertor.inserts(table_name, self.content):
|
for insert_script in Convertor.inserts(table_name, self.content):
|
||||||
insert_script = self.escape_insert_columns(insert_script)
|
|
||||||
# 对日期数据添加 TO_DATE 转换
|
# 对日期数据添加 TO_DATE 转换
|
||||||
insert_script = re.sub(
|
insert_script = re.sub(
|
||||||
r"('\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}')",
|
r"('\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}')",
|
||||||
|
|
@ -871,9 +771,7 @@ class DM8Convertor(Convertor):
|
||||||
type = type.lower()
|
type = type.lower()
|
||||||
|
|
||||||
if type == "varchar":
|
if type == "varchar":
|
||||||
# MySQL varchar(n) is character-oriented. DM8 may treat varchar(n)
|
return f"varchar({size})"
|
||||||
# as bytes, so use explicit CHAR semantics for generated scripts.
|
|
||||||
return f"varchar({size} char)"
|
|
||||||
if type in ("int", "int unsigned"):
|
if type in ("int", "int unsigned"):
|
||||||
return "int"
|
return "int"
|
||||||
if type in ("bigint", "bigint unsigned"):
|
if type in ("bigint", "bigint unsigned"):
|
||||||
|
|
@ -979,8 +877,6 @@ SET IDENTITY_INSERT {table_name.lower()} OFF;
|
||||||
|
|
||||||
|
|
||||||
class KingbaseConvertor(PostgreSQLConvertor):
|
class KingbaseConvertor(PostgreSQLConvertor):
|
||||||
reserved_column_names = {"level"}
|
|
||||||
|
|
||||||
def __init__(self, src):
|
def __init__(self, src):
|
||||||
super().__init__(src)
|
super().__init__(src)
|
||||||
self.db_type = "Kingbase"
|
self.db_type = "Kingbase"
|
||||||
|
|
@ -999,7 +895,7 @@ class KingbaseConvertor(PostgreSQLConvertor):
|
||||||
if full_type == "text":
|
if full_type == "text":
|
||||||
nullable = "NULL"
|
nullable = "NULL"
|
||||||
default = f"DEFAULT {col['default']}" if col["default"] is not None else ""
|
default = f"DEFAULT {col['default']}" if col["default"] is not None else ""
|
||||||
return f"{self.escape_column_name(name)} {full_type} {nullable} {default}"
|
return f"{name} {full_type} {nullable} {default}"
|
||||||
|
|
||||||
table_name = ddl["table_name"].lower()
|
table_name = ddl["table_name"].lower()
|
||||||
columns = [f"{_generate_column(col).strip()}" for col in ddl["columns"]]
|
columns = [f"{_generate_column(col).strip()}" for col in ddl["columns"]]
|
||||||
|
|
@ -1019,32 +915,23 @@ CREATE TABLE {table_name} (
|
||||||
|
|
||||||
|
|
||||||
class OpengaussConvertor(KingbaseConvertor):
|
class OpengaussConvertor(KingbaseConvertor):
|
||||||
reserved_column_names = set()
|
|
||||||
|
|
||||||
def __init__(self, src):
|
def __init__(self, src):
|
||||||
super().__init__(src)
|
super().__init__(src)
|
||||||
self.db_type = "OpenGauss"
|
self.db_type = "OpenGauss"
|
||||||
|
|
||||||
|
|
||||||
class HighGoConvertor(PostgreSQLConvertor):
|
|
||||||
def __init__(self, src):
|
|
||||||
super().__init__(src)
|
|
||||||
self.db_type = "HighGo"
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
parser = argparse.ArgumentParser(description="芋道系统数据库转换工具")
|
parser = argparse.ArgumentParser(description="芋道系统数据库转换工具")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"type",
|
"type",
|
||||||
type=str,
|
type=str,
|
||||||
help="目标数据库类型",
|
help="目标数据库类型",
|
||||||
choices=["postgres", "oracle", "sqlserver", "dm8", "kingbase", "opengauss", "highgo"],
|
choices=["postgres", "oracle", "sqlserver", "dm8", "kingbase", "opengauss"],
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"path",
|
"path",
|
||||||
type=str,
|
type=str,
|
||||||
help="源数据库脚本路径",
|
help="源数据库脚本路径",
|
||||||
nargs="?",
|
|
||||||
default="../mysql/ruoyi-vue-pro.sql"
|
default="../mysql/ruoyi-vue-pro.sql"
|
||||||
)
|
)
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
@ -1063,8 +950,6 @@ def main():
|
||||||
convertor = KingbaseConvertor(sql_file)
|
convertor = KingbaseConvertor(sql_file)
|
||||||
elif args.type == "opengauss":
|
elif args.type == "opengauss":
|
||||||
convertor = OpengaussConvertor(sql_file)
|
convertor = OpengaussConvertor(sql_file)
|
||||||
elif args.type == "highgo":
|
|
||||||
convertor = HighGoConvertor(sql_file)
|
|
||||||
else:
|
else:
|
||||||
raise NotImplementedError(f"不支持目标数据库类型: {args.type}")
|
raise NotImplementedError(f"不支持目标数据库类型: {args.type}")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@ volumes:
|
||||||
dm8: { }
|
dm8: { }
|
||||||
kingbase: { }
|
kingbase: { }
|
||||||
opengauss: { }
|
opengauss: { }
|
||||||
highgo: { }
|
|
||||||
|
|
||||||
services:
|
services:
|
||||||
mysql:
|
mysql:
|
||||||
|
|
@ -22,7 +21,7 @@ services:
|
||||||
volumes:
|
volumes:
|
||||||
- mysql:/var/lib/mysql/
|
- mysql:/var/lib/mysql/
|
||||||
# 注入初始化脚本
|
# 注入初始化脚本
|
||||||
- ../mysql/ruoyi-vue-pro.sql:/docker-entrypoint-initdb.d/init.sql:ro
|
- ./mysql/ruoyi-vue-pro.sql:/docker-entrypoint-initdb.d/init.sql:ro
|
||||||
command:
|
command:
|
||||||
--default-authentication-plugin=mysql_native_password
|
--default-authentication-plugin=mysql_native_password
|
||||||
--character-set-server=utf8mb4
|
--character-set-server=utf8mb4
|
||||||
|
|
@ -133,15 +132,3 @@ services:
|
||||||
- opengauss:/var/lib/opengauss
|
- opengauss:/var/lib/opengauss
|
||||||
- ../opengauss/ruoyi-vue-pro.sql:/tmp/schema.sql:ro
|
- ../opengauss/ruoyi-vue-pro.sql:/tmp/schema.sql:ro
|
||||||
# docker compose exec opengauss bash -c '/usr/local/opengauss/bin/gsql -U $GS_USERNAME -W $GS_PASSWORD -d postgres -f /tmp/schema.sql'
|
# docker compose exec opengauss bash -c '/usr/local/opengauss/bin/gsql -U $GS_USERNAME -W $GS_PASSWORD -d postgres -f /tmp/schema.sql'
|
||||||
|
|
||||||
highgo:
|
|
||||||
# 使用瀚高官方提供的 Docker 镜像,加载后打成本地标签:
|
|
||||||
# docker tag <image>:<tag> highgo:local
|
|
||||||
image: highgo:local
|
|
||||||
restart: unless-stopped
|
|
||||||
ports:
|
|
||||||
- "5866:5866"
|
|
||||||
volumes:
|
|
||||||
- highgo:/home/highgo/hgdb/data
|
|
||||||
- ../highgo/quartz.sql:/tmp/quartz.sql:ro
|
|
||||||
- ../highgo/ruoyi-vue-pro.sql:/tmp/schema.sql:ro
|
|
||||||
|
|
|
||||||
|
|
@ -14,32 +14,32 @@
|
||||||
<url>https://github.com/YunaiV/ruoyi-vue-pro</url>
|
<url>https://github.com/YunaiV/ruoyi-vue-pro</url>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<revision>2026.05-jdk8-SNAPSHOT</revision>
|
<revision>2026.03-jdk8-SNAPSHOT</revision>
|
||||||
<flatten-maven-plugin.version>1.6.0</flatten-maven-plugin.version>
|
<flatten-maven-plugin.version>1.6.0</flatten-maven-plugin.version>
|
||||||
<!-- 统一依赖管理 -->
|
<!-- 统一依赖管理 -->
|
||||||
<spring.framework.version>5.3.39</spring.framework.version>
|
<spring.framework.version>5.3.39</spring.framework.version>
|
||||||
<spring.security.version>5.8.16</spring.security.version>
|
<spring.security.version>5.8.16</spring.security.version>
|
||||||
<spring.boot.version>2.7.18</spring.boot.version>
|
<spring.boot.version>2.7.18</spring.boot.version>
|
||||||
<spring.cloud.version>2021.0.9</spring.cloud.version> <!-- Spring Boot 2.X 最多使用 2021.0.9 版本 -->
|
<spring.cloud.version>2021.0.9</spring.cloud.version>
|
||||||
<spring.cloud.alibaba.version>2021.0.6.2</spring.cloud.alibaba.version> <!-- Spring Boot 2.X 最多使用 2021.0.6.2 版本 -->
|
<spring.cloud.alibaba.version>2021.0.6.2</spring.cloud.alibaba.version>
|
||||||
<!-- Web 相关 -->
|
<!-- Web 相关 -->
|
||||||
<servlet.versoin>2.5</servlet.versoin>
|
<servlet.versoin>2.5</servlet.versoin>
|
||||||
<springdoc.version>1.8.0</springdoc.version>
|
<springdoc.version>1.8.0</springdoc.version>
|
||||||
<knife4j.version>4.5.0</knife4j.version>
|
<knife4j.version>4.5.0</knife4j.version>
|
||||||
<!-- DB 相关 -->
|
<!-- DB 相关 -->
|
||||||
<druid.version>1.2.28</druid.version>
|
<druid.version>1.2.27</druid.version>
|
||||||
<mybatis.version>3.5.19</mybatis.version>
|
<mybatis.version>3.5.19</mybatis.version>
|
||||||
<mybatis-plus.version>3.5.16</mybatis-plus.version>
|
<mybatis-plus.version>3.5.15</mybatis-plus.version>
|
||||||
<mybatis-plus-join.version>1.5.7</mybatis-plus-join.version>
|
<mybatis-plus-join.version>1.5.5</mybatis-plus-join.version>
|
||||||
<dynamic-datasource.version>4.5.0</dynamic-datasource.version>
|
<dynamic-datasource.version>4.5.0</dynamic-datasource.version>
|
||||||
<easy-trans.version>3.1.5</easy-trans.version>
|
<easy-trans.version>3.0.6</easy-trans.version>
|
||||||
<redisson.version>4.6.1</redisson.version>
|
<redisson.version>3.52.0</redisson.version>
|
||||||
<dm8.jdbc.version>8.1.3.140</dm8.jdbc.version>
|
<dm8.jdbc.version>8.1.3.140</dm8.jdbc.version>
|
||||||
<kingbase.jdbc.version>9.0.1.jre7</kingbase.jdbc.version>
|
<kingbase.jdbc.version>8.6.0</kingbase.jdbc.version>
|
||||||
<opengauss.jdbc.version>7.0.0-RC3-og</opengauss.jdbc.version>
|
<opengauss.jdbc.version>5.1.0</opengauss.jdbc.version>
|
||||||
<taos.version>3.8.4</taos.version>
|
<taos.version>3.7.9</taos.version>
|
||||||
<!-- 消息队列 -->
|
<!-- 消息队列 -->
|
||||||
<rocketmq-spring.version>2.3.6</rocketmq-spring.version>
|
<rocketmq-spring.version>2.3.5</rocketmq-spring.version>
|
||||||
<!-- RPC 相关 -->
|
<!-- RPC 相关 -->
|
||||||
<!-- Config 配置中心相关 -->
|
<!-- Config 配置中心相关 -->
|
||||||
<!-- Job 定时任务相关 -->
|
<!-- Job 定时任务相关 -->
|
||||||
|
|
@ -52,48 +52,42 @@
|
||||||
<opentracing.version>0.33.0</opentracing.version>
|
<opentracing.version>0.33.0</opentracing.version>
|
||||||
<!-- Test 测试相关 -->
|
<!-- Test 测试相关 -->
|
||||||
<podam.version>7.2.11.RELEASE</podam.version> <!-- Spring Boot 2.X 最多使用 7.2.11 版本 -->
|
<podam.version>7.2.11.RELEASE</podam.version> <!-- Spring Boot 2.X 最多使用 7.2.11 版本 -->
|
||||||
<jedis-mock.version>1.1.15</jedis-mock.version>
|
<jedis-mock.version>1.1.12</jedis-mock.version>
|
||||||
<mockito-inline.version>4.11.0</mockito-inline.version>
|
<mockito-inline.version>4.11.0</mockito-inline.version>
|
||||||
<!-- Bpm 工作流相关 -->
|
<!-- Bpm 工作流相关 -->
|
||||||
<flowable.version>6.8.1</flowable.version>
|
<flowable.version>6.8.0</flowable.version>
|
||||||
<!-- 工具类相关 -->
|
<!-- 工具类相关 -->
|
||||||
<anji-plus-captcha.version>1.4.0</anji-plus-captcha.version>
|
<anji-plus-captcha.version>1.4.0</anji-plus-captcha.version>
|
||||||
<jsoup.version>1.22.2</jsoup.version>
|
<jsoup.version>1.21.2</jsoup.version>
|
||||||
<sensitive-word.version>0.29.5</sensitive-word.version>
|
<lombok.version>1.18.42</lombok.version>
|
||||||
<pinyin4j.version>2.5.1</pinyin4j.version>
|
|
||||||
<lombok.version>1.18.46</lombok.version>
|
|
||||||
<mapstruct.version>1.6.3</mapstruct.version>
|
<mapstruct.version>1.6.3</mapstruct.version>
|
||||||
<hutool-5.version>5.8.46</hutool-5.version>
|
<hutool-5.version>5.8.42</hutool-5.version>
|
||||||
<fastexcel.version>1.3.0</fastexcel.version>
|
<fastexcel.version>1.3.0</fastexcel.version>
|
||||||
<velocity.version>2.4</velocity.version> <!-- JDK8 不能从 2.4 升级到 2.4.1,会报包不存在!!!! -->
|
<velocity.version>2.4</velocity.version> <!-- JDK8 不能从 2.4 升级到 2.4.1,会报包不存在!!!! -->
|
||||||
<fastjson.version>1.2.83</fastjson.version>
|
<fastjson.version>1.2.83</fastjson.version>
|
||||||
<fastjson2.version>2.0.62</fastjson2.version>
|
<guava.version>33.5.0-jre</guava.version>
|
||||||
<guava.version>33.6.0-jre</guava.version>
|
|
||||||
<transmittable-thread-local.version>2.14.5</transmittable-thread-local.version>
|
<transmittable-thread-local.version>2.14.5</transmittable-thread-local.version>
|
||||||
<commons-net.version>3.13.0</commons-net.version>
|
<commons-net.version>3.12.0</commons-net.version>
|
||||||
<commons-lang3.version>3.20.0</commons-lang3.version>
|
<commons-lang3.version>3.20.0</commons-lang3.version>
|
||||||
<jsch.version>2.28.3</jsch.version>
|
<jsch.version>2.27.7</jsch.version>
|
||||||
<tika-core.version>2.9.3</tika-core.version> <!-- JDK8 不能从 2.9.3 升级到 3.X,会报 JDK8 不支持 -->
|
<tika-core.version>2.9.3</tika-core.version> <!-- JDK8 不能从 2.9.3 升级到 3.X,会报 JDK8 不支持 -->
|
||||||
<ip2region.version>2.7.0</ip2region.version>
|
<ip2region.version>2.7.0</ip2region.version>
|
||||||
<bizlog-sdk.version>3.0.6</bizlog-sdk.version>
|
<bizlog-sdk.version>3.0.6</bizlog-sdk.version>
|
||||||
<reflections.version>0.10.2</reflections.version>
|
<reflections.version>0.10.2</reflections.version>
|
||||||
<netty.version>4.2.15.Final</netty.version>
|
<netty.version>4.2.9.Final</netty.version>
|
||||||
<mqtt.version>1.2.5</mqtt.version>
|
<mqtt.version>1.2.5</mqtt.version>
|
||||||
<vertx.version>4.5.26</vertx.version>
|
<vertx.version>4.5.22</vertx.version>
|
||||||
<okhttp.version>4.12.0</okhttp.version>
|
<okhttp.version>4.12.0</okhttp.version>
|
||||||
<californium.version>3.14.0</californium.version>
|
<californium.version>3.12.0</californium.version>
|
||||||
<j2mod.version>3.3.0</j2mod.version>
|
<j2mod.version>3.2.1</j2mod.version>
|
||||||
<httpclient5.version>5.5.2</httpclient5.version> <!-- WxJava 4.8.x 需要 HttpClient5 5.4+,Spring Boot 2.7 默认 5.1.4 不兼容 -->
|
|
||||||
<httpcore5.version>5.3.6</httpcore5.version> <!-- 配套 httpclient5 5.5.2,Spring Boot 2.7 默认 5.1.5 不兼容 -->
|
|
||||||
<!-- 三方云服务相关 -->
|
<!-- 三方云服务相关 -->
|
||||||
<awssdk.version>2.46.17</awssdk.version>
|
<awssdk.version>2.40.15</awssdk.version>
|
||||||
<justauth.version>1.16.7</justauth.version>
|
<justauth.version>1.16.7</justauth.version>
|
||||||
<justauth-starter.version>1.4.0</justauth-starter.version>
|
<justauth-starter.version>1.4.0</justauth-starter.version>
|
||||||
<jimureport.version>2.3.4</jimureport.version>
|
<jimureport.version>2.1.3</jimureport.version>
|
||||||
<jimubi.version>2.3.2</jimubi.version>
|
<jimubi.version>2.3.0</jimubi.version>
|
||||||
<weixin-java.version>4.8.4-20260623.211820</weixin-java.version>
|
<weixin-java.version>4.7.9-20251224.161447</weixin-java.version>
|
||||||
<bouncycastle.version>1.80</bouncycastle.version>
|
<alipay-sdk-java.version>4.40.607.ALL</alipay-sdk-java.version>
|
||||||
<alipay-sdk-java.version>4.40.865.ALL</alipay-sdk-java.version>
|
|
||||||
<!-- 专属于 JDK8 安全漏洞升级 -->
|
<!-- 专属于 JDK8 安全漏洞升级 -->
|
||||||
<logback.version>1.2.13</logback.version> <!-- 无法使用 1.3.X 版本,启动会报错 -->
|
<logback.version>1.2.13</logback.version> <!-- 无法使用 1.3.X 版本,启动会报错 -->
|
||||||
</properties>
|
</properties>
|
||||||
|
|
@ -277,7 +271,7 @@
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.dromara</groupId> <!-- VO 数据翻译 -->
|
<groupId>com.fhs-opensource</groupId> <!-- VO 数据翻译 -->
|
||||||
<artifactId>easy-trans-spring-boot-starter</artifactId>
|
<artifactId>easy-trans-spring-boot-starter</artifactId>
|
||||||
<version>${easy-trans.version}</version>
|
<version>${easy-trans.version}</version>
|
||||||
<exclusions>
|
<exclusions>
|
||||||
|
|
@ -292,12 +286,12 @@
|
||||||
</exclusions>
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.dromara</groupId>
|
<groupId>com.fhs-opensource</groupId>
|
||||||
<artifactId>easy-trans-mybatis-plus-extend</artifactId>
|
<artifactId>easy-trans-mybatis-plus-extend</artifactId>
|
||||||
<version>${easy-trans.version}</version>
|
<version>${easy-trans.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.dromara</groupId>
|
<groupId>com.fhs-opensource</groupId>
|
||||||
<artifactId>easy-trans-anno</artifactId>
|
<artifactId>easy-trans-anno</artifactId>
|
||||||
<version>${easy-trans.version}</version>
|
<version>${easy-trans.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
@ -313,8 +307,8 @@
|
||||||
</exclusion>
|
</exclusion>
|
||||||
<exclusion>
|
<exclusion>
|
||||||
<groupId>org.redisson</groupId>
|
<groupId>org.redisson</groupId>
|
||||||
<!-- Redisson 4.6.x 默认依赖 redisson-spring-data-41(适配 Spring Data Redis 4.x),排除后使用下方的 spring-data-27 适配 Spring Boot 2.7 -->
|
<!-- 使用 redisson-spring-data-27 替代,解决 Tuple NoClassDefFoundError 报错 -->
|
||||||
<artifactId>redisson-spring-data-41</artifactId>
|
<artifactId>redisson-spring-data-35</artifactId>
|
||||||
</exclusion>
|
</exclusion>
|
||||||
</exclusions>
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
@ -580,11 +574,6 @@
|
||||||
<artifactId>fastjson</artifactId>
|
<artifactId>fastjson</artifactId>
|
||||||
<version>${fastjson.version}</version>
|
<version>${fastjson.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>com.alibaba.fastjson2</groupId>
|
|
||||||
<artifactId>fastjson2</artifactId>
|
|
||||||
<version>${fastjson2.version}</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.google.guava</groupId>
|
<groupId>com.google.guava</groupId>
|
||||||
|
|
@ -633,18 +622,6 @@
|
||||||
<version>${jsoup.version}</version>
|
<version>${jsoup.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.github.houbb</groupId>
|
|
||||||
<artifactId>sensitive-word</artifactId> <!-- 敏感词检测:trie 树高效匹配 -->
|
|
||||||
<version>${sensitive-word.version}</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.belerweb</groupId>
|
|
||||||
<artifactId>pinyin4j</artifactId> <!-- 汉字转拼音:作为 hutool PinyinUtil 的底层引擎 -->
|
|
||||||
<version>${pinyin4j.version}</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.reflections</groupId>
|
<groupId>org.reflections</groupId>
|
||||||
<artifactId>reflections</artifactId>
|
<artifactId>reflections</artifactId>
|
||||||
|
|
@ -702,23 +679,6 @@
|
||||||
<version>${j2mod.version}</version>
|
<version>${j2mod.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- WxJava 4.8.x 需要 HttpClient5 5.4+,覆盖 Spring Boot 2.7 默认的 5.1.4 -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.httpcomponents.client5</groupId>
|
|
||||||
<artifactId>httpclient5</artifactId>
|
|
||||||
<version>${httpclient5.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.httpcomponents.core5</groupId>
|
|
||||||
<artifactId>httpcore5</artifactId>
|
|
||||||
<version>${httpcore5.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.httpcomponents.core5</groupId>
|
|
||||||
<artifactId>httpcore5-h2</artifactId>
|
|
||||||
<version>${httpcore5.version}</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- 三方云服务相关 -->
|
<!-- 三方云服务相关 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>software.amazon.awssdk</groupId>
|
<groupId>software.amazon.awssdk</groupId>
|
||||||
|
|
@ -756,24 +716,6 @@
|
||||||
</exclusions>
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- 锁定 weixin-java 传递依赖,避免 Maven 版本范围自动升级到 1.80.2 后 Fat Jar 启动失败。
|
|
||||||
反馈:https://t.zsxq.com/pCVBo -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.bouncycastle</groupId>
|
|
||||||
<artifactId>bcprov-jdk18on</artifactId>
|
|
||||||
<version>${bouncycastle.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.bouncycastle</groupId>
|
|
||||||
<artifactId>bcutil-jdk18on</artifactId>
|
|
||||||
<version>${bouncycastle.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.bouncycastle</groupId>
|
|
||||||
<artifactId>bcpkix-jdk18on</artifactId>
|
|
||||||
<version>${bouncycastle.version}</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.github.binarywang</groupId>
|
<groupId>com.github.binarywang</groupId>
|
||||||
<artifactId>weixin-java-pay</artifactId>
|
<artifactId>weixin-java-pay</artifactId>
|
||||||
|
|
|
||||||
|
|
@ -53,8 +53,8 @@
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>javax.servlet</groupId>
|
<groupId>jakarta.servlet</groupId>
|
||||||
<artifactId>javax.servlet-api</artifactId>
|
<artifactId>jakarta.servlet-api</artifactId>
|
||||||
<scope>provided</scope> <!-- 设置为 provided,只有工具类需要使用到 -->
|
<scope>provided</scope> <!-- 设置为 provided,只有工具类需要使用到 -->
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
|
@ -125,8 +125,8 @@
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>javax.validation</groupId>
|
<groupId>jakarta.validation</groupId>
|
||||||
<artifactId>validation-api</artifactId>
|
<artifactId>jakarta.validation-api</artifactId>
|
||||||
<scope>provided</scope> <!-- 设置为 provided,主要是 PageParam 使用到 -->
|
<scope>provided</scope> <!-- 设置为 provided,主要是 PageParam 使用到 -->
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
|
@ -146,7 +146,7 @@
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.dromara</groupId> <!-- VO 数据翻译 -->
|
<groupId>com.fhs-opensource</groupId> <!-- VO 数据翻译 -->
|
||||||
<artifactId>easy-trans-anno</artifactId> <!-- 默认引入的原因,方便 xxx-module-api 包使用 -->
|
<artifactId>easy-trans-anno</artifactId> <!-- 默认引入的原因,方便 xxx-module-api 包使用 -->
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -124,22 +124,6 @@ public class CollectionUtils {
|
||||||
return from.stream().filter(filter).map(func).filter(Objects::nonNull).collect(Collectors.toSet());
|
return from.stream().filter(filter).map(func).filter(Objects::nonNull).collect(Collectors.toSet());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T, U> Set<U> convertLinkedSet(Collection<T> from, Function<T, U> func) {
|
|
||||||
if (CollUtil.isEmpty(from)) {
|
|
||||||
return new LinkedHashSet<>();
|
|
||||||
}
|
|
||||||
return from.stream().map(func).filter(Objects::nonNull)
|
|
||||||
.collect(Collectors.toCollection(LinkedHashSet::new));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T, U> Set<U> convertLinkedSet(Collection<T> from, Function<T, U> func, Predicate<T> filter) {
|
|
||||||
if (CollUtil.isEmpty(from)) {
|
|
||||||
return new LinkedHashSet<>();
|
|
||||||
}
|
|
||||||
return from.stream().filter(filter).map(func).filter(Objects::nonNull)
|
|
||||||
.collect(Collectors.toCollection(LinkedHashSet::new));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T, K> Map<K, T> convertMapByFilter(Collection<T> from, Predicate<T> filter, Function<T, K> keyFunc) {
|
public static <T, K> Map<K, T> convertMapByFilter(Collection<T> from, Predicate<T> filter, Function<T, K> keyFunc) {
|
||||||
if (CollUtil.isEmpty(from)) {
|
if (CollUtil.isEmpty(from)) {
|
||||||
return new HashMap<>();
|
return new HashMap<>();
|
||||||
|
|
@ -388,14 +372,4 @@ public class CollectionUtils {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 把单元素 head 与集合 tail 合并成新 List(head 在前,tail 顺序保留)
|
|
||||||
*/
|
|
||||||
public static <T> List<T> of(T head, Collection<T> tail) {
|
|
||||||
List<T> list = new ArrayList<>();
|
|
||||||
list.add(head);
|
|
||||||
CollUtil.addAll(list, tail);
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -3,6 +3,7 @@ package cn.iocoder.yudao.framework.common.util.date;
|
||||||
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.collection.CollUtil;
|
||||||
import cn.hutool.core.date.DatePattern;
|
import cn.hutool.core.date.DatePattern;
|
||||||
import cn.hutool.core.date.LocalDateTimeUtil;
|
import cn.hutool.core.date.LocalDateTimeUtil;
|
||||||
|
import cn.hutool.core.date.TemporalAccessorUtil;
|
||||||
import cn.hutool.core.lang.Assert;
|
import cn.hutool.core.lang.Assert;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.iocoder.yudao.framework.common.enums.DateIntervalEnum;
|
import cn.iocoder.yudao.framework.common.enums.DateIntervalEnum;
|
||||||
|
|
@ -15,7 +16,6 @@ import java.time.temporal.ChronoUnit;
|
||||||
import java.time.temporal.TemporalAdjusters;
|
import java.time.temporal.TemporalAdjusters;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.TimeZone;
|
|
||||||
|
|
||||||
import static cn.hutool.core.date.DatePattern.*;
|
import static cn.hutool.core.date.DatePattern.*;
|
||||||
|
|
||||||
|
|
@ -33,11 +33,6 @@ public class LocalDateTimeUtils {
|
||||||
|
|
||||||
public static DateTimeFormatter UTC_MS_WITH_XXX_OFFSET_FORMATTER = createFormatter(UTC_MS_WITH_XXX_OFFSET_PATTERN);
|
public static DateTimeFormatter UTC_MS_WITH_XXX_OFFSET_FORMATTER = createFormatter(UTC_MS_WITH_XXX_OFFSET_PATTERN);
|
||||||
|
|
||||||
/**
|
|
||||||
* 默认时区
|
|
||||||
*/
|
|
||||||
private static final ZoneId DEFAULT_ZONE_ID = TimeZone.getTimeZone(DateUtils.TIME_ZONE_DEFAULT).toZoneId();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 解析时间
|
* 解析时间
|
||||||
*
|
*
|
||||||
|
|
@ -70,27 +65,6 @@ public class LocalDateTimeUtils {
|
||||||
return date.isAfter(LocalDateTime.now());
|
return date.isAfter(LocalDateTime.now());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 将 Unix 秒时间戳转换为默认时区的本地时间
|
|
||||||
*
|
|
||||||
* @param epochSecond Unix 秒时间戳
|
|
||||||
* @return 本地时间
|
|
||||||
*/
|
|
||||||
public static LocalDateTime ofEpochSecond(long epochSecond) {
|
|
||||||
return ofEpochSecond(epochSecond, DEFAULT_ZONE_ID);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 将 Unix 秒时间戳转换为指定时区的本地时间
|
|
||||||
*
|
|
||||||
* @param epochSecond Unix 秒时间戳
|
|
||||||
* @param zoneId 时区编号
|
|
||||||
* @return 本地时间
|
|
||||||
*/
|
|
||||||
public static LocalDateTime ofEpochSecond(long epochSecond, ZoneId zoneId) {
|
|
||||||
return LocalDateTime.ofInstant(Instant.ofEpochSecond(epochSecond), zoneId);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建指定时间
|
* 创建指定时间
|
||||||
*
|
*
|
||||||
|
|
@ -262,23 +236,6 @@ public class LocalDateTimeUtils {
|
||||||
return LocalDateTime.now().with(TemporalAdjusters.firstDayOfYear()).with(LocalTime.MIN);
|
return LocalDateTime.now().with(TemporalAdjusters.firstDayOfYear()).with(LocalTime.MIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取最近 N 天的 0 点时刻序列(升序,含今天)
|
|
||||||
* <p>
|
|
||||||
* 例:getLatestDays(3) 返回 [前天 00:00, 昨天 00:00, 今天 00:00]
|
|
||||||
*
|
|
||||||
* @param days 天数(含今天)
|
|
||||||
* @return 升序的 LocalDateTime 列表
|
|
||||||
*/
|
|
||||||
public static List<LocalDateTime> getLatestDays(int days) {
|
|
||||||
LocalDateTime today = getToday();
|
|
||||||
List<LocalDateTime> dates = new ArrayList<>(days);
|
|
||||||
for (int i = days - 1; i >= 0; i--) {
|
|
||||||
dates.add(today.minusDays(i));
|
|
||||||
}
|
|
||||||
return dates;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<LocalDateTime[]> getDateRangeList(LocalDateTime startTime,
|
public static List<LocalDateTime[]> getDateRangeList(LocalDateTime startTime,
|
||||||
LocalDateTime endTime,
|
LocalDateTime endTime,
|
||||||
Integer interval) {
|
Integer interval) {
|
||||||
|
|
@ -345,21 +302,6 @@ public class LocalDateTimeUtils {
|
||||||
return timeRanges;
|
return timeRanges;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取从开始日期起的日期列表
|
|
||||||
*
|
|
||||||
* @param startDate 开始日期
|
|
||||||
* @param days 天数
|
|
||||||
* @return 日期列表,包含开始日期
|
|
||||||
*/
|
|
||||||
public static List<LocalDate> getDateList(LocalDate startDate, int days) {
|
|
||||||
List<LocalDate> dateList = new ArrayList<>(days);
|
|
||||||
for (int i = 0; i < days; i++) {
|
|
||||||
dateList.add(startDate.plusDays(i));
|
|
||||||
}
|
|
||||||
return dateList;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 格式化时间范围
|
* 格式化时间范围
|
||||||
*
|
*
|
||||||
|
|
@ -423,18 +365,7 @@ public class LocalDateTimeUtils {
|
||||||
* @throws DateTimeException 如果转换过程中发生时间超出范围或其他时间处理异常
|
* @throws DateTimeException 如果转换过程中发生时间超出范围或其他时间处理异常
|
||||||
*/
|
*/
|
||||||
public static Long toEpochSecond(LocalDateTime sourceDateTime) {
|
public static Long toEpochSecond(LocalDateTime sourceDateTime) {
|
||||||
return toEpochSecond(sourceDateTime, DEFAULT_ZONE_ID);
|
return TemporalAccessorUtil.toInstant(sourceDateTime).getEpochSecond();
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 将给定的 {@link LocalDateTime} 按指定时区转换为自 Unix 纪元时间(1970-01-01T00:00:00Z)以来的秒数。
|
|
||||||
*
|
|
||||||
* @param sourceDateTime 需要转换的本地日期时间,不能为空
|
|
||||||
* @param zoneId 时区编号
|
|
||||||
* @return 自 1970-01-01T00:00:00Z 起的秒数(epoch second)
|
|
||||||
*/
|
|
||||||
public static Long toEpochSecond(LocalDateTime sourceDateTime, ZoneId zoneId) {
|
|
||||||
return sourceDateTime.atZone(zoneId).toEpochSecond();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
package cn.iocoder.yudao.framework.common.util.http;
|
package cn.iocoder.yudao.framework.common.util.http;
|
||||||
|
|
||||||
import cn.hutool.core.codec.Base64;
|
import cn.hutool.core.codec.Base64;
|
||||||
|
import cn.hutool.core.map.TableMap;
|
||||||
import cn.hutool.core.net.url.UrlBuilder;
|
import cn.hutool.core.net.url.UrlBuilder;
|
||||||
|
import cn.hutool.core.util.ReflectUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.hutool.http.HttpRequest;
|
import cn.hutool.http.HttpRequest;
|
||||||
import cn.hutool.http.HttpResponse;
|
import cn.hutool.http.HttpResponse;
|
||||||
|
|
@ -9,7 +11,6 @@ import lombok.SneakyThrows;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
import org.springframework.web.util.UriComponents;
|
import org.springframework.web.util.UriComponents;
|
||||||
import org.springframework.web.util.UriComponentsBuilder;
|
import org.springframework.web.util.UriComponentsBuilder;
|
||||||
import org.springframework.web.util.UriUtils;
|
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
|
@ -60,65 +61,19 @@ public class HttpUtils {
|
||||||
*/
|
*/
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
public static String decodeUrlPath(String path) {
|
public static String decodeUrlPath(String path) {
|
||||||
if (StrUtil.isEmpty(path)) {
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
// 先将 + 替换为 %2B,避免被 URLDecoder 解码为空格
|
// 先将 + 替换为 %2B,避免被 URLDecoder 解码为空格
|
||||||
String encoded = path.replace("+", "%2B");
|
String encoded = path.replace("+", "%2B");
|
||||||
return URLDecoder.decode(encoded, StandardCharsets.UTF_8.name());
|
return URLDecoder.decode(encoded, StandardCharsets.UTF_8.name());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@SuppressWarnings("unchecked")
|
||||||
* 编码 URL 路径,按路径段编码,保留 / 分隔符
|
|
||||||
*
|
|
||||||
* @param path URL 路径,例如 20250602/xxx.pdf
|
|
||||||
* @return 编码后的路径
|
|
||||||
*/
|
|
||||||
public static String encodeUrlPath(String path) {
|
|
||||||
if (StrUtil.isEmpty(path)) {
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
String[] segments = path.split(StrUtil.SLASH, -1);
|
|
||||||
StringBuilder result = new StringBuilder(path.length());
|
|
||||||
for (int i = 0; i < segments.length; i++) {
|
|
||||||
if (i > 0) {
|
|
||||||
result.append(StrUtil.SLASH);
|
|
||||||
}
|
|
||||||
result.append(encodeUrlPathSegment(segments[i]));
|
|
||||||
}
|
|
||||||
return result.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 编码 URL 路径段
|
|
||||||
*
|
|
||||||
* @param segment URL 路径段
|
|
||||||
* @return 编码后的路径段
|
|
||||||
*/
|
|
||||||
public static String encodeUrlPathSegment(String segment) {
|
|
||||||
return UriUtils.encodePathSegment(segment, StandardCharsets.UTF_8);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String removeUrlPathQueryAndFragment(String path) {
|
|
||||||
if (StrUtil.isEmpty(path)) {
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
int endIndex = path.length();
|
|
||||||
int queryIndex = path.indexOf('?');
|
|
||||||
if (queryIndex >= 0) {
|
|
||||||
endIndex = queryIndex;
|
|
||||||
}
|
|
||||||
int fragmentIndex = path.indexOf('#');
|
|
||||||
if (fragmentIndex >= 0 && fragmentIndex < endIndex) {
|
|
||||||
endIndex = fragmentIndex;
|
|
||||||
}
|
|
||||||
return path.substring(0, endIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String replaceUrlQuery(String url, String key, String value) {
|
public static String replaceUrlQuery(String url, String key, String value) {
|
||||||
UrlBuilder builder = UrlBuilder.of(url, Charset.defaultCharset());
|
UrlBuilder builder = UrlBuilder.of(url, Charset.defaultCharset());
|
||||||
// 先移除;再添加
|
// 先移除
|
||||||
builder.getQuery().remove(key);
|
TableMap<CharSequence, CharSequence> query = (TableMap<CharSequence, CharSequence>)
|
||||||
|
ReflectUtil.getFieldValue(builder.getQuery(), "query");
|
||||||
|
query.remove(key);
|
||||||
|
// 后添加
|
||||||
builder.addQuery(key, value);
|
builder.addQuery(key, value);
|
||||||
return builder.build();
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
|
@ -255,14 +210,4 @@ public class HttpUtils {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* WebSocket URL 切换成 HTTP URL:ws:// → http://;wss:// → https://;其它格式原样保留
|
|
||||||
*
|
|
||||||
* @param url 原始 URL
|
|
||||||
* @return 切换协议后的 URL
|
|
||||||
*/
|
|
||||||
public static String wsUrlToHttp(String url) {
|
|
||||||
return StrUtil.startWithIgnoreCase(url, "ws") ? "http" + url.substring(2) : url;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,14 +6,12 @@ import cn.hutool.json.JSONUtil;
|
||||||
import cn.iocoder.yudao.framework.common.util.json.databind.TimestampLocalDateTimeDeserializer;
|
import cn.iocoder.yudao.framework.common.util.json.databind.TimestampLocalDateTimeDeserializer;
|
||||||
import cn.iocoder.yudao.framework.common.util.json.databind.TimestampLocalDateTimeSerializer;
|
import cn.iocoder.yudao.framework.common.util.json.databind.TimestampLocalDateTimeSerializer;
|
||||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||||
import com.fasterxml.jackson.core.JacksonException;
|
|
||||||
import com.fasterxml.jackson.core.type.TypeReference;
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||||
import com.fasterxml.jackson.databind.module.SimpleModule;
|
import com.fasterxml.jackson.databind.module.SimpleModule;
|
||||||
import com.fasterxml.jackson.databind.json.JsonMapper;
|
|
||||||
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
|
|
@ -24,7 +22,6 @@ import java.lang.reflect.Type;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* JSON 工具类
|
* JSON 工具类
|
||||||
|
|
@ -35,19 +32,17 @@ import java.util.Map;
|
||||||
public class JsonUtils {
|
public class JsonUtils {
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
private static ObjectMapper objectMapper = buildObjectMapper();
|
private static ObjectMapper objectMapper = new ObjectMapper();
|
||||||
|
|
||||||
private static ObjectMapper buildObjectMapper() {
|
static {
|
||||||
SimpleModule simpleModule = new JavaTimeModule()
|
objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
|
||||||
|
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
||||||
|
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); // 忽略 null 值
|
||||||
// 解决 LocalDateTime 的序列化
|
// 解决 LocalDateTime 的序列化
|
||||||
|
SimpleModule simpleModule = new JavaTimeModule()
|
||||||
.addSerializer(LocalDateTime.class, TimestampLocalDateTimeSerializer.INSTANCE)
|
.addSerializer(LocalDateTime.class, TimestampLocalDateTimeSerializer.INSTANCE)
|
||||||
.addDeserializer(LocalDateTime.class, TimestampLocalDateTimeDeserializer.INSTANCE);
|
.addDeserializer(LocalDateTime.class, TimestampLocalDateTimeDeserializer.INSTANCE);
|
||||||
return JsonMapper.builder()
|
objectMapper.registerModules(simpleModule);
|
||||||
.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS)
|
|
||||||
.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
|
|
||||||
.defaultPropertyInclusion(JsonInclude.Value.construct(JsonInclude.Include.NON_NULL, JsonInclude.Include.NON_NULL))
|
|
||||||
.addModule(simpleModule)
|
|
||||||
.build();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -82,7 +77,7 @@ public class JsonUtils {
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
return objectMapper.readValue(text, clazz);
|
return objectMapper.readValue(text, clazz);
|
||||||
} catch (JacksonException e) {
|
} catch (IOException e) {
|
||||||
log.error("json parse err,json:{}", text, e);
|
log.error("json parse err,json:{}", text, e);
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
|
@ -96,7 +91,7 @@ public class JsonUtils {
|
||||||
JsonNode treeNode = objectMapper.readTree(text);
|
JsonNode treeNode = objectMapper.readTree(text);
|
||||||
JsonNode pathNode = treeNode.path(path);
|
JsonNode pathNode = treeNode.path(path);
|
||||||
return objectMapper.readValue(pathNode.toString(), clazz);
|
return objectMapper.readValue(pathNode.toString(), clazz);
|
||||||
} catch (JacksonException e) {
|
} catch (IOException e) {
|
||||||
log.error("json parse err,json:{}", text, e);
|
log.error("json parse err,json:{}", text, e);
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
|
@ -108,7 +103,7 @@ public class JsonUtils {
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
return objectMapper.readValue(text, objectMapper.getTypeFactory().constructType(type));
|
return objectMapper.readValue(text, objectMapper.getTypeFactory().constructType(type));
|
||||||
} catch (JacksonException e) {
|
} catch (IOException e) {
|
||||||
log.error("json parse err,json:{}", text, e);
|
log.error("json parse err,json:{}", text, e);
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
|
@ -157,7 +152,7 @@ public class JsonUtils {
|
||||||
public static <T> T parseObject(String text, TypeReference<T> typeReference) {
|
public static <T> T parseObject(String text, TypeReference<T> typeReference) {
|
||||||
try {
|
try {
|
||||||
return objectMapper.readValue(text, typeReference);
|
return objectMapper.readValue(text, typeReference);
|
||||||
} catch (JacksonException e) {
|
} catch (IOException e) {
|
||||||
log.error("json parse err,json:{}", text, e);
|
log.error("json parse err,json:{}", text, e);
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
|
@ -173,42 +168,7 @@ public class JsonUtils {
|
||||||
public static <T> T parseObjectQuietly(String text, TypeReference<T> typeReference) {
|
public static <T> T parseObjectQuietly(String text, TypeReference<T> typeReference) {
|
||||||
try {
|
try {
|
||||||
return objectMapper.readValue(text, typeReference);
|
return objectMapper.readValue(text, typeReference);
|
||||||
} catch (JacksonException e) {
|
} catch (IOException e) {
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 解析 JSON 字符串成 Map,空字符串或解析失败返回 null
|
|
||||||
*
|
|
||||||
* @param text JSON 字符串
|
|
||||||
* @return Map 对象
|
|
||||||
*/
|
|
||||||
public static Map<String, Object> parseMap(String text) {
|
|
||||||
if (StrUtil.isEmpty(text)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
return objectMapper.readValue(text, new TypeReference<Map<String, Object>>() {});
|
|
||||||
} catch (JacksonException e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 解析 JSON 字符串成指定类型的对象,如果解析失败,则返回 null
|
|
||||||
*
|
|
||||||
* @param text 字符串
|
|
||||||
* @param clazz 类型
|
|
||||||
* @return 指定类型的对象
|
|
||||||
*/
|
|
||||||
public static <T> T parseObjectQuietly(String text, Class<T> clazz) {
|
|
||||||
if (StrUtil.isEmpty(text)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
return objectMapper.readValue(text, clazz);
|
|
||||||
} catch (JacksonException e) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -219,7 +179,7 @@ public class JsonUtils {
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
return objectMapper.readValue(text, objectMapper.getTypeFactory().constructCollectionType(List.class, clazz));
|
return objectMapper.readValue(text, objectMapper.getTypeFactory().constructCollectionType(List.class, clazz));
|
||||||
} catch (JacksonException e) {
|
} catch (IOException e) {
|
||||||
log.error("json parse err,json:{}", text, e);
|
log.error("json parse err,json:{}", text, e);
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
|
@ -233,7 +193,7 @@ public class JsonUtils {
|
||||||
JsonNode treeNode = objectMapper.readTree(text);
|
JsonNode treeNode = objectMapper.readTree(text);
|
||||||
JsonNode pathNode = treeNode.path(path);
|
JsonNode pathNode = treeNode.path(path);
|
||||||
return objectMapper.readValue(pathNode.toString(), objectMapper.getTypeFactory().constructCollectionType(List.class, clazz));
|
return objectMapper.readValue(pathNode.toString(), objectMapper.getTypeFactory().constructCollectionType(List.class, clazz));
|
||||||
} catch (JacksonException e) {
|
} catch (IOException e) {
|
||||||
log.error("json parse err,json:{}", text, e);
|
log.error("json parse err,json:{}", text, e);
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
|
@ -242,7 +202,7 @@ public class JsonUtils {
|
||||||
public static JsonNode parseTree(String text) {
|
public static JsonNode parseTree(String text) {
|
||||||
try {
|
try {
|
||||||
return objectMapper.readTree(text);
|
return objectMapper.readTree(text);
|
||||||
} catch (JacksonException e) {
|
} catch (IOException e) {
|
||||||
log.error("json parse err,json:{}", text, e);
|
log.error("json parse err,json:{}", text, e);
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
|
@ -257,14 +217,6 @@ public class JsonUtils {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getText(JsonNode node, String fieldName) {
|
|
||||||
if (node == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
JsonNode value = node.get(fieldName);
|
|
||||||
return value != null && !value.isNull() ? value.asText() : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isJson(String text) {
|
public static boolean isJson(String text) {
|
||||||
return JSONUtil.isTypeJSON(text);
|
return JSONUtil.isTypeJSON(text);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@ package cn.iocoder.yudao.framework.common.util.string;
|
||||||
import cn.hutool.core.text.StrPool;
|
import cn.hutool.core.text.StrPool;
|
||||||
import cn.hutool.core.util.ArrayUtil;
|
import cn.hutool.core.util.ArrayUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.hutool.extra.pinyin.PinyinUtil;
|
|
||||||
import org.aspectj.lang.JoinPoint;
|
import org.aspectj.lang.JoinPoint;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
@ -79,25 +78,6 @@ public class StrUtils {
|
||||||
.collect(Collectors.joining("\n"));
|
.collect(Collectors.joining("\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 转小写拼音,字之间以空格分隔,便于调用方按需拼接 / 取首字母 / 拼音搜索
|
|
||||||
*
|
|
||||||
* 例:「老张」→ "lao zhang"、「ZhangSan」→ "zhangsan"
|
|
||||||
* 英文 / 数字 / 符号原样返回,空值返回 null
|
|
||||||
*
|
|
||||||
* 注意:底层依赖 hutool-extra 的 {@link PinyinUtil},需要业务模块自行引入拼音引擎依赖
|
|
||||||
* (pinyin4j / TinyPinyin / Bopomofo4j 任选其一),否则运行时会抛 NoClassDefFoundError
|
|
||||||
*
|
|
||||||
* @param str 字符串
|
|
||||||
* @return 拼音串(保留空格分隔)
|
|
||||||
*/
|
|
||||||
public static String toPinyin(String str) {
|
|
||||||
if (StrUtil.isBlank(str)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return PinyinUtil.getPinyin(str);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 拼接方法的参数
|
* 拼接方法的参数
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
package org.dromara.trans.service;
|
package com.fhs.trans.service;
|
||||||
|
|
||||||
import org.dromara.core.trans.vo.VO;
|
import com.fhs.core.trans.vo.VO;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
@ -1,82 +0,0 @@
|
||||||
package cn.iocoder.yudao.framework.common.util.http;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@link HttpUtils} 的单元测试
|
|
||||||
*/
|
|
||||||
public class HttpUtilsTest {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testEncodeUrlPath() {
|
|
||||||
// 准备参数
|
|
||||||
String path = "avatar/中文 100%+文件.jpg";
|
|
||||||
|
|
||||||
// 调用
|
|
||||||
String result = HttpUtils.encodeUrlPath(path);
|
|
||||||
|
|
||||||
// 断言
|
|
||||||
assertEquals("avatar/%E4%B8%AD%E6%96%87%20100%25+%E6%96%87%E4%BB%B6.jpg", result);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testDecodeUrlPath() {
|
|
||||||
// 准备参数:+ 是路径字符,不应该按 query parameter 语义解码为空格
|
|
||||||
String path = "avatar/%E4%B8%AD%E6%96%87%20100%25+%E6%96%87%E4%BB%B6.jpg";
|
|
||||||
|
|
||||||
// 调用
|
|
||||||
String result = HttpUtils.decodeUrlPath(path);
|
|
||||||
|
|
||||||
// 断言
|
|
||||||
assertEquals("avatar/中文 100%+文件.jpg", result);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testRemoveUrlPathQueryAndFragment() {
|
|
||||||
assertEquals("avatar/test.jpg", HttpUtils.removeUrlPathQueryAndFragment("avatar/test.jpg?token=1#preview"));
|
|
||||||
assertEquals("avatar/test.jpg", HttpUtils.removeUrlPathQueryAndFragment("avatar/test.jpg#preview?token=1"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testReplaceUrlQuery_replace() {
|
|
||||||
// 准备参数
|
|
||||||
String url = "https://www.iocoder.cn/path?a=1&b=2";
|
|
||||||
// 调用
|
|
||||||
String result = HttpUtils.replaceUrlQuery(url, "a", "3");
|
|
||||||
// 断言:被替换的 key 会移到末尾,原顺序的其它参数保留
|
|
||||||
assertEquals("https://www.iocoder.cn/path?b=2&a=3", result);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testReplaceUrlQuery_add() {
|
|
||||||
// 准备参数
|
|
||||||
String url = "https://www.iocoder.cn/path?a=1";
|
|
||||||
// 调用
|
|
||||||
String result = HttpUtils.replaceUrlQuery(url, "b", "2");
|
|
||||||
// 断言
|
|
||||||
assertEquals("https://www.iocoder.cn/path?a=1&b=2", result);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testReplaceUrlQuery_noQuery() {
|
|
||||||
// 准备参数:原 URL 没有 query
|
|
||||||
String url = "https://www.iocoder.cn/path";
|
|
||||||
// 调用
|
|
||||||
String result = HttpUtils.replaceUrlQuery(url, "a", "1");
|
|
||||||
// 断言
|
|
||||||
assertEquals("https://www.iocoder.cn/path?a=1", result);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testReplaceUrlQuery_emptyValue() {
|
|
||||||
// 准备参数:value 为空字符串
|
|
||||||
String url = "https://www.iocoder.cn/path?a=1";
|
|
||||||
// 调用
|
|
||||||
String result = HttpUtils.replaceUrlQuery(url, "a", "");
|
|
||||||
// 断言:保留 key,value 为空
|
|
||||||
assertEquals("https://www.iocoder.cn/path?a=", result);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -4,7 +4,7 @@ import cn.hutool.core.collection.CollUtil;
|
||||||
import cn.hutool.core.util.ArrayUtil;
|
import cn.hutool.core.util.ArrayUtil;
|
||||||
import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission;
|
import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission;
|
||||||
import cn.iocoder.yudao.framework.datapermission.core.aop.DataPermissionContextHolder;
|
import cn.iocoder.yudao.framework.datapermission.core.aop.DataPermissionContextHolder;
|
||||||
import org.dromara.trans.service.impl.SimpleTransService;
|
import com.fhs.trans.service.impl.SimpleTransService;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
@ -65,7 +65,7 @@ public class DataPermissionRuleFactoryImpl implements DataPermissionRuleFactory
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 判断是否为数据翻译 {@link org.dromara.core.trans.anno.Trans} 的调用
|
* 判断是否为数据翻译 {@link com.fhs.core.trans.anno.Trans} 的调用
|
||||||
*
|
*
|
||||||
* 目前暂时只有这个办法,已经和 easy-trans 做过沟通
|
* 目前暂时只有这个办法,已经和 easy-trans 做过沟通
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -5,12 +5,7 @@ import cn.iocoder.yudao.framework.ip.core.Area;
|
||||||
import cn.iocoder.yudao.framework.ip.core.enums.AreaTypeEnum;
|
import cn.iocoder.yudao.framework.ip.core.enums.AreaTypeEnum;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link AreaUtils} 的单元测试
|
* {@link AreaUtils} 的单元测试
|
||||||
|
|
@ -36,46 +31,6 @@ public class AreaUtilsTest {
|
||||||
assertEquals(AreaUtils.format(110105), "北京市 北京市 朝阳区");
|
assertEquals(AreaUtils.format(110105), "北京市 北京市 朝阳区");
|
||||||
assertEquals(AreaUtils.format(1), "中国");
|
assertEquals(AreaUtils.format(1), "中国");
|
||||||
assertEquals(AreaUtils.format(2), "蒙古");
|
assertEquals(AreaUtils.format(2), "蒙古");
|
||||||
// 中国台湾省:省/市/区三级
|
|
||||||
assertEquals(AreaUtils.format(710101), "台湾省 台北市 中正区");
|
|
||||||
// 自定义分隔符
|
|
||||||
assertEquals(AreaUtils.format(110105, "/"), "北京市/北京市/朝阳区");
|
|
||||||
// 不存在的编号
|
|
||||||
assertNull(AreaUtils.format(-1));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testParseArea() {
|
|
||||||
// 调用:通过路径解析得到地区
|
|
||||||
Area area = AreaUtils.parseArea("北京市/北京市/朝阳区");
|
|
||||||
// 断言
|
|
||||||
assertNotNull(area);
|
|
||||||
assertEquals(area.getId(), 110105);
|
|
||||||
// 路径不存在时返回 null
|
|
||||||
assertNull(AreaUtils.parseArea("不存在/路径"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testGetParentIdByType() {
|
|
||||||
// 调用:朝阳区向上找省
|
|
||||||
Integer provinceId = AreaUtils.getParentIdByType(110105, AreaTypeEnum.PROVINCE);
|
|
||||||
// 断言
|
|
||||||
assertEquals(provinceId, 110000);
|
|
||||||
// 自身就是目标类型
|
|
||||||
assertEquals(AreaUtils.getParentIdByType(110000, AreaTypeEnum.PROVINCE), 110000);
|
|
||||||
// 不存在的编号返回 null
|
|
||||||
assertNull(AreaUtils.getParentIdByType(-1, AreaTypeEnum.PROVINCE));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testGetByType() {
|
|
||||||
// 调用:获取所有省份
|
|
||||||
List<Area> provinces = AreaUtils.getByType(AreaTypeEnum.PROVINCE, area -> area);
|
|
||||||
// 断言:包含北京、台湾、香港、澳门
|
|
||||||
assertTrue(provinces.stream().anyMatch(area -> "北京市".equals(area.getName())));
|
|
||||||
assertTrue(provinces.stream().anyMatch(area -> "台湾省".equals(area.getName())));
|
|
||||||
assertTrue(provinces.stream().anyMatch(area -> "香港特别行政区".equals(area.getName())));
|
|
||||||
assertTrue(provinces.stream().anyMatch(area -> "澳门特别行政区".equals(area.getName())));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package cn.iocoder.yudao.framework.tenant.config;
|
package cn.iocoder.yudao.framework.tenant.config;
|
||||||
|
|
||||||
|
import cn.hutool.extra.spring.SpringUtil;
|
||||||
import cn.iocoder.yudao.framework.common.biz.system.tenant.TenantCommonApi;
|
import cn.iocoder.yudao.framework.common.biz.system.tenant.TenantCommonApi;
|
||||||
import cn.iocoder.yudao.framework.common.enums.WebFilterOrderEnum;
|
import cn.iocoder.yudao.framework.common.enums.WebFilterOrderEnum;
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils;
|
import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils;
|
||||||
|
|
@ -22,7 +23,6 @@ import cn.iocoder.yudao.framework.web.config.WebProperties;
|
||||||
import cn.iocoder.yudao.framework.web.core.handler.GlobalExceptionHandler;
|
import cn.iocoder.yudao.framework.web.core.handler.GlobalExceptionHandler;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
|
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor;
|
import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor;
|
||||||
import javax.annotation.Resource;
|
|
||||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
|
|
@ -45,7 +45,11 @@ import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
|
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
|
||||||
import org.springframework.web.util.pattern.PathPattern;
|
import org.springframework.web.util.pattern.PathPattern;
|
||||||
|
|
||||||
import java.util.*;
|
import javax.annotation.Resource;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
|
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
|
||||||
|
|
||||||
|
|
@ -59,6 +63,13 @@ public class YudaoTenantAutoConfiguration {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public TenantFrameworkService tenantFrameworkService(TenantCommonApi tenantApi) {
|
public TenantFrameworkService tenantFrameworkService(TenantCommonApi tenantApi) {
|
||||||
|
// 参见 https://gitee.com/zhijiantianya/yudao-cloud/issues/IC6YZF
|
||||||
|
try {
|
||||||
|
TenantCommonApi tenantApiImpl = SpringUtil.getBean("tenantApiImpl", TenantCommonApi.class);
|
||||||
|
if (tenantApiImpl != null) {
|
||||||
|
tenantApi = tenantApiImpl;
|
||||||
|
}
|
||||||
|
} catch (Exception ignored) {}
|
||||||
return new TenantFrameworkServiceImpl(tenantApi);
|
return new TenantFrameworkServiceImpl(tenantApi);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -156,9 +167,14 @@ public class YudaoTenantAutoConfiguration {
|
||||||
|
|
||||||
// ========== MQ ==========
|
// ========== MQ ==========
|
||||||
|
|
||||||
@Configuration(proxyBeanMethods = false)
|
/**
|
||||||
@ConditionalOnClass(name = "cn.iocoder.yudao.framework.mq.redis.core.interceptor.RedisMessageInterceptor")
|
* 多租户 Redis 消息队列的配置类
|
||||||
public static class TenantRedisMQConfiguration {
|
*
|
||||||
|
* 为什么要单独一个配置类呢?如果直接把 TenantRedisMessageInterceptor Bean 的初始化放外面,会报 RedisMessageInterceptor 类不存在的错误
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
@ConditionalOnClass(name = "cn.iocoder.yudao.framework.mq.redis.core.RedisMQTemplate")
|
||||||
|
public static class TenantRedisMQAutoConfiguration {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public TenantRedisMessageInterceptor tenantRedisMessageInterceptor() {
|
public TenantRedisMessageInterceptor tenantRedisMessageInterceptor() {
|
||||||
|
|
@ -167,26 +183,24 @@ public class YudaoTenantAutoConfiguration {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Configuration(proxyBeanMethods = false)
|
|
||||||
@ConditionalOnClass(name = "org.springframework.amqp.rabbit.core.RabbitTemplate")
|
|
||||||
public static class TenantRabbitMQConfiguration {
|
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
|
@ConditionalOnClass(name = "org.springframework.amqp.rabbit.core.RabbitTemplate")
|
||||||
public TenantRabbitMQInitializer tenantRabbitMQInitializer() {
|
public TenantRabbitMQInitializer tenantRabbitMQInitializer() {
|
||||||
return new TenantRabbitMQInitializer();
|
return new TenantRabbitMQInitializer();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Configuration(proxyBeanMethods = false)
|
|
||||||
@ConditionalOnClass(name = "org.apache.rocketmq.spring.core.RocketMQTemplate")
|
|
||||||
public static class TenantRocketMQConfiguration {
|
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
|
@ConditionalOnClass(name = "org.apache.rocketmq.spring.core.RocketMQTemplate")
|
||||||
public TenantRocketMQInitializer tenantRocketMQInitializer() {
|
public TenantRocketMQInitializer tenantRocketMQInitializer() {
|
||||||
return new TenantRocketMQInitializer();
|
return new TenantRocketMQInitializer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ========== Job ==========
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnClass(name = "com.xxl.job.core.handler.annotation.XxlJob")
|
||||||
|
public TenantJobAspect tenantJobAspect(TenantFrameworkService tenantFrameworkService) {
|
||||||
|
return new TenantJobAspect(tenantFrameworkService);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ========== Redis ==========
|
// ========== Redis ==========
|
||||||
|
|
@ -202,25 +216,7 @@ public class YudaoTenantAutoConfiguration {
|
||||||
RedisCacheWriter cacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory,
|
RedisCacheWriter cacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory,
|
||||||
BatchStrategies.scan(yudaoCacheProperties.getRedisScanBatchSize()));
|
BatchStrategies.scan(yudaoCacheProperties.getRedisScanBatchSize()));
|
||||||
// 创建 TenantRedisCacheManager 对象
|
// 创建 TenantRedisCacheManager 对象
|
||||||
TenantRedisCacheManager cacheManager = new TenantRedisCacheManager(cacheWriter, redisCacheConfiguration,
|
return new TenantRedisCacheManager(cacheWriter, redisCacheConfiguration, tenantProperties.getIgnoreCaches());
|
||||||
tenantProperties.getIgnoreCaches());
|
|
||||||
// 开启事务感知:@Transactional 方法内的 @CacheEvict / @CachePut 自动延迟到 afterCommit,
|
|
||||||
// 避免事务未提交就清缓存被并发读穿写脏值;无事务时立即生效,行为不变
|
|
||||||
cacheManager.setTransactionAware(true);
|
|
||||||
return cacheManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ========== Job ==========
|
|
||||||
|
|
||||||
@Configuration(proxyBeanMethods = false)
|
|
||||||
@ConditionalOnClass(name = "com.xxl.job.core.context.XxlJobContext")
|
|
||||||
public static class TenantJobConfiguration {
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public TenantJobAspect tenantJobAspect(TenantFrameworkService tenantFrameworkService) {
|
|
||||||
return new TenantJobAspect(tenantFrameworkService);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -42,8 +42,8 @@
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>javax.servlet</groupId>
|
<groupId>jakarta.servlet</groupId>
|
||||||
<artifactId>javax.servlet-api</artifactId>
|
<artifactId>jakarta.servlet-api</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- RPC 相关 -->
|
<!-- RPC 相关 -->
|
||||||
|
|
|
||||||
|
|
@ -42,8 +42,8 @@
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>javax.servlet</groupId>
|
<groupId>jakarta.servlet</groupId>
|
||||||
<artifactId>javax.servlet-api</artifactId>
|
<artifactId>jakarta.servlet-api</artifactId>
|
||||||
<scope>provided</scope> <!-- 设置为 provided,只有 ExcelUtils 使用 -->
|
<scope>provided</scope> <!-- 设置为 provided,只有 ExcelUtils 使用 -->
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -41,8 +41,8 @@
|
||||||
|
|
||||||
<!-- 工具类相关 -->
|
<!-- 工具类相关 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>javax.validation</groupId>
|
<groupId>jakarta.validation</groupId>
|
||||||
<artifactId>validation-api</artifactId>
|
<artifactId>jakarta.validation-api</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
|
||||||
|
|
@ -35,8 +35,8 @@
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>javax.servlet</groupId>
|
<groupId>jakarta.servlet</groupId>
|
||||||
<artifactId>javax.servlet-api</artifactId>
|
<artifactId>jakarta.servlet-api</artifactId>
|
||||||
<scope>provided</scope> <!-- 设置为 provided,只有 TraceFilter 使用 -->
|
<scope>provided</scope> <!-- 设置为 provided,只有 TraceFilter 使用 -->
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ import cn.iocoder.yudao.framework.mq.redis.core.stream.AbstractRedisStreamMessag
|
||||||
import cn.iocoder.yudao.framework.redis.config.YudaoRedisAutoConfiguration;
|
import cn.iocoder.yudao.framework.redis.config.YudaoRedisAutoConfiguration;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.redisson.api.RedissonClient;
|
import org.redisson.api.RedissonClient;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
|
|
@ -69,8 +70,7 @@ public class YudaoRedisMQConsumerAutoConfiguration {
|
||||||
public RedisPendingMessageResendJob redisPendingMessageResendJob(List<AbstractRedisStreamMessageListener<?>> listeners,
|
public RedisPendingMessageResendJob redisPendingMessageResendJob(List<AbstractRedisStreamMessageListener<?>> listeners,
|
||||||
RedisMQTemplate redisTemplate,
|
RedisMQTemplate redisTemplate,
|
||||||
RedissonClient redissonClient) {
|
RedissonClient redissonClient) {
|
||||||
return new RedisPendingMessageResendJob(listeners, redisTemplate, redissonClient,
|
return new RedisPendingMessageResendJob(listeners, redisTemplate, redissonClient);
|
||||||
RedisPendingMessageResendJob.DEFAULT_RESEND_LOCK_KEY);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -81,8 +81,7 @@ public class YudaoRedisMQConsumerAutoConfiguration {
|
||||||
public RedisStreamMessageCleanupJob redisStreamMessageCleanupJob(List<AbstractRedisStreamMessageListener<?>> listeners,
|
public RedisStreamMessageCleanupJob redisStreamMessageCleanupJob(List<AbstractRedisStreamMessageListener<?>> listeners,
|
||||||
RedisMQTemplate redisTemplate,
|
RedisMQTemplate redisTemplate,
|
||||||
RedissonClient redissonClient) {
|
RedissonClient redissonClient) {
|
||||||
return new RedisStreamMessageCleanupJob(listeners, redisTemplate, redissonClient,
|
return new RedisStreamMessageCleanupJob(listeners, redisTemplate, redissonClient);
|
||||||
RedisStreamMessageCleanupJob.DEFAULT_CLEANUP_LOCK_KEY);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -23,9 +23,7 @@ import java.util.Objects;
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class RedisPendingMessageResendJob {
|
public class RedisPendingMessageResendJob {
|
||||||
|
|
||||||
public static final String DEFAULT_RESEND_LOCK_KEY = "redis:stream:pending-message-resend:lock";
|
private static final String LOCK_KEY = "redis:stream:pending-message-resend:lock";
|
||||||
|
|
||||||
public static final String IOT_RESEND_LOCK_KEY = "redis:stream:pending-message-resend:lock:iot";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 消息超时时间,默认 5 分钟
|
* 消息超时时间,默认 5 分钟
|
||||||
|
|
@ -38,27 +36,23 @@ public class RedisPendingMessageResendJob {
|
||||||
private final List<AbstractRedisStreamMessageListener<?>> listeners;
|
private final List<AbstractRedisStreamMessageListener<?>> listeners;
|
||||||
private final RedisMQTemplate redisTemplate;
|
private final RedisMQTemplate redisTemplate;
|
||||||
private final RedissonClient redissonClient;
|
private final RedissonClient redissonClient;
|
||||||
private final String resendLockKey;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 一分钟执行一次,这里选择每分钟的 35 秒执行,是为了避免整点任务过多的问题
|
* 一分钟执行一次,这里选择每分钟的 35 秒执行,是为了避免整点任务过多的问题
|
||||||
*/
|
*/
|
||||||
@Scheduled(cron = "35 * * * * ?")
|
@Scheduled(cron = "35 * * * * ?")
|
||||||
public void messageResend() {
|
public void messageResend() {
|
||||||
RLock lock = redissonClient.getLock(resendLockKey);
|
RLock lock = redissonClient.getLock(LOCK_KEY);
|
||||||
|
// 尝试加锁
|
||||||
if (lock.tryLock()) {
|
if (lock.tryLock()) {
|
||||||
try {
|
try {
|
||||||
execute();
|
execute();
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
log.error("[messageResend][执行异常][lockKey={}]", resendLockKey, ex);
|
log.error("[messageResend][执行异常]", ex);
|
||||||
} finally {
|
} finally {
|
||||||
if (lock.isHeldByCurrentThread()) {
|
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
log.debug("[messageResend][未获取到锁,跳过本轮][lockKey={}]", resendLockKey);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -23,16 +23,7 @@ import java.util.List;
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class RedisStreamMessageCleanupJob {
|
public class RedisStreamMessageCleanupJob {
|
||||||
|
|
||||||
/**
|
private static final String LOCK_KEY = "redis:stream:message-cleanup:lock";
|
||||||
* 业务 MQ(Spring 容器内 AbstractRedisStreamMessageListener)清理任务使用的分布式锁
|
|
||||||
*/
|
|
||||||
public static final String DEFAULT_CLEANUP_LOCK_KEY = "redis:stream:message-cleanup:lock";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* IoT Redis 总线清理任务使用的分布式锁(须与 {@link #DEFAULT_CLEANUP_LOCK_KEY} 区分,否则会共抢一把锁,
|
|
||||||
* 同一时刻只有一侧能执行 XTRIM,另一侧 Stream 可能无限积压)
|
|
||||||
*/
|
|
||||||
public static final String IOT_CLEANUP_LOCK_KEY = "redis:stream:message-cleanup:lock:iot";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 保留的消息数量,默认保留最近 10000 条消息
|
* 保留的消息数量,默认保留最近 10000 条消息
|
||||||
|
|
@ -42,30 +33,23 @@ public class RedisStreamMessageCleanupJob {
|
||||||
private final List<AbstractRedisStreamMessageListener<?>> listeners;
|
private final List<AbstractRedisStreamMessageListener<?>> listeners;
|
||||||
private final RedisMQTemplate redisTemplate;
|
private final RedisMQTemplate redisTemplate;
|
||||||
private final RedissonClient redissonClient;
|
private final RedissonClient redissonClient;
|
||||||
/**
|
|
||||||
* Redisson 锁键(多 Bean 注册清理任务时必须各不相同)
|
|
||||||
*/
|
|
||||||
private final String cleanupLockKey;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 每小时执行一次清理任务
|
* 每小时执行一次清理任务
|
||||||
*/
|
*/
|
||||||
@Scheduled(cron = "0 0 * * * ?")
|
@Scheduled(cron = "0 0 * * * ?")
|
||||||
public void cleanup() {
|
public void cleanup() {
|
||||||
RLock lock = redissonClient.getLock(cleanupLockKey);
|
RLock lock = redissonClient.getLock(LOCK_KEY);
|
||||||
|
// 尝试加锁
|
||||||
if (lock.tryLock()) {
|
if (lock.tryLock()) {
|
||||||
try {
|
try {
|
||||||
execute();
|
execute();
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
log.error("[cleanup][执行异常][lockKey={}]", cleanupLockKey, ex);
|
log.error("[cleanup][执行异常]", ex);
|
||||||
} finally {
|
} finally {
|
||||||
if (lock.isHeldByCurrentThread()) {
|
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
log.debug("[cleanup][未获取到锁,跳过本轮][lockKey={}]", cleanupLockKey);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -75,8 +59,8 @@ public class RedisStreamMessageCleanupJob {
|
||||||
StreamOperations<String, Object, Object> ops = redisTemplate.getRedisTemplate().opsForStream();
|
StreamOperations<String, Object, Object> ops = redisTemplate.getRedisTemplate().opsForStream();
|
||||||
listeners.forEach(listener -> {
|
listeners.forEach(listener -> {
|
||||||
try {
|
try {
|
||||||
// 使用 XTRIM MAXLEN 精确裁剪(approximate=false),避免 ~ 模式下长期明显高于上限
|
// 使用 XTRIM 命令清理消息,只保留最近的 MAX_LEN 条消息
|
||||||
Long trimCount = ops.trim(listener.getStreamKey(), MAX_COUNT, false);
|
Long trimCount = ops.trim(listener.getStreamKey(), MAX_COUNT, true);
|
||||||
if (trimCount != null && trimCount > 0) {
|
if (trimCount != null && trimCount > 0) {
|
||||||
log.info("[execute][Stream({}) 清理消息数量({})]", listener.getStreamKey(), trimCount);
|
log.info("[execute][Stream({}) 清理消息数量({})]", listener.getStreamKey(), trimCount);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -87,20 +87,13 @@
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.dromara</groupId> <!-- VO 数据翻译 -->
|
<groupId>com.fhs-opensource</groupId> <!-- VO 数据翻译 -->
|
||||||
<artifactId>easy-trans-spring-boot-starter</artifactId>
|
<artifactId>easy-trans-spring-boot-starter</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.dromara</groupId>
|
<groupId>com.fhs-opensource</groupId>
|
||||||
<artifactId>easy-trans-mybatis-plus-extend</artifactId>
|
<artifactId>easy-trans-mybatis-plus-extend</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- Test 测试相关 -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-starter-test</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import com.baomidou.mybatisplus.annotation.FieldFill;
|
||||||
import com.baomidou.mybatisplus.annotation.TableField;
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
import com.baomidou.mybatisplus.annotation.TableLogic;
|
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||||
import org.dromara.core.trans.vo.TransPojo;
|
import com.fhs.core.trans.vo.TransPojo;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import org.apache.ibatis.type.JdbcType;
|
import org.apache.ibatis.type.JdbcType;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,49 +20,51 @@ public enum DbTypeEnum {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* H2
|
* H2
|
||||||
|
*
|
||||||
|
* 注意:H2 不支持 find_in_set 函数
|
||||||
*/
|
*/
|
||||||
H2(DbType.H2, "H2", "POSITION(',' || CAST(#{value} AS VARCHAR) || ',' IN ',' || #{column} || ',') > 0"),
|
H2(DbType.H2, "H2", ""),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MySQL
|
* MySQL
|
||||||
*/
|
*/
|
||||||
MY_SQL(DbType.MYSQL, "MySQL", "FIND_IN_SET(#{value}, #{column}) <> 0"),
|
MY_SQL(DbType.MYSQL, "MySQL", "FIND_IN_SET('#{value}', #{column}) <> 0"),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Oracle
|
* Oracle
|
||||||
*/
|
*/
|
||||||
ORACLE(DbType.ORACLE, "Oracle", "INSTR(',' || #{column} || ',', ',' || #{value} || ',') > 0"),
|
ORACLE(DbType.ORACLE, "Oracle", "FIND_IN_SET('#{value}', #{column}) <> 0"),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PostgreSQL
|
* PostgreSQL
|
||||||
*
|
*
|
||||||
* 华为 openGauss 使用 ProductName 与 PostgreSQL 相同
|
* 华为 openGauss 使用 ProductName 与 PostgreSQL 相同
|
||||||
*/
|
*/
|
||||||
POSTGRE_SQL(DbType.POSTGRE_SQL, "PostgreSQL", "POSITION(',' || CAST(#{value} AS VARCHAR) || ',' IN ',' || #{column} || ',') > 0"),
|
POSTGRE_SQL(DbType.POSTGRE_SQL,"PostgreSQL", "POSITION('#{value}' IN #{column}) <> 0"),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SQL Server
|
* SQL Server
|
||||||
*/
|
*/
|
||||||
SQL_SERVER(DbType.SQL_SERVER, "Microsoft SQL Server", "CHARINDEX(',' + CAST(#{value} AS varchar(255)) + ',', ',' + #{column} + ',') > 0"),
|
SQL_SERVER(DbType.SQL_SERVER, "Microsoft SQL Server", "CHARINDEX(',' + #{value} + ',', ',' + #{column} + ',') <> 0"),
|
||||||
/**
|
/**
|
||||||
* SQL Server 2005
|
* SQL Server 2005
|
||||||
*/
|
*/
|
||||||
SQL_SERVER2005(DbType.SQL_SERVER2005, "Microsoft SQL Server 2005", "CHARINDEX(',' + CAST(#{value} AS varchar(255)) + ',', ',' + #{column} + ',') > 0"),
|
SQL_SERVER2005(DbType.SQL_SERVER2005, "Microsoft SQL Server 2005", "CHARINDEX(',' + #{value} + ',', ',' + #{column} + ',') <> 0"),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 达梦
|
* 达梦
|
||||||
*/
|
*/
|
||||||
DM(DbType.DM, "DM DBMS", "FIND_IN_SET(#{value}, #{column}) <> 0"),
|
DM(DbType.DM, "DM DBMS", "FIND_IN_SET('#{value}', #{column}) <> 0"),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 人大金仓
|
* 人大金仓
|
||||||
*/
|
*/
|
||||||
KINGBASE_ES(DbType.KINGBASE_ES, "KingbaseES", "POSITION(',' || CAST(#{value} AS VARCHAR) || ',' IN ',' || #{column} || ',') > 0"),
|
KINGBASE_ES(DbType.KINGBASE_ES, "KingbaseES", "POSITION('#{value}' IN #{column}) <> 0"),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* OceanBase
|
* OceanBase
|
||||||
*/
|
*/
|
||||||
OCEAN_BASE(DbType.OCEAN_BASE, "OceanBase", "FIND_IN_SET(#{value}, #{column}) <> 0")
|
OCEAN_BASE(DbType.OCEAN_BASE, "OceanBase", "FIND_IN_SET('#{value}', #{column}) <> 0")
|
||||||
|
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
@ -93,9 +95,7 @@ public enum DbTypeEnum {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getFindInSetTemplate(DbType dbType) {
|
public static String getFindInSetTemplate(DbType dbType) {
|
||||||
return Optional.ofNullable(MAP_BY_MP.get(dbType))
|
return Optional.of(MAP_BY_MP.get(dbType).getFindInSetTemplate())
|
||||||
.map(DbTypeEnum::getFindInSetTemplate)
|
|
||||||
.filter(StrUtil::isNotBlank)
|
|
||||||
.orElseThrow(() -> new IllegalArgumentException("FIND_IN_SET not supported"));
|
.orElseThrow(() -> new IllegalArgumentException("FIND_IN_SET not supported"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -119,31 +119,6 @@ public interface BaseMapperX<T> extends MPJBaseMapper<T> {
|
||||||
return selectOne(new LambdaQueryWrapper<T>().eq(field1, value1).eq(field2, value2).eq(field3, value3));
|
return selectOne(new LambdaQueryWrapper<T>().eq(field1, value1).eq(field2, value2).eq(field3, value3));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 获得满足条件的一条记录,并使用 FOR UPDATE 锁定。
|
|
||||||
*
|
|
||||||
* 注意:需要在事务中调用,否则锁会立即释放。
|
|
||||||
*
|
|
||||||
* @param queryWrapper 查询条件
|
|
||||||
* @return 实体
|
|
||||||
*/
|
|
||||||
default T selectOneForUpdate(LambdaQueryWrapper<T> queryWrapper) {
|
|
||||||
return selectOne(queryWrapper.last("FOR UPDATE"));
|
|
||||||
}
|
|
||||||
|
|
||||||
default T selectOneForUpdate(SFunction<T, ?> field, Object value) {
|
|
||||||
return selectOneForUpdate(new LambdaQueryWrapper<T>().eq(field, value));
|
|
||||||
}
|
|
||||||
|
|
||||||
default T selectOneForUpdate(SFunction<T, ?> field1, Object value1, SFunction<T, ?> field2, Object value2) {
|
|
||||||
return selectOneForUpdate(new LambdaQueryWrapper<T>().eq(field1, value1).eq(field2, value2));
|
|
||||||
}
|
|
||||||
|
|
||||||
default T selectOneForUpdate(SFunction<T, ?> field1, Object value1, SFunction<T, ?> field2, Object value2,
|
|
||||||
SFunction<T, ?> field3, Object value3) {
|
|
||||||
return selectOneForUpdate(new LambdaQueryWrapper<T>().eq(field1, value1).eq(field2, value2).eq(field3, value3));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取满足条件的第 1 条记录
|
* 获取满足条件的第 1 条记录
|
||||||
*
|
*
|
||||||
|
|
@ -170,17 +145,6 @@ public interface BaseMapperX<T> extends MPJBaseMapper<T> {
|
||||||
return CollUtil.getFirst(list);
|
return CollUtil.getFirst(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取满足条件的最新一条记录
|
|
||||||
* <p>
|
|
||||||
* 目的:解决并发场景下,插入多条记录后,使用 selectOne 会报错的问题
|
|
||||||
*
|
|
||||||
* @param queryWrapper 查询条件
|
|
||||||
* @return 最新一条;不存在返回 null
|
|
||||||
*/
|
|
||||||
default T selectLastOne(LambdaQueryWrapper<T> queryWrapper) {
|
|
||||||
return CollUtil.getLast(selectList(queryWrapper));
|
|
||||||
}
|
|
||||||
|
|
||||||
default Long selectCount() {
|
default Long selectCount() {
|
||||||
return selectCount(new QueryWrapper<>());
|
return selectCount(new QueryWrapper<>());
|
||||||
|
|
|
||||||
|
|
@ -24,12 +24,6 @@ public class LambdaQueryWrapperX<T> extends LambdaQueryWrapper<T> {
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
public LambdaQueryWrapperX<T> likeRightIfPresent(SFunction<T, ?> column, String val) {
|
|
||||||
if (StringUtils.hasText(val)) {
|
|
||||||
return (LambdaQueryWrapperX<T>) super.likeRight(column, val);
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LambdaQueryWrapperX<T> inIfPresent(SFunction<T, ?> column, Collection<?> values) {
|
public LambdaQueryWrapperX<T> inIfPresent(SFunction<T, ?> column, Collection<?> values) {
|
||||||
if (ObjectUtil.isAllNotEmpty(values) && !ArrayUtil.isEmpty(values)) {
|
if (ObjectUtil.isAllNotEmpty(values) && !ArrayUtil.isEmpty(values)) {
|
||||||
|
|
|
||||||
|
|
@ -27,13 +27,6 @@ public class MPJLambdaWrapperX<T> extends MPJLambdaWrapper<T> {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public <S> MPJLambdaWrapperX<T> likeRightIfPresent(SFunction<S, ?> column, String val) {
|
|
||||||
if (StringUtils.hasText(val)) {
|
|
||||||
return (MPJLambdaWrapperX<T>) super.likeRight(column, val);
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public <S> MPJLambdaWrapperX<T> inIfPresent(SFunction<S, ?> column, Collection<?> values) {
|
public <S> MPJLambdaWrapperX<T> inIfPresent(SFunction<S, ?> column, Collection<?> values) {
|
||||||
if (ObjectUtil.isAllNotEmpty(values) && !ArrayUtil.isEmpty(values)) {
|
if (ObjectUtil.isAllNotEmpty(values) && !ArrayUtil.isEmpty(values)) {
|
||||||
return (MPJLambdaWrapperX<T>) super.in(column, values);
|
return (MPJLambdaWrapperX<T>) super.in(column, values);
|
||||||
|
|
@ -109,6 +102,7 @@ public class MPJLambdaWrapperX<T> extends MPJLambdaWrapper<T> {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ========== 重写父类方法,方便链式调用 ==========
|
// ========== 重写父类方法,方便链式调用 ==========
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -25,13 +25,6 @@ public class QueryWrapperX<T> extends QueryWrapper<T> {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public QueryWrapperX<T> likeRightIfPresent(String column, String val) {
|
|
||||||
if (StringUtils.hasText(val)) {
|
|
||||||
return (QueryWrapperX<T>) super.likeRight(column, val);
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public QueryWrapperX<T> inIfPresent(String column, Collection<?> values) {
|
public QueryWrapperX<T> inIfPresent(String column, Collection<?> values) {
|
||||||
if (!CollectionUtils.isEmpty(values)) {
|
if (!CollectionUtils.isEmpty(values)) {
|
||||||
return (QueryWrapperX<T>) super.in(column, values);
|
return (QueryWrapperX<T>) super.in(column, values);
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,6 @@ import net.sf.jsqlparser.schema.Table;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MyBatis 工具类
|
* MyBatis 工具类
|
||||||
|
|
@ -32,12 +31,6 @@ public class MyBatisUtils {
|
||||||
|
|
||||||
private static final String MYSQL_ESCAPE_CHARACTER = "`";
|
private static final String MYSQL_ESCAPE_CHARACTER = "`";
|
||||||
|
|
||||||
private static final Pattern SAFE_COLUMN_NAME_PATTERN = Pattern.compile("^[a-zA-Z0-9_]+(\\.[a-zA-Z0-9_]+)*$");
|
|
||||||
|
|
||||||
private static final String FIND_IN_SET_VALUE_PLACEHOLDER = "#{value}";
|
|
||||||
|
|
||||||
private static final String FIND_IN_SET_COLUMN_PLACEHOLDER = "#{column}";
|
|
||||||
|
|
||||||
public static <T> Page<T> buildPage(PageParam pageParam) {
|
public static <T> Page<T> buildPage(PageParam pageParam) {
|
||||||
return buildPage(pageParam, null);
|
return buildPage(pageParam, null);
|
||||||
}
|
}
|
||||||
|
|
@ -49,11 +42,8 @@ public class MyBatisUtils {
|
||||||
// 排序字段
|
// 排序字段
|
||||||
if (CollUtil.isNotEmpty(sortingFields)) {
|
if (CollUtil.isNotEmpty(sortingFields)) {
|
||||||
for (SortingField sortingField : sortingFields) {
|
for (SortingField sortingField : sortingFields) {
|
||||||
String columnName = buildSafeOrderColumn(sortingField.getField());
|
page.addOrder(new OrderItem().setAsc(SortingField.ORDER_ASC.equals(sortingField.getOrder()))
|
||||||
if (columnName == null) {
|
.setColumn(StrUtil.toUnderlineCase(sortingField.getField())));
|
||||||
continue;
|
|
||||||
}
|
|
||||||
page.addOrder(new OrderItem().setAsc(isAscOrder(sortingField.getOrder())).setColumn(columnName));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return page;
|
return page;
|
||||||
|
|
@ -67,29 +57,23 @@ public class MyBatisUtils {
|
||||||
if (wrapper instanceof QueryWrapper) {
|
if (wrapper instanceof QueryWrapper) {
|
||||||
QueryWrapper<T> query = (QueryWrapper<T>) wrapper;
|
QueryWrapper<T> query = (QueryWrapper<T>) wrapper;
|
||||||
for (SortingField sortingField : sortingFields) {
|
for (SortingField sortingField : sortingFields) {
|
||||||
String columnName = buildSafeOrderColumn(sortingField.getField());
|
query.orderBy(true,
|
||||||
if (columnName == null) {
|
SortingField.ORDER_ASC.equals(sortingField.getOrder()),
|
||||||
continue;
|
StrUtil.toUnderlineCase(sortingField.getField()));
|
||||||
}
|
|
||||||
query.orderBy(true, isAscOrder(sortingField.getOrder()), columnName);
|
|
||||||
}
|
}
|
||||||
} else if (wrapper instanceof LambdaQueryWrapper) {
|
} else if (wrapper instanceof LambdaQueryWrapper) {
|
||||||
// LambdaQueryWrapper 不直接支持字符串字段排序,使用 last 方法拼接 ORDER BY
|
// LambdaQueryWrapper 不直接支持字符串字段排序,使用 last 方法拼接 ORDER BY
|
||||||
LambdaQueryWrapper<T> lambdaQuery = (LambdaQueryWrapper<T>) wrapper;
|
LambdaQueryWrapper<T> lambdaQuery = (LambdaQueryWrapper<T>) wrapper;
|
||||||
StringBuilder orderBy = new StringBuilder();
|
StringBuilder orderBy = new StringBuilder();
|
||||||
for (SortingField sortingField : sortingFields) {
|
for (SortingField sortingField : sortingFields) {
|
||||||
String columnName = buildSafeOrderColumn(sortingField.getField());
|
|
||||||
if (columnName == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (StrUtil.isNotEmpty(orderBy)) {
|
if (StrUtil.isNotEmpty(orderBy)) {
|
||||||
orderBy.append(", ");
|
orderBy.append(", ");
|
||||||
}
|
}
|
||||||
orderBy.append(columnName).append(" ").append(getOrderDirection(sortingField.getOrder()));
|
orderBy.append(StrUtil.toUnderlineCase(sortingField.getField()))
|
||||||
|
.append(" ")
|
||||||
|
.append(SortingField.ORDER_ASC.equals(sortingField.getOrder()) ? "ASC" : "DESC");
|
||||||
}
|
}
|
||||||
if (StrUtil.isNotEmpty(orderBy)) {
|
|
||||||
lambdaQuery.last("ORDER BY " + orderBy);
|
lambdaQuery.last("ORDER BY " + orderBy);
|
||||||
}
|
|
||||||
// 另外个思路:https://blog.csdn.net/m0_59084856/article/details/138450913
|
// 另外个思路:https://blog.csdn.net/m0_59084856/article/details/138450913
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalArgumentException("Unsupported wrapper type: " + wrapper.getClass().getName());
|
throw new IllegalArgumentException("Unsupported wrapper type: " + wrapper.getClass().getName());
|
||||||
|
|
@ -97,22 +81,6 @@ public class MyBatisUtils {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isAscOrder(String order) {
|
|
||||||
return SortingField.ORDER_ASC.equals(order);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getOrderDirection(String order) {
|
|
||||||
return isAscOrder(order) ? "ASC" : "DESC";
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String buildSafeOrderColumn(String field) {
|
|
||||||
String columnName = StrUtil.toUnderlineCase(field);
|
|
||||||
if (StrUtil.isEmpty(columnName) || !SAFE_COLUMN_NAME_PATTERN.matcher(columnName).matches()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return columnName;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 将拦截器添加到链中
|
* 将拦截器添加到链中
|
||||||
* 由于 MybatisPlusInterceptor 不支持添加拦截器,所以只能全量设置
|
* 由于 MybatisPlusInterceptor 不支持添加拦截器,所以只能全量设置
|
||||||
|
|
@ -161,43 +129,15 @@ public class MyBatisUtils {
|
||||||
/**
|
/**
|
||||||
* 跨数据库的 find_in_set 实现
|
* 跨数据库的 find_in_set 实现
|
||||||
*
|
*
|
||||||
* @param columnName 字段名称
|
* @param column 字段名称
|
||||||
|
* @param value 查询值(不带单引号)
|
||||||
* @return sql
|
* @return sql
|
||||||
*/
|
*/
|
||||||
public static String findInSet(String columnName) {
|
public static String findInSet(String column, Object value) {
|
||||||
return findInSet(columnName, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 跨数据库的 find_in_set 实现,适用于同一个 apply 语句中有多个参数的场景
|
|
||||||
*
|
|
||||||
* @param columnName 字段名称
|
|
||||||
* @param paramIndex apply 参数序号
|
|
||||||
* @return sql
|
|
||||||
*/
|
|
||||||
public static String findInSetWithParamIndex(String columnName, int paramIndex) {
|
|
||||||
return findInSet(columnName, paramIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String findInSet(String columnName, int paramIndex) {
|
|
||||||
DbType dbType = JdbcUtils.getDbType();
|
DbType dbType = JdbcUtils.getDbType();
|
||||||
return findInSet(dbType, columnName, paramIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
static String findInSet(DbType dbType, String columnName, int paramIndex) {
|
|
||||||
if (!isSafeColumnName(columnName)) {
|
|
||||||
throw new IllegalArgumentException("Invalid column name: " + columnName);
|
|
||||||
}
|
|
||||||
if (paramIndex < 0) {
|
|
||||||
throw new IllegalArgumentException("Invalid param index: " + paramIndex);
|
|
||||||
}
|
|
||||||
return DbTypeEnum.getFindInSetTemplate(dbType)
|
return DbTypeEnum.getFindInSetTemplate(dbType)
|
||||||
.replace(FIND_IN_SET_COLUMN_PLACEHOLDER, columnName)
|
.replace("#{column}", column)
|
||||||
.replace(FIND_IN_SET_VALUE_PLACEHOLDER, "{" + paramIndex + "}");
|
.replace("#{value}", StrUtil.toString(value));
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean isSafeColumnName(String columnName) {
|
|
||||||
return StrUtil.isNotEmpty(columnName) && SAFE_COLUMN_NAME_PATTERN.matcher(columnName).matches();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,15 @@
|
||||||
package cn.iocoder.yudao.framework.translate.config;
|
package cn.iocoder.yudao.framework.translate.config;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.translate.core.TranslateUtils;
|
import cn.iocoder.yudao.framework.translate.core.TranslateUtils;
|
||||||
import org.dromara.trans.service.impl.TransService;
|
import com.fhs.trans.service.impl.TransService;
|
||||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
|
|
||||||
@AutoConfiguration
|
@AutoConfiguration
|
||||||
public class YudaoTranslateAutoConfiguration {
|
public class YudaoTranslateAutoConfiguration {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnBean(TransService.class)
|
@SuppressWarnings({"InstantiationOfUtilityClass", "SpringJavaInjectionPointsAutowiringInspection"})
|
||||||
@SuppressWarnings("InstantiationOfUtilityClass")
|
|
||||||
public TranslateUtils translateUtils(TransService transService) {
|
public TranslateUtils translateUtils(TransService transService) {
|
||||||
TranslateUtils.init(transService);
|
TranslateUtils.init(transService);
|
||||||
return new TranslateUtils();
|
return new TranslateUtils();
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
package cn.iocoder.yudao.framework.translate.core;
|
package cn.iocoder.yudao.framework.translate.core;
|
||||||
|
|
||||||
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.collection.CollUtil;
|
||||||
import org.dromara.core.trans.vo.VO;
|
import com.fhs.core.trans.vo.VO;
|
||||||
import org.dromara.trans.service.impl.TransService;
|
import com.fhs.trans.service.impl.TransService;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,173 +0,0 @@
|
||||||
package cn.iocoder.yudao.framework.mybatis.core.util;
|
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.SortingField;
|
|
||||||
import com.baomidou.mybatisplus.annotation.DbType;
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
||||||
import com.baomidou.mybatisplus.core.metadata.OrderItem;
|
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@link MyBatisUtils} 的单元测试
|
|
||||||
*/
|
|
||||||
public class MyBatisUtilsTest {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testBuildPage_sortingFields() {
|
|
||||||
// 准备参数
|
|
||||||
PageParam pageParam = new PageParam();
|
|
||||||
pageParam.setPageNo(2);
|
|
||||||
pageParam.setPageSize(20);
|
|
||||||
List<SortingField> sortingFields = Arrays.asList(
|
|
||||||
new SortingField("userName", SortingField.ORDER_ASC),
|
|
||||||
new SortingField("u.id", SortingField.ORDER_DESC),
|
|
||||||
new SortingField("name desc", SortingField.ORDER_DESC));
|
|
||||||
|
|
||||||
// 调用
|
|
||||||
Page<Object> page = MyBatisUtils.buildPage(pageParam, sortingFields);
|
|
||||||
|
|
||||||
// 断言
|
|
||||||
assertEquals(2, page.getCurrent());
|
|
||||||
assertEquals(20, page.getSize());
|
|
||||||
assertEquals(2, page.orders().size());
|
|
||||||
assertOrderItem(page.orders().get(0), "user_name", true);
|
|
||||||
assertOrderItem(page.orders().get(1), "u.id", false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testAddOrder_queryWrapper() {
|
|
||||||
// 准备参数
|
|
||||||
QueryWrapper<Object> query = new QueryWrapper<>();
|
|
||||||
List<SortingField> sortingFields = Arrays.asList(
|
|
||||||
new SortingField("userName", SortingField.ORDER_ASC),
|
|
||||||
new SortingField("u.id", SortingField.ORDER_DESC),
|
|
||||||
new SortingField("name;drop", SortingField.ORDER_ASC));
|
|
||||||
|
|
||||||
// 调用
|
|
||||||
MyBatisUtils.addOrder(query, sortingFields);
|
|
||||||
|
|
||||||
// 断言
|
|
||||||
assertEquals(" ORDER BY user_name ASC,u.id DESC", query.getSqlSegment());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testAddOrder_lambdaQueryWrapper() {
|
|
||||||
// 准备参数
|
|
||||||
LambdaQueryWrapper<Object> query = new LambdaQueryWrapper<>();
|
|
||||||
List<SortingField> sortingFields = Arrays.asList(
|
|
||||||
new SortingField("userName", SortingField.ORDER_ASC),
|
|
||||||
new SortingField("u.id", SortingField.ORDER_DESC),
|
|
||||||
new SortingField("name`", SortingField.ORDER_ASC));
|
|
||||||
|
|
||||||
// 调用
|
|
||||||
MyBatisUtils.addOrder(query, sortingFields);
|
|
||||||
|
|
||||||
// 断言
|
|
||||||
assertEquals(" ORDER BY user_name ASC, u.id DESC", query.getSqlSegment());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testAddOrder_lambdaQueryWrapper_invalidSortingFields() {
|
|
||||||
// 准备参数
|
|
||||||
LambdaQueryWrapper<Object> query = new LambdaQueryWrapper<>();
|
|
||||||
List<SortingField> sortingFields = Arrays.asList(
|
|
||||||
new SortingField("name desc", SortingField.ORDER_ASC),
|
|
||||||
new SortingField("name;drop", SortingField.ORDER_DESC));
|
|
||||||
|
|
||||||
// 调用
|
|
||||||
MyBatisUtils.addOrder(query, sortingFields);
|
|
||||||
|
|
||||||
// 断言
|
|
||||||
assertEquals("", query.getSqlSegment());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testOrderDirection() {
|
|
||||||
assertTrue(MyBatisUtils.isAscOrder(SortingField.ORDER_ASC));
|
|
||||||
assertFalse(MyBatisUtils.isAscOrder(SortingField.ORDER_DESC));
|
|
||||||
assertEquals("ASC", MyBatisUtils.getOrderDirection(SortingField.ORDER_ASC));
|
|
||||||
assertEquals("DESC", MyBatisUtils.getOrderDirection(SortingField.ORDER_DESC));
|
|
||||||
assertEquals("DESC", MyBatisUtils.getOrderDirection(null));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testFindInSet() {
|
|
||||||
assertEquals("FIND_IN_SET({0}, websites) <> 0",
|
|
||||||
MyBatisUtils.findInSet(DbType.MYSQL, "websites", 0));
|
|
||||||
assertEquals("POSITION(',' || CAST({0} AS VARCHAR) || ',' IN ',' || websites || ',') > 0",
|
|
||||||
MyBatisUtils.findInSet(DbType.H2, "websites", 0));
|
|
||||||
assertEquals("INSTR(',' || t.websites || ',', ',' || {0} || ',') > 0",
|
|
||||||
MyBatisUtils.findInSet(DbType.ORACLE, "t.websites", 0));
|
|
||||||
assertEquals("POSITION(',' || CAST({1} AS VARCHAR) || ',' IN ',' || websites || ',') > 0",
|
|
||||||
MyBatisUtils.findInSet(DbType.POSTGRE_SQL, "websites", 1));
|
|
||||||
assertEquals("CHARINDEX(',' + CAST({2} AS varchar(255)) + ',', ',' + websites + ',') > 0",
|
|
||||||
MyBatisUtils.findInSet(DbType.SQL_SERVER, "websites", 2));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testFindInSet_invalidColumnName() {
|
|
||||||
assertThrows(IllegalArgumentException.class,
|
|
||||||
() -> MyBatisUtils.findInSet(DbType.MYSQL, "websites;drop table system_tenant", 0));
|
|
||||||
assertThrows(IllegalArgumentException.class,
|
|
||||||
() -> MyBatisUtils.findInSet(DbType.MYSQL, "FIND_IN_SET(value, websites)", 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testFindInSet_invalidParamIndex() {
|
|
||||||
assertThrows(IllegalArgumentException.class,
|
|
||||||
() -> MyBatisUtils.findInSet(DbType.MYSQL, "websites", -1));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testFindInSet_applyBindsValue() {
|
|
||||||
// 准备参数
|
|
||||||
QueryWrapper<Object> query = new QueryWrapper<>();
|
|
||||||
String value = "test' OR 1 = 1";
|
|
||||||
|
|
||||||
// 调用
|
|
||||||
query.apply(MyBatisUtils.findInSet(DbType.MYSQL, "to_mails", 0), value);
|
|
||||||
|
|
||||||
// 断言:SQL 片段里只有 MyBatis Plus 参数占位,用户输入不会被直接拼接进去
|
|
||||||
assertEquals("(FIND_IN_SET(#{ew.paramNameValuePairs.MPGENVAL1}, to_mails) <> 0)",
|
|
||||||
query.getSqlSegment());
|
|
||||||
assertFalse(query.getSqlSegment().contains(value));
|
|
||||||
assertEquals(value, query.getParamNameValuePairs().get("MPGENVAL1"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testFindInSet_applyBindsMultipleValues() {
|
|
||||||
// 准备参数
|
|
||||||
QueryWrapper<Object> query = new QueryWrapper<>();
|
|
||||||
String value1 = "1' OR 1 = 1";
|
|
||||||
String value2 = "2' OR 1 = 1";
|
|
||||||
|
|
||||||
// 调用
|
|
||||||
query.apply(MyBatisUtils.findInSet(DbType.MYSQL, "tag_ids", 0)
|
|
||||||
+ " OR " + MyBatisUtils.findInSet(DbType.MYSQL, "tag_ids", 1), value1, value2);
|
|
||||||
|
|
||||||
// 断言:多个参数都由 MyBatis Plus 生成占位符,不拼接用户输入
|
|
||||||
assertEquals("(FIND_IN_SET(#{ew.paramNameValuePairs.MPGENVAL1}, tag_ids) <> 0"
|
|
||||||
+ " OR FIND_IN_SET(#{ew.paramNameValuePairs.MPGENVAL2}, tag_ids) <> 0)",
|
|
||||||
query.getSqlSegment());
|
|
||||||
assertFalse(query.getSqlSegment().contains(value1));
|
|
||||||
assertFalse(query.getSqlSegment().contains(value2));
|
|
||||||
assertEquals(value1, query.getParamNameValuePairs().get("MPGENVAL1"));
|
|
||||||
assertEquals(value2, query.getParamNameValuePairs().get("MPGENVAL2"));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void assertOrderItem(OrderItem orderItem, String column, boolean asc) {
|
|
||||||
assertEquals(column, orderItem.getColumn());
|
|
||||||
assertEquals(asc, orderItem.isAsc());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -75,12 +75,8 @@ public class YudaoCacheAutoConfiguration {
|
||||||
RedisConnectionFactory connectionFactory = Objects.requireNonNull(redisTemplate.getConnectionFactory());
|
RedisConnectionFactory connectionFactory = Objects.requireNonNull(redisTemplate.getConnectionFactory());
|
||||||
RedisCacheWriter cacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory,
|
RedisCacheWriter cacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory,
|
||||||
BatchStrategies.scan(yudaoCacheProperties.getRedisScanBatchSize()));
|
BatchStrategies.scan(yudaoCacheProperties.getRedisScanBatchSize()));
|
||||||
// 创建 TimeoutRedisCacheManager 对象
|
// 创建 TenantRedisCacheManager 对象
|
||||||
TimeoutRedisCacheManager cacheManager = new TimeoutRedisCacheManager(cacheWriter, redisCacheConfiguration);
|
return new TimeoutRedisCacheManager(cacheWriter, redisCacheConfiguration);
|
||||||
// 开启事务感知:@Transactional 方法内的 @CacheEvict / @CachePut 自动延迟到 afterCommit,
|
|
||||||
// 避免事务未提交就清缓存被并发读穿写脏值;无事务时立即生效,行为不变
|
|
||||||
cacheManager.setTransactionAware(true);
|
|
||||||
return cacheManager;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ package cn.iocoder.yudao.framework.redis.config;
|
||||||
import cn.hutool.core.util.ReflectUtil;
|
import cn.hutool.core.util.ReflectUtil;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||||
import org.redisson.spring.starter.RedissonAutoConfigurationV2;
|
import org.redisson.spring.starter.RedissonAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||||
|
|
@ -13,7 +13,7 @@ import org.springframework.data.redis.serializer.RedisSerializer;
|
||||||
/**
|
/**
|
||||||
* Redis 配置类
|
* Redis 配置类
|
||||||
*/
|
*/
|
||||||
@AutoConfiguration(before = RedissonAutoConfigurationV2.class) // 目的:使用自己定义的 RedisTemplate Bean
|
@AutoConfiguration(before = RedissonAutoConfiguration.class) // 目的:使用自己定义的 RedisTemplate Bean
|
||||||
public class YudaoRedisAutoConfiguration {
|
public class YudaoRedisAutoConfiguration {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -28,10 +28,9 @@ public class YudaoRedisAutoConfiguration {
|
||||||
// 使用 String 序列化方式,序列化 KEY 。
|
// 使用 String 序列化方式,序列化 KEY 。
|
||||||
template.setKeySerializer(RedisSerializer.string());
|
template.setKeySerializer(RedisSerializer.string());
|
||||||
template.setHashKeySerializer(RedisSerializer.string());
|
template.setHashKeySerializer(RedisSerializer.string());
|
||||||
// 使用 JSON 序列化方式,序列化 VALUE
|
// 使用 JSON 序列化方式(库是 Jackson ),序列化 VALUE 。
|
||||||
RedisSerializer<?> redisSerializer = buildRedisSerializer();
|
template.setValueSerializer(buildRedisSerializer());
|
||||||
template.setValueSerializer(redisSerializer);
|
template.setHashValueSerializer(buildRedisSerializer());
|
||||||
template.setHashValueSerializer(redisSerializer);
|
|
||||||
return template;
|
return template;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -39,8 +39,8 @@
|
||||||
|
|
||||||
<!-- 工具相关 -->
|
<!-- 工具相关 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>javax.validation</groupId>
|
<groupId>jakarta.validation</groupId>
|
||||||
<artifactId>validation-api</artifactId>
|
<artifactId>jakarta.validation-api</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ import cn.iocoder.yudao.framework.test.config.RedisTestConfiguration;
|
||||||
import cn.iocoder.yudao.framework.test.config.SqlInitializationTestConfiguration;
|
import cn.iocoder.yudao.framework.test.config.SqlInitializationTestConfiguration;
|
||||||
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure;
|
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure;
|
||||||
import com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration;
|
import com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration;
|
||||||
import org.redisson.spring.starter.RedissonAutoConfigurationV2;
|
import org.redisson.spring.starter.RedissonAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
|
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
|
import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
|
||||||
|
|
@ -44,7 +44,7 @@ public class BaseDbAndRedisUnitTest {
|
||||||
RedisTestConfiguration.class, // Redis 测试配置类,用于启动 RedisServer
|
RedisTestConfiguration.class, // Redis 测试配置类,用于启动 RedisServer
|
||||||
YudaoRedisAutoConfiguration.class, // 自己的 Redis 配置类
|
YudaoRedisAutoConfiguration.class, // 自己的 Redis 配置类
|
||||||
RedisAutoConfiguration.class, // Spring Redis 自动配置类
|
RedisAutoConfiguration.class, // Spring Redis 自动配置类
|
||||||
RedissonAutoConfigurationV2.class, // Redisson 自动配置类
|
RedissonAutoConfiguration.class, // Redisson 自动配置类
|
||||||
|
|
||||||
// 其它配置类
|
// 其它配置类
|
||||||
SpringUtil.class
|
SpringUtil.class
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ package cn.iocoder.yudao.framework.test.core.ut;
|
||||||
import cn.hutool.extra.spring.SpringUtil;
|
import cn.hutool.extra.spring.SpringUtil;
|
||||||
import cn.iocoder.yudao.framework.redis.config.YudaoRedisAutoConfiguration;
|
import cn.iocoder.yudao.framework.redis.config.YudaoRedisAutoConfiguration;
|
||||||
import cn.iocoder.yudao.framework.test.config.RedisTestConfiguration;
|
import cn.iocoder.yudao.framework.test.config.RedisTestConfiguration;
|
||||||
import org.redisson.spring.starter.RedissonAutoConfigurationV2;
|
import org.redisson.spring.starter.RedissonAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
|
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
import org.springframework.context.annotation.Import;
|
import org.springframework.context.annotation.Import;
|
||||||
|
|
@ -25,7 +25,7 @@ public class BaseRedisUnitTest {
|
||||||
RedisTestConfiguration.class, // Redis 测试配置类,用于启动 RedisServer
|
RedisTestConfiguration.class, // Redis 测试配置类,用于启动 RedisServer
|
||||||
RedisAutoConfiguration.class, // Spring Redis 自动配置类
|
RedisAutoConfiguration.class, // Spring Redis 自动配置类
|
||||||
YudaoRedisAutoConfiguration.class, // 自己的 Redis 配置类
|
YudaoRedisAutoConfiguration.class, // 自己的 Redis 配置类
|
||||||
RedissonAutoConfigurationV2.class, // Redisson 自动配置类
|
RedissonAutoConfiguration.class, // Redisson 自动配置类
|
||||||
|
|
||||||
// 其它配置类
|
// 其它配置类
|
||||||
SpringUtil.class
|
SpringUtil.class
|
||||||
|
|
|
||||||
|
|
@ -69,7 +69,7 @@ public class ApiAccessLogFilter extends ApiRequestFilter {
|
||||||
LocalDateTime beginTime = LocalDateTime.now();
|
LocalDateTime beginTime = LocalDateTime.now();
|
||||||
// 提前获得参数,避免 XssFilter 过滤处理
|
// 提前获得参数,避免 XssFilter 过滤处理
|
||||||
Map<String, String> queryString = ServletUtils.getParamMap(request);
|
Map<String, String> queryString = ServletUtils.getParamMap(request);
|
||||||
String requestBody = ServletUtils.getBody(request);
|
String requestBody = ServletUtils.isJsonRequest(request) ? ServletUtils.getBody(request) : null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 继续过滤器
|
// 继续过滤器
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ public class ApiAccessLogInterceptor implements HandlerInterceptor {
|
||||||
// 打印 request 日志
|
// 打印 request 日志
|
||||||
if (!SpringUtils.isProd()) {
|
if (!SpringUtils.isProd()) {
|
||||||
Map<String, String> queryString = ServletUtils.getParamMap(request);
|
Map<String, String> queryString = ServletUtils.getParamMap(request);
|
||||||
String requestBody = ServletUtils.getBody(request);
|
String requestBody = ServletUtils.isJsonRequest(request) ? ServletUtils.getBody(request) : null;
|
||||||
if (CollUtil.isEmpty(queryString) && StrUtil.isEmpty(requestBody)) {
|
if (CollUtil.isEmpty(queryString) && StrUtil.isEmpty(requestBody)) {
|
||||||
log.info("[preHandle][开始请求 URL({}) 无参数]", request.getRequestURI());
|
log.info("[preHandle][开始请求 URL({}) 无参数]", request.getRequestURI());
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -37,14 +37,8 @@ public class BannerApplicationRunner implements ApplicationRunner {
|
||||||
System.out.println("[商城系统 yudao-module-mall 教程][参考 https://cloud.iocoder.cn/mall/build/ 开启]");
|
System.out.println("[商城系统 yudao-module-mall 教程][参考 https://cloud.iocoder.cn/mall/build/ 开启]");
|
||||||
// ERP 系统
|
// ERP 系统
|
||||||
System.out.println("[ERP 系统 yudao-module-erp - 教程][参考 https://cloud.iocoder.cn/erp/build/ 开启]");
|
System.out.println("[ERP 系统 yudao-module-erp - 教程][参考 https://cloud.iocoder.cn/erp/build/ 开启]");
|
||||||
// WMS 仓库管理系统
|
|
||||||
System.out.println("[WMS 仓库管理系统 yudao-module-wms - 教程][参考 https://cloud.iocoder.cn/wms/build/ 开启]");
|
|
||||||
// CRM 系统
|
// CRM 系统
|
||||||
System.out.println("[CRM 系统 yudao-module-crm - 教程][参考 https://cloud.iocoder.cn/crm/build/ 开启]");
|
System.out.println("[CRM 系统 yudao-module-crm - 教程][参考 https://cloud.iocoder.cn/crm/build/ 开启]");
|
||||||
// MES 系统
|
|
||||||
System.out.println("[MES 系统 yudao-module-mes - 教程][参考 https://cloud.iocoder.cn/mes/build/ 开启]");
|
|
||||||
// IM 即时通讯
|
|
||||||
System.out.println("[IM 即时通讯 yudao-module-im - 教程][参考 https://cloud.iocoder.cn/im/build/ 开启]");
|
|
||||||
// 微信公众号
|
// 微信公众号
|
||||||
System.out.println("[微信公众号 yudao-module-mp 教程][参考 https://cloud.iocoder.cn/mp/build/ 开启]");
|
System.out.println("[微信公众号 yudao-module-mp 教程][参考 https://cloud.iocoder.cn/mp/build/ 开启]");
|
||||||
// 支付平台
|
// 支付平台
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ import java.util.Map;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
@AutoConfiguration(beforeName = {
|
@AutoConfiguration(beforeName = {
|
||||||
"org.dromara.trans.config.TransServiceConfig" // cloud 独有:避免一键改包后,RestTemplate 初始化的冲突。可见 https://t.zsxq.com/T4yj7 帖子
|
"com.fhs.trans.config.TransServiceConfig" // cloud 独有:避免一键改包后,RestTemplate 初始化的冲突。可见 https://t.zsxq.com/T4yj7 帖子
|
||||||
})
|
})
|
||||||
@EnableConfigurationProperties(WebProperties.class)
|
@EnableConfigurationProperties(WebProperties.class)
|
||||||
public class YudaoWebAutoConfiguration {
|
public class YudaoWebAutoConfiguration {
|
||||||
|
|
|
||||||
|
|
@ -410,43 +410,25 @@ public class GlobalExceptionHandler {
|
||||||
return CommonResult.error(NOT_IMPLEMENTED.getCode(),
|
return CommonResult.error(NOT_IMPLEMENTED.getCode(),
|
||||||
"[ERP 系统 yudao-module-erp - 表结构未导入][参考 https://cloud.iocoder.cn/erp/build/ 开启]");
|
"[ERP 系统 yudao-module-erp - 表结构未导入][参考 https://cloud.iocoder.cn/erp/build/ 开启]");
|
||||||
}
|
}
|
||||||
// 6. WMS 仓库管理系统
|
// 6. CRM 系统
|
||||||
if (message.contains("wms_")) {
|
|
||||||
log.error("[WMS 仓库管理系统 yudao-module-wms - 表结构未导入][参考 https://cloud.iocoder.cn/wms/build/ 开启]");
|
|
||||||
return CommonResult.error(NOT_IMPLEMENTED.getCode(),
|
|
||||||
"[WMS 仓库管理系统 yudao-module-wms - 表结构未导入][参考 https://cloud.iocoder.cn/wms/build/ 开启]");
|
|
||||||
}
|
|
||||||
// 7. CRM 系统
|
|
||||||
if (message.contains("crm_")) {
|
if (message.contains("crm_")) {
|
||||||
log.error("[CRM 系统 yudao-module-crm - 表结构未导入][参考 https://cloud.iocoder.cn/crm/build/ 开启]");
|
log.error("[CRM 系统 yudao-module-crm - 表结构未导入][参考 https://cloud.iocoder.cn/crm/build/ 开启]");
|
||||||
return CommonResult.error(NOT_IMPLEMENTED.getCode(),
|
return CommonResult.error(NOT_IMPLEMENTED.getCode(),
|
||||||
"[CRM 系统 yudao-module-crm - 表结构未导入][参考 https://cloud.iocoder.cn/crm/build/ 开启]");
|
"[CRM 系统 yudao-module-crm - 表结构未导入][参考 https://cloud.iocoder.cn/crm/build/ 开启]");
|
||||||
}
|
}
|
||||||
// 8. MES 系统
|
// 7. 支付平台
|
||||||
if (message.contains("mes_")) {
|
|
||||||
log.error("[MES 系统 yudao-module-mes - 表结构未导入][参考 https://cloud.iocoder.cn/mes/build/ 开启]");
|
|
||||||
return CommonResult.error(NOT_IMPLEMENTED.getCode(),
|
|
||||||
"[MES 系统 yudao-module-mes - 表结构未导入][参考 https://cloud.iocoder.cn/mes/build/ 开启]");
|
|
||||||
}
|
|
||||||
// 9. IM 即时通讯
|
|
||||||
if (message.contains("im_")) {
|
|
||||||
log.error("[IM 即时通讯 yudao-module-im - 表结构未导入][参考 https://cloud.iocoder.cn/im/build/ 开启]");
|
|
||||||
return CommonResult.error(NOT_IMPLEMENTED.getCode(),
|
|
||||||
"[IM 即时通讯 yudao-module-im - 表结构未导入][参考 https://cloud.iocoder.cn/im/build/ 开启]");
|
|
||||||
}
|
|
||||||
// 10. 支付平台
|
|
||||||
if (message.contains("pay_")) {
|
if (message.contains("pay_")) {
|
||||||
log.error("[支付模块 yudao-module-pay - 表结构未导入][参考 https://cloud.iocoder.cn/pay/build/ 开启]");
|
log.error("[支付模块 yudao-module-pay - 表结构未导入][参考 https://cloud.iocoder.cn/pay/build/ 开启]");
|
||||||
return CommonResult.error(NOT_IMPLEMENTED.getCode(),
|
return CommonResult.error(NOT_IMPLEMENTED.getCode(),
|
||||||
"[支付模块 yudao-module-pay - 表结构未导入][参考 https://cloud.iocoder.cn/pay/build/ 开启]");
|
"[支付模块 yudao-module-pay - 表结构未导入][参考 https://cloud.iocoder.cn/pay/build/ 开启]");
|
||||||
}
|
}
|
||||||
// 11. AI 大模型
|
// 8. AI 大模型
|
||||||
if (message.contains("ai_")) {
|
if (message.contains("ai_")) {
|
||||||
log.error("[AI 大模型 yudao-module-ai - 表结构未导入][参考 https://cloud.iocoder.cn/ai/build/ 开启]");
|
log.error("[AI 大模型 yudao-module-ai - 表结构未导入][参考 https://cloud.iocoder.cn/ai/build/ 开启]");
|
||||||
return CommonResult.error(NOT_IMPLEMENTED.getCode(),
|
return CommonResult.error(NOT_IMPLEMENTED.getCode(),
|
||||||
"[AI 大模型 yudao-module-ai - 表结构未导入][参考 https://cloud.iocoder.cn/ai/build/ 开启]");
|
"[AI 大模型 yudao-module-ai - 表结构未导入][参考 https://cloud.iocoder.cn/ai/build/ 开启]");
|
||||||
}
|
}
|
||||||
// 12. IoT 物联网
|
// 9. IoT 物联网
|
||||||
if (message.contains("iot_")) {
|
if (message.contains("iot_")) {
|
||||||
log.error("[IoT 物联网 yudao-module-iot - 表结构未导入][参考 https://doc.iocoder.cn/iot/build/ 开启]");
|
log.error("[IoT 物联网 yudao-module-iot - 表结构未导入][参考 https://doc.iocoder.cn/iot/build/ 开启]");
|
||||||
return CommonResult.error(NOT_IMPLEMENTED.getCode(),
|
return CommonResult.error(NOT_IMPLEMENTED.getCode(),
|
||||||
|
|
|
||||||
|
|
@ -76,7 +76,7 @@ public class JsonWebSocketMessageHandler extends TextWebSocketHandler {
|
||||||
Long tenantId = WebSocketFrameworkUtils.getTenantId(session);
|
Long tenantId = WebSocketFrameworkUtils.getTenantId(session);
|
||||||
TenantUtils.execute(tenantId, () -> messageListener.onMessage(session, messageObj));
|
TenantUtils.execute(tenantId, () -> messageListener.onMessage(session, messageObj));
|
||||||
} catch (Throwable ex) {
|
} catch (Throwable ex) {
|
||||||
log.error("[handleTextMessage][session({}) message({}) 处理异常]", session.getId(), message.getPayload(), ex);
|
log.error("[handleTextMessage][session({}) message({}) 处理异常]", session.getId(), message.getPayload());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,10 +27,9 @@ public class LoginUserHandshakeInterceptor implements HandshakeInterceptor {
|
||||||
public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response,
|
public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response,
|
||||||
WebSocketHandler wsHandler, Map<String, Object> attributes) {
|
WebSocketHandler wsHandler, Map<String, Object> attributes) {
|
||||||
LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
|
LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
|
||||||
if (loginUser == null) {
|
if (loginUser != null) {
|
||||||
return false;
|
|
||||||
}
|
|
||||||
WebSocketFrameworkUtils.setLoginUser(loginUser, attributes);
|
WebSocketFrameworkUtils.setLoginUser(loginUser, attributes);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,11 @@
|
||||||
<artifactId>javax.servlet-api</artifactId>
|
<artifactId>javax.servlet-api</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>javax.servlet</groupId>
|
||||||
|
<artifactId>javax.servlet-api</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.github.xiaoymin</groupId> <!-- 接口文档 -->
|
<groupId>com.github.xiaoymin</groupId> <!-- 接口文档 -->
|
||||||
<artifactId>knife4j-gateway-spring-boot-starter</artifactId>
|
<artifactId>knife4j-gateway-spring-boot-starter</artifactId>
|
||||||
|
|
|
||||||
|
|
@ -39,14 +39,8 @@ public class BannerApplicationRunner implements ApplicationRunner {
|
||||||
System.out.println("[商城系统 yudao-module-mall 教程][参考 https://cloud.iocoder.cn/mall/build/ 开启]");
|
System.out.println("[商城系统 yudao-module-mall 教程][参考 https://cloud.iocoder.cn/mall/build/ 开启]");
|
||||||
// ERP 系统
|
// ERP 系统
|
||||||
System.out.println("[ERP 系统 yudao-module-erp - 教程][参考 https://cloud.iocoder.cn/erp/build/ 开启]");
|
System.out.println("[ERP 系统 yudao-module-erp - 教程][参考 https://cloud.iocoder.cn/erp/build/ 开启]");
|
||||||
// WMS 仓库管理系统
|
|
||||||
System.out.println("[WMS 仓库管理系统 yudao-module-wms - 教程][参考 https://cloud.iocoder.cn/wms/build/ 开启]");
|
|
||||||
// CRM 系统
|
// CRM 系统
|
||||||
System.out.println("[CRM 系统 yudao-module-crm - 教程][参考 https://cloud.iocoder.cn/crm/build/ 开启]");
|
System.out.println("[CRM 系统 yudao-module-crm - 教程][参考 https://cloud.iocoder.cn/crm/build/ 开启]");
|
||||||
// MES 系统
|
|
||||||
System.out.println("[MES 系统 yudao-module-mes - 教程][参考 https://cloud.iocoder.cn/mes/build/ 开启]");
|
|
||||||
// IM 即时通讯
|
|
||||||
System.out.println("[IM 即时通讯 yudao-module-im - 教程][参考 https://cloud.iocoder.cn/im/build/ 开启]");
|
|
||||||
// 微信公众号
|
// 微信公众号
|
||||||
System.out.println("[微信公众号 yudao-module-mp 教程][参考 https://cloud.iocoder.cn/mp/build/ 开启]");
|
System.out.println("[微信公众号 yudao-module-mp 教程][参考 https://cloud.iocoder.cn/mp/build/ 开启]");
|
||||||
// 支付平台
|
// 支付平台
|
||||||
|
|
|
||||||
|
|
@ -199,20 +199,6 @@ spring:
|
||||||
- Path=/admin-api/mes/**
|
- Path=/admin-api/mes/**
|
||||||
filters:
|
filters:
|
||||||
- RewritePath=/admin-api/mes/v3/api-docs, /v3/api-docs # 配置,保证转发到 /v3/api-docs
|
- RewritePath=/admin-api/mes/v3/api-docs, /v3/api-docs # 配置,保证转发到 /v3/api-docs
|
||||||
## wms-server 服务
|
|
||||||
- id: wms-admin-api # 路由的编号
|
|
||||||
uri: grayLb://wms-server
|
|
||||||
predicates: # 断言,作为路由的匹配条件,对应 RouteDefinition 数组
|
|
||||||
- Path=/admin-api/wms/**
|
|
||||||
filters:
|
|
||||||
- RewritePath=/admin-api/wms/v3/api-docs, /v3/api-docs # 配置,保证转发到 /v3/api-docs
|
|
||||||
## im-server 服务
|
|
||||||
- id: im-admin-api # 路由的编号
|
|
||||||
uri: grayLb://im-server
|
|
||||||
predicates: # 断言,作为路由的匹配条件,对应 RouteDefinition 数组
|
|
||||||
- Path=/admin-api/im/**
|
|
||||||
filters:
|
|
||||||
- RewritePath=/admin-api/im/v3/api-docs, /v3/api-docs # 配置,保证转发到 /v3/api-docs
|
|
||||||
x-forwarded:
|
x-forwarded:
|
||||||
prefix-enabled: false # 避免 Swagger 重复带上额外的 /admin-api/system 前缀
|
prefix-enabled: false # 避免 Swagger 重复带上额外的 /admin-api/system 前缀
|
||||||
default-filters: # 全局过滤器,对应 GatewayFilterDefinition 数组
|
default-filters: # 全局过滤器,对应 GatewayFilterDefinition 数组
|
||||||
|
|
@ -275,12 +261,6 @@ knife4j:
|
||||||
- name: mes-server
|
- name: mes-server
|
||||||
service-name: mes-server
|
service-name: mes-server
|
||||||
url: /admin-api/mes/v3/api-docs
|
url: /admin-api/mes/v3/api-docs
|
||||||
- name: wms-server
|
|
||||||
service-name: wms-server
|
|
||||||
url: /admin-api/wms/v3/api-docs
|
|
||||||
- name: im-server
|
|
||||||
service-name: im-server
|
|
||||||
url: /admin-api/im/v3/api-docs
|
|
||||||
|
|
||||||
--- #################### 芋道相关配置 ####################
|
--- #################### 芋道相关配置 ####################
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,9 +19,9 @@
|
||||||
国外:OpenAI、Ollama、Midjourney、StableDiffusion、Suno
|
国外:OpenAI、Ollama、Midjourney、StableDiffusion、Suno
|
||||||
</description>
|
</description>
|
||||||
<properties>
|
<properties>
|
||||||
<spring-ai.version>1.1.5</spring-ai.version>
|
<spring-ai.version>1.1.2</spring-ai.version>
|
||||||
<!-- https://mvnrepository.com/artifact/com.alibaba.cloud.ai/spring-ai-alibaba -->
|
<!-- https://mvnrepository.com/artifact/com.alibaba.cloud.ai/spring-ai-alibaba -->
|
||||||
<alibaba-ai.version>1.1.2.2</alibaba-ai.version>
|
<alibaba-ai.version>1.1.0.0-RC2</alibaba-ai.version>
|
||||||
<tinyflow.version>1.2.6</tinyflow.version>
|
<tinyflow.version>1.2.6</tinyflow.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ import cn.iocoder.yudao.module.ai.controller.admin.chat.vo.conversation.AiChatCo
|
||||||
import cn.iocoder.yudao.module.ai.dal.dataobject.chat.AiChatConversationDO;
|
import cn.iocoder.yudao.module.ai.dal.dataobject.chat.AiChatConversationDO;
|
||||||
import cn.iocoder.yudao.module.ai.service.chat.AiChatConversationService;
|
import cn.iocoder.yudao.module.ai.service.chat.AiChatConversationService;
|
||||||
import cn.iocoder.yudao.module.ai.service.chat.AiChatMessageService;
|
import cn.iocoder.yudao.module.ai.service.chat.AiChatMessageService;
|
||||||
import org.dromara.core.trans.anno.TransMethodResult;
|
import com.fhs.core.trans.anno.TransMethodResult;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.Parameter;
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,9 @@ package cn.iocoder.yudao.module.ai.controller.admin.chat.vo.conversation;
|
||||||
|
|
||||||
import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiModelDO;
|
import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiModelDO;
|
||||||
import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatRoleDO;
|
import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatRoleDO;
|
||||||
import org.dromara.core.trans.anno.Trans;
|
import com.fhs.core.trans.anno.Trans;
|
||||||
import org.dromara.core.trans.constant.TransType;
|
import com.fhs.core.trans.constant.TransType;
|
||||||
import org.dromara.core.trans.vo.VO;
|
import com.fhs.core.trans.vo.VO;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -83,15 +83,6 @@ public class AiKnowledgeSegmentController {
|
||||||
return success(true);
|
return success(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@DeleteMapping("/delete")
|
|
||||||
@Operation(summary = "删除段落")
|
|
||||||
@Parameter(name = "id", description = "段落编号", required = true, example = "1024")
|
|
||||||
@PreAuthorize("@ss.hasPermission('ai:knowledge:delete')")
|
|
||||||
public CommonResult<Boolean> deleteKnowledgeSegment(@RequestParam("id") Long id) {
|
|
||||||
segmentService.deleteKnowledgeSegment(id);
|
|
||||||
return success(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/split")
|
@GetMapping("/split")
|
||||||
@Operation(summary = "切片内容")
|
@Operation(summary = "切片内容")
|
||||||
@Parameters({
|
@Parameters({
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ import cn.iocoder.yudao.module.ai.controller.admin.model.vo.chatRole.AiChatRoleS
|
||||||
import cn.iocoder.yudao.module.ai.controller.admin.model.vo.chatRole.AiChatRoleSaveReqVO;
|
import cn.iocoder.yudao.module.ai.controller.admin.model.vo.chatRole.AiChatRoleSaveReqVO;
|
||||||
import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatRoleDO;
|
import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatRoleDO;
|
||||||
import cn.iocoder.yudao.module.ai.service.model.AiChatRoleService;
|
import cn.iocoder.yudao.module.ai.service.model.AiChatRoleService;
|
||||||
import org.dromara.core.trans.anno.TransMethodResult;
|
import com.fhs.core.trans.anno.TransMethodResult;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.Parameter;
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
package cn.iocoder.yudao.module.ai.controller.admin.model.vo.chatRole;
|
package cn.iocoder.yudao.module.ai.controller.admin.model.vo.chatRole;
|
||||||
|
|
||||||
import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiModelDO;
|
import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiModelDO;
|
||||||
import org.dromara.core.trans.anno.Trans;
|
import com.fhs.core.trans.anno.Trans;
|
||||||
import org.dromara.core.trans.constant.TransType;
|
import com.fhs.core.trans.constant.TransType;
|
||||||
import org.dromara.core.trans.vo.VO;
|
import com.fhs.core.trans.vo.VO;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -109,7 +109,6 @@ public class AiImageServiceImpl implements AiImageService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Async
|
@Async
|
||||||
@SuppressWarnings("ConstantValue")
|
|
||||||
public void executeDrawImage(AiImageDO image, AiImageDrawReqVO reqVO, AiModelDO model) {
|
public void executeDrawImage(AiImageDO image, AiImageDrawReqVO reqVO, AiModelDO model) {
|
||||||
try {
|
try {
|
||||||
// 1.1 构建请求
|
// 1.1 构建请求
|
||||||
|
|
@ -165,8 +164,8 @@ public class AiImageServiceImpl implements AiImageService {
|
||||||
.build();
|
.build();
|
||||||
} else if (ObjUtil.equal(model.getPlatform(), AiPlatformEnum.TONG_YI.getPlatform())) {
|
} else if (ObjUtil.equal(model.getPlatform(), AiPlatformEnum.TONG_YI.getPlatform())) {
|
||||||
return DashScopeImageOptions.builder()
|
return DashScopeImageOptions.builder()
|
||||||
.model(model.getModel()).n(1)
|
.withModel(model.getModel()).withN(1)
|
||||||
.height(draw.getHeight()).width(draw.getWidth())
|
.withHeight(draw.getHeight()).withWidth(draw.getWidth())
|
||||||
.build();
|
.build();
|
||||||
} else if (ObjUtil.equal(model.getPlatform(), AiPlatformEnum.YI_YAN.getPlatform())) {
|
} else if (ObjUtil.equal(model.getPlatform(), AiPlatformEnum.YI_YAN.getPlatform())) {
|
||||||
return QianFanImageOptions.builder()
|
return QianFanImageOptions.builder()
|
||||||
|
|
|
||||||
|
|
@ -98,13 +98,6 @@ public interface AiKnowledgeSegmentService {
|
||||||
*/
|
*/
|
||||||
void updateKnowledgeSegmentStatus(AiKnowledgeSegmentUpdateStatusReqVO reqVO);
|
void updateKnowledgeSegmentStatus(AiKnowledgeSegmentUpdateStatusReqVO reqVO);
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除知识库段落
|
|
||||||
*
|
|
||||||
* @param id 段落编号
|
|
||||||
*/
|
|
||||||
void deleteKnowledgeSegment(Long id);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 重新索引知识库下的所有文档段落
|
* 重新索引知识库下的所有文档段落
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -141,19 +141,6 @@ public class AiKnowledgeSegmentServiceImpl implements AiKnowledgeSegmentService
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void deleteKnowledgeSegment(Long id) {
|
|
||||||
// 1. 校验段落存在
|
|
||||||
AiKnowledgeSegmentDO segment = validateKnowledgeSegmentExists(id);
|
|
||||||
|
|
||||||
// 2. 删除向量
|
|
||||||
VectorStore vectorStore = getVectorStoreById(segment.getKnowledgeId());
|
|
||||||
deleteVectorStore(vectorStore, segment);
|
|
||||||
|
|
||||||
// 3. 删除段落记录
|
|
||||||
segmentMapper.deleteById(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deleteKnowledgeSegmentByDocumentId(Long documentId) {
|
public void deleteKnowledgeSegmentByDocumentId(Long documentId) {
|
||||||
// 1. 查询需要删除的段落
|
// 1. 查询需要删除的段落
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,7 @@
|
||||||
package cn.iocoder.yudao.module.ai.util;
|
package cn.iocoder.yudao.module.ai.util;
|
||||||
|
|
||||||
import cn.hutool.core.map.MapUtil;
|
|
||||||
import cn.hutool.core.util.ObjUtil;
|
import cn.hutool.core.util.ObjUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.iocoder.yudao.framework.common.util.collection.SetUtils;
|
|
||||||
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
|
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
|
||||||
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
|
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
|
||||||
import cn.iocoder.yudao.module.ai.enums.model.AiPlatformEnum;
|
import cn.iocoder.yudao.module.ai.enums.model.AiPlatformEnum;
|
||||||
|
|
@ -35,28 +33,6 @@ public class AiUtils {
|
||||||
public static final String TOOL_CONTEXT_LOGIN_USER = "LOGIN_USER";
|
public static final String TOOL_CONTEXT_LOGIN_USER = "LOGIN_USER";
|
||||||
public static final String TOOL_CONTEXT_TENANT_ID = "TENANT_ID";
|
public static final String TOOL_CONTEXT_TENANT_ID = "TENANT_ID";
|
||||||
|
|
||||||
/**
|
|
||||||
* 通义千问支持多模态的模型
|
|
||||||
*
|
|
||||||
* @see <a href="https://bailian.console.aliyun.com/cn-beijing/?tab=model#/model-market/all?providers=qwen&capabilities=VU">模型广场</a>
|
|
||||||
* @see <a href="https://help.aliyun.com/zh/model-studio/error-code#error-url">必须开启 withMultiModel 参数</a>
|
|
||||||
*/
|
|
||||||
public static final Set<String> TONG_YI_MULTI_MODELS = SetUtils.asSet(
|
|
||||||
// qwen3.5 / 3.6 系列(统一多模态主干)
|
|
||||||
"qwen3.6-plus", "qwen3.6-flash",
|
|
||||||
"qwen3.5-plus", "qwen3.5-flash",
|
|
||||||
// qwen-vl 视觉理解
|
|
||||||
"qwen3-vl-plus", "qwen3-vl-flash",
|
|
||||||
"qwen-vl-max", "qwen-vl-plus",
|
|
||||||
"qwen2.5-vl-72b-instruct", "qwen2.5-vl-32b-instruct",
|
|
||||||
"qwen2.5-vl-7b-instruct", "qwen2.5-vl-3b-instruct",
|
|
||||||
// qvq 视觉推理
|
|
||||||
"qvq-max", "qvq-plus",
|
|
||||||
// qwen-omni 全模态
|
|
||||||
"qwen3.5-omni-plus", "qwen3.5-omni-flash",
|
|
||||||
"qwen3-omni-flash", "qwen-omni-turbo"
|
|
||||||
);
|
|
||||||
|
|
||||||
public static ChatOptions buildChatOptions(AiPlatformEnum platform, String model, Double temperature, Integer maxTokens) {
|
public static ChatOptions buildChatOptions(AiPlatformEnum platform, String model, Double temperature, Integer maxTokens) {
|
||||||
return buildChatOptions(platform, model, temperature, maxTokens, null, null);
|
return buildChatOptions(platform, model, temperature, maxTokens, null, null);
|
||||||
}
|
}
|
||||||
|
|
@ -68,10 +44,9 @@ public class AiUtils {
|
||||||
// noinspection EnhancedSwitchMigration
|
// noinspection EnhancedSwitchMigration
|
||||||
switch (platform) {
|
switch (platform) {
|
||||||
case TONG_YI:
|
case TONG_YI:
|
||||||
return DashScopeChatOptions.builder().model(model).temperature(temperature).maxToken(maxTokens)
|
return DashScopeChatOptions.builder().withModel(model).withTemperature(temperature).withMaxToken(maxTokens)
|
||||||
.enableThinking(true) // TODO 芋艿:默认都开启 thinking 模式,后续可以让用户配置
|
.withEnableThinking(true) // TODO 芋艿:默认都开启 thinking 模式,后续可以让用户配置
|
||||||
.multiModel(TONG_YI_MULTI_MODELS.contains(model)) // 是否多模态模型
|
.withToolCallbacks(toolCallbacks).withToolContext(toolContext).build();
|
||||||
.toolCallbacks(toolCallbacks).toolContext(toolContext).build();
|
|
||||||
case YI_YAN:
|
case YI_YAN:
|
||||||
return QianFanChatOptions.builder().model(model).temperature(temperature).maxTokens(maxTokens).build();
|
return QianFanChatOptions.builder().model(model).temperature(temperature).maxTokens(maxTokens).build();
|
||||||
case DEEP_SEEK:
|
case DEEP_SEEK:
|
||||||
|
|
@ -150,13 +125,10 @@ public class AiUtils {
|
||||||
|| response.getResult().getOutput() == null) {
|
|| response.getResult().getOutput() == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
AssistantMessage output = response.getResult().getOutput();
|
if (response.getResult().getOutput() instanceof DeepSeekAssistantMessage) {
|
||||||
// DeepSeek 通过专属 AssistantMessage 暴露 reasoningContent
|
return ((DeepSeekAssistantMessage) (response.getResult().getOutput())).getReasoningContent();
|
||||||
if (output instanceof DeepSeekAssistantMessage) {
|
|
||||||
return ((DeepSeekAssistantMessage) output).getReasoningContent();
|
|
||||||
}
|
}
|
||||||
// 通义千问等通过 metadata 透传 reasoningContent
|
return null;
|
||||||
return MapUtil.getStr(output.getMetadata(), "reasoningContent");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -103,7 +103,7 @@ xxl:
|
||||||
# Lock4j 配置项
|
# Lock4j 配置项
|
||||||
lock4j:
|
lock4j:
|
||||||
acquire-timeout: 3000 # 获取分布式锁超时时间,默认为 3000 毫秒
|
acquire-timeout: 3000 # 获取分布式锁超时时间,默认为 3000 毫秒
|
||||||
expire: 30000 # 分布式锁的超时时间,默认为 30000 毫秒
|
expire: 30000 # 分布式锁的超时时间,默认为 30 毫秒
|
||||||
|
|
||||||
--- #################### 监控相关配置 ####################
|
--- #################### 监控相关配置 ####################
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,6 @@ spring:
|
||||||
url: jdbc:mysql://127.0.0.1:3306/ruoyi-vue-pro?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true&rewriteBatchedStatements=true # MySQL Connector/J 8.X 连接的示例
|
url: jdbc:mysql://127.0.0.1:3306/ruoyi-vue-pro?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true&rewriteBatchedStatements=true # MySQL Connector/J 8.X 连接的示例
|
||||||
# url: jdbc:mysql://127.0.0.1:3306/ruoyi-vue-pro?useSSL=true&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true # MySQL Connector/J 5.X 连接的示例
|
# url: jdbc:mysql://127.0.0.1:3306/ruoyi-vue-pro?useSSL=true&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true # MySQL Connector/J 5.X 连接的示例
|
||||||
# url: jdbc:postgresql://127.0.0.1:5432/ruoyi-vue-pro # PostgreSQL 连接的示例
|
# url: jdbc:postgresql://127.0.0.1:5432/ruoyi-vue-pro # PostgreSQL 连接的示例
|
||||||
# url: jdbc:postgresql://127.0.0.1:5866/ruoyi-vue-pro # 瀚高 HighGo 连接的示例
|
|
||||||
# url: jdbc:oracle:thin:@127.0.0.1:1521:xe # Oracle 连接的示例
|
# url: jdbc:oracle:thin:@127.0.0.1:1521:xe # Oracle 连接的示例
|
||||||
# url: jdbc:sqlserver://127.0.0.1:1433;DatabaseName=ruoyi-vue-pro # SQLServer 连接的示例
|
# url: jdbc:sqlserver://127.0.0.1:1433;DatabaseName=ruoyi-vue-pro # SQLServer 连接的示例
|
||||||
# url: jdbc:dm://10.211.55.4:5236?schema=RUOYI_VUE_PRO # DM 连接的示例
|
# url: jdbc:dm://10.211.55.4:5236?schema=RUOYI_VUE_PRO # DM 连接的示例
|
||||||
|
|
@ -72,8 +71,6 @@ spring:
|
||||||
# password: JSm:g(*%lU4ZAkz06cd52KqT3)i1?H7W # SQL Server 连接的示例
|
# password: JSm:g(*%lU4ZAkz06cd52KqT3)i1?H7W # SQL Server 连接的示例
|
||||||
# username: SYSDBA # DM 连接的示例
|
# username: SYSDBA # DM 连接的示例
|
||||||
# password: SYSDBA # DM 连接的示例
|
# password: SYSDBA # DM 连接的示例
|
||||||
# username: root # 瀚高 HighGo 连接的示例
|
|
||||||
# password: 123456 # 瀚高 HighGo 连接的示例
|
|
||||||
slave: # 模拟从库,可根据自己需要修改
|
slave: # 模拟从库,可根据自己需要修改
|
||||||
lazy: true # 开启懒加载,保证启动速度
|
lazy: true # 开启懒加载,保证启动速度
|
||||||
url: jdbc:mysql://127.0.0.1:3306/ruoyi-vue-pro?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true&rewriteBatchedStatements=true
|
url: jdbc:mysql://127.0.0.1:3306/ruoyi-vue-pro?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true&rewriteBatchedStatements=true
|
||||||
|
|
@ -101,7 +98,7 @@ xxl:
|
||||||
# Lock4j 配置项
|
# Lock4j 配置项
|
||||||
lock4j:
|
lock4j:
|
||||||
acquire-timeout: 3000 # 获取分布式锁超时时间,默认为 3000 毫秒
|
acquire-timeout: 3000 # 获取分布式锁超时时间,默认为 3000 毫秒
|
||||||
expire: 30000 # 分布式锁的超时时间,默认为 30000 毫秒
|
expire: 30000 # 分布式锁的超时时间,默认为 30 毫秒
|
||||||
|
|
||||||
--- #################### 监控相关配置 ####################
|
--- #################### 监控相关配置 ####################
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,15 +34,15 @@ public class TongYiChatModelTests {
|
||||||
|
|
||||||
private final DashScopeChatModel chatModel = DashScopeChatModel.builder()
|
private final DashScopeChatModel chatModel = DashScopeChatModel.builder()
|
||||||
.dashScopeApi(DashScopeApi.builder()
|
.dashScopeApi(DashScopeApi.builder()
|
||||||
.apiKey("sk-cd9f39e99ea54840bd1888282325f55a") // https://bailian.console.aliyun.com/cn-beijing/?tab=model#/api-key 获取密钥
|
.apiKey("sk-47aa124781be4bfb95244cc62f63f7d0")
|
||||||
.build())
|
.build())
|
||||||
.defaultOptions(DashScopeChatOptions.builder()
|
.defaultOptions(DashScopeChatOptions.builder()
|
||||||
.multiModel(true) // 注意:当使用 qwen3.6-plus 等多模态模型,需要设置为 true,可见 https://help.aliyun.com/zh/model-studio/error-code#error-url 链接
|
// .withModel("qwen1.5-72b-chat") // 模型
|
||||||
.model("qwen3.6-plus") // 模型
|
.withModel("qwen3-235b-a22b-thinking-2507") // 模型
|
||||||
// .model("deepseek-r1") // 模型(deepseek-r1)
|
// .withModel("deepseek-r1") // 模型(deepseek-r1)
|
||||||
// .model("deepseek-v3") // 模型(deepseek-v3)
|
// .withModel("deepseek-v3") // 模型(deepseek-v3)
|
||||||
// .model("deepseek-r1-distill-qwen-1.5b") // 模型(deepseek-r1-distill-qwen-1.5b)
|
// .withModel("deepseek-r1-distill-qwen-1.5b") // 模型(deepseek-r1-distill-qwen-1.5b)
|
||||||
// .enableThinking(true)
|
// .withEnableThinking(true)
|
||||||
.build())
|
.build())
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
|
@ -85,9 +85,9 @@ public class TongYiChatModelTests {
|
||||||
List<Message> messages = new ArrayList<>();
|
List<Message> messages = new ArrayList<>();
|
||||||
messages.add(new UserMessage("详细分析下,如何设计一个电商系统?"));
|
messages.add(new UserMessage("详细分析下,如何设计一个电商系统?"));
|
||||||
DashScopeChatOptions options = DashScopeChatOptions.builder()
|
DashScopeChatOptions options = DashScopeChatOptions.builder()
|
||||||
.model("qwen3.6-plus").multiModel(true)
|
.withModel("qwen3-235b-a22b-thinking-2507")
|
||||||
// .withModel("qwen-max-2025-01-25")
|
// .withModel("qwen-max-2025-01-25")
|
||||||
.enableThinking(true) // 必须设置,否则会报错
|
.withEnableThinking(true) // 必须设置,否则会报错
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
// 调用
|
// 调用
|
||||||
|
|
@ -112,8 +112,8 @@ public class TongYiChatModelTests {
|
||||||
Document document01 = new Document("abc");
|
Document document01 = new Document("abc");
|
||||||
Document document02 = new Document("sapring");
|
Document document02 = new Document("sapring");
|
||||||
RerankOptions options = DashScopeRerankOptions.builder()
|
RerankOptions options = DashScopeRerankOptions.builder()
|
||||||
.topN(1)
|
.withTopN(1)
|
||||||
.model("gte-rerank-v2")
|
.withModel("gte-rerank-v2")
|
||||||
.build();
|
.build();
|
||||||
RerankRequest rerankRequest = new RerankRequest(
|
RerankRequest rerankRequest = new RerankRequest(
|
||||||
query,
|
query,
|
||||||
|
|
|
||||||
|
|
@ -12,34 +12,23 @@ import org.springframework.ai.image.ImageResponse;
|
||||||
/**
|
/**
|
||||||
* {@link DashScopeImageModel} 集成测试类
|
* {@link DashScopeImageModel} 集成测试类
|
||||||
*
|
*
|
||||||
* TODO @芋艿:注:spring-ai-alibaba-dashscope(1.1.2.2)的 {@code DashScopeImageApi#resolveImagePath} 未给 {@code wan2.7-image} 加路由分支,
|
|
||||||
* 会落到默认的 {@code text2image/image-synthesis} 异步端点 + 旧版 {@code prompt} 入参,
|
|
||||||
* 而该模型实际要求 {@code multimodal-generation/generation} 同步端点 + {@code messages} 入参,
|
|
||||||
* 端点、异步头、入参结构全部对不上,所以走 SDK 直接调用必失败。
|
|
||||||
*
|
|
||||||
* 临时方案:改用 SDK 已支持的 {@code wan2.6-image}(异步)或 {@code qwen-image}(同步);
|
|
||||||
* 或在项目内同包同名覆盖 {@code DashScopeImageApi},把 {@code wan2.7*} 也路由到 {@code wan2.6-image} 那条 {@code image-generation/generation} 异步分支。
|
|
||||||
*
|
|
||||||
* @author fansili
|
* @author fansili
|
||||||
*/
|
*/
|
||||||
public class TongYiImagesModelTest {
|
public class TongYiImagesModelTest {
|
||||||
|
|
||||||
private final DashScopeImageModel imageModel = DashScopeImageModel.builder()
|
private final DashScopeImageModel imageModel = DashScopeImageModel.builder()
|
||||||
.dashScopeApi(DashScopeImageApi.builder()
|
.dashScopeApi(DashScopeImageApi.builder()
|
||||||
.apiKey("sk-cd9f39e99ea54840bd1888282325f55a") // https://bailian.console.aliyun.com/cn-beijing/?tab=model#/api-key 获取密钥
|
.apiKey("sk-47aa124781be4bfb95244cc62f63f7d0")
|
||||||
.build())
|
.build())
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
// TODO @芋艿:
|
|
||||||
@Test
|
@Test
|
||||||
@Disabled
|
@Disabled
|
||||||
public void imageCallTest() {
|
public void imageCallTest() {
|
||||||
// 准备参数
|
// 准备参数
|
||||||
ImageOptions options = DashScopeImageOptions.builder()
|
ImageOptions options = DashScopeImageOptions.builder()
|
||||||
.model("wan2.7-image")
|
.withModel("wanx-v1")
|
||||||
// .withSize("2k")
|
.withHeight(256).withWidth(256)
|
||||||
.height(768).width(768)
|
|
||||||
.n(1)
|
|
||||||
.build();
|
.build();
|
||||||
ImagePrompt prompt = new ImagePrompt("中国长城!", options);
|
ImagePrompt prompt = new ImagePrompt("中国长城!", options);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,38 +0,0 @@
|
||||||
package cn.iocoder.yudao.module.bpm.enums.definition;
|
|
||||||
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* BPM 条件表达式操作符枚举
|
|
||||||
*
|
|
||||||
* @author Lesan
|
|
||||||
*/
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
@Getter
|
|
||||||
public enum BpmConditionOpCodeEnum {
|
|
||||||
|
|
||||||
EQ("==", "等于", " var:getOrDefault(%s, null) == %s "),
|
|
||||||
NE("!=", "不等于", " var:getOrDefault(%s, null) != %s "),
|
|
||||||
GT(">", "大于", " var:getOrDefault(%s, null) > %s "),
|
|
||||||
GE(">=", "大于等于", " var:getOrDefault(%s, null) >= %s "),
|
|
||||||
LT("<", "小于", " var:getOrDefault(%s, null) < %s "),
|
|
||||||
LE("<=", "小于等于", " var:getOrDefault(%s, null) <= %s "),
|
|
||||||
|
|
||||||
CONTAINS("contain", "包含", " var:contains(%s, %s) "),
|
|
||||||
NOT_CONTAINS("!contain", "不包含", " !var:contains(%s, %s) ");
|
|
||||||
|
|
||||||
private final String code;
|
|
||||||
private final String des;
|
|
||||||
private final String symbol;
|
|
||||||
|
|
||||||
public static BpmConditionOpCodeEnum fromCode(String code) {
|
|
||||||
for (BpmConditionOpCodeEnum op : BpmConditionOpCodeEnum.values()) {
|
|
||||||
if (op.code.equalsIgnoreCase(code)) {
|
|
||||||
return op;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw new IllegalArgumentException("未知操作符: " + code);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,27 +0,0 @@
|
||||||
package cn.iocoder.yudao.module.bpm.enums.task;
|
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Getter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 附件类型枚举
|
|
||||||
*
|
|
||||||
* @author jason
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
@AllArgsConstructor
|
|
||||||
public enum BpmAttachmentTypeEnum {
|
|
||||||
|
|
||||||
TASK_ATTACHMENT("1", "用户任务附件");
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 操作类型
|
|
||||||
* <p>
|
|
||||||
* 由于 BPM attachment 类型为 String,所以这里就不使用 Integer
|
|
||||||
*/
|
|
||||||
private final String type;
|
|
||||||
/**
|
|
||||||
* 操作名字
|
|
||||||
*/
|
|
||||||
private final String name;
|
|
||||||
}
|
|
||||||
|
|
@ -2,8 +2,6 @@ package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form;
|
||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 流程表单字段 VO
|
* 流程表单字段 VO
|
||||||
*/
|
*/
|
||||||
|
|
@ -22,9 +20,5 @@ public class BpmFormFieldVO {
|
||||||
* 字段标题
|
* 字段标题
|
||||||
*/
|
*/
|
||||||
private String title;
|
private String title;
|
||||||
/**
|
|
||||||
* 子表单字段(处理布局组件)
|
|
||||||
*/
|
|
||||||
private List<BpmFormFieldVO> children;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -196,7 +196,6 @@ public class BpmProcessInstanceController {
|
||||||
@GetMapping("/get-bpmn-model-view")
|
@GetMapping("/get-bpmn-model-view")
|
||||||
@Operation(summary = "获取流程实例的 BPMN 模型视图", description = "在【流程详细】界面中,进行调用")
|
@Operation(summary = "获取流程实例的 BPMN 模型视图", description = "在【流程详细】界面中,进行调用")
|
||||||
@Parameter(name = "id", description = "流程实例的编号", required = true)
|
@Parameter(name = "id", description = "流程实例的编号", required = true)
|
||||||
@PreAuthorize("@ss.hasPermission('bpm:process-instance:query')")
|
|
||||||
public CommonResult<BpmProcessInstanceBpmnModelViewRespVO> getProcessInstanceBpmnModelView(
|
public CommonResult<BpmProcessInstanceBpmnModelViewRespVO> getProcessInstanceBpmnModelView(
|
||||||
@RequestParam(value = "id") String id) {
|
@RequestParam(value = "id") String id) {
|
||||||
return success(processInstanceService.getProcessInstanceBpmnModelView(id));
|
return success(processInstanceService.getProcessInstanceBpmnModelView(id));
|
||||||
|
|
|
||||||
|
|
@ -66,15 +66,15 @@ public class BpmProcessInstanceCopyController {
|
||||||
Map<String, HistoricProcessInstance> processInstanceMap = processInstanceService.getHistoricProcessInstanceMap(
|
Map<String, HistoricProcessInstance> processInstanceMap = processInstanceService.getHistoricProcessInstanceMap(
|
||||||
convertSet(pageResult.getList(), BpmProcessInstanceCopyDO::getProcessInstanceId));
|
convertSet(pageResult.getList(), BpmProcessInstanceCopyDO::getProcessInstanceId));
|
||||||
Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertListByFlatMap(pageResult.getList(),
|
Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertListByFlatMap(pageResult.getList(),
|
||||||
copy -> Stream.of(copy.getStartUserId(), copy.getUserId())));
|
copy -> Stream.of(copy.getStartUserId(), Long.parseLong(copy.getCreator()))));
|
||||||
Map<String, BpmProcessDefinitionInfoDO> processDefinitionInfoMap = processDefinitionService.getProcessDefinitionInfoMap(
|
Map<String, BpmProcessDefinitionInfoDO> processDefinitionInfoMap = processDefinitionService.getProcessDefinitionInfoMap(
|
||||||
convertSet(pageResult.getList(), BpmProcessInstanceCopyDO::getProcessDefinitionId));
|
convertSet(pageResult.getList(), BpmProcessInstanceCopyDO::getProcessDefinitionId));
|
||||||
return success(convertPage(pageResult, copy -> {
|
return success(convertPage(pageResult, copy -> {
|
||||||
BpmProcessInstanceCopyRespVO copyVO = BeanUtils.toBean(copy, BpmProcessInstanceCopyRespVO.class);
|
BpmProcessInstanceCopyRespVO copyVO = BeanUtils.toBean(copy, BpmProcessInstanceCopyRespVO.class);
|
||||||
MapUtils.findAndThen(userMap, copy.getUserId(),
|
MapUtils.findAndThen(userMap, Long.valueOf(copy.getCreator()),
|
||||||
user -> copyVO.setCreateUser(BeanUtils.toBean(user, UserSimpleBaseVO.class)));
|
|
||||||
MapUtils.findAndThen(userMap, copy.getStartUserId(),
|
|
||||||
user -> copyVO.setStartUser(BeanUtils.toBean(user, UserSimpleBaseVO.class)));
|
user -> copyVO.setStartUser(BeanUtils.toBean(user, UserSimpleBaseVO.class)));
|
||||||
|
MapUtils.findAndThen(userMap, copy.getStartUserId(),
|
||||||
|
user -> copyVO.setCreateUser(BeanUtils.toBean(user, UserSimpleBaseVO.class)));
|
||||||
MapUtils.findAndThen(processInstanceMap, copyVO.getProcessInstanceId(),
|
MapUtils.findAndThen(processInstanceMap, copyVO.getProcessInstanceId(),
|
||||||
processInstance -> {
|
processInstance -> {
|
||||||
copyVO.setSummary(FlowableUtils.getSummary(
|
copyVO.setSummary(FlowableUtils.getSummary(
|
||||||
|
|
|
||||||
|
|
@ -107,9 +107,6 @@ public class BpmApprovalDetailRespVO {
|
||||||
@Schema(description = "签名", example = "https://www.iocoder.cn/sign.png")
|
@Schema(description = "签名", example = "https://www.iocoder.cn/sign.png")
|
||||||
private String signPicUrl;
|
private String signPicUrl;
|
||||||
|
|
||||||
@Schema(description = "附件", example = "[https://test.yudao.iocoder.cn/20260609/test.txt]")
|
|
||||||
private List<String> attachments;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,9 +21,6 @@ public class BpmTaskApproveReqVO {
|
||||||
@Schema(description = "签名", example = "https://www.iocoder.cn/sign.png")
|
@Schema(description = "签名", example = "https://www.iocoder.cn/sign.png")
|
||||||
private String signPicUrl;
|
private String signPicUrl;
|
||||||
|
|
||||||
@Schema(description = "附件", example = "[https://test.yudao.iocoder.cn/20260609/test.txt]")
|
|
||||||
private List<String> attachments;
|
|
||||||
|
|
||||||
@Schema(description = "变量实例(动态表单)", requiredMode = Schema.RequiredMode.REQUIRED)
|
@Schema(description = "变量实例(动态表单)", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
private Map<String, Object> variables;
|
private Map<String, Object> variables;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
import javax.validation.constraints.NotEmpty;
|
import javax.validation.constraints.NotEmpty;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Schema(description = "管理后台 - 不通过流程任务的 Request VO")
|
@Schema(description = "管理后台 - 不通过流程任务的 Request VO")
|
||||||
@Data
|
@Data
|
||||||
|
|
@ -17,7 +16,4 @@ public class BpmTaskRejectReqVO {
|
||||||
@Schema(description = "审批意见", requiredMode = Schema.RequiredMode.REQUIRED, example = "不错不错!")
|
@Schema(description = "审批意见", requiredMode = Schema.RequiredMode.REQUIRED, example = "不错不错!")
|
||||||
private String reason;
|
private String reason;
|
||||||
|
|
||||||
@Schema(description = "附件", example = "[https://test.yudao.iocoder.cn/20260609/test.txt]")
|
|
||||||
private List<String> attachments;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,6 @@ import cn.iocoder.yudao.framework.common.util.collection.SetUtils;
|
||||||
import cn.iocoder.yudao.framework.common.util.date.DateUtils;
|
import cn.iocoder.yudao.framework.common.util.date.DateUtils;
|
||||||
import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
|
import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
|
||||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||||
import cn.iocoder.yudao.module.bpm.api.event.BpmProcessInstanceStatusEvent;
|
|
||||||
import cn.iocoder.yudao.module.bpm.controller.admin.base.user.UserSimpleBaseVO;
|
import cn.iocoder.yudao.module.bpm.controller.admin.base.user.UserSimpleBaseVO;
|
||||||
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.BpmModelMetaInfoVO;
|
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.BpmModelMetaInfoVO;
|
||||||
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO;
|
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO;
|
||||||
|
|
@ -22,6 +21,7 @@ import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskRespVO;
|
||||||
import cn.iocoder.yudao.module.bpm.convert.definition.BpmProcessDefinitionConvert;
|
import cn.iocoder.yudao.module.bpm.convert.definition.BpmProcessDefinitionConvert;
|
||||||
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmCategoryDO;
|
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmCategoryDO;
|
||||||
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO;
|
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO;
|
||||||
|
import cn.iocoder.yudao.module.bpm.api.event.BpmProcessInstanceStatusEvent;
|
||||||
import cn.iocoder.yudao.module.bpm.enums.task.BpmTaskStatusEnum;
|
import cn.iocoder.yudao.module.bpm.enums.task.BpmTaskStatusEnum;
|
||||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnVariableConstants;
|
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnVariableConstants;
|
||||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils;
|
import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils;
|
||||||
|
|
@ -34,7 +34,6 @@ import org.flowable.bpmn.model.BpmnModel;
|
||||||
import org.flowable.engine.history.HistoricProcessInstance;
|
import org.flowable.engine.history.HistoricProcessInstance;
|
||||||
import org.flowable.engine.repository.ProcessDefinition;
|
import org.flowable.engine.repository.ProcessDefinition;
|
||||||
import org.flowable.engine.runtime.ProcessInstance;
|
import org.flowable.engine.runtime.ProcessInstance;
|
||||||
import org.flowable.engine.task.Attachment;
|
|
||||||
import org.flowable.task.api.Task;
|
import org.flowable.task.api.Task;
|
||||||
import org.flowable.task.api.history.HistoricTaskInstance;
|
import org.flowable.task.api.history.HistoricTaskInstance;
|
||||||
import org.mapstruct.Mapper;
|
import org.mapstruct.Mapper;
|
||||||
|
|
@ -201,14 +200,13 @@ public interface BpmProcessInstanceConvert {
|
||||||
return userVO;
|
return userVO;
|
||||||
}
|
}
|
||||||
|
|
||||||
default BpmApprovalDetailRespVO.ActivityNodeTask buildApprovalTaskInfo(HistoricTaskInstance task, List<Attachment> attachments) {
|
default BpmApprovalDetailRespVO.ActivityNodeTask buildApprovalTaskInfo(HistoricTaskInstance task) {
|
||||||
if (task == null) {
|
if (task == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return BeanUtils.toBean(task, BpmApprovalDetailRespVO.ActivityNodeTask.class)
|
return BeanUtils.toBean(task, BpmApprovalDetailRespVO.ActivityNodeTask.class)
|
||||||
.setStatus(FlowableUtils.getTaskStatus(task)).setReason(FlowableUtils.getTaskReason(task))
|
.setStatus(FlowableUtils.getTaskStatus(task)).setReason(FlowableUtils.getTaskReason(task))
|
||||||
.setSignPicUrl(FlowableUtils.getTaskSignPicUrl(task))
|
.setSignPicUrl(FlowableUtils.getTaskSignPicUrl(task));
|
||||||
.setAttachments(convertList(attachments, Attachment::getUrl));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
default Set<Long> parseUserIds(HistoricProcessInstance processInstance,
|
default Set<Long> parseUserIds(HistoricProcessInstance processInstance,
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ public class BpmOALeaveDO extends BaseDO {
|
||||||
/**
|
/**
|
||||||
* 请假类型
|
* 请假类型
|
||||||
*/
|
*/
|
||||||
private Integer type;
|
private String type;
|
||||||
/**
|
/**
|
||||||
* 原因
|
* 原因
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -7,10 +7,10 @@ import org.springframework.stereotype.Component;
|
||||||
/**
|
/**
|
||||||
* 根据流程变量 variable 的类型,转换参数的值
|
* 根据流程变量 variable 的类型,转换参数的值
|
||||||
*
|
*
|
||||||
* @deprecated 已无调用方
|
* 目前用于 ConditionNodeConvert 的 buildConditionExpression 方法中
|
||||||
|
*
|
||||||
* @author jason
|
* @author jason
|
||||||
*/
|
*/
|
||||||
@Deprecated // TODO @芋艿:兼容老版本,预计 27 年删除;
|
|
||||||
@Component
|
@Component
|
||||||
public class VariableConvertByTypeExpressionFunction extends AbstractFlowableVariableExpressionFunction {
|
public class VariableConvertByTypeExpressionFunction extends AbstractFlowableVariableExpressionFunction {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ public enum BpmTaskCandidateStrategyEnum implements ArrayValuable<Integer> {
|
||||||
MULTI_DEPT_LEADER_MULTI(23, "连续多级部门的负责人"),
|
MULTI_DEPT_LEADER_MULTI(23, "连续多级部门的负责人"),
|
||||||
POST(22, "岗位"),
|
POST(22, "岗位"),
|
||||||
USER(30, "用户"),
|
USER(30, "用户"),
|
||||||
APPROVE_USER_SELECT(34, "审批人自选"), // 当前审批人,可在审批时,选择下一个节点的审批人
|
APPROVE_USER_SELECT(34, "审批人自身"), // 当前审批人,可在审批时,选择下一个节点的审批人
|
||||||
START_USER_SELECT(35, "发起人自选"), // 申请人自己,可在提交申请时,选择此节点的审批人
|
START_USER_SELECT(35, "发起人自选"), // 申请人自己,可在提交申请时,选择此节点的审批人
|
||||||
START_USER(36, "发起人自己"), // 申请人自己, 一般紧挨开始节点,常用于发起人信息审核场景
|
START_USER(36, "发起人自己"), // 申请人自己, 一般紧挨开始节点,常用于发起人信息审核场景
|
||||||
START_USER_DEPT_LEADER(37, "发起人部门负责人"),
|
START_USER_DEPT_LEADER(37, "发起人部门负责人"),
|
||||||
|
|
|
||||||
|
|
@ -456,54 +456,6 @@ public class BpmnModelUtils {
|
||||||
return new ArrayList<>();
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据节点,递归获取上游 source 为 UserTask 的入口连线
|
|
||||||
*
|
|
||||||
* 1. 如果当前节点的直接入口连线 source 就是 UserTask,则直接返回该连线
|
|
||||||
* 2. 如果当前节点的直接入口连线 source 不是 UserTask,则继续向上递归查找
|
|
||||||
* 3. 如果递归过程中遇到 StartEvent 或 SubProcess,则停止该分支继续向上查找
|
|
||||||
*
|
|
||||||
* @param source 起始节点
|
|
||||||
* @return 上游连接 UserTask 的入口连线列表
|
|
||||||
*/
|
|
||||||
public static List<SequenceFlow> getElementIncomingUserTaskFlows(FlowElement source) {
|
|
||||||
List<SequenceFlow> result = new ArrayList<>();
|
|
||||||
collectElementIncomingUserTaskFlows(source, new HashSet<>(), new HashSet<>(), result);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void collectElementIncomingUserTaskFlows(FlowElement source, Set<String> visitedSequenceFlowIds,
|
|
||||||
Set<String> resultSequenceFlowIds, List<SequenceFlow> result) {
|
|
||||||
// 如果是开始节点或子流程,则停止该分支向上查找
|
|
||||||
if (source == null || source instanceof StartEvent || source instanceof SubProcess) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// 获取入口连线
|
|
||||||
List<SequenceFlow> incomingFlows = getElementIncomingFlows(source);
|
|
||||||
if (CollUtil.isEmpty(incomingFlows)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 循环找到目标元素
|
|
||||||
for (SequenceFlow incomingFlow : incomingFlows) {
|
|
||||||
// 如果发现连线重复,说明连线已经走过。跳过
|
|
||||||
if (incomingFlow == null || !visitedSequenceFlowIds.add(incomingFlow.getId())) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// 如果 source 是 UserTask,则添加到结果中
|
|
||||||
FlowElement sourceFlowElement = incomingFlow.getSourceFlowElement();
|
|
||||||
if (sourceFlowElement instanceof UserTask) {
|
|
||||||
if (resultSequenceFlowIds.add(incomingFlow.getId())) {
|
|
||||||
result.add(incomingFlow);
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// 递归向上查找 UserTask
|
|
||||||
collectElementIncomingUserTaskFlows(sourceFlowElement, visitedSequenceFlowIds,
|
|
||||||
resultSequenceFlowIds, result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据节点,获取出口连线
|
* 根据节点,获取出口连线
|
||||||
*
|
*
|
||||||
|
|
@ -958,88 +910,13 @@ public class BpmnModelUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查找起始节点下一个用户任务列表, 该方法会递归向下查找:跳过非 UserTask 节点, 支持网关条件判断
|
* 查找起始节点下一个用户任务列表列表
|
||||||
*
|
|
||||||
* <ul>
|
|
||||||
* <li>排他网关:走满足条件的唯一一条路径(含默认路径兜底)</li>
|
|
||||||
* <li>包容网关:走所有满足条件的路径</li>
|
|
||||||
* <li>并行网关:走所有出口路径</li>
|
|
||||||
* </ul>
|
|
||||||
*
|
|
||||||
* @param currentElement 当前节点
|
|
||||||
* @param bpmnModel BPMN 模型
|
|
||||||
* @param variables 流程变量(用于网关条件判断)
|
|
||||||
* @return 下一个用户任务节点列表
|
|
||||||
*/
|
|
||||||
public static List<UserTask> getNextUserTasks(FlowElement currentElement, BpmnModel bpmnModel,
|
|
||||||
Map<String, Object> variables) {
|
|
||||||
return getNextUserTasks(currentElement, bpmnModel, variables, new HashSet<>(), new ArrayList<>());
|
|
||||||
}
|
|
||||||
|
|
||||||
private static List<UserTask> getNextUserTasks(FlowElement currentElement, BpmnModel bpmnModel,
|
|
||||||
Map<String, Object> variables,
|
|
||||||
Set<String> hasSequenceFlow, List<UserTask> userTaskList) {
|
|
||||||
// 1. 根据节点类型决定要遍历的出口连线
|
|
||||||
// 网关需要根据条件表达式筛选;其它节点直接取所有 outgoing flows
|
|
||||||
List<SequenceFlow> outgoingFlows;
|
|
||||||
if (currentElement instanceof Gateway) {
|
|
||||||
outgoingFlows = getGatewayOutgoingFlows((Gateway) currentElement, variables);
|
|
||||||
} else {
|
|
||||||
outgoingFlows = getElementOutgoingFlows(currentElement);
|
|
||||||
}
|
|
||||||
if (CollUtil.isEmpty(outgoingFlows)) {
|
|
||||||
return userTaskList;
|
|
||||||
}
|
|
||||||
// 2. 遍历出口连线,递归查找用户任务
|
|
||||||
for (SequenceFlow outgoingFlow : outgoingFlows) {
|
|
||||||
// 防止连线成环导致死循环
|
|
||||||
if (hasSequenceFlow.contains(outgoingFlow.getId())) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
hasSequenceFlow.add(outgoingFlow.getId());
|
|
||||||
// 获取目标节点
|
|
||||||
FlowElement targetElement = bpmnModel.getFlowElement(outgoingFlow.getTargetRef());
|
|
||||||
if (targetElement == null || targetElement instanceof EndEvent) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (targetElement instanceof UserTask) {
|
|
||||||
// 找到用户任务:加入结果
|
|
||||||
userTaskList.add((UserTask) targetElement);
|
|
||||||
} else {
|
|
||||||
// 非用户任务(网关、服务任务、中间事件等):继续递归向下查找
|
|
||||||
getNextUserTasks(targetElement, bpmnModel, variables, hasSequenceFlow, userTaskList);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return userTaskList;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据网关类型与流程变量,筛选网关的出口连线
|
|
||||||
*
|
|
||||||
* @param gateway 网关节点
|
|
||||||
* @param variables 流程变量
|
|
||||||
* @return 命中的出口连线列表
|
|
||||||
*/
|
|
||||||
private static List<SequenceFlow> getGatewayOutgoingFlows(Gateway gateway, Map<String, Object> variables) {
|
|
||||||
if (gateway instanceof ExclusiveGateway) {
|
|
||||||
SequenceFlow matchFlow = findMatchSequenceFlowByExclusiveGateway(gateway, variables);
|
|
||||||
return matchFlow == null ? Collections.emptyList() : Collections.singletonList(matchFlow);
|
|
||||||
}
|
|
||||||
if (gateway instanceof InclusiveGateway) {
|
|
||||||
return new ArrayList<>(findMatchSequenceFlowsByInclusiveGateway(gateway, variables));
|
|
||||||
}
|
|
||||||
// 默认(并行网关等):走所有出口
|
|
||||||
return gateway.getOutgoingFlows();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查找起始节点下一个用户任务列表列表, 不判断网关条件
|
|
||||||
*
|
*
|
||||||
* @param source 起始节点
|
* @param source 起始节点
|
||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
public static List<UserTask> getNextUserTasks(FlowElement source) {
|
public static List<UserTask> getNextUserTasks(FlowElement source) {
|
||||||
return getNextUserTasks(source, new HashSet<>(), new ArrayList<>());
|
return getNextUserTasks(source, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.bpm.framework.flowable.core.util;
|
||||||
|
|
||||||
import cn.hutool.core.map.MapUtil;
|
import cn.hutool.core.map.MapUtil;
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
|
||||||
import cn.hutool.extra.spring.SpringUtil;
|
import cn.hutool.extra.spring.SpringUtil;
|
||||||
import cn.iocoder.yudao.framework.common.core.KeyValue;
|
import cn.iocoder.yudao.framework.common.core.KeyValue;
|
||||||
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
|
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
|
||||||
|
|
@ -12,7 +11,6 @@ import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form.BpmFormFi
|
||||||
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO;
|
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO;
|
||||||
import cn.iocoder.yudao.module.bpm.enums.definition.BpmModelFormTypeEnum;
|
import cn.iocoder.yudao.module.bpm.enums.definition.BpmModelFormTypeEnum;
|
||||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnVariableConstants;
|
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnVariableConstants;
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import org.flowable.common.engine.api.delegate.Expression;
|
import org.flowable.common.engine.api.delegate.Expression;
|
||||||
import org.flowable.common.engine.api.variable.VariableContainer;
|
import org.flowable.common.engine.api.variable.VariableContainer;
|
||||||
|
|
@ -28,7 +26,6 @@ import org.flowable.engine.runtime.ProcessInstance;
|
||||||
import org.flowable.task.api.TaskInfo;
|
import org.flowable.task.api.TaskInfo;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
@ -247,10 +244,12 @@ public class FlowableUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 解析表单配置
|
// 解析表单配置
|
||||||
Map<String, BpmFormFieldVO> formFieldsMap = new LinkedHashMap<>();
|
Map<String, BpmFormFieldVO> formFieldsMap = new HashMap<>();
|
||||||
processDefinitionInfo.getFormFields().forEach(formFieldStr -> {
|
processDefinitionInfo.getFormFields().forEach(formFieldStr -> {
|
||||||
JsonNode formFieldNode = JsonUtils.parseObject(formFieldStr, JsonNode.class);
|
BpmFormFieldVO formField = JsonUtils.parseObject(formFieldStr, BpmFormFieldVO.class);
|
||||||
parseFormField(formFieldNode, formFieldsMap);
|
if (formField != null) {
|
||||||
|
formFieldsMap.put(formField.getField(), formField);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// 情况一:当自定义了摘要
|
// 情况一:当自定义了摘要
|
||||||
|
|
@ -274,40 +273,6 @@ public class FlowableUtils {
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 递归解析表单字段
|
|
||||||
*/
|
|
||||||
private static void parseFormField(JsonNode formFieldNode, Map<String, BpmFormFieldVO> formFieldsMap) {
|
|
||||||
if (formFieldNode == null || !formFieldNode.isObject()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 如果 children 里存在对象节点,说明是布局组件;字符串节点是分割线、标签、文字等展示组件内容,直接跳过。
|
|
||||||
JsonNode children = formFieldNode.get("children");
|
|
||||||
if (children != null && children.isArray() && children.size() > 0) {
|
|
||||||
boolean hasObjectChild = false;
|
|
||||||
for (JsonNode child : children) {
|
|
||||||
if (!child.isObject()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
hasObjectChild = true;
|
|
||||||
parseFormField(child, formFieldsMap);
|
|
||||||
}
|
|
||||||
if (hasObjectChild) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 真实字段才加入 map
|
|
||||||
BpmFormFieldVO formField = new BpmFormFieldVO()
|
|
||||||
.setType(JsonUtils.getText(formFieldNode, "type"))
|
|
||||||
.setField(JsonUtils.getText(formFieldNode, "field"))
|
|
||||||
.setTitle(JsonUtils.getText(formFieldNode, "title"));
|
|
||||||
if (StrUtil.isNotBlank(formField.getField())) {
|
|
||||||
formFieldsMap.put(formField.getField(), formField);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ========== Task 相关的工具方法 ==========
|
// ========== Task 相关的工具方法 ==========
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -707,9 +707,10 @@ public class SimpleModelUtils {
|
||||||
List<String> list = convertList(item.getRules(), (rule) -> {
|
List<String> list = convertList(item.getRules(), (rule) -> {
|
||||||
String rightSide = NumberUtil.isNumber(rule.getRightSide()) ? rule.getRightSide()
|
String rightSide = NumberUtil.isNumber(rule.getRightSide()) ? rule.getRightSide()
|
||||||
: "\"" + rule.getRightSide() + "\""; // 如果非数值类型加引号
|
: "\"" + rule.getRightSide() + "\""; // 如果非数值类型加引号
|
||||||
return String.format(BpmConditionOpCodeEnum.fromCode(rule.getOpCode()).getSymbol(),
|
return String.format(" vars:getOrDefault(%s, null) %s var:convertByType(%s,%s) ",
|
||||||
rule.getLeftSide(), // 左侧:读取变量
|
rule.getLeftSide(), // 左侧:读取变量
|
||||||
rightSide); // 右侧:取值变量
|
rule.getOpCode(), // 中间:操作符,比较
|
||||||
|
rule.getLeftSide(), rightSide); // 右侧:转换变量,VariableConvertByTypeExpressionFunction
|
||||||
});
|
});
|
||||||
// 构造条件组的表达式
|
// 构造条件组的表达式
|
||||||
Boolean and = item.getAnd();
|
Boolean and = item.getAnd();
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
package cn.iocoder.yudao.module.bpm.service.definition.dto;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.module.bpm.enums.definition.BpmModelFormTypeEnum;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BPM 流程 MetaInfo Response DTO
|
||||||
|
* 主要用于 { Model#setMetaInfo(String)} 的存储
|
||||||
|
*
|
||||||
|
* 最终,它的字段和 {@link cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO} 是一致的
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class BpmModelMetaInfoRespDTO {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 流程图标
|
||||||
|
*/
|
||||||
|
private String icon;
|
||||||
|
/**
|
||||||
|
* 流程描述
|
||||||
|
*/
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 表单类型
|
||||||
|
*/
|
||||||
|
private Integer formType;
|
||||||
|
/**
|
||||||
|
* 表单编号
|
||||||
|
* 在表单类型为 {@link BpmModelFormTypeEnum#NORMAL} 时
|
||||||
|
*/
|
||||||
|
private Long formId;
|
||||||
|
/**
|
||||||
|
* 自定义表单的提交路径,使用 Vue 的路由地址
|
||||||
|
* 在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时
|
||||||
|
*/
|
||||||
|
private String formCustomCreatePath;
|
||||||
|
/**
|
||||||
|
* 自定义表单的查看路径,使用 Vue 的路由地址
|
||||||
|
* 在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时
|
||||||
|
*/
|
||||||
|
private String formCustomViewPath;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -7,6 +7,7 @@ import cn.hutool.core.date.DateUtil;
|
||||||
import cn.hutool.core.lang.Assert;
|
import cn.hutool.core.lang.Assert;
|
||||||
import cn.hutool.core.util.*;
|
import cn.hutool.core.util.*;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
|
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||||
import cn.iocoder.yudao.framework.common.util.date.DateUtils;
|
import cn.iocoder.yudao.framework.common.util.date.DateUtils;
|
||||||
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
|
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
|
||||||
import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
|
import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
|
||||||
|
|
@ -24,7 +25,6 @@ import cn.iocoder.yudao.module.bpm.dal.redis.BpmProcessIdRedisDAO;
|
||||||
import cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants;
|
import cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants;
|
||||||
import cn.iocoder.yudao.module.bpm.enums.definition.BpmModelTypeEnum;
|
import cn.iocoder.yudao.module.bpm.enums.definition.BpmModelTypeEnum;
|
||||||
import cn.iocoder.yudao.module.bpm.enums.definition.BpmSimpleModelNodeTypeEnum;
|
import cn.iocoder.yudao.module.bpm.enums.definition.BpmSimpleModelNodeTypeEnum;
|
||||||
import cn.iocoder.yudao.module.bpm.enums.task.BpmAttachmentTypeEnum;
|
|
||||||
import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceStatusEnum;
|
import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceStatusEnum;
|
||||||
import cn.iocoder.yudao.module.bpm.enums.task.BpmReasonEnum;
|
import cn.iocoder.yudao.module.bpm.enums.task.BpmReasonEnum;
|
||||||
import cn.iocoder.yudao.module.bpm.enums.task.BpmTaskStatusEnum;
|
import cn.iocoder.yudao.module.bpm.enums.task.BpmTaskStatusEnum;
|
||||||
|
|
@ -55,7 +55,6 @@ import org.flowable.engine.repository.ProcessDefinition;
|
||||||
import org.flowable.engine.runtime.Execution;
|
import org.flowable.engine.runtime.Execution;
|
||||||
import org.flowable.engine.runtime.ProcessInstance;
|
import org.flowable.engine.runtime.ProcessInstance;
|
||||||
import org.flowable.engine.runtime.ProcessInstanceBuilder;
|
import org.flowable.engine.runtime.ProcessInstanceBuilder;
|
||||||
import org.flowable.engine.task.Attachment;
|
|
||||||
import org.flowable.task.api.Task;
|
import org.flowable.task.api.Task;
|
||||||
import org.flowable.task.api.history.HistoricTaskInstance;
|
import org.flowable.task.api.history.HistoricTaskInstance;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
|
|
@ -276,10 +275,11 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
|
||||||
processVariables.putAll(reqVO.getProcessVariables());
|
processVariables.putAll(reqVO.getProcessVariables());
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3.1 获取下一个将要执行的节点集合
|
// 3. 获取下一个将要执行的节点集合
|
||||||
FlowElement flowElement = bpmnModel.getFlowElement(task.getTaskDefinitionKey());
|
FlowElement flowElement = bpmnModel.getFlowElement(task.getTaskDefinitionKey());
|
||||||
// 3.2 获取 UserTask 节点
|
List<FlowNode> nextFlowNodes = BpmnModelUtils.getNextFlowNodes(flowElement, bpmnModel, processVariables);
|
||||||
List<UserTask> nextUserTaskList = BpmnModelUtils.getNextUserTasks(flowElement, bpmnModel, processVariables);
|
// 仅仅获取 UserTask 节点 TODO add from jason:如果网关节点和网关节点相连,获取下个 UserTask. 貌似有点不准。
|
||||||
|
List<FlowNode> nextUserTaskList = CollectionUtils.filterList(nextFlowNodes, node -> node instanceof UserTask);
|
||||||
List<ActivityNode> nextActivityNodes = convertList(nextUserTaskList, node -> new ActivityNode().setId(node.getId())
|
List<ActivityNode> nextActivityNodes = convertList(nextUserTaskList, node -> new ActivityNode().setId(node.getId())
|
||||||
.setName(node.getName()).setNodeType(BpmSimpleModelNodeTypeEnum.APPROVE_NODE.getType())
|
.setName(node.getName()).setNodeType(BpmSimpleModelNodeTypeEnum.APPROVE_NODE.getType())
|
||||||
.setStatus(BpmTaskStatusEnum.RUNNING.getStatus())
|
.setStatus(BpmTaskStatusEnum.RUNNING.getStatus())
|
||||||
|
|
@ -404,13 +404,8 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
|
||||||
// 遍历 tasks 列表,只处理已结束的 UserTask
|
// 遍历 tasks 列表,只处理已结束的 UserTask
|
||||||
// 为什么不通过 activities 呢?因为,加签场景下,它只存在于 tasks,没有 activities,导致如果遍历 activities 的话,它无法成为一个节点
|
// 为什么不通过 activities 呢?因为,加签场景下,它只存在于 tasks,没有 activities,导致如果遍历 activities 的话,它无法成为一个节点
|
||||||
List<HistoricTaskInstance> endTasks = filterList(tasks, task -> task.getEndTime() != null);
|
List<HistoricTaskInstance> endTasks = filterList(tasks, task -> task.getEndTime() != null);
|
||||||
// 获取已完成节点的附件
|
|
||||||
Set<String> endTaskIds = convertSet(endTasks, HistoricTaskInstance::getId);
|
|
||||||
List<Attachment> attachments = taskService.getAttachments(historicProcessInstance.getId(), endTaskIds, BpmAttachmentTypeEnum.TASK_ATTACHMENT);
|
|
||||||
Map<String, List<Attachment>> taskAttachmentMap = convertMultiMap(attachments, Attachment::getTaskId);
|
|
||||||
List<ActivityNode> approvalNodes = convertList(endTasks, task -> {
|
List<ActivityNode> approvalNodes = convertList(endTasks, task -> {
|
||||||
FlowElement flowNode = BpmnModelUtils.getFlowElementById(bpmnModel, task.getTaskDefinitionKey());
|
FlowElement flowNode = BpmnModelUtils.getFlowElementById(bpmnModel, task.getTaskDefinitionKey());
|
||||||
List<Attachment> taskAttachments = taskAttachmentMap.get(task.getId());
|
|
||||||
ActivityNode activityNode = new ActivityNode().setId(task.getTaskDefinitionKey()).setName(task.getName())
|
ActivityNode activityNode = new ActivityNode().setId(task.getTaskDefinitionKey()).setName(task.getName())
|
||||||
.setNodeType(START_USER_NODE_ID.equals(task.getTaskDefinitionKey())
|
.setNodeType(START_USER_NODE_ID.equals(task.getTaskDefinitionKey())
|
||||||
? BpmSimpleModelNodeTypeEnum.START_USER_NODE.getType()
|
? BpmSimpleModelNodeTypeEnum.START_USER_NODE.getType()
|
||||||
|
|
@ -419,7 +414,7 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
|
||||||
.setStatus(getEndActivityNodeStatus(task))
|
.setStatus(getEndActivityNodeStatus(task))
|
||||||
.setCandidateStrategy(BpmnModelUtils.parseCandidateStrategy(flowNode))
|
.setCandidateStrategy(BpmnModelUtils.parseCandidateStrategy(flowNode))
|
||||||
.setStartTime(DateUtils.of(task.getCreateTime())).setEndTime(DateUtils.of(task.getEndTime()))
|
.setStartTime(DateUtils.of(task.getCreateTime())).setEndTime(DateUtils.of(task.getEndTime()))
|
||||||
.setTasks(singletonList(BpmProcessInstanceConvert.INSTANCE.buildApprovalTaskInfo(task, taskAttachments)));
|
.setTasks(singletonList(BpmProcessInstanceConvert.INSTANCE.buildApprovalTaskInfo(task)));
|
||||||
// 如果是取消状态,则跳过
|
// 如果是取消状态,则跳过
|
||||||
if (BpmTaskStatusEnum.isCancelStatus(activityNode.getStatus())) {
|
if (BpmTaskStatusEnum.isCancelStatus(activityNode.getStatus())) {
|
||||||
return null;
|
return null;
|
||||||
|
|
@ -533,14 +528,14 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
|
||||||
if (task == null) {
|
if (task == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
activityNode.getTasks().add(BpmProcessInstanceConvert.INSTANCE.buildApprovalTaskInfo(task, null));
|
activityNode.getTasks().add(BpmProcessInstanceConvert.INSTANCE.buildApprovalTaskInfo(task));
|
||||||
// 加签子任务,需要过滤掉已经完成的加签子任务
|
// 加签子任务,需要过滤掉已经完成的加签子任务
|
||||||
List<HistoricTaskInstance> childrenTasks = filterList(
|
List<HistoricTaskInstance> childrenTasks = filterList(
|
||||||
taskService.getAllChildrenTaskListByParentTaskId(activity.getTaskId(), tasks),
|
taskService.getAllChildrenTaskListByParentTaskId(activity.getTaskId(), tasks),
|
||||||
childTask -> childTask.getEndTime() == null);
|
childTask -> childTask.getEndTime() == null);
|
||||||
if (CollUtil.isNotEmpty(childrenTasks)) {
|
if (CollUtil.isNotEmpty(childrenTasks)) {
|
||||||
activityNode.getTasks().addAll(
|
activityNode.getTasks().addAll(
|
||||||
convertList(childrenTasks, item->BpmProcessInstanceConvert.INSTANCE.buildApprovalTaskInfo(item, null)));
|
convertList(childrenTasks, BpmProcessInstanceConvert.INSTANCE::buildApprovalTaskInfo));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 处理每个任务的 candidateUsers 属性:如果是依次审批,需要预测它的后续审批人。因为 Task 是审批完一个,创建一个新的 Task
|
// 处理每个任务的 candidateUsers 属性:如果是依次审批,需要预测它的后续审批人。因为 Task 是审批完一个,创建一个新的 Task
|
||||||
|
|
|
||||||
|
|
@ -4,10 +4,8 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||||
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.*;
|
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.*;
|
||||||
import cn.iocoder.yudao.module.bpm.enums.definition.BpmUserTaskTimeoutHandlerTypeEnum;
|
import cn.iocoder.yudao.module.bpm.enums.definition.BpmUserTaskTimeoutHandlerTypeEnum;
|
||||||
import cn.iocoder.yudao.module.bpm.enums.task.BpmAttachmentTypeEnum;
|
|
||||||
import org.flowable.bpmn.model.UserTask;
|
import org.flowable.bpmn.model.UserTask;
|
||||||
import org.flowable.engine.history.HistoricActivityInstance;
|
import org.flowable.engine.history.HistoricActivityInstance;
|
||||||
import org.flowable.engine.task.Attachment;
|
|
||||||
import org.flowable.task.api.Task;
|
import org.flowable.task.api.Task;
|
||||||
import org.flowable.task.api.TaskInfo;
|
import org.flowable.task.api.TaskInfo;
|
||||||
import org.flowable.task.api.history.HistoricTaskInstance;
|
import org.flowable.task.api.history.HistoricTaskInstance;
|
||||||
|
|
@ -16,7 +14,6 @@ import javax.validation.Valid;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 流程任务实例 Service 接口
|
* 流程任务实例 Service 接口
|
||||||
|
|
@ -187,17 +184,6 @@ public interface BpmTaskService {
|
||||||
*/
|
*/
|
||||||
List<HistoricTaskInstance> getFinishedTaskListByProcessInstanceIdWithoutCancel(String processInstanceId);
|
List<HistoricTaskInstance> getFinishedTaskListByProcessInstanceIdWithoutCancel(String processInstanceId);
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据条件获取附件
|
|
||||||
*
|
|
||||||
* @param processInstanceId 流程 id
|
|
||||||
* @param taskIds 任务 id 集合
|
|
||||||
* @param attachmentType 附件类型
|
|
||||||
* @return 附件集合
|
|
||||||
*/
|
|
||||||
List<Attachment> getAttachments(String processInstanceId, Set<String> taskIds, BpmAttachmentTypeEnum attachmentType);
|
|
||||||
|
|
||||||
// ========== Update 写入相关方法 ==========
|
// ========== Update 写入相关方法 ==========
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.bpm.service.task;
|
||||||
|
|
||||||
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.collection.CollUtil;
|
||||||
import cn.hutool.core.convert.Convert;
|
import cn.hutool.core.convert.Convert;
|
||||||
import cn.hutool.core.io.FileUtil;
|
|
||||||
import cn.hutool.core.lang.Assert;
|
import cn.hutool.core.lang.Assert;
|
||||||
import cn.hutool.core.util.*;
|
import cn.hutool.core.util.*;
|
||||||
import cn.hutool.extra.spring.SpringUtil;
|
import cn.hutool.extra.spring.SpringUtil;
|
||||||
|
|
@ -20,7 +19,10 @@ import cn.iocoder.yudao.module.bpm.convert.task.BpmTaskConvert;
|
||||||
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO;
|
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO;
|
||||||
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO;
|
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO;
|
||||||
import cn.iocoder.yudao.module.bpm.enums.definition.*;
|
import cn.iocoder.yudao.module.bpm.enums.definition.*;
|
||||||
import cn.iocoder.yudao.module.bpm.enums.task.*;
|
import cn.iocoder.yudao.module.bpm.enums.task.BpmCommentTypeEnum;
|
||||||
|
import cn.iocoder.yudao.module.bpm.enums.task.BpmReasonEnum;
|
||||||
|
import cn.iocoder.yudao.module.bpm.enums.task.BpmTaskSignTypeEnum;
|
||||||
|
import cn.iocoder.yudao.module.bpm.enums.task.BpmTaskStatusEnum;
|
||||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmTaskCandidateStrategyEnum;
|
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmTaskCandidateStrategyEnum;
|
||||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnVariableConstants;
|
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnVariableConstants;
|
||||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmHttpRequestUtils;
|
import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmHttpRequestUtils;
|
||||||
|
|
@ -45,7 +47,6 @@ import org.flowable.engine.history.HistoricActivityInstance;
|
||||||
import org.flowable.engine.runtime.ActivityInstance;
|
import org.flowable.engine.runtime.ActivityInstance;
|
||||||
import org.flowable.engine.runtime.Execution;
|
import org.flowable.engine.runtime.Execution;
|
||||||
import org.flowable.engine.runtime.ProcessInstance;
|
import org.flowable.engine.runtime.ProcessInstance;
|
||||||
import org.flowable.engine.task.Attachment;
|
|
||||||
import org.flowable.task.api.DelegationState;
|
import org.flowable.task.api.DelegationState;
|
||||||
import org.flowable.task.api.Task;
|
import org.flowable.task.api.Task;
|
||||||
import org.flowable.task.api.TaskInfo;
|
import org.flowable.task.api.TaskInfo;
|
||||||
|
|
@ -509,18 +510,6 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
||||||
.orderByHistoricTaskInstanceStartTime().asc().list();
|
.orderByHistoricTaskInstanceStartTime().asc().list();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<Attachment> getAttachments(String processInstanceId, Set<String> taskIds, BpmAttachmentTypeEnum attachmentType) {
|
|
||||||
List<Attachment> result = taskService.getProcessInstanceAttachments(processInstanceId);
|
|
||||||
if (CollUtil.isNotEmpty(taskIds)) {
|
|
||||||
result = filterList(result, attachment -> taskIds.contains(attachment.getTaskId()));
|
|
||||||
}
|
|
||||||
if (attachmentType != null) {
|
|
||||||
result = filterList(result, attachment -> attachmentType.getType().equals(attachment.getType()));
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 判断指定用户,是否是当前任务的审批人
|
* 判断指定用户,是否是当前任务的审批人
|
||||||
*
|
*
|
||||||
|
|
@ -603,11 +592,6 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
||||||
// 2.2 添加评论
|
// 2.2 添加评论
|
||||||
taskService.addComment(task.getId(), task.getProcessInstanceId(), BpmCommentTypeEnum.APPROVE.getType(),
|
taskService.addComment(task.getId(), task.getProcessInstanceId(), BpmCommentTypeEnum.APPROVE.getType(),
|
||||||
BpmCommentTypeEnum.APPROVE.formatComment(reqVO.getReason()));
|
BpmCommentTypeEnum.APPROVE.formatComment(reqVO.getReason()));
|
||||||
// 2.3 添加附件
|
|
||||||
if (CollUtil.isNotEmpty(reqVO.getAttachments())) {
|
|
||||||
reqVO.getAttachments().forEach(attachment -> taskService.createAttachment(BpmAttachmentTypeEnum.TASK_ATTACHMENT.getType(),
|
|
||||||
task.getId(), task.getProcessInstanceId(), FileUtil.getName(URLUtil.getPath(attachment)), null, attachment));
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. 设置流程变量。如果流程变量前端传空,需要从历史实例中获取,原因:前端表单如果在当前节点无可编辑的字段时 variables 一定会为空
|
// 3. 设置流程变量。如果流程变量前端传空,需要从历史实例中获取,原因:前端表单如果在当前节点无可编辑的字段时 variables 一定会为空
|
||||||
// 场景一:A 节点发起,B 节点表单无可编辑字段,审批通过时,C 节点需要流程变量获取下一个执行节点,但因为 B 节点无可编辑的字段,variables 为空,流程可能出现问题。
|
// 场景一:A 节点发起,B 节点表单无可编辑字段,审批通过时,C 节点需要流程变量获取下一个执行节点,但因为 B 节点无可编辑的字段,variables 为空,流程可能出现问题。
|
||||||
|
|
@ -634,14 +618,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
||||||
runtimeService.setVariable(task.getProcessInstanceId(), BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_NEED_SIMULATE_TASK_IDS, needSimulateTaskIdsByReturn);
|
runtimeService.setVariable(task.getProcessInstanceId(), BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_NEED_SIMULATE_TASK_IDS, needSimulateTaskIdsByReturn);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 6. 清理退回设置的不自动通过的变量。仅在该标记存在时才删除,避免每次完成任务都产生无谓的 DB delete
|
// 6. 调用 BPM complete 去完成任务
|
||||||
String returnFlagKey = String.format(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_RETURN_FLAG, task.getTaskDefinitionKey());
|
|
||||||
if (runtimeService.hasVariable(task.getProcessInstanceId(), returnFlagKey)) {
|
|
||||||
log.info("[approveTask][taskId({}) 清理退回标记变量({})]", task.getId(), returnFlagKey);
|
|
||||||
runtimeService.removeVariable(task.getProcessInstanceId(), returnFlagKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 7. 调用 BPM complete 去完成任务
|
|
||||||
taskService.complete(task.getId(), variables, true);
|
taskService.complete(task.getId(), variables, true);
|
||||||
|
|
||||||
// 【加签专属】处理加签任务
|
// 【加签专属】处理加签任务
|
||||||
|
|
@ -669,10 +646,10 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
||||||
}
|
}
|
||||||
// 1. 获取下一个将要执行的节点集合
|
// 1. 获取下一个将要执行的节点集合
|
||||||
FlowElement flowElement = bpmnModel.getFlowElement(taskDefinitionKey);
|
FlowElement flowElement = bpmnModel.getFlowElement(taskDefinitionKey);
|
||||||
List<UserTask> nextFlowNodes = getNextUserTasks(flowElement, bpmnModel, variables);
|
List<FlowNode> nextFlowNodes = getNextFlowNodes(flowElement, bpmnModel, variables);
|
||||||
|
|
||||||
// 2. 校验选择的下一个节点的审批人,是否合法
|
// 2. 校验选择的下一个节点的审批人,是否合法
|
||||||
for (UserTask nextFlowNode : nextFlowNodes) {
|
for (FlowNode nextFlowNode : nextFlowNodes) {
|
||||||
Integer candidateStrategy = parseCandidateStrategy(nextFlowNode);
|
Integer candidateStrategy = parseCandidateStrategy(nextFlowNode);
|
||||||
// 2.1 情况一:如果节点中的审批人策略为 发起人自选
|
// 2.1 情况一:如果节点中的审批人策略为 发起人自选
|
||||||
if (ObjUtil.equals(candidateStrategy, BpmTaskCandidateStrategyEnum.START_USER_SELECT.getStrategy())) {
|
if (ObjUtil.equals(candidateStrategy, BpmTaskCandidateStrategyEnum.START_USER_SELECT.getStrategy())) {
|
||||||
|
|
@ -698,12 +675,8 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
||||||
|
|
||||||
// 2.2 情况二:如果节点中的审批人策略为 审批人,在审批时选择下一个节点的审批人,并且该节点的审批人为空
|
// 2.2 情况二:如果节点中的审批人策略为 审批人,在审批时选择下一个节点的审批人,并且该节点的审批人为空
|
||||||
if (ObjUtil.equals(candidateStrategy, BpmTaskCandidateStrategyEnum.APPROVE_USER_SELECT.getStrategy())) {
|
if (ObjUtil.equals(candidateStrategy, BpmTaskCandidateStrategyEnum.APPROVE_USER_SELECT.getStrategy())) {
|
||||||
// 特殊:如果当前节点已经存在审批人,则不允许覆盖。 例如并行节点后,设置的审批人自选节点。 https://t.zsxq.com/daxv1
|
|
||||||
Map<String, List<Long>> approveUserSelectAssignees = FlowableUtils.getApproveUserSelectAssignees(processInstance.getProcessVariables());
|
|
||||||
if (approveUserSelectAssignees != null && CollUtil.isNotEmpty(approveUserSelectAssignees.get(nextFlowNode.getId()))) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// 如果节点存在,但未配置审批人
|
// 如果节点存在,但未配置审批人
|
||||||
|
Map<String, List<Long>> approveUserSelectAssignees = FlowableUtils.getApproveUserSelectAssignees(processInstance.getProcessVariables());
|
||||||
List<Long> assignees = nextAssignees != null ? nextAssignees.get(nextFlowNode.getId()) : null;
|
List<Long> assignees = nextAssignees != null ? nextAssignees.get(nextFlowNode.getId()) : null;
|
||||||
if (CollUtil.isEmpty(assignees)) {
|
if (CollUtil.isEmpty(assignees)) {
|
||||||
throw exception(PROCESS_INSTANCE_APPROVE_USER_SELECT_ASSIGNEES_NOT_CONFIG, nextFlowNode.getName());
|
throw exception(PROCESS_INSTANCE_APPROVE_USER_SELECT_ASSIGNEES_NOT_CONFIG, nextFlowNode.getName());
|
||||||
|
|
@ -837,13 +810,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
||||||
// 2.2 添加流程评论
|
// 2.2 添加流程评论
|
||||||
taskService.addComment(task.getId(), task.getProcessInstanceId(), BpmCommentTypeEnum.REJECT.getType(),
|
taskService.addComment(task.getId(), task.getProcessInstanceId(), BpmCommentTypeEnum.REJECT.getType(),
|
||||||
BpmCommentTypeEnum.REJECT.formatComment(reqVO.getReason()));
|
BpmCommentTypeEnum.REJECT.formatComment(reqVO.getReason()));
|
||||||
// 2.3 添加附件
|
// 2.3 如果当前任务时被加签的,则加它的根任务也标记成未通过
|
||||||
if (CollUtil.isNotEmpty(reqVO.getAttachments())) {
|
|
||||||
reqVO.getAttachments().forEach(attachment -> taskService.createAttachment(BpmAttachmentTypeEnum.TASK_ATTACHMENT.getType(),
|
|
||||||
task.getId(), task.getProcessInstanceId(), FileUtil.getName(URLUtil.getPath(attachment)), null, attachment));
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2.4 如果当前任务时被加签的,则加它的根任务也标记成未通过
|
|
||||||
// 疑问:为什么要标记未通过呢?
|
// 疑问:为什么要标记未通过呢?
|
||||||
// 回答:例如说 A 任务被向前加签除 B 任务时,B 任务被审批不通过,此时 A 会被取消。而 yudao-ui-admin-vue3 不展示“已取消”的任务,导致展示不出审批不通过的细节。
|
// 回答:例如说 A 任务被向前加签除 B 任务时,B 任务被审批不通过,此时 A 会被取消。而 yudao-ui-admin-vue3 不展示“已取消”的任务,导致展示不出审批不通过的细节。
|
||||||
if (task.getParentTaskId() != null) {
|
if (task.getParentTaskId() != null) {
|
||||||
|
|
@ -955,12 +922,14 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
||||||
// 为什么不直接使用 runTaskKeyList 呢?因为可能存在多个审批分支,例如说:A -> B -> C 和 D -> F,而只要 C 撤回到 A,需要排除掉 F
|
// 为什么不直接使用 runTaskKeyList 呢?因为可能存在多个审批分支,例如说:A -> B -> C 和 D -> F,而只要 C 撤回到 A,需要排除掉 F
|
||||||
List<UserTask> returnUserTaskList = BpmnModelUtils.iteratorFindChildUserTasks(targetElement, runTaskKeyList, null, null);
|
List<UserTask> returnUserTaskList = BpmnModelUtils.iteratorFindChildUserTasks(targetElement, runTaskKeyList, null, null);
|
||||||
List<String> returnTaskKeyList = convertList(returnUserTaskList, UserTask::getId);
|
List<String> returnTaskKeyList = convertList(returnUserTaskList, UserTask::getId);
|
||||||
|
|
||||||
// 2. 给当前要被退回的 task 数组,设置退回意见
|
// 2. 给当前要被退回的 task 数组,设置退回意见
|
||||||
taskList.forEach(task -> {
|
taskList.forEach(task -> {
|
||||||
// 需要排除掉,不需要设置退回意见的任务
|
// 需要排除掉,不需要设置退回意见的任务
|
||||||
if (!returnTaskKeyList.contains(task.getTaskDefinitionKey())) {
|
if (!returnTaskKeyList.contains(task.getTaskDefinitionKey())) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 判断是否分配给自己任务,因为会签任务,一个节点会有多个任务
|
// 判断是否分配给自己任务,因为会签任务,一个节点会有多个任务
|
||||||
if (isAssignUserTask(userId, task)) { // 情况一:自己的任务,进行 RETURN 标记
|
if (isAssignUserTask(userId, task)) { // 情况一:自己的任务,进行 RETURN 标记
|
||||||
// 2.1.1 添加评论
|
// 2.1.1 添加评论
|
||||||
|
|
@ -981,17 +950,14 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
||||||
// 相关 issue: https://github.com/flowable/flowable-engine/issues/3944
|
// 相关 issue: https://github.com/flowable/flowable-engine/issues/3944
|
||||||
// ② flowable 7.2.0 版本后,继续使用 moveActivityIdsToSingleActivityId 方法。原因:flowable 7.2.0 版本修复了该问题。
|
// ② flowable 7.2.0 版本后,继续使用 moveActivityIdsToSingleActivityId 方法。原因:flowable 7.2.0 版本修复了该问题。
|
||||||
// 相关 issue:https://github.com/YunaiV/ruoyi-vue-pro/issues/1018
|
// 相关 issue:https://github.com/YunaiV/ruoyi-vue-pro/issues/1018
|
||||||
// ③ moveActivityIdsToSingleActivityId 使用遇到问题, 相关 issue https://gitee.com/zhijiantianya/yudao-cloud/issues/IJM8MS
|
|
||||||
// 改成 moveExecutionsToSingleActivityId 好像并没有遇到 ② 提到的超时提醒失效的问题。暂时先改回 moveExecutionsToSingleActivityId
|
|
||||||
// ④ moveExecutionsToSingleActivityId 回退多实例的时候不会去删除多实例根, 应改成 moveActivityIdsToSingleActivityId
|
|
||||||
// flowable 8.0.0 修复上面相关问题, 还修复了并行分支回退的问题 https://t.zsxq.com/z4d9i。
|
|
||||||
runtimeService.createChangeActivityStateBuilder()
|
runtimeService.createChangeActivityStateBuilder()
|
||||||
.processInstanceId(currentTask.getProcessInstanceId())
|
.processInstanceId(currentTask.getProcessInstanceId())
|
||||||
.moveActivityIdsToSingleActivityId(returnTaskKeyList, reqVO.getTargetTaskDefinitionKey())
|
.moveActivityIdsToSingleActivityId(returnTaskKeyList, reqVO.getTargetTaskDefinitionKey())
|
||||||
// 设置需要预测的任务 ids 的流程变量,用于辅助预测
|
// 设置需要预测的任务 ids 的流程变量,用于辅助预测
|
||||||
.processVariable(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_NEED_SIMULATE_TASK_IDS, needSimulateTaskDefinitionKeys)
|
.processVariable(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_NEED_SIMULATE_TASK_IDS, needSimulateTaskDefinitionKeys)
|
||||||
// 设置流程变量节点退回标记, 用于退回到节点,不执行 BpmUserTaskAssignStartUserHandlerTypeEnum 策略,导致自动通过
|
// 设置流程变量(local)节点退回标记, 用于退回到节点,不执行 BpmUserTaskAssignStartUserHandlerTypeEnum 策略,导致自动通过
|
||||||
.processVariable(String.format(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_RETURN_FLAG, reqVO.getTargetTaskDefinitionKey()), Boolean.TRUE)
|
.localVariable(reqVO.getTargetTaskDefinitionKey(),
|
||||||
|
String.format(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_RETURN_FLAG, reqVO.getTargetTaskDefinitionKey()), Boolean.TRUE)
|
||||||
.changeState();
|
.changeState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1498,8 +1464,6 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 需要基于 instance 设置租户编号,避免 Flowable 内部异步执行时【例如:超时自动通过】 丢失租户编号
|
|
||||||
FlowableUtils.execute(processInstance.getTenantId(), () -> {
|
|
||||||
// 自动去重,通过自动审批的方式
|
// 自动去重,通过自动审批的方式
|
||||||
BpmProcessDefinitionInfoDO processDefinitionInfo = bpmProcessDefinitionService.getProcessDefinitionInfo(task.getProcessDefinitionId());
|
BpmProcessDefinitionInfoDO processDefinitionInfo = bpmProcessDefinitionService.getProcessDefinitionInfo(task.getProcessDefinitionId());
|
||||||
if (processDefinitionInfo == null) {
|
if (processDefinitionInfo == null) {
|
||||||
|
|
@ -1507,29 +1471,27 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (processDefinitionInfo.getAutoApprovalType() != null) {
|
if (processDefinitionInfo.getAutoApprovalType() != null) {
|
||||||
HistoricTaskInstanceQuery approvedTaskQuery = historyService.createHistoricTaskInstanceQuery()
|
HistoricTaskInstanceQuery sameAssigneeQuery = historyService.createHistoricTaskInstanceQuery()
|
||||||
.processInstanceId(task.getProcessInstanceId())
|
.processInstanceId(task.getProcessInstanceId())
|
||||||
|
.taskAssignee(task.getAssignee()) // 相同审批人
|
||||||
.taskVariableValueEquals(BpmnVariableConstants.TASK_VARIABLE_STATUS, BpmTaskStatusEnum.APPROVE.getStatus())
|
.taskVariableValueEquals(BpmnVariableConstants.TASK_VARIABLE_STATUS, BpmTaskStatusEnum.APPROVE.getStatus())
|
||||||
.finished();
|
.finished();
|
||||||
if (BpmAutoApproveTypeEnum.APPROVE_ALL.getType().equals(processDefinitionInfo.getAutoApprovalType())
|
if (BpmAutoApproveTypeEnum.APPROVE_ALL.getType().equals(processDefinitionInfo.getAutoApprovalType())
|
||||||
&& approvedTaskQuery.taskAssignee(task.getAssignee()).count() > 0) {
|
&& sameAssigneeQuery.count() > 0) {
|
||||||
getSelf().approveTask(Long.valueOf(task.getAssignee()), new BpmTaskApproveReqVO().setId(task.getId())
|
getSelf().approveTask(Long.valueOf(task.getAssignee()), new BpmTaskApproveReqVO().setId(task.getId())
|
||||||
.setReason(BpmAutoApproveTypeEnum.APPROVE_ALL.getName()));
|
.setReason(BpmAutoApproveTypeEnum.APPROVE_ALL.getName()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 连续审批的节点自动通过
|
|
||||||
if (BpmAutoApproveTypeEnum.APPROVE_SEQUENT.getType().equals(processDefinitionInfo.getAutoApprovalType())) {
|
if (BpmAutoApproveTypeEnum.APPROVE_SEQUENT.getType().equals(processDefinitionInfo.getAutoApprovalType())) {
|
||||||
BpmnModel bpmnModel = modelService.getBpmnModelByDefinitionId(processInstance.getProcessDefinitionId());
|
BpmnModel bpmnModel = modelService.getBpmnModelByDefinitionId(processInstance.getProcessDefinitionId());
|
||||||
if (bpmnModel == null) {
|
if (bpmnModel == null) {
|
||||||
log.error("[processTaskAssigned][taskId({}) 没有找到流程模型({})]", task.getId(), task.getProcessDefinitionId());
|
log.error("[processTaskAssigned][taskId({}) 没有找到流程模型({})]", task.getId(), task.getProcessDefinitionId());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
List<String> sourceTaskIds = convertList(BpmnModelUtils.getElementIncomingUserTaskFlows( // 获取所有的上一个 UserTask 节点连线
|
List<String> sourceTaskIds = convertList(BpmnModelUtils.getElementIncomingFlows( // 获取所有上一个节点
|
||||||
BpmnModelUtils.getFlowElementById(bpmnModel, task.getTaskDefinitionKey())),
|
BpmnModelUtils.getFlowElementById(bpmnModel, task.getTaskDefinitionKey())),
|
||||||
SequenceFlow::getSourceRef);
|
SequenceFlow::getSourceRef);
|
||||||
approvedTaskQuery.taskDefinitionKeys(sourceTaskIds).orderByTaskCreateTime().desc(); // 设置 taskIds, 并按创建时间倒序排序
|
if (sameAssigneeQuery.taskDefinitionKeys(sourceTaskIds).count() > 0) {
|
||||||
HistoricTaskInstance firstHisTask = CollUtil.getFirst(approvedTaskQuery.list());
|
|
||||||
if (firstHisTask != null && StrUtil.equals(firstHisTask.getAssignee(), task.getAssignee())) {
|
|
||||||
getSelf().approveTask(Long.valueOf(task.getAssignee()), new BpmTaskApproveReqVO().setId(task.getId())
|
getSelf().approveTask(Long.valueOf(task.getAssignee()), new BpmTaskApproveReqVO().setId(task.getId())
|
||||||
.setReason(BpmAutoApproveTypeEnum.APPROVE_SEQUENT.getName()));
|
.setReason(BpmAutoApproveTypeEnum.APPROVE_SEQUENT.getName()));
|
||||||
return;
|
return;
|
||||||
|
|
@ -1544,8 +1506,8 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
FlowElement userTaskElement = BpmnModelUtils.getFlowElementById(bpmnModel, task.getTaskDefinitionKey());
|
FlowElement userTaskElement = BpmnModelUtils.getFlowElementById(bpmnModel, task.getTaskDefinitionKey());
|
||||||
// 判断是否为退回或者驳回:如果是退回或者驳回不走这个策略
|
// 判断是否为退回或者驳回:如果是退回或者驳回不走这个策略(使用 local variable)
|
||||||
Boolean returnTaskFlag = runtimeService.getVariable(processInstance.getProcessInstanceId(),
|
Boolean returnTaskFlag = runtimeService.getVariableLocal(task.getExecutionId(),
|
||||||
String.format(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_RETURN_FLAG, task.getTaskDefinitionKey()), Boolean.class);
|
String.format(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_RETURN_FLAG, task.getTaskDefinitionKey()), Boolean.class);
|
||||||
Boolean skipStartUserNodeFlag = Convert.toBool(runtimeService.getVariable(processInstance.getProcessInstanceId(),
|
Boolean skipStartUserNodeFlag = Convert.toBool(runtimeService.getVariable(processInstance.getProcessInstanceId(),
|
||||||
BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_SKIP_START_USER_NODE, String.class));
|
BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_SKIP_START_USER_NODE, String.class));
|
||||||
|
|
@ -1595,8 +1557,8 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 注意:需要基于 instance 设置租户编号,避免 Flowable 内部异步时,丢失租户编号
|
||||||
// 发送消息
|
FlowableUtils.execute(processInstance.getTenantId(), () -> {
|
||||||
AdminUserRespDTO startUser = adminUserApi.getUser(Long.valueOf(processInstance.getStartUserId())).getCheckedData();
|
AdminUserRespDTO startUser = adminUserApi.getUser(Long.valueOf(processInstance.getStartUserId())).getCheckedData();
|
||||||
messageService.sendMessageWhenTaskAssigned(BpmTaskConvert.INSTANCE.convert(processInstance, startUser, task));
|
messageService.sendMessageWhenTaskAssigned(BpmTaskConvert.INSTANCE.convert(processInstance, startUser, task));
|
||||||
});
|
});
|
||||||
|
|
|
||||||