Merge branch 'master' of https://gitee.com/zhijiantianya/ruoyi-vue-pro into feature/notify

# Conflicts:
#	sql/mysql/ruoyi-vue-pro.sql
#	yudao-ui-admin/src/utils/dict.js
plp
YunaiV 3 years ago
commit 143035d798

@ -1,6 +1,4 @@
**严肃声明:现在、未来都不会有商业版本,所有功能全部开源!** **严肃声明:现在、未来都不会有商业版本,所有代码全部开源!**
**拒绝虚假开源,售卖商业版,程序员不骗程序员!!**
**「我喜欢写代码,乐此不疲」** **「我喜欢写代码,乐此不疲」**
**「我喜欢做开源,以此为乐」** **「我喜欢做开源,以此为乐」**
@ -23,9 +21,11 @@
> >
> 😜 给项目点点 Star 吧,这对我们真的很重要! > 😜 给项目点点 Star 吧,这对我们真的很重要!
![架构图](https://static.iocoder.cn/ruoyi-vue-pro-architecture.png)
* 管理后台的 Vue3 版本采用 [vue-element-plus-admin](https://gitee.com/kailong110120130/vue-element-plus-admin) Vue2 版本采用 [vue-element-admin](https://github.com/PanJiaChen/vue-element-admin) * 管理后台的 Vue3 版本采用 [vue-element-plus-admin](https://gitee.com/kailong110120130/vue-element-plus-admin) Vue2 版本采用 [vue-element-admin](https://github.com/PanJiaChen/vue-element-admin)
* 管理后台的移动端采用 [uni-app](https://github.com/dcloudio/uni-app) 方案,一份代码多终端适配,同时支持 APP、小程序、H5 * 管理后台的移动端采用 [uni-app](https://github.com/dcloudio/uni-app) 方案,一份代码多终端适配,同时支持 APP、小程序、H5
* 后端采用 Spring Boot、MySQL + MyBatis Plus、Redis + Redisson * 后端采用 Spring Boot 多模块架构、MySQL + MyBatis Plus、Redis + Redisson
* 数据库可使用 MySQL、Oracle、PostgreSQL、SQL Server、MariaDB、国产达梦 DM、TiDB 等 * 数据库可使用 MySQL、Oracle、PostgreSQL、SQL Server、MariaDB、国产达梦 DM、TiDB 等
* 权限认证使用 Spring Security & Token & Redis支持多终端、多种用户的认证系统支持 SSO 单点登录 * 权限认证使用 Spring Security & Token & Redis支持多终端、多种用户的认证系统支持 SSO 单点登录
* 支持加载动态权限菜单,按钮级别权限控制,本地缓存提升性能 * 支持加载动态权限菜单,按钮级别权限控制,本地缓存提升性能
@ -33,25 +33,42 @@
* 工作流使用 Flowable支持动态表单、在线设计流程、会签 / 或签、多种任务分配方式 * 工作流使用 Flowable支持动态表单、在线设计流程、会签 / 或签、多种任务分配方式
* 高效率开发,使用代码生成器可以一键生成前后端代码 + 单元测试 + Swagger 接口文档 + Validator 参数校验 * 高效率开发,使用代码生成器可以一键生成前后端代码 + 单元测试 + Swagger 接口文档 + Validator 参数校验
* 集成微信小程序、微信公众号、企业微信、钉钉等三方登陆,集成支付宝、微信等支付与退款 * 集成微信小程序、微信公众号、企业微信、钉钉等三方登陆,集成支付宝、微信等支付与退款
* 集成阿里云、腾讯云、云片等短信渠道,集成 MinIO、阿里云、腾讯云、七牛云等云存储服务 * 集成阿里云、腾讯云等短信渠道,集成 MinIO、阿里云、腾讯云、七牛云等云存储服务
* 集成报表设计器,支持数据报表、图形报表、打印设计等 * 集成报表设计器,支持数据报表、图形报表、打印设计等
| 项目名 | 说明 | 传说门 | | 项目名 | 说明 | 传送门 |
|--------------------|------------------------|-------------------------------------------------------------------------------------------------------------------------------------| |----------------------|------------------------|-------------------------------------------------------------------------------------------------------------------------------------|
| `ruoyi-vue-pro` | Spring Boot 多模块 | **[Gitee](https://gitee.com/zhijiantianya/ruoyi-vue-pro)**     [Github](https://github.com/YunaiV/ruoyi-vue-pro) | | `ruoyi-vue-pro` | Spring Boot 多模块 | **[Gitee](https://gitee.com/zhijiantianya/ruoyi-vue-pro)**     [Github](https://github.com/YunaiV/ruoyi-vue-pro) |
| `yudao-cloud` | Spring Cloud 微服务 | **[Gitee](https://gitee.com/zhijiantianya/yudao-cloud)**     [Github](https://github.com/YunaiV/yudao-cloud) | | `yudao-cloud` | Spring Cloud 微服务 | **[Gitee](https://gitee.com/zhijiantianya/yudao-cloud)**     [Github](https://github.com/YunaiV/yudao-cloud) |
| `Spring-Boot-Labs` | Spring Boot & Cloud 入门 | **[Gitee](https://gitee.com/zhijiantianya/SpringBoot-Labs)**     [Github](https://github.com/YunaiV/SpringBoot-Labs) | | `Spring-Boot-Labs` | Spring Boot & Cloud 入门 | **[Gitee](https://gitee.com/zhijiantianya/SpringBoot-Labs)**     [Github](https://github.com/YunaiV/SpringBoot-Labs) |
| `ruoyi-vue-pro-mini` | 精简版:移除工作流、支付等模块 | **[Gitee](https://gitee.com/zhijiantianya/ruoyi-vue-pro/tree/mini)** |
## 😎 开源协议
**为什么推荐使用本项目?**
① 本项目采用比 Apache 2.0 更宽松的 [MIT License](https://gitee.com/zhijiantianya/ruoyi-vue-pro/blob/master/LICENSE) 开源协议,个人与企业可 100% 免费使用不用保留类作者、Copyright 信息。
② 代码全部开源,不会像其他项目一样,只开源部分代码,让你无法了解整个项目的架构设计。[国产开源项目对比](https://www.yuque.com/xiatian-bsgny/lm0ec1/wqf8mn)
![开源项目对比](https://static.iocoder.cn/project-vs.png?imageView2/2/format/webp/w/1280)
③ 代码整洁、架构整洁,遵循《阿里巴巴 Java 开发手册》规范代码注释详细57000 行 Java 代码22000 行代码注释。
## 🐼 内置功能 ## 🐼 内置功能
分成多种内置功能: 系统内置多种多种业务功能,可以用于快速你的业务系统:
![功能分层](https://static.iocoder.cn/ruoyi-vue-pro-biz.png)
* 系统功能 * 系统功能
* 基础设施 * 基础设施
* 工作流程 * 工作流程
* 支付系统 * 支付系统
* 商城系统 * 会员中心
* 数据报表 * 数据报表
* 商城系统
* 微信公众号
> 友情提示:本项目基于 RuoYi-Vue 修改,**重构优化**后端的代码,**美化**前端的界面。 > 友情提示:本项目基于 RuoYi-Vue 修改,**重构优化**后端的代码,**美化**前端的界面。
> >
@ -73,13 +90,15 @@
| 🚀 | 租户管理 | 配置系统租户,支持 SaaS 场景下的多租户功能 | | 🚀 | 租户管理 | 配置系统租户,支持 SaaS 场景下的多租户功能 |
| 🚀 | 租户套餐 | 配置租户套餐,自定每个租户的菜单、操作、按钮的权限 | | 🚀 | 租户套餐 | 配置租户套餐,自定每个租户的菜单、操作、按钮的权限 |
| | 字典管理 | 对系统中经常使用的一些较为固定的数据进行维护 | | | 字典管理 | 对系统中经常使用的一些较为固定的数据进行维护 |
| 🚀 | 短信管理 | 短信渠道、短息模板、短信日志,对接阿里云、云片等主流短信平台 | | 🚀 | 短信管理 | 短信渠道、短息模板、短信日志,对接阿里云、腾讯云等主流短信平台 |
| 🚀 | 邮件管理 | 邮箱账号、邮件模版、邮件发送日志,支持所有邮件平台 |
| 🚀 | 操作日志 | 系统正常操作日志记录和查询,集成 Swagger 生成日志内容 | | 🚀 | 操作日志 | 系统正常操作日志记录和查询,集成 Swagger 生成日志内容 |
| ⭐️ | 登录日志 | 系统登录日志记录查询,包含登录异常 | | ⭐️ | 登录日志 | 系统登录日志记录查询,包含登录异常 |
| 🚀 | 错误码管理 | 系统所有错误码的管理,可在线修改错误提示,无需重启服务 | | 🚀 | 错误码管理 | 系统所有错误码的管理,可在线修改错误提示,无需重启服务 |
| | 通知公告 | 系统通知公告信息发布维护 | | | 通知公告 | 系统通知公告信息发布维护 |
| 🚀 | 敏感词 | 配置系统敏感词,支持标签分组 | | 🚀 | 敏感词 | 配置系统敏感词,支持标签分组 |
| 🚀 | 应用管理 | 管理 SSO 单点登录的应用,支持多种 OAuth2 授权方式 | | 🚀 | 应用管理 | 管理 SSO 单点登录的应用,支持多种 OAuth2 授权方式 |
| 🚀 | 地区管理 | 展示省份、城市、区镇等城市信息,支持 IP 对应城市 |
### 工作流程 ### 工作流程
@ -114,7 +133,7 @@ ps核心功能已经实现正在对接微信小程序中...
| | 表单构建 | 拖动表单元素生成相应的 HTML 代码,支持导出 JSON、Vue 文件 | | | 表单构建 | 拖动表单元素生成相应的 HTML 代码,支持导出 JSON、Vue 文件 |
| 🚀 | 配置管理 | 对系统动态配置常用参数,支持 SpringBoot 加载 | | 🚀 | 配置管理 | 对系统动态配置常用参数,支持 SpringBoot 加载 |
| ⭐️ | 定时任务 | 在线(添加、修改、删除)任务调度包含执行结果日志 | | ⭐️ | 定时任务 | 在线(添加、修改、删除)任务调度包含执行结果日志 |
| 🚀 | 文件服务 | 支持将文件存储到 S3MinIO、阿里云、腾讯云、七牛云、本地、FTP、数据库等 | | 🚀 | 文件服务 | 支持将文件存储到 S3MinIO、阿里云、腾讯云、七牛云、本地、FTP、数据库等 |
| 🚀 | API 日志 | 包括 RESTful API 访问日志、异常日志两部分,方便排查 API 相关的问题 | | 🚀 | API 日志 | 包括 RESTful API 访问日志、异常日志两部分,方便排查 API 相关的问题 |
| | MySQL 监控 | 监视当前系统数据库连接池状态可进行分析SQL找出系统性能瓶颈 | | | MySQL 监控 | 监视当前系统数据库连接池状态可进行分析SQL找出系统性能瓶颈 |
| | Redis 监控 | 监控 Redis 数据库的使用情况,使用的 Redis Key 管理 | | | Redis 监控 | 监控 Redis 数据库的使用情况,使用的 Redis Key 管理 |
@ -135,6 +154,21 @@ ps核心功能已经实现正在对接微信小程序中...
| 🚀 | 报表设计器 | 支持数据报表、图形报表、打印设计等 | | 🚀 | 报表设计器 | 支持数据报表、图形报表、打印设计等 |
| 🚀 | 大屏设计器 | 建设中... 拖拽式实现可视化数据大屏 | | 🚀 | 大屏设计器 | 建设中... 拖拽式实现可视化数据大屏 |
### 微信公众号
| | 功能 | 描述 |
|-----|--------|-------------------------------|
| 🚀 | 账号管理 | 配置接入的微信公众号,可支持多个公众号 |
| 🚀 | 数据统计 | 统计公众号的用户增减、累计用户、消息概况、接口分析等数据 |
| 🚀 | 粉丝管理 | 查看已关注、取关的粉丝列表,可对粉丝进行同步、打标签等操作 |
| 🚀 | 消息管理 | 查看粉丝发送的消息列表,可主动回复粉丝消息 |
| 🚀 | 自动回复 | 自动回复粉丝发送的消息,支持关注回复、消息回复、关键字回复 |
| 🚀 | 标签管理 | 对公众号的标签进行创建、查询、修改、删除等操作 |
| 🚀 | 菜单管理 | 自定义公众号的菜单,也可以从公众号同步菜单 |
| 🚀 | 素材管理 | 管理公众号的图片、语音、视频等素材,支持在线播放语音、视频 |
| 🚀 | 图文草稿箱 | 新增常用的图文素材到草稿箱,可发布到公众号 |
| 🚀 | 图文发表记录 | 查看已发布成功的图文素材,支持删除操作 |
### 商城系统 ### 商城系统
建设中... 建设中...
@ -151,89 +185,90 @@ ps核心功能已经实现正在对接微信小程序中...
## 🐨 技术栈 ## 🐨 技术栈
| 项目 | 说明 | | 项目 | 说明 |
|-----------------------|--------------------| |------------------------------|--------------------|
| `yudao-dependencies` | Maven 依赖版本管理 | | `yudao-dependencies` | Maven 依赖版本管理 |
| `yudao-framework` | Java 框架拓展 | | `yudao-framework` | Java 框架拓展 |
| `yudao-server` | 管理后台 + 用户 APP 的服务端 | | `yudao-server` | 管理后台 + 用户 APP 的服务端 |
| `yudao-ui-admin` | 管理后台的 Vue2 前端项目 | | `yudao-ui-admin` | 管理后台的 Vue2 前端项目 |
| `yudao-ui-admin-vue3` | 管理后台的 Vue3 前端项目 | | `yudao-ui-admin-vue3` | 管理后台的 Vue3 前端项目 |
| `yudao-ui-admin-uniapp` | 管理后台的 uni-app 多端项目 | | `yudao-ui-admin-uniapp` | 管理后台的 uni-app 多端项目 |
| `yudao-ui-app` | 用户 APP 的 UI 界面 | | `yudao-ui-app` | 用户 APP 的 UI 界面 |
| `yudao-module-system` | 系统功能的 Module 模块 | | `yudao-module-system` | 系统功能的 Module 模块 |
| `yudao-module-member` | 会员中心的 Module 模块 | | `yudao-module-member` | 会员中心的 Module 模块 |
| `yudao-module-infra` | 基础设施的 Module 模块 | | `yudao-module-infra` | 基础设施的 Module 模块 |
| `yudao-module-tool` | 研发工具的 Module 模块 | | `yudao-module-bpm` | 工作流程的 Module 模块 |
| `yudao-module-bpm` | 工作流程的 Module 模块 | | `yudao-module-pay` | 支付系统的 Module 模块 |
| `yudao-module-pay` | 支付系统的 Module 模块 | | `yudao-module-mall` | 商城系统的 Module 模块 |
| `yudao-module-mp` | 微信公众号的 Module 模块 |
| `yudao-module-visualization` | 大屏报表 Module 模块 |
### 后端 ### 后端
| 框架 | 说明 | 版本 | 学习指南 | | 框架 | 说明 | 版本 | 学习指南 |
|---------------------------------------------------------------------------------------------|-----------------------|-----------|----------------------------------------------------------------| |---------------------------------------------------------------------------------------------|------------------|-------------|----------------------------------------------------------------|
| [Spring Boot](https://spring.io/projects/spring-boot) | 应用开发框架 | 2.6.10 | [文档](https://github.com/YunaiV/SpringBoot-Labs) | | [Spring Boot](https://spring.io/projects/spring-boot) | 应用开发框架 | 2.7.7 | [文档](https://github.com/YunaiV/SpringBoot-Labs) |
| [MySQL](https://www.mysql.com/cn/) | 数据库服务器 | 5.7 | | | [MySQL](https://www.mysql.com/cn/) | 数据库服务器 | 5.7 / 8.0+ | |
| [Druid](https://github.com/alibaba/druid) | JDBC 连接池、监控组件 | 1.2.11 | [文档](http://www.iocoder.cn/Spring-Boot/datasource-pool/?yudao) | | [Druid](https://github.com/alibaba/druid) | JDBC 连接池、监控组件 | 1.2.15 | [文档](http://www.iocoder.cn/Spring-Boot/datasource-pool/?yudao) |
| [MyBatis Plus](https://mp.baomidou.com/) | MyBatis 增强工具包 | 3.5.2 | [文档](http://www.iocoder.cn/Spring-Boot/MyBatis/?yudao) | | [MyBatis Plus](https://mp.baomidou.com/) | MyBatis 增强工具包 | 3.5.3.1 | [文档](http://www.iocoder.cn/Spring-Boot/MyBatis/?yudao) |
| [Dynamic Datasource](https://dynamic-datasource.com/) | 动态数据源 | 3.5.0 | [文档](http://www.iocoder.cn/Spring-Boot/datasource-pool/?yudao) | | [Dynamic Datasource](https://dynamic-datasource.com/) | 动态数据源 | 3.6.1 | [文档](http://www.iocoder.cn/Spring-Boot/datasource-pool/?yudao) |
| [Redis](https://redis.io/) | key-value 数据库 | 5.0 | | | [Redis](https://redis.io/) | key-value 数据库 | 5.0 / 6.0 | |
| [Redisson](https://github.com/redisson/redisson) | Redis 客户端 | 3.17.4 | [文档](http://www.iocoder.cn/Spring-Boot/Redis/?yudao) | | [Redisson](https://github.com/redisson/redisson) | Redis 客户端 | 3.18.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.20 | [文档](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.6.5 | [文档](http://www.iocoder.cn/Spring-Boot/Spring-Security/?yudao) | | [Spring Security](https://github.com/spring-projects/spring-security) | Spring 安全框架 | 5.7.6 | [文档](http://www.iocoder.cn/Spring-Boot/Spring-Security/?yudao) |
| [Hibernate Validator](https://github.com/hibernate/hibernate-validator) | 参数校验组件 | 6.2.3 | [文档](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.7.0 | [文档](https://doc.iocoder.cn/bpm/) | | [Flowable](https://github.com/flowable/flowable-engine) | 工作流引擎 | 6.8.0 | [文档](https://doc.iocoder.cn/bpm/) |
| [Quartz](https://github.com/quartz-scheduler) | 任务调度组件 | 2.3.2 | [文档](http://www.iocoder.cn/Spring-Boot/Job/?yudao) | | [Quartz](https://github.com/quartz-scheduler) | 任务调度组件 | 2.3.2 | [文档](http://www.iocoder.cn/Spring-Boot/Job/?yudao) |
| [Knife4j](https://gitee.com/xiaoym/knife4j) | Swagger 增强 UI 实现 | 3.0.3 | [文档](http://www.iocoder.cn/Spring-Boot/Swagger/?yudao) | | [Knife4j](https://gitee.com/xiaoym/knife4j) | Swagger 增强 UI 实现 | 3.0.3 | [文档](http://www.iocoder.cn/Spring-Boot/Swagger/?yudao) |
| [Resilience4j](https://github.com/resilience4j/resilience4j) | 服务保障组件 | 1.7.1 | [文档](http://www.iocoder.cn/Spring-Boot/Resilience4j/?yudao) | | [Resilience4j](https://github.com/resilience4j/resilience4j) | 服务保障组件 | 1.7.1 | [文档](http://www.iocoder.cn/Spring-Boot/Resilience4j/?yudao) |
| [SkyWalking](https://skywalking.apache.org/) | 分布式应用追踪系统 | 8.5.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.6.7 | [文档](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.3 | | | [Jackson](https://github.com/FasterXML/jackson) | JSON 工具库 | 2.13.3 | |
| [MapStruct](https://mapstruct.org/) | Java Bean 转换 | 1.4.1 | [文档](http://www.iocoder.cn/Spring-Boot/MapStruct/?yudao) | | [MapStruct](https://mapstruct.org/) | Java Bean 转换 | 1.5.3.Final | [文档](http://www.iocoder.cn/Spring-Boot/MapStruct/?yudao) |
| [Lombok](https://projectlombok.org/) | 消除冗长的 Java 代码 | 1.16.14 | [文档](http://www.iocoder.cn/Spring-Boot/Lombok/?yudao) | | [Lombok](https://projectlombok.org/) | 消除冗长的 Java 代码 | 1.18.24 | [文档](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.0.0 | - | | [Mockito](https://github.com/mockito/mockito) | Java Mock 框架 | 4.8.0 | - |
### [管理后台 Vue2 前端](./yudao-ui-admin) ### [管理后台 Vue2 前端](./yudao-ui-admin)
| 框架 | 说明 | 版本 | | 框架 | 说明 | 版本 |
|------------------------------------------------------------------------------|---------------|--------| |------------------------------------------------------------------------------|---------------|--------|
| [Vue](https://cn.vuejs.org/index.html) | JavaScript 框架 | 2.6.12 | | [Vue](https://cn.vuejs.org/index.html) | JavaScript 框架 | 2.7.14 |
| [Vue Element Admin](https://panjiachen.github.io/vue-element-admin-site/zh/) | 后台前端解决方案 | - | | [Vue Element Admin](https://panjiachen.github.io/vue-element-admin-site/zh/) | 后台前端解决方案 | - |
### [管理后台 Vue3 前端](./yudao-ui-admin-vue3) ### [管理后台 Vue3 前端](./yudao-ui-admin-vue3)
| 框架 | 说明 | 版本 | | 框架 | 说明 | 版本 |
|----------------------------------------------------------------------|------------------|--------| |----------------------------------------------------------------------|:------------:|:------:|
| [Vue](https://staging-cn.vuejs.org/) | Vue 框架 | 3.2.37 | | [Vue](https://staging-cn.vuejs.org/) | Vue 框架 | 3.2.45 |
| [Vite](https://cn.vitejs.dev//) | 开发与构建工具 | 3.0.4 | | [Vite](https://cn.vitejs.dev//) | 开发与构建工具 | 4.0.4 |
| [Element Plus](https://element-plus.org/zh-CN/) | Element Plus | 2.2.12 | | [Element Plus](https://element-plus.org/zh-CN/) | Element Plus | 2.2.28 |
| [TypeScript](https://www.typescriptlang.org/docs/) | TypeScript | 4.7.4 | | [TypeScript](https://www.typescriptlang.org/docs/) | TypeScript | 4.9.4 |
| [pinia](https://pinia.vuejs.org/) | Vue 存储库 替代 vuex5 | 2.0.17 | | [pinia](https://pinia.vuejs.org/) | vuex5 | 2.0.28 |
| [vue-i18n](https://kazupon.github.io/vue-i18n/zh/introduction.html/) | 国际化 | 9.2.0 | | [vue-i18n](https://kazupon.github.io/vue-i18n/zh/introduction.html/) | 国际化 | 9.2.2 |
| [windicss](https://cn.windicss.org/) | 下一代工具优先的 CSS 框架 | 3.5.6 | | [vxe-table](https://vxetable.cn/) | vue最强表单 | 4.3.9 |
| [iconify](https://icon-sets.iconify.design/) | 在线图标库 | 2.2.1 |
### [管理后台 uni-app 跨端](./yudao-ui-admin-uniapp) ### [管理后台 uni-app 跨端](./yudao-ui-admin-uniapp)
| 框架 | 说明 | 版本 | | 框架 | 说明 | 版本 |
|----------------------------------------------------------------------|------------------|--------| |-------------------------------------------------|--------------------|--------|
| [uni-app](hhttps://github.com/dcloudio/uni-app) | 跨平台框架 | 2.0.0 | | [uni-app](hhttps://github.com/dcloudio/uni-app) | 跨平台框架 | 2.0.0 |
| [uni-ui](https://github.com/dcloudio/uni-ui) | 基于 uni-app 的 UI 框架 | 1.4.20 | | [uni-ui](https://github.com/dcloudio/uni-ui) | 基于 uni-app 的 UI 框架 | 1.4.20 |
## 🐷 演示图 ## 🐷 演示图
### 系统功能 ### 系统功能
| 模块 | biu | biu | biu | | 模块 | biu | biu | biu |
|----------|--------------------------------------------------------------------|------------------------------------------------------------------|------------------------------------------------------------------| |------------|--------------------------------------------------------------------|------------------------------------------------------------------|------------------------------------------------------------------|
| 登录 & 首页 | ![登录](https://static.iocoder.cn/images/ruoyi-vue-pro/登录.jpg?imageView2/2/format/webp/w/1280) | ![首页](https://static.iocoder.cn/images/ruoyi-vue-pro/首页.jpg?imageView2/2/format/webp/w/1280) | ![个人中心](https://static.iocoder.cn/images/ruoyi-vue-pro/个人中心.jpg?imageView2/2/format/webp/w/1280) | | 登录 & 首页 | ![登录](https://static.iocoder.cn/images/ruoyi-vue-pro/登录.jpg?imageView2/2/format/webp/w/1280) | ![首页](https://static.iocoder.cn/images/ruoyi-vue-pro/首页.jpg?imageView2/2/format/webp/w/1280) | ![个人中心](https://static.iocoder.cn/images/ruoyi-vue-pro/个人中心.jpg?imageView2/2/format/webp/w/1280) |
| 用户 & 应用 | ![用户管理](https://static.iocoder.cn/images/ruoyi-vue-pro/用户管理.jpg?imageView2/2/format/webp/w/1280) | ![令牌管理](https://static.iocoder.cn/images/ruoyi-vue-pro/令牌管理.jpg?imageView2/2/format/webp/w/1280) | ![应用管理](https://static.iocoder.cn/images/ruoyi-vue-pro/应用管理.jpg?imageView2/2/format/webp/w/1280) | | 用户 & 应用 | ![用户管理](https://static.iocoder.cn/images/ruoyi-vue-pro/用户管理.jpg?imageView2/2/format/webp/w/1280) | ![令牌管理](https://static.iocoder.cn/images/ruoyi-vue-pro/令牌管理.jpg?imageView2/2/format/webp/w/1280) | ![应用管理](https://static.iocoder.cn/images/ruoyi-vue-pro/应用管理.jpg?imageView2/2/format/webp/w/1280) |
| 租户 & 套餐 | ![租户管理](https://static.iocoder.cn/images/ruoyi-vue-pro/租户管理.jpg?imageView2/2/format/webp/w/1280) | ![租户套餐](https://static.iocoder.cn/images/ruoyi-vue-pro/租户套餐.png) | - | | 租户 & 套餐 | ![租户管理](https://static.iocoder.cn/images/ruoyi-vue-pro/租户管理.jpg?imageView2/2/format/webp/w/1280) | ![租户套餐](https://static.iocoder.cn/images/ruoyi-vue-pro/租户套餐.png) | - |
| 部门 & 岗位 | ![部门管理](https://static.iocoder.cn/images/ruoyi-vue-pro/部门管理.jpg?imageView2/2/format/webp/w/1280) | ![岗位管理](https://static.iocoder.cn/images/ruoyi-vue-pro/岗位管理.jpg?imageView2/2/format/webp/w/1280) | - | | 部门 & 岗位 | ![部门管理](https://static.iocoder.cn/images/ruoyi-vue-pro/部门管理.jpg?imageView2/2/format/webp/w/1280) | ![岗位管理](https://static.iocoder.cn/images/ruoyi-vue-pro/岗位管理.jpg?imageView2/2/format/webp/w/1280) | - |
| 菜单 & 角色 | ![菜单管理](https://static.iocoder.cn/images/ruoyi-vue-pro/菜单管理.jpg?imageView2/2/format/webp/w/1280) | ![角色管理](https://static.iocoder.cn/images/ruoyi-vue-pro/角色管理.jpg?imageView2/2/format/webp/w/1280) | - | | 菜单 & 角色 | ![菜单管理](https://static.iocoder.cn/images/ruoyi-vue-pro/菜单管理.jpg?imageView2/2/format/webp/w/1280) | ![角色管理](https://static.iocoder.cn/images/ruoyi-vue-pro/角色管理.jpg?imageView2/2/format/webp/w/1280) | - |
| 审计日志 | ![操作日志](https://static.iocoder.cn/images/ruoyi-vue-pro/操作日志.jpg?imageView2/2/format/webp/w/1280) | ![登录日志](https://static.iocoder.cn/images/ruoyi-vue-pro/登录日志.jpg?imageView2/2/format/webp/w/1280) | - | | 审计日志 | ![操作日志](https://static.iocoder.cn/images/ruoyi-vue-pro/操作日志.jpg?imageView2/2/format/webp/w/1280) | ![登录日志](https://static.iocoder.cn/images/ruoyi-vue-pro/登录日志.jpg?imageView2/2/format/webp/w/1280) | - |
| 短信 | ![短信渠道](https://static.iocoder.cn/images/ruoyi-vue-pro/短信渠道.jpg?imageView2/2/format/webp/w/1280) | ![短信模板](https://static.iocoder.cn/images/ruoyi-vue-pro/短信模板.jpg?imageView2/2/format/webp/w/1280) | ![短信日志](https://static.iocoder.cn/images/ruoyi-vue-pro/短信日志.jpg?imageView2/2/format/webp/w/1280) | | 短信 | ![短信渠道](https://static.iocoder.cn/images/ruoyi-vue-pro/短信渠道.jpg?imageView2/2/format/webp/w/1280) | ![短信模板](https://static.iocoder.cn/images/ruoyi-vue-pro/短信模板.jpg?imageView2/2/format/webp/w/1280) | ![短信日志](https://static.iocoder.cn/images/ruoyi-vue-pro/短信日志.jpg?imageView2/2/format/webp/w/1280) |
| 字典 & 敏感词 | ![字典类型](https://static.iocoder.cn/images/ruoyi-vue-pro/字典类型.jpg?imageView2/2/format/webp/w/1280) | ![字典数据](https://static.iocoder.cn/images/ruoyi-vue-pro/字典数据.jpg?imageView2/2/format/webp/w/1280) | ![敏感词](https://static.iocoder.cn/images/ruoyi-vue-pro/敏感词.jpg?imageView2/2/format/webp/w/1280) | | 字典 & 敏感词 | ![字典类型](https://static.iocoder.cn/images/ruoyi-vue-pro/字典类型.jpg?imageView2/2/format/webp/w/1280) | ![字典数据](https://static.iocoder.cn/images/ruoyi-vue-pro/字典数据.jpg?imageView2/2/format/webp/w/1280) | ![敏感词](https://static.iocoder.cn/images/ruoyi-vue-pro/敏感词.jpg?imageView2/2/format/webp/w/1280) |
| 错误码 & 通知 | ![错误码管理](https://static.iocoder.cn/images/ruoyi-vue-pro/错误码管理.jpg?imageView2/2/format/webp/w/1280) | ![通知公告](https://static.iocoder.cn/images/ruoyi-vue-pro/通知公告.jpg?imageView2/2/format/webp/w/1280) | - | | 错误码 & 通知 | ![错误码管理](https://static.iocoder.cn/images/ruoyi-vue-pro/错误码管理.jpg?imageView2/2/format/webp/w/1280) | ![通知公告](https://static.iocoder.cn/images/ruoyi-vue-pro/通知公告.jpg?imageView2/2/format/webp/w/1280) | - |
### 工作流程 ### 工作流程

@ -5,7 +5,7 @@
"adminTenentId": "1", "adminTenentId": "1",
"appApi": "http://127.0.0.1:48080/app-api", "appApi": "http://127.0.0.1:48080/app-api",
"appToken": "test1", "appToken": "test247",
"appTenentId": "1" "appTenentId": "1"
}, },
"gateway": { "gateway": {
@ -15,6 +15,6 @@
"appApi": "http://127.0.0.1:8888/app-api", "appApi": "http://127.0.0.1:8888/app-api",
"appToken": "test1", "appToken": "test1",
"appTenentId": "1" "appTenantId": "1"
} }
} }

@ -12,14 +12,17 @@
<module>yudao-framework</module> <module>yudao-framework</module>
<!-- Server 主项目 --> <!-- Server 主项目 -->
<module>yudao-server</module> <module>yudao-server</module>
<!-- 各种 module 拓展 --> <!-- 各种 module 拓展 -->
<module>yudao-module-member</module> <module>yudao-module-member</module>
<module>yudao-module-bpm</module>
<module>yudao-module-system</module> <module>yudao-module-system</module>
<module>yudao-module-infra</module> <module>yudao-module-infra</module>
<module>yudao-module-pay</module> <module>yudao-module-pay</module>
<module>yudao-module-mall</module> <!-- <module>yudao-module-bpm</module>-->
<module>yudao-module-visualization</module> <!-- <module>yudao-module-visualization</module>-->
<!-- <module>yudao-module-mp</module>-->
<!-- <module>yudao-module-mall</module>-->
<!-- 示例项目 -->
<module>yudao-example</module>
</modules> </modules>
<name>${project.artifactId}</name> <name>${project.artifactId}</name>
@ -27,16 +30,17 @@
<url>https://github.com/YunaiV/ruoyi-vue-pro</url> <url>https://github.com/YunaiV/ruoyi-vue-pro</url>
<properties> <properties>
<revision>1.6.3-snapshot</revision> <revision>1.6.6-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>
<maven.compiler.target>${java.version}</maven.compiler.target> <maven.compiler.target>${java.version}</maven.compiler.target>
<maven-surefire-plugin.version>3.0.0-M5</maven-surefire-plugin.version> <maven-surefire-plugin.version>3.0.0-M5</maven-surefire-plugin.version>
<maven-compiler-plugin.version>3.8.0</maven-compiler-plugin.version> <maven-compiler-plugin.version>3.8.1</maven-compiler-plugin.version>
<!-- 看看咋放到 bom 里 --> <!-- 看看咋放到 bom 里 -->
<lombok.version>1.18.20</lombok.version> <lombok.version>1.18.24</lombok.version>
<mapstruct.version>1.4.1.Final</mapstruct.version> <spring.boot.version>2.7.7</spring.boot.version>
<mapstruct.version>1.5.3.Final</mapstruct.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties> </properties>
@ -62,13 +66,19 @@
<artifactId>maven-surefire-plugin</artifactId> <artifactId>maven-surefire-plugin</artifactId>
<version>${maven-surefire-plugin.version}</version> <version>${maven-surefire-plugin.version}</version>
</plugin> </plugin>
<!-- maven-compiler-plugin 插件,解决 Lombok + MapStruct 组合 --> <!-- maven-compiler-plugin 插件,解决 spring-boot-configuration-processor + Lombok + MapStruct 组合 -->
<!-- https://stackoverflow.com/questions/33483697/re-run-spring-boot-configuration-annotation-processor-to-update-generated-metada -->
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId> <artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version> <version>${maven-compiler-plugin.version}</version>
<configuration> <configuration>
<annotationProcessorPaths> <annotationProcessorPaths>
<path>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<version>${spring.boot.version}</version>
</path>
<path> <path>
<groupId>org.projectlombok</groupId> <groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId> <artifactId>lombok</artifactId>

@ -418,17 +418,19 @@ CREATE TABLE `jimu_report_data_source` (
`update_by` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '', `update_by` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '',
`update_time` datetime NULL DEFAULT NULL COMMENT '', `update_time` datetime NULL DEFAULT NULL COMMENT '',
`connect_times` int(1) UNSIGNED NULL DEFAULT 0 COMMENT '', `connect_times` int(1) UNSIGNED NULL DEFAULT 0 COMMENT '',
`tenant_id` varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '',
`type` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '(report:;drag:)',
PRIMARY KEY (`id`) USING BTREE, PRIMARY KEY (`id`) USING BTREE,
INDEX `idx_jmdatasource_report_id`(`report_id`) USING BTREE, INDEX `idx_jmdatasource_report_id`(`report_id`) USING BTREE,
INDEX `idx_jmdatasource_code`(`code`) USING BTREE INDEX `idx_jmdatasource_code`(`code`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = DYNAMIC;
-- ---------------------------- -- ----------------------------
-- Records of jimu_report_data_source -- Records of jimu_report_data_source
-- ---------------------------- -- ----------------------------
INSERT INTO `jimu_report_data_source` VALUES ('1324261983692902402', 'jeewx', '1324261770294071296', '', NULL, 'MYSQL', 'com.mysql.jdbc.Driver', 'jdbc:mysql://127.0.0.1:3306/jeewx-boot?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8', 'root', 'root', 'jeecg', '2020-11-05 16:07:15', NULL, '2020-11-05 16:07:15', 0); INSERT INTO `jimu_report_data_source` VALUES ('1324261983692902402', 'jeewx', '1324261770294071296', '', NULL, 'MYSQL', 'com.mysql.jdbc.Driver', 'jdbc:mysql://127.0.0.1:3306/jeewx-boot?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8', 'root', 'root', 'jeecg', '2020-11-05 16:07:15', NULL, '2020-11-05 16:07:15', 0, NULL, 'report');
INSERT INTO `jimu_report_data_source` VALUES ('26d21fe4f27920d2f56abc8d90a8e527', 'oracle', '1308645288868712448', '', NULL, 'ORACLE', 'oracle.jdbc.OracleDriver', 'jdbc:oracle:thin:@192.168.1.199:1521:helowin', 'jeecgbootbpm', 'jeecg196283', 'admin', '2021-01-05 19:26:24', NULL, '2021-01-05 19:26:24', 1); INSERT INTO `jimu_report_data_source` VALUES ('26d21fe4f27920d2f56abc8d90a8e527', 'oracle', '1308645288868712448', '', NULL, 'ORACLE', 'oracle.jdbc.OracleDriver', 'jdbc:oracle:thin:@192.168.1.199:1521:helowin', 'jeecgbootbpm', 'jeecg196283', 'admin', '2021-01-05 19:26:24', NULL, '2021-01-05 19:26:24', 1, NULL, 'report');
INSERT INTO `jimu_report_data_source` VALUES ('8f90daf47d15d35ca6cf420748b8b9ba', 'localhost', '1316944968992034816', '', NULL, 'MYSQL5.7', 'com.mysql.cj.jdbc.Driver', 'jdbc:mysql://127.0.0.1:3306/jeecg-boot?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8', 'root', 'root', 'admin', '2021-01-13 14:34:00', NULL, '2021-01-13 14:34:00', 0); INSERT INTO `jimu_report_data_source` VALUES ('8f90daf47d15d35ca6cf420748b8b9ba', 'localhost', '1316944968992034816', '', NULL, 'MYSQL5.7', 'com.mysql.cj.jdbc.Driver', 'jdbc:mysql://127.0.0.1:3306/jeecg-boot?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8', 'root', 'root', 'admin', '2021-01-13 14:34:00', NULL, '2021-01-13 14:34:00', 0, NULL, 'report');
-- ---------------------------- -- ----------------------------
-- Table structure for jimu_report_db -- Table structure for jimu_report_db
@ -1342,6 +1344,7 @@ CREATE TABLE `jimu_report_share` (
`last_update_time` datetime NULL DEFAULT NULL COMMENT '', `last_update_time` datetime NULL DEFAULT NULL COMMENT '',
`term_of_validity` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '(0:1:12:7)', `term_of_validity` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '(0:1:12:7)',
`status` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '(01)', `status` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '(01)',
`preview_lock_status` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '',
PRIMARY KEY (`id`) USING BTREE PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '' ROW_FORMAT = Dynamic; ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '' ROW_FORMAT = Dynamic;

File diff suppressed because one or more lines are too long

@ -1,6 +1,9 @@
-- ---------------------------- -- ----------------------------
-- Table structure for system_menu -- Table structure for system_menu
-- icon -- icon
-- 使 yudao-ui-admin-vue3
-- 使 yudao-ui-admin-vue3
-- 使 yudao-ui-admin-vue3
-- ---------------------------- -- ----------------------------
DROP TABLE IF EXISTS `system_menu`; DROP TABLE IF EXISTS `system_menu`;
CREATE TABLE `system_menu` ( CREATE TABLE `system_menu` (
@ -257,7 +260,8 @@ INSERT INTO `system_menu` VALUES (1264, '客户端查询', 'system:oauth2-client
INSERT INTO `system_menu` VALUES (1265, '', 'system:oauth2-client:create', 3, 2, 1263, '', '', '', 0, b'1', b'1', '', '2022-05-10 16:26:33', '1', '2022-05-11 00:31:23', b'0'); INSERT INTO `system_menu` VALUES (1265, '', 'system:oauth2-client:create', 3, 2, 1263, '', '', '', 0, b'1', b'1', '', '2022-05-10 16:26:33', '1', '2022-05-11 00:31:23', b'0');
INSERT INTO `system_menu` VALUES (1266, '', 'system:oauth2-client:update', 3, 3, 1263, '', '', '', 0, b'1', b'1', '', '2022-05-10 16:26:33', '1', '2022-05-11 00:31:28', b'0'); INSERT INTO `system_menu` VALUES (1266, '', 'system:oauth2-client:update', 3, 3, 1263, '', '', '', 0, b'1', b'1', '', '2022-05-10 16:26:33', '1', '2022-05-11 00:31:28', b'0');
INSERT INTO `system_menu` VALUES (1267, '', 'system:oauth2-client:delete', 3, 4, 1263, '', '', '', 0, b'1', b'1', '', '2022-05-10 16:26:33', '1', '2022-05-11 00:31:33', b'0'); INSERT INTO `system_menu` VALUES (1267, '', 'system:oauth2-client:delete', 3, 4, 1263, '', '', '', 0, b'1', b'1', '', '2022-05-10 16:26:33', '1', '2022-05-11 00:31:33', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1281, '', '', 1, 12, 0, '/visualization', 'ep:histogram', NULL, 0, b'1', b'1', '1', '2022-07-10 20:22:15', '1', '2022-07-10 20:33:30', b'0'); INSERT INTO `system_menu` VALUES (1281, '', '', 1, 12, 0, '/visualization', 'ep:histogram', NULL, 0, b'1', b'1', '1', '2022-07-10 20:22:15', '1', '2022-07-10 20:33:30', b'0');
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1282, '', '', 2, 1, 1281, 'jimu-report', 'ep:histogram', 'visualization/jmreport/index', 0, b'1', b'1', '1', '2022-07-10 20:26:36', '1', '2022-07-28 21:17:34', b'0'); INSERT INTO `system_menu` VALUES (1282, '', '', 2, 1, 1281, 'jimu-report', 'ep:histogram', 'visualization/jmreport/index', 0, b'1', b'1', '1', '2022-07-10 20:26:36', '1', '2022-07-28 21:17:34', b'0');
INSERT INTO `system_menu` VALUES (1283, 'webSocket', '', 2, 14, 2, 'webSocket', 'ep:turn-off', 'infra/webSocket/index', 0, b'1', b'1', '1', '2023-01-01 11:43:04', '1', '2023-01-01 11:43:04', b'0');
SET FOREIGN_KEY_CHECKS = 1; SET FOREIGN_KEY_CHECKS = 1;

File diff suppressed because it is too large Load Diff

@ -1,287 +0,0 @@
/*
Navicat Premium Data Transfer
Source Server : 127.0.0.1
Source Server Type : MySQL
Source Server Version : 80026
Source Host : localhost:3306
Source Schema : ruoyi-vue-pro
Target Server Type : MySQL
Target Server Version : 80026
File Encoding : 65001
Date: 05/02/2022 00:50:30
*/
SET
FOREIGN_KEY_CHECKS = 0;
SET NAMES utf8mb4;
-- ----------------------------
-- Table structure for product_category
-- ----------------------------
DROP TABLE IF EXISTS `product_category`;
CREATE TABLE `product_category`
(
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '',
`parent_id` bigint NOT NULL COMMENT '',
`name` varchar(255) NOT NULL COMMENT '',
`icon` varchar(100) NOT NULL DEFAULT '#' COMMENT '',
`banner_url` varchar(255) NOT NULL COMMENT '',
`sort` int DEFAULT '0' COMMENT '',
`description` varchar(1024) DEFAULT NULL COMMENT '',
`status` tinyint NOT NULL COMMENT '',
`creator` varchar(64) DEFAULT '' COMMENT '',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '',
`updater` varchar(64) DEFAULT '' COMMENT '',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '',
`tenant_id` bigint NOT NULL DEFAULT '0' COMMENT '',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB COMMENT='';
-- ----------------------------
-- Table structure for product_brand
-- ----------------------------
DROP TABLE IF EXISTS `product_brand`;
CREATE TABLE `product_brand`
(
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '',
`category_id` bigint NOT NULL COMMENT '',
`name` varchar(255) NOT NULL COMMENT '',
`banner_url` varchar(255) NOT NULL COMMENT '',
`sort` int DEFAULT '0' COMMENT '',
`description` varchar(1024) DEFAULT NULL COMMENT '',
`status` tinyint NOT NULL COMMENT '',
`creator` varchar(64) DEFAULT '' COMMENT '',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '',
`updater` varchar(64) DEFAULT '' COMMENT '',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '',
`tenant_id` bigint NOT NULL DEFAULT '0' COMMENT '',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB COMMENT='';
-- TODO id : 2000 2001
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`)
VALUES (2000, '', '', 1, 1, 0, '/mall', 'merchant', NULL, 0);
INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`)
VALUES (2001, '', '', 1, 1, 2000, 'product', 'dict', NULL, 0);
-- SQL
INSERT INTO `system_menu`(`name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`)
VALUES ('', '', 2, 0, 2001, 'category', '', 'mall/product/category/index', 0);
-- ID
SELECT @parentId := LAST_INSERT_ID();
-- SQL
INSERT INTO `system_menu`(`name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`)
VALUES ('', 'product:category:query', 3, 1, @parentId, '', '', '', 0);
INSERT INTO `system_menu`(`name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`)
VALUES ('', 'product:category:create', 3, 2, @parentId, '', '', '', 0);
INSERT INTO `system_menu`(`name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`)
VALUES ('', 'product:category:update', 3, 3, @parentId, '', '', '', 0);
INSERT INTO `system_menu`(`name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`)
VALUES ('', 'product:category:delete', 3, 4, @parentId, '', '', '', 0);
INSERT INTO `system_menu`(`name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`)
VALUES ('', 'product:category:export', 3, 5, @parentId, '', '', '', 0);
-- SQL
INSERT INTO `system_menu`(`name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`)
VALUES ('', '', 2, 1, 2001, 'brand', '', 'mall/product/brand/index', 0);
-- ID
SELECT @parentId := LAST_INSERT_ID();
-- SQL
INSERT INTO `system_menu`(`name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`)
VALUES ('', 'product:brand:query', 3, 1, @parentId, '', '', '', 0);
INSERT INTO `system_menu`(`name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`)
VALUES ('', 'product:brand:create', 3, 2, @parentId, '', '', '', 0);
INSERT INTO `system_menu`(`name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`)
VALUES ('', 'product:brand:update', 3, 3, @parentId, '', '', '', 0);
INSERT INTO `system_menu`(`name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`)
VALUES ('', 'product:brand:delete', 3, 4, @parentId, '', '', '', 0);
INSERT INTO `system_menu`(`name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`)
VALUES ('', 'product:brand:export', 3, 5, @parentId, '', '', '', 0);
-- ----------------------------
-- Table structure for market_activity
-- ----------------------------
DROP TABLE IF EXISTS `market_activity`;
CREATE TABLE `market_activity`
(
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '',
`title` varchar(50) NOT NULL DEFAULT '' COMMENT '',
`activity_type` tinyint(4) NOT NULL COMMENT '',
`status` tinyint(4) NOT NULL DEFAULT '-1' COMMENT '',
`start_time` datetime NOT NULL COMMENT '',
`end_time` datetime NOT NULL COMMENT '',
`invalid_time` datetime DEFAULT NULL COMMENT '',
`delete_time` datetime DEFAULT NULL COMMENT '',
`time_limited_discount` varchar(2000) DEFAULT NULL COMMENT '使 JSON ',
`full_privilege` varchar(2000) DEFAULT NULL COMMENT '使 JSON ',
`creator` varchar(64) DEFAULT '' COMMENT '',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '',
`updater` varchar(64) DEFAULT '' COMMENT '',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '',
`tenant_id` bigint NOT NULL DEFAULT '0' COMMENT '',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='';
-- SQL
INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status)
VALUES ('', '', 2, 3, 2001, 'property', '', 'mall/product/property/index', 0);
-- ID
SELECT @parentId := LAST_INSERT_ID();
-- SQL
INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status)
VALUES ('', 'product:property:query', 3, 1, @parentId, '', '', '', 0);
INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status)
VALUES ('', 'product:property:create', 3, 2, @parentId, '', '', '', 0);
INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status)
VALUES ('', 'product:property:update', 3, 3, @parentId, '', '', '', 0);
INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status)
VALUES ('', 'product:property:delete', 3, 4, @parentId, '', '', '', 0);
INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status)
VALUES ('', 'product:property:export', 3, 5, @parentId, '', '', '', 0);
-- SQL
INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status)
VALUES ('', '', 2, 2, 2001, 'spu', '', 'mall/product/spu/index', 0);
-- ID
SELECT @parentId := LAST_INSERT_ID();
-- SQL
INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status)
VALUES ('', 'product:spu:query', 3, 1, @parentId, '', '', '', 0);
INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status)
VALUES ('', 'product:spu:create', 3, 2, @parentId, '', '', '', 0);
INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status)
VALUES ('', 'product:spu:update', 3, 3, @parentId, '', '', '', 0);
INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status)
VALUES ('', 'product:spu:delete', 3, 4, @parentId, '', '', '', 0);
INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status)
VALUES ('', 'product:spu:export', 3, 5, @parentId, '', '', '', 0);
--
drop table if exists product_property;
create table product_property
(
id bigint NOT NULL AUTO_INCREMENT comment '',
name varchar(64) comment '',
status tinyint comment ' 0 1 ',
create_time datetime default current_timestamp comment '',
update_time datetime default current_timestamp on update current_timestamp comment '',
creator varchar(64) comment '',
updater varchar(64) comment '',
tenant_id bigint NOT NULL DEFAULT '0' COMMENT '',
deleted bit(1) NOT NULL DEFAULT b'0' COMMENT '',
primary key (id),
key idx_name ( name (32)) comment ''
) comment '' character set utf8mb4
collate utf8mb4_general_ci;
--
drop table if exists product_property_value;
create table product_property_value
(
id bigint NOT NULL AUTO_INCREMENT COMMENT '',
property_id bigint comment 'id',
name varchar(128) comment '',
status tinyint comment ' 1 2 ',
create_time datetime default current_timestamp comment '',
update_time datetime default current_timestamp on update current_timestamp comment '',
creator varchar(64) comment '',
updater varchar(64) comment '',
tenant_id bigint NOT NULL DEFAULT '0' COMMENT '',
deleted bit(1) NOT NULL DEFAULT b'0' COMMENT '',
primary key (id)
) comment '' character set utf8mb4
collate utf8mb4_general_ci;
-- spu
drop table if exists product_spu;
create table product_spu
(
id bigint NOT NULL AUTO_INCREMENT COMMENT '',
name varchar(128) comment '',
sell_point varchar(128) not null comment '',
description text not null comment '',
category_id bigint not null comment 'id',
pic_urls varchar(1024) not null default '' comment '\n *\n * \n 15',
sort int not null default 0 comment '',
like_count int comment '',
price int comment ' 使',
quantity int comment '',
status bit(1) comment ' 0 1 ',
create_time datetime default current_timestamp comment '',
update_time datetime default current_timestamp on update current_timestamp comment '',
creator varchar(64) comment '',
updater varchar(64) comment '',
tenant_id bigint NOT NULL DEFAULT '0' COMMENT '',
deleted bit(1) NOT NULL DEFAULT b'0' COMMENT '',
primary key (id)
) comment 'spu' character set utf8mb4
collate utf8mb4_general_ci;
-- sku
drop table if exists product_sku;
create table product_sku
(
id bigint NOT NULL AUTO_INCREMENT COMMENT '',
spu_id bigint not null comment 'spu',
properties varchar(64) not null comment '-json [{propertId: , valueId: }, {propertId: , valueId: }]',
price int not null DEFAULT -1 comment '',
original_price int not null DEFAULT -1 comment ' ',
cost_price int not null DEFAULT -1 comment ' ',
bar_code varchar(64) not null comment '',
pic_url VARCHAR(128) not null comment '',
status tinyint comment ' 0- 1-',
create_time datetime default current_timestamp comment '',
update_time datetime default current_timestamp on update current_timestamp comment '',
creator varchar(64) comment '',
updater varchar(64) comment '',
tenant_id bigint NOT NULL DEFAULT '0' COMMENT '',
deleted bit(1) NOT NULL DEFAULT b'0' COMMENT '',
primary key (id)
) comment 'sku' character set utf8mb4
collate utf8mb4_general_ci;
---Market-BannerSQL
drop table if exists market_banner;
CREATE TABLE `market_banner` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'Banner',
`title` varchar(64) NOT NULL DEFAULT '' COMMENT 'Banner',
`pic_url` varchar(255) NOT NULL COMMENT 'URL',
`status` tinyint(4) NOT NULL DEFAULT '-1' COMMENT '',
`url` varchar(255) NOT NULL COMMENT '',
`creator` varchar(64) DEFAULT '' COMMENT '',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '',
`updater` varchar(64) DEFAULT '' COMMENT '',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '',
`tenant_id` bigint(20) NOT NULL DEFAULT '0' COMMENT '',
`sort` tinyint(4) DEFAULT NULL COMMENT '',
`memo` varchar(255) DEFAULT NULL COMMENT '',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COMMENT='Banner';
-- SQL
INSERT INTO `system_menu`(`id`,`name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`)
VALUES (2002, 'Banner', '', 2, 1, 2000, 'brand', '', 'mall/market/banner/index', 0);
-- ID
SELECT @parentId := LAST_INSERT_ID();
-- SQL
INSERT INTO `system_menu`(`name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`)
VALUES ('Banner', 'market:banner:query', 3, 1, @parentId, '', '', '', 0);
INSERT INTO `system_menu`(`name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`)
VALUES ('Banner', 'market:banner:create', 3, 2, @parentId, '', '', '', 0);
INSERT INTO `system_menu`(`name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`)
VALUES ('Banner', 'market:banner:update', 3, 3, @parentId, '', '', '', 0);
INSERT INTO `system_menu`(`name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`)
VALUES ('Banner', 'market:banner:delete', 3, 4, @parentId, '', '', '', 0);

@ -38,8 +38,8 @@ NOCOMPRESS
PCTFREE 10 PCTFREE 10
INITRANS 1 INITRANS 1
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -96,8 +96,8 @@ NOCOMPRESS
PCTFREE 10 PCTFREE 10
INITRANS 1 INITRANS 1
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -159,8 +159,8 @@ NOCOMPRESS
PCTFREE 10 PCTFREE 10
INITRANS 1 INITRANS 1
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -224,8 +224,8 @@ NOCOMPRESS
PCTFREE 10 PCTFREE 10
INITRANS 1 INITRANS 1
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -284,8 +284,8 @@ NOCOMPRESS
PCTFREE 10 PCTFREE 10
INITRANS 1 INITRANS 1
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -342,8 +342,8 @@ NOCOMPRESS
PCTFREE 10 PCTFREE 10
INITRANS 1 INITRANS 1
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -400,8 +400,8 @@ NOCOMPRESS
PCTFREE 10 PCTFREE 10
INITRANS 1 INITRANS 1
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -463,8 +463,8 @@ NOCOMPRESS
PCTFREE 10 PCTFREE 10
INITRANS 1 INITRANS 1
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -543,8 +543,8 @@ NOCOMPRESS
PCTFREE 10 PCTFREE 10
INITRANS 1 INITRANS 1
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -645,8 +645,8 @@ NOCOMPRESS
PCTFREE 10 PCTFREE 10
INITRANS 1 INITRANS 1
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -718,8 +718,8 @@ NOCOMPRESS
PCTFREE 10 PCTFREE 10
INITRANS 1 INITRANS 1
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -780,8 +780,8 @@ NOCOMPRESS
PCTFREE 10 PCTFREE 10
INITRANS 1 INITRANS 1
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -839,8 +839,8 @@ NOCOMPRESS
PCTFREE 10 PCTFREE 10
INITRANS 1 INITRANS 1
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -892,8 +892,8 @@ NOCOMPRESS
PCTFREE 10 PCTFREE 10
INITRANS 1 INITRANS 1
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -945,8 +945,8 @@ NOCOMPRESS
PCTFREE 10 PCTFREE 10
INITRANS 1 INITRANS 1
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -999,8 +999,8 @@ NOCOMPRESS
PCTFREE 10 PCTFREE 10
INITRANS 1 INITRANS 1
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -1053,8 +1053,8 @@ NOCOMPRESS
PCTFREE 10 PCTFREE 10
INITRANS 1 INITRANS 1
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -1113,8 +1113,8 @@ NOCOMPRESS
PCTFREE 10 PCTFREE 10
INITRANS 1 INITRANS 1
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -1169,8 +1169,8 @@ NOCOMPRESS
PCTFREE 10 PCTFREE 10
INITRANS 1 INITRANS 1
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -1226,8 +1226,8 @@ NOCOMPRESS
PCTFREE 10 PCTFREE 10
INITRANS 1 INITRANS 1
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -1284,8 +1284,8 @@ NOCOMPRESS
PCTFREE 10 PCTFREE 10
INITRANS 1 INITRANS 1
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -1341,8 +1341,8 @@ NOCOMPRESS
PCTFREE 10 PCTFREE 10
INITRANS 1 INITRANS 1
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -1398,8 +1398,8 @@ NOCOMPRESS
PCTFREE 10 PCTFREE 10
INITRANS 1 INITRANS 1
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -1451,8 +1451,8 @@ NOCOMPRESS
PCTFREE 10 PCTFREE 10
INITRANS 1 INITRANS 1
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -1510,8 +1510,8 @@ NOCOMPRESS
PCTFREE 10 PCTFREE 10
INITRANS 1 INITRANS 1
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -1589,8 +1589,8 @@ NOCOMPRESS
PCTFREE 10 PCTFREE 10
INITRANS 1 INITRANS 1
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -1665,8 +1665,8 @@ NOCOMPRESS
PCTFREE 10 PCTFREE 10
INITRANS 1 INITRANS 1
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -1742,8 +1742,8 @@ NOCOMPRESS
PCTFREE 10 PCTFREE 10
INITRANS 1 INITRANS 1
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -1807,8 +1807,8 @@ NOCOMPRESS
PCTFREE 10 PCTFREE 10
INITRANS 1 INITRANS 1
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -1840,8 +1840,8 @@ NOCOMPRESS
PCTFREE 10 PCTFREE 10
INITRANS 1 INITRANS 1
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -1875,8 +1875,8 @@ NOCOMPRESS
PCTFREE 10 PCTFREE 10
INITRANS 1 INITRANS 1
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -1919,8 +1919,8 @@ NOCOMPRESS
PCTFREE 10 PCTFREE 10
INITRANS 1 INITRANS 1
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -1959,8 +1959,8 @@ NOCOMPRESS
PCTFREE 10 PCTFREE 10
INITRANS 1 INITRANS 1
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -1992,8 +1992,8 @@ NOCOMPRESS
PCTFREE 10 PCTFREE 10
INITRANS 1 INITRANS 1
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -2026,8 +2026,8 @@ NOCOMPRESS
PCTFREE 10 PCTFREE 10
INITRANS 1 INITRANS 1
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -2060,8 +2060,8 @@ NOCOMPRESS
PCTFREE 10 PCTFREE 10
INITRANS 1 INITRANS 1
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -2097,8 +2097,8 @@ NOCOMPRESS
PCTFREE 10 PCTFREE 10
INITRANS 1 INITRANS 1
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -2141,8 +2141,8 @@ NOCOMPRESS
PCTFREE 10 PCTFREE 10
INITRANS 1 INITRANS 1
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -2187,8 +2187,8 @@ NOCOMPRESS
PCTFREE 10 PCTFREE 10
INITRANS 1 INITRANS 1
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -2232,8 +2232,8 @@ NOCOMPRESS
PCTFREE 10 PCTFREE 10
INITRANS 1 INITRANS 1
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -2303,8 +2303,8 @@ NOCOMPRESS
PCTFREE 10 PCTFREE 10
INITRANS 1 INITRANS 1
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -2454,7 +2454,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 ('62', '0', '', '0', 'infra_api_error_log_process_status', '0', 'primary', NULL, NULL, NULL, TO_DATE('2021-02-26 07:07:19', 'SYYYY-MM-DD HH24:MI:SS'), '1', TO_DATE('2022-02-16 20:14:17', 'SYYYY-MM-DD HH24:MI:SS'), '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 ('62', '0', '', '0', 'infra_api_error_log_process_status', '0', 'primary', NULL, NULL, NULL, TO_DATE('2021-02-26 07:07:19', 'SYYYY-MM-DD HH24:MI:SS'), '1', TO_DATE('2022-02-16 20:14:17', 'SYYYY-MM-DD HH24:MI:SS'), '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 ('63', '1', '', '1', 'infra_api_error_log_process_status', '0', 'success', NULL, NULL, NULL, TO_DATE('2021-02-26 07:07:26', 'SYYYY-MM-DD HH24:MI:SS'), '1', TO_DATE('2022-02-16 20:14:08', 'SYYYY-MM-DD HH24:MI:SS'), '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 ('63', '1', '', '1', 'infra_api_error_log_process_status', '0', 'success', NULL, NULL, NULL, TO_DATE('2021-02-26 07:07:26', 'SYYYY-MM-DD HH24:MI:SS'), '1', TO_DATE('2022-02-16 20:14:08', 'SYYYY-MM-DD HH24:MI:SS'), '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 ('64', '2', '', '2', 'infra_api_error_log_process_status', '0', 'danger', NULL, NULL, NULL, TO_DATE('2021-02-26 07:07:34', 'SYYYY-MM-DD HH24:MI:SS'), '1', TO_DATE('2022-02-16 20:14:14', 'SYYYY-MM-DD HH24:MI:SS'), '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 ('64', '2', '', '2', 'infra_api_error_log_process_status', '0', 'danger', NULL, NULL, NULL, TO_DATE('2021-02-26 07:07:34', 'SYYYY-MM-DD HH24:MI:SS'), '1', TO_DATE('2022-02-16 20:14:14', 'SYYYY-MM-DD HH24:MI:SS'), '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 ('65', '1', '', 'YUN_PIAN', 'system_sms_channel_code', '0', 'success', NULL, NULL, '1', TO_DATE('2021-04-05 01:05:14', 'SYYYY-MM-DD HH24:MI:SS'), '1', TO_DATE('2022-02-16 10:09:55', 'SYYYY-MM-DD HH24:MI:SS'), '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 ('66', '2', '', 'ALIYUN', 'system_sms_channel_code', '0', 'primary', NULL, NULL, '1', TO_DATE('2021-04-05 01:05:26', 'SYYYY-MM-DD HH24:MI:SS'), '1', TO_DATE('2022-02-16 10:09:52', 'SYYYY-MM-DD HH24:MI:SS'), '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 ('66', '2', '', 'ALIYUN', 'system_sms_channel_code', '0', 'primary', NULL, NULL, '1', TO_DATE('2021-04-05 01:05:26', 'SYYYY-MM-DD HH24:MI:SS'), '1', TO_DATE('2022-02-16 10:09:52', 'SYYYY-MM-DD HH24:MI:SS'), '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 ('67', '1', '', '1', 'system_sms_template_type', '0', 'warning', NULL, NULL, '1', TO_DATE('2021-04-05 21:50:57', 'SYYYY-MM-DD HH24:MI:SS'), '1', TO_DATE('2022-02-16 12:48:30', 'SYYYY-MM-DD HH24:MI:SS'), '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 ('67', '1', '', '1', 'system_sms_template_type', '0', 'warning', NULL, NULL, '1', TO_DATE('2021-04-05 21:50:57', 'SYYYY-MM-DD HH24:MI:SS'), '1', TO_DATE('2022-02-16 12:48:30', 'SYYYY-MM-DD HH24:MI:SS'), '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 ('68', '2', '', '2', 'system_sms_template_type', '0', 'primary', NULL, NULL, '1', TO_DATE('2021-04-05 21:51:08', 'SYYYY-MM-DD HH24:MI:SS'), '1', TO_DATE('2022-02-16 12:48:27', 'SYYYY-MM-DD HH24:MI:SS'), '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 ('68', '2', '', '2', 'system_sms_template_type', '0', 'primary', NULL, NULL, '1', TO_DATE('2021-04-05 21:51:08', 'SYYYY-MM-DD HH24:MI:SS'), '1', TO_DATE('2022-02-16 12:48:27', 'SYYYY-MM-DD HH24:MI:SS'), '0');
@ -2475,25 +2474,26 @@ COMMIT;
-- Table structure for SYSTEM_DICT_TYPE -- Table structure for SYSTEM_DICT_TYPE
-- ---------------------------- -- ----------------------------
DROP TABLE "SYSTEM_DICT_TYPE"; DROP TABLE "SYSTEM_DICT_TYPE";
CREATE TABLE "SYSTEM_DICT_TYPE" ( CREATE TABLE "SYSTEM_DICT_TYPE"(
"ID" NUMBER(20,0) NOT NULL, "ID" NUMBER(20,0) NOT NULL,
"NAME" NVARCHAR2(100), "NAME" NVARCHAR2(100),
"TYPE" NVARCHAR2(100), "TYPE" NVARCHAR2(100),
"STATUS" NUMBER(4,0) NOT NULL, "STATUS" NUMBER(4,0) NOT NULL,
"REMARK" NVARCHAR2(500), "REMARK" NVARCHAR2(500),
"CREATOR" NVARCHAR2(64), "CREATOR" NVARCHAR2(64),
"CREATE_TIME" DATE NOT NULL, "CREATE_TIME" DATE NOT NULL,
"UPDATER" NVARCHAR2(64), "UPDATER" NVARCHAR2(64),
"UPDATE_TIME" DATE NOT NULL, "UPDATE_TIME" DATE NOT NULL,
"DELETED" NUMBER(1,0) DEFAULT 0 NOT NULL "DELETED_TIME" DATE,
"DELETED" NUMBER(1,0) DEFAULT 0 NOT NULL
) )
LOGGING LOGGING
NOCOMPRESS NOCOMPRESS
PCTFREE 10 PCTFREE 10
INITRANS 1 INITRANS 1
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -2504,25 +2504,54 @@ PARALLEL 1
NOCACHE NOCACHE
DISABLE ROW MOVEMENT DISABLE ROW MOVEMENT
; ;
COMMENT ON COLUMN "SYSTEM_DICT_TYPE"."ID" IS ''; COMMENT
COMMENT ON COLUMN "SYSTEM_DICT_TYPE"."NAME" IS ''; ON COLUMN "SYSTEM_DICT_TYPE"."ID" IS '';
COMMENT ON COLUMN "SYSTEM_DICT_TYPE"."TYPE" IS ''; COMMENT
COMMENT ON COLUMN "SYSTEM_DICT_TYPE"."STATUS" IS '0 1'; ON COLUMN "SYSTEM_DICT_TYPE"."NAME" IS '';
COMMENT ON COLUMN "SYSTEM_DICT_TYPE"."REMARK" IS ''; COMMENT
COMMENT ON COLUMN "SYSTEM_DICT_TYPE"."CREATOR" IS ''; ON COLUMN "SYSTEM_DICT_TYPE"."TYPE" IS '';
COMMENT ON COLUMN "SYSTEM_DICT_TYPE"."CREATE_TIME" IS ''; COMMENT
COMMENT ON COLUMN "SYSTEM_DICT_TYPE"."UPDATER" IS ''; ON COLUMN "SYSTEM_DICT_TYPE"."STATUS" IS '0 1';
COMMENT ON COLUMN "SYSTEM_DICT_TYPE"."UPDATE_TIME" IS ''; COMMENT
COMMENT ON COLUMN "SYSTEM_DICT_TYPE"."DELETED" IS ''; ON COLUMN "SYSTEM_DICT_TYPE"."REMARK" IS '';
COMMENT ON TABLE "SYSTEM_DICT_TYPE" IS ''; COMMENT
ON COLUMN "SYSTEM_DICT_TYPE"."CREATOR" IS '';
COMMENT
ON COLUMN "SYSTEM_DICT_TYPE"."CREATE_TIME" IS '';
COMMENT
ON COLUMN "SYSTEM_DICT_TYPE"."UPDATER" IS '';
COMMENT
ON COLUMN "SYSTEM_DICT_TYPE"."UPDATE_TIME" IS '';
COMMENT
ON COLUMN "SYSTEM_DICT_TYPE"."DELETED_TIME" IS '';
COMMENT
ON COLUMN "SYSTEM_DICT_TYPE"."DELETED" IS '';
COMMENT
ON TABLE "SYSTEM_DICT_TYPE" IS '';
-- ---------------------------- -- ----------------------------
-- Records of SYSTEM_DICT_TYPE -- Records of SYSTEM_DICT_TYPE
-- ---------------------------- -- ----------------------------
INSERT INTO "SYSTEM_DICT_TYPE" ("ID", "NAME", "TYPE", "STATUS", "REMARK", "CREATOR", "CREATE_TIME", "UPDATER", "UPDATE_TIME", "DELETED") VALUES ('1', '', 'system_user_sex', '0', NULL, 'admin', TO_DATE('2021-01-05 17:03:48', 'SYYYY-MM-DD HH24:MI:SS'), '1', TO_DATE('2022-05-01 12:55:56', 'SYYYY-MM-DD HH24:MI:SS'), '0'); INSERT INTO "SYSTEM_DICT_TYPE" ("ID", "NAME", "TYPE", "STATUS", "REMARK", "CREATOR", "CREATE_TIME", "UPDATER",
INSERT INTO "SYSTEM_DICT_TYPE" ("ID", "NAME", "TYPE", "STATUS", "REMARK", "CREATOR", "CREATE_TIME", "UPDATER", "UPDATE_TIME", "DELETED") VALUES ('6', '', 'infra_config_type', '0', NULL, 'admin', TO_DATE('2021-01-05 17:03:48', 'SYYYY-MM-DD HH24:MI:SS'), NULL, TO_DATE('2022-02-01 16:36:54', 'SYYYY-MM-DD HH24:MI:SS'), '0'); "UPDATE_TIME", "DELETED")
INSERT INTO "SYSTEM_DICT_TYPE" ("ID", "NAME", "TYPE", "STATUS", "REMARK", "CREATOR", "CREATE_TIME", "UPDATER", "UPDATE_TIME", "DELETED") VALUES ('7', '', 'system_notice_type', '0', NULL, 'admin', TO_DATE('2021-01-05 17:03:48', 'SYYYY-MM-DD HH24:MI:SS'), NULL, TO_DATE('2022-02-01 16:35:26', 'SYYYY-MM-DD HH24:MI:SS'), '0'); VALUES ('1', '', 'system_user_sex', '0', NULL, 'admin',
INSERT INTO "SYSTEM_DICT_TYPE" ("ID", "NAME", "TYPE", "STATUS", "REMARK", "CREATOR", "CREATE_TIME", "UPDATER", "UPDATE_TIME", "DELETED") VALUES ('9', '', 'system_operate_type', '0', NULL, 'admin', TO_DATE('2021-01-05 17:03:48', 'SYYYY-MM-DD HH24:MI:SS'), '1', TO_DATE('2022-02-16 09:32:21', 'SYYYY-MM-DD HH24:MI:SS'), '0'); TO_DATE('2021-01-05 17:03:48', 'SYYYY-MM-DD HH24:MI:SS'), '1',
TO_DATE('2022-05-01 12:55:56', 'SYYYY-MM-DD HH24:MI:SS'), '0');
INSERT INTO "SYSTEM_DICT_TYPE" ("ID", "NAME", "TYPE", "STATUS", "REMARK", "CREATOR", "CREATE_TIME", "UPDATER",
"UPDATE_TIME", "DELETED")
VALUES ('6', '', 'infra_config_type', '0', NULL, 'admin',
TO_DATE('2021-01-05 17:03:48', 'SYYYY-MM-DD HH24:MI:SS'), NULL,
TO_DATE('2022-02-01 16:36:54', 'SYYYY-MM-DD HH24:MI:SS'), '0');
INSERT INTO "SYSTEM_DICT_TYPE" ("ID", "NAME", "TYPE", "STATUS", "REMARK", "CREATOR", "CREATE_TIME", "UPDATER",
"UPDATE_TIME", "DELETED")
VALUES ('7', '', 'system_notice_type', '0', NULL, 'admin',
TO_DATE('2021-01-05 17:03:48', 'SYYYY-MM-DD HH24:MI:SS'), NULL,
TO_DATE('2022-02-01 16:35:26', 'SYYYY-MM-DD HH24:MI:SS'), '0');
INSERT INTO "SYSTEM_DICT_TYPE" ("ID", "NAME", "TYPE", "STATUS", "REMARK", "CREATOR", "CREATE_TIME", "UPDATER",
"UPDATE_TIME", "DELETED")
VALUES ('9', '', 'system_operate_type', '0', NULL, 'admin',
TO_DATE('2021-01-05 17:03:48', 'SYYYY-MM-DD HH24:MI:SS'), '1',
TO_DATE('2022-02-16 09:32:21', 'SYYYY-MM-DD HH24:MI:SS'), '0');
INSERT INTO "SYSTEM_DICT_TYPE" ("ID", "NAME", "TYPE", "STATUS", "REMARK", "CREATOR", "CREATE_TIME", "UPDATER", "UPDATE_TIME", "DELETED") VALUES ('10', '', 'common_status', '0', NULL, 'admin', TO_DATE('2021-01-05 17:03:48', 'SYYYY-MM-DD HH24:MI:SS'), NULL, TO_DATE('2022-02-01 16:21:28', 'SYYYY-MM-DD HH24:MI:SS'), '0'); INSERT INTO "SYSTEM_DICT_TYPE" ("ID", "NAME", "TYPE", "STATUS", "REMARK", "CREATOR", "CREATE_TIME", "UPDATER", "UPDATE_TIME", "DELETED") VALUES ('10', '', 'common_status', '0', NULL, 'admin', TO_DATE('2021-01-05 17:03:48', 'SYYYY-MM-DD HH24:MI:SS'), NULL, TO_DATE('2022-02-01 16:21:28', 'SYYYY-MM-DD HH24:MI:SS'), '0');
INSERT INTO "SYSTEM_DICT_TYPE" ("ID", "NAME", "TYPE", "STATUS", "REMARK", "CREATOR", "CREATE_TIME", "UPDATER", "UPDATE_TIME", "DELETED") VALUES ('11', 'Boolean ', 'infra_boolean_string', '0', 'boolean ', NULL, TO_DATE('2021-01-19 03:20:08', 'SYYYY-MM-DD HH24:MI:SS'), NULL, TO_DATE('2022-02-01 16:37:10', 'SYYYY-MM-DD HH24:MI:SS'), '0'); INSERT INTO "SYSTEM_DICT_TYPE" ("ID", "NAME", "TYPE", "STATUS", "REMARK", "CREATOR", "CREATE_TIME", "UPDATER", "UPDATE_TIME", "DELETED") VALUES ('11', 'Boolean ', 'infra_boolean_string', '0', 'boolean ', NULL, TO_DATE('2021-01-19 03:20:08', 'SYYYY-MM-DD HH24:MI:SS'), NULL, TO_DATE('2022-02-01 16:37:10', 'SYYYY-MM-DD HH24:MI:SS'), '0');
INSERT INTO "SYSTEM_DICT_TYPE" ("ID", "NAME", "TYPE", "STATUS", "REMARK", "CREATOR", "CREATE_TIME", "UPDATER", "UPDATE_TIME", "DELETED") VALUES ('104', '', 'system_login_result', '0', '', NULL, TO_DATE('2021-01-18 06:17:11', 'SYYYY-MM-DD HH24:MI:SS'), NULL, TO_DATE('2022-02-01 16:36:00', 'SYYYY-MM-DD HH24:MI:SS'), '0'); INSERT INTO "SYSTEM_DICT_TYPE" ("ID", "NAME", "TYPE", "STATUS", "REMARK", "CREATOR", "CREATE_TIME", "UPDATER", "UPDATE_TIME", "DELETED") VALUES ('104', '', 'system_login_result', '0', '', NULL, TO_DATE('2021-01-18 06:17:11', 'SYYYY-MM-DD HH24:MI:SS'), NULL, TO_DATE('2022-02-01 16:36:00', 'SYYYY-MM-DD HH24:MI:SS'), '0');
@ -2583,8 +2612,8 @@ NOCOMPRESS
PCTFREE 10 PCTFREE 10
INITRANS 1 INITRANS 1
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -2642,8 +2671,8 @@ NOCOMPRESS
PCTFREE 10 PCTFREE 10
INITRANS 1 INITRANS 1
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -2706,8 +2735,8 @@ NOCOMPRESS
PCTFREE 10 PCTFREE 10
INITRANS 1 INITRANS 1
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -2995,8 +3024,8 @@ NOCOMPRESS
PCTFREE 10 PCTFREE 10
INITRANS 1 INITRANS 1
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -3051,8 +3080,8 @@ NOCOMPRESS
PCTFREE 10 PCTFREE 10
INITRANS 1 INITRANS 1
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -3109,8 +3138,8 @@ NOCOMPRESS
PCTFREE 10 PCTFREE 10
INITRANS 1 INITRANS 1
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -3176,8 +3205,8 @@ NOCOMPRESS
PCTFREE 10 PCTFREE 10
INITRANS 1 INITRANS 1
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -3245,8 +3274,8 @@ NOCOMPRESS
PCTFREE 10 PCTFREE 10
INITRANS 1 INITRANS 1
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -3307,8 +3336,8 @@ NOCOMPRESS
PCTFREE 10 PCTFREE 10
INITRANS 1 INITRANS 1
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -3377,8 +3406,8 @@ NOCOMPRESS
PCTFREE 10 PCTFREE 10
INITRANS 1 INITRANS 1
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -3446,8 +3475,8 @@ NOCOMPRESS
PCTFREE 10 PCTFREE 10
INITRANS 1 INITRANS 1
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -3508,8 +3537,8 @@ NOCOMPRESS
PCTFREE 10 PCTFREE 10
INITRANS 1 INITRANS 1
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -3569,8 +3598,8 @@ NOCOMPRESS
PCTFREE 10 PCTFREE 10
INITRANS 1 INITRANS 1
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -3759,8 +3788,8 @@ NOCOMPRESS
PCTFREE 10 PCTFREE 10
INITRANS 1 INITRANS 1
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -3815,8 +3844,8 @@ NOCOMPRESS
PCTFREE 10 PCTFREE 10
INITRANS 1 INITRANS 1
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -3845,7 +3874,6 @@ COMMENT ON TABLE "SYSTEM_SMS_CHANNEL" IS '短信渠道';
-- ---------------------------- -- ----------------------------
-- Records of SYSTEM_SMS_CHANNEL -- Records of SYSTEM_SMS_CHANNEL
-- ---------------------------- -- ----------------------------
INSERT INTO "SYSTEM_SMS_CHANNEL" ("ID", "SIGNATURE", "CODE", "STATUS", "REMARK", "API_KEY", "API_SECRET", "CALLBACK_URL", "CREATOR", "CREATE_TIME", "UPDATER", "UPDATE_TIME", "DELETED") VALUES ('1', '', 'YUN_PIAN', '0', '', '1555a14277cb8a608cf45a9e6a80d510', NULL, 'http://vdwapu.natappfree.cc/admin-api/system/sms/callback/yunpian', NULL, TO_DATE('2021-03-31 06:12:20', 'SYYYY-MM-DD HH24:MI:SS'), '1', TO_DATE('2022-02-23 16:48:44', 'SYYYY-MM-DD HH24:MI:SS'), '0');
INSERT INTO "SYSTEM_SMS_CHANNEL" ("ID", "SIGNATURE", "CODE", "STATUS", "REMARK", "API_KEY", "API_SECRET", "CALLBACK_URL", "CREATOR", "CREATE_TIME", "UPDATER", "UPDATE_TIME", "DELETED") VALUES ('2', 'Ballcat', 'ALIYUN', '0', '', 'LTAI5tCnKso2uG3kJ5gRav88', 'fGJ5SNXL7P1NHNRmJ7DJaMJGPyE55C', NULL, NULL, TO_DATE('2021-03-31 11:53:10', 'SYYYY-MM-DD HH24:MI:SS'), '1', TO_DATE('2021-04-14 00:08:37', 'SYYYY-MM-DD HH24:MI:SS'), '0'); INSERT INTO "SYSTEM_SMS_CHANNEL" ("ID", "SIGNATURE", "CODE", "STATUS", "REMARK", "API_KEY", "API_SECRET", "CALLBACK_URL", "CREATOR", "CREATE_TIME", "UPDATER", "UPDATE_TIME", "DELETED") VALUES ('2', 'Ballcat', 'ALIYUN', '0', '', 'LTAI5tCnKso2uG3kJ5gRav88', 'fGJ5SNXL7P1NHNRmJ7DJaMJGPyE55C', NULL, NULL, TO_DATE('2021-03-31 11:53:10', 'SYYYY-MM-DD HH24:MI:SS'), '1', TO_DATE('2021-04-14 00:08:37', 'SYYYY-MM-DD HH24:MI:SS'), '0');
INSERT INTO "SYSTEM_SMS_CHANNEL" ("ID", "SIGNATURE", "CODE", "STATUS", "REMARK", "API_KEY", "API_SECRET", "CALLBACK_URL", "CREATOR", "CREATE_TIME", "UPDATER", "UPDATE_TIME", "DELETED") VALUES ('4', '', 'DEBUG_DING_TALK', '0', '123', '696b5d8ead48071237e4aa5861ff08dbadb2b4ded1c688a7b7c9afc615579859', 'SEC5c4e5ff888bc8a9923ae47f59e7ccd30af1f14d93c55b4e2c9cb094e35aeed67', NULL, '1', TO_DATE('2021-04-13 00:23:14', 'SYYYY-MM-DD HH24:MI:SS'), '1', TO_DATE('2021-04-14 00:07:10', 'SYYYY-MM-DD HH24:MI:SS'), '0'); INSERT INTO "SYSTEM_SMS_CHANNEL" ("ID", "SIGNATURE", "CODE", "STATUS", "REMARK", "API_KEY", "API_SECRET", "CALLBACK_URL", "CREATOR", "CREATE_TIME", "UPDATER", "UPDATE_TIME", "DELETED") VALUES ('4', '', 'DEBUG_DING_TALK', '0', '123', '696b5d8ead48071237e4aa5861ff08dbadb2b4ded1c688a7b7c9afc615579859', 'SEC5c4e5ff888bc8a9923ae47f59e7ccd30af1f14d93c55b4e2c9cb094e35aeed67', NULL, '1', TO_DATE('2021-04-13 00:23:14', 'SYYYY-MM-DD HH24:MI:SS'), '1', TO_DATE('2021-04-14 00:07:10', 'SYYYY-MM-DD HH24:MI:SS'), '0');
COMMIT; COMMIT;
@ -3877,8 +3905,8 @@ NOCOMPRESS
PCTFREE 10 PCTFREE 10
INITRANS 1 INITRANS 1
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -3953,8 +3981,8 @@ NOCOMPRESS
PCTFREE 10 PCTFREE 10
INITRANS 1 INITRANS 1
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -4029,8 +4057,8 @@ NOCOMPRESS
PCTFREE 10 PCTFREE 10
INITRANS 1 INITRANS 1
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -4102,8 +4130,8 @@ NOCOMPRESS
PCTFREE 10 PCTFREE 10
INITRANS 1 INITRANS 1
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -4165,8 +4193,8 @@ NOCOMPRESS
PCTFREE 10 PCTFREE 10
INITRANS 1 INITRANS 1
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -4224,8 +4252,8 @@ NOCOMPRESS
PCTFREE 10 PCTFREE 10
INITRANS 1 INITRANS 1
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -4286,8 +4314,8 @@ NOCOMPRESS
PCTFREE 10 PCTFREE 10
INITRANS 1 INITRANS 1
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -4360,8 +4388,8 @@ NOCOMPRESS
PCTFREE 10 PCTFREE 10
INITRANS 1 INITRANS 1
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -4412,8 +4440,8 @@ NOCOMPRESS
PCTFREE 10 PCTFREE 10
INITRANS 1 INITRANS 1
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -5401,8 +5429,8 @@ CREATE INDEX "IDX_QRTZ_FT_INST_JOB_REQ_RCVRY"
PCTFREE 10 PCTFREE 10
INITRANS 2 INITRANS 2
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -5418,8 +5446,8 @@ CREATE INDEX "IDX_QRTZ_FT_JG"
PCTFREE 10 PCTFREE 10
INITRANS 2 INITRANS 2
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -5433,8 +5461,8 @@ CREATE INDEX "IDX_QRTZ_FT_J_G"
PCTFREE 10 PCTFREE 10
INITRANS 2 INITRANS 2
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -5449,8 +5477,8 @@ CREATE INDEX "IDX_QRTZ_FT_TG"
PCTFREE 10 PCTFREE 10
INITRANS 2 INITRANS 2
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -5485,8 +5513,8 @@ CREATE INDEX "IDX_QRTZ_J_GRP"
PCTFREE 10 PCTFREE 10
INITRANS 2 INITRANS 2
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -5500,8 +5528,8 @@ CREATE INDEX "IDX_QRTZ_J_REQ_RECOVERY"
PCTFREE 10 PCTFREE 10
INITRANS 2 INITRANS 2
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -5625,8 +5653,8 @@ CREATE INDEX "IDX_QRTZ_T_C"
PCTFREE 10 PCTFREE 10
INITRANS 2 INITRANS 2
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -5640,8 +5668,8 @@ CREATE INDEX "IDX_QRTZ_T_J"
PCTFREE 10 PCTFREE 10
INITRANS 2 INITRANS 2
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -5657,8 +5685,8 @@ CREATE INDEX "IDX_QRTZ_T_JG"
PCTFREE 10 PCTFREE 10
INITRANS 2 INITRANS 2
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -5672,8 +5700,8 @@ CREATE INDEX "IDX_QRTZ_T_NEXT_FIRE_TIME"
PCTFREE 10 PCTFREE 10
INITRANS 2 INITRANS 2
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -5687,8 +5715,8 @@ CREATE INDEX "IDX_QRTZ_T_NFT_ST"
PCTFREE 10 PCTFREE 10
INITRANS 2 INITRANS 2
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -5704,8 +5732,8 @@ CREATE INDEX "IDX_QRTZ_T_NFT_ST_MISFIRE"
PCTFREE 10 PCTFREE 10
INITRANS 2 INITRANS 2
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1
@ -5719,8 +5747,8 @@ CREATE INDEX "IDX_QRTZ_T_STATE"
PCTFREE 10 PCTFREE 10
INITRANS 2 INITRANS 2
STORAGE ( STORAGE (
INITIAL 65536 INITIAL 65536
NEXT 1048576 NEXT 1048576
MINEXTENTS 1 MINEXTENTS 1
MAXEXTENTS 2147483645 MAXEXTENTS 2147483645
FREELISTS 1 FREELISTS 1

@ -20,7 +20,7 @@
-- Sequence structure for bpm_form_seq -- Sequence structure for bpm_form_seq
-- ---------------------------- -- ----------------------------
DROP SEQUENCE IF EXISTS "bpm_form_seq"; DROP SEQUENCE IF EXISTS "bpm_form_seq";
CREATE SEQUENCE "bpm_form_seq" CREATE SEQUENCE "bpm_form_seq"
INCREMENT 1 INCREMENT 1
MAXVALUE 9223372036854775807 MAXVALUE 9223372036854775807
CACHE 1; CACHE 1;
@ -29,7 +29,7 @@ CACHE 1;
-- Sequence structure for bpm_oa_leave_seq -- Sequence structure for bpm_oa_leave_seq
-- ---------------------------- -- ----------------------------
DROP SEQUENCE IF EXISTS "bpm_oa_leave_seq"; DROP SEQUENCE IF EXISTS "bpm_oa_leave_seq";
CREATE SEQUENCE "bpm_oa_leave_seq" CREATE SEQUENCE "bpm_oa_leave_seq"
INCREMENT 1 INCREMENT 1
MAXVALUE 9223372036854775807 MAXVALUE 9223372036854775807
CACHE 1; CACHE 1;
@ -38,7 +38,7 @@ CACHE 1;
-- Sequence structure for bpm_process_definition_ext_seq -- Sequence structure for bpm_process_definition_ext_seq
-- ---------------------------- -- ----------------------------
DROP SEQUENCE IF EXISTS "bpm_process_definition_ext_seq"; DROP SEQUENCE IF EXISTS "bpm_process_definition_ext_seq";
CREATE SEQUENCE "bpm_process_definition_ext_seq" CREATE SEQUENCE "bpm_process_definition_ext_seq"
INCREMENT 1 INCREMENT 1
MAXVALUE 9223372036854775807 MAXVALUE 9223372036854775807
CACHE 1; CACHE 1;
@ -47,7 +47,7 @@ CACHE 1;
-- Sequence structure for bpm_process_instance_ext_seq -- Sequence structure for bpm_process_instance_ext_seq
-- ---------------------------- -- ----------------------------
DROP SEQUENCE IF EXISTS "bpm_process_instance_ext_seq"; DROP SEQUENCE IF EXISTS "bpm_process_instance_ext_seq";
CREATE SEQUENCE "bpm_process_instance_ext_seq" CREATE SEQUENCE "bpm_process_instance_ext_seq"
INCREMENT 1 INCREMENT 1
MAXVALUE 9223372036854775807 MAXVALUE 9223372036854775807
CACHE 1; CACHE 1;
@ -56,7 +56,7 @@ CACHE 1;
-- Sequence structure for bpm_task_assign_rule_seq -- Sequence structure for bpm_task_assign_rule_seq
-- ---------------------------- -- ----------------------------
DROP SEQUENCE IF EXISTS "bpm_task_assign_rule_seq"; DROP SEQUENCE IF EXISTS "bpm_task_assign_rule_seq";
CREATE SEQUENCE "bpm_task_assign_rule_seq" CREATE SEQUENCE "bpm_task_assign_rule_seq"
INCREMENT 1 INCREMENT 1
MAXVALUE 9223372036854775807 MAXVALUE 9223372036854775807
CACHE 1; CACHE 1;
@ -65,7 +65,7 @@ CACHE 1;
-- Sequence structure for bpm_task_ext_seq -- Sequence structure for bpm_task_ext_seq
-- ---------------------------- -- ----------------------------
DROP SEQUENCE IF EXISTS "bpm_task_ext_seq"; DROP SEQUENCE IF EXISTS "bpm_task_ext_seq";
CREATE SEQUENCE "bpm_task_ext_seq" CREATE SEQUENCE "bpm_task_ext_seq"
INCREMENT 1 INCREMENT 1
MAXVALUE 9223372036854775807 MAXVALUE 9223372036854775807
CACHE 1; CACHE 1;
@ -74,7 +74,7 @@ CACHE 1;
-- Sequence structure for bpm_user_group_seq -- Sequence structure for bpm_user_group_seq
-- ---------------------------- -- ----------------------------
DROP SEQUENCE IF EXISTS "bpm_user_group_seq"; DROP SEQUENCE IF EXISTS "bpm_user_group_seq";
CREATE SEQUENCE "bpm_user_group_seq" CREATE SEQUENCE "bpm_user_group_seq"
INCREMENT 1 INCREMENT 1
MAXVALUE 9223372036854775807 MAXVALUE 9223372036854775807
CACHE 1; CACHE 1;
@ -83,7 +83,7 @@ CACHE 1;
-- Sequence structure for infra_api_access_log_seq -- Sequence structure for infra_api_access_log_seq
-- ---------------------------- -- ----------------------------
DROP SEQUENCE IF EXISTS "infra_api_access_log_seq"; DROP SEQUENCE IF EXISTS "infra_api_access_log_seq";
CREATE SEQUENCE "infra_api_access_log_seq" CREATE SEQUENCE "infra_api_access_log_seq"
INCREMENT 1 INCREMENT 1
MAXVALUE 9223372036854775807 MAXVALUE 9223372036854775807
CACHE 1; CACHE 1;
@ -92,7 +92,7 @@ CACHE 1;
-- Sequence structure for infra_api_error_log_seq -- Sequence structure for infra_api_error_log_seq
-- ---------------------------- -- ----------------------------
DROP SEQUENCE IF EXISTS "infra_api_error_log_seq"; DROP SEQUENCE IF EXISTS "infra_api_error_log_seq";
CREATE SEQUENCE "infra_api_error_log_seq" CREATE SEQUENCE "infra_api_error_log_seq"
INCREMENT 1 INCREMENT 1
MAXVALUE 9223372036854775807 MAXVALUE 9223372036854775807
CACHE 1; CACHE 1;
@ -101,7 +101,7 @@ CACHE 1;
-- Sequence structure for infra_codegen_column_seq -- Sequence structure for infra_codegen_column_seq
-- ---------------------------- -- ----------------------------
DROP SEQUENCE IF EXISTS "infra_codegen_column_seq"; DROP SEQUENCE IF EXISTS "infra_codegen_column_seq";
CREATE SEQUENCE "infra_codegen_column_seq" CREATE SEQUENCE "infra_codegen_column_seq"
INCREMENT 1 INCREMENT 1
MAXVALUE 9223372036854775807 MAXVALUE 9223372036854775807
CACHE 1; CACHE 1;
@ -110,7 +110,7 @@ CACHE 1;
-- Sequence structure for infra_codegen_table_seq -- Sequence structure for infra_codegen_table_seq
-- ---------------------------- -- ----------------------------
DROP SEQUENCE IF EXISTS "infra_codegen_table_seq"; DROP SEQUENCE IF EXISTS "infra_codegen_table_seq";
CREATE SEQUENCE "infra_codegen_table_seq" CREATE SEQUENCE "infra_codegen_table_seq"
INCREMENT 1 INCREMENT 1
MAXVALUE 9223372036854775807 MAXVALUE 9223372036854775807
CACHE 1; CACHE 1;
@ -119,7 +119,7 @@ CACHE 1;
-- Sequence structure for infra_config_seq -- Sequence structure for infra_config_seq
-- ---------------------------- -- ----------------------------
DROP SEQUENCE IF EXISTS "infra_config_seq"; DROP SEQUENCE IF EXISTS "infra_config_seq";
CREATE SEQUENCE "infra_config_seq" CREATE SEQUENCE "infra_config_seq"
INCREMENT 1 INCREMENT 1
MAXVALUE 9223372036854775807 MAXVALUE 9223372036854775807
CACHE 1; CACHE 1;
@ -128,7 +128,7 @@ CACHE 1;
-- Sequence structure for infra_data_source_config_seq -- Sequence structure for infra_data_source_config_seq
-- ---------------------------- -- ----------------------------
DROP SEQUENCE IF EXISTS "infra_data_source_config_seq"; DROP SEQUENCE IF EXISTS "infra_data_source_config_seq";
CREATE SEQUENCE "infra_data_source_config_seq" CREATE SEQUENCE "infra_data_source_config_seq"
INCREMENT 1 INCREMENT 1
MAXVALUE 9223372036854775807 MAXVALUE 9223372036854775807
CACHE 1; CACHE 1;
@ -137,7 +137,7 @@ CACHE 1;
-- Sequence structure for infra_file_config_seq -- Sequence structure for infra_file_config_seq
-- ---------------------------- -- ----------------------------
DROP SEQUENCE IF EXISTS "infra_file_config_seq"; DROP SEQUENCE IF EXISTS "infra_file_config_seq";
CREATE SEQUENCE "infra_file_config_seq" CREATE SEQUENCE "infra_file_config_seq"
INCREMENT 1 INCREMENT 1
MAXVALUE 9223372036854775807 MAXVALUE 9223372036854775807
CACHE 1; CACHE 1;
@ -146,7 +146,7 @@ CACHE 1;
-- Sequence structure for infra_file_content_seq -- Sequence structure for infra_file_content_seq
-- ---------------------------- -- ----------------------------
DROP SEQUENCE IF EXISTS "infra_file_content_seq"; DROP SEQUENCE IF EXISTS "infra_file_content_seq";
CREATE SEQUENCE "infra_file_content_seq" CREATE SEQUENCE "infra_file_content_seq"
INCREMENT 1 INCREMENT 1
MAXVALUE 9223372036854775807 MAXVALUE 9223372036854775807
CACHE 1; CACHE 1;
@ -155,7 +155,7 @@ CACHE 1;
-- Sequence structure for infra_file_seq -- Sequence structure for infra_file_seq
-- ---------------------------- -- ----------------------------
DROP SEQUENCE IF EXISTS "infra_file_seq"; DROP SEQUENCE IF EXISTS "infra_file_seq";
CREATE SEQUENCE "infra_file_seq" CREATE SEQUENCE "infra_file_seq"
INCREMENT 1 INCREMENT 1
MAXVALUE 9223372036854775807 MAXVALUE 9223372036854775807
CACHE 1; CACHE 1;
@ -164,7 +164,7 @@ CACHE 1;
-- Sequence structure for infra_job_log_seq -- Sequence structure for infra_job_log_seq
-- ---------------------------- -- ----------------------------
DROP SEQUENCE IF EXISTS "infra_job_log_seq"; DROP SEQUENCE IF EXISTS "infra_job_log_seq";
CREATE SEQUENCE "infra_job_log_seq" CREATE SEQUENCE "infra_job_log_seq"
INCREMENT 1 INCREMENT 1
MAXVALUE 9223372036854775807 MAXVALUE 9223372036854775807
CACHE 1; CACHE 1;
@ -173,7 +173,7 @@ CACHE 1;
-- Sequence structure for infra_job_seq -- Sequence structure for infra_job_seq
-- ---------------------------- -- ----------------------------
DROP SEQUENCE IF EXISTS "infra_job_seq"; DROP SEQUENCE IF EXISTS "infra_job_seq";
CREATE SEQUENCE "infra_job_seq" CREATE SEQUENCE "infra_job_seq"
INCREMENT 1 INCREMENT 1
MAXVALUE 9223372036854775807 MAXVALUE 9223372036854775807
CACHE 1; CACHE 1;
@ -182,7 +182,7 @@ CACHE 1;
-- Sequence structure for infra_test_demo_seq -- Sequence structure for infra_test_demo_seq
-- ---------------------------- -- ----------------------------
DROP SEQUENCE IF EXISTS "infra_test_demo_seq"; DROP SEQUENCE IF EXISTS "infra_test_demo_seq";
CREATE SEQUENCE "infra_test_demo_seq" CREATE SEQUENCE "infra_test_demo_seq"
INCREMENT 1 INCREMENT 1
MAXVALUE 9223372036854775807 MAXVALUE 9223372036854775807
CACHE 1; CACHE 1;
@ -191,7 +191,7 @@ CACHE 1;
-- Sequence structure for member_user_seq -- Sequence structure for member_user_seq
-- ---------------------------- -- ----------------------------
DROP SEQUENCE IF EXISTS "member_user_seq"; DROP SEQUENCE IF EXISTS "member_user_seq";
CREATE SEQUENCE "member_user_seq" CREATE SEQUENCE "member_user_seq"
INCREMENT 1 INCREMENT 1
MAXVALUE 9223372036854775807 MAXVALUE 9223372036854775807
CACHE 1; CACHE 1;
@ -200,7 +200,7 @@ CACHE 1;
-- Sequence structure for pay_app_seq -- Sequence structure for pay_app_seq
-- ---------------------------- -- ----------------------------
DROP SEQUENCE IF EXISTS "pay_app_seq"; DROP SEQUENCE IF EXISTS "pay_app_seq";
CREATE SEQUENCE "pay_app_seq" CREATE SEQUENCE "pay_app_seq"
INCREMENT 1 INCREMENT 1
MAXVALUE 9223372036854775807 MAXVALUE 9223372036854775807
CACHE 1; CACHE 1;
@ -209,7 +209,7 @@ CACHE 1;
-- Sequence structure for pay_channel_seq -- Sequence structure for pay_channel_seq
-- ---------------------------- -- ----------------------------
DROP SEQUENCE IF EXISTS "pay_channel_seq"; DROP SEQUENCE IF EXISTS "pay_channel_seq";
CREATE SEQUENCE "pay_channel_seq" CREATE SEQUENCE "pay_channel_seq"
INCREMENT 1 INCREMENT 1
MAXVALUE 9223372036854775807 MAXVALUE 9223372036854775807
CACHE 1; CACHE 1;
@ -218,7 +218,7 @@ CACHE 1;
-- Sequence structure for pay_merchant_seq -- Sequence structure for pay_merchant_seq
-- ---------------------------- -- ----------------------------
DROP SEQUENCE IF EXISTS "pay_merchant_seq"; DROP SEQUENCE IF EXISTS "pay_merchant_seq";
CREATE SEQUENCE "pay_merchant_seq" CREATE SEQUENCE "pay_merchant_seq"
INCREMENT 1 INCREMENT 1
MAXVALUE 9223372036854775807 MAXVALUE 9223372036854775807
CACHE 1; CACHE 1;
@ -227,7 +227,7 @@ CACHE 1;
-- Sequence structure for pay_notify_log_seq -- Sequence structure for pay_notify_log_seq
-- ---------------------------- -- ----------------------------
DROP SEQUENCE IF EXISTS "pay_notify_log_seq"; DROP SEQUENCE IF EXISTS "pay_notify_log_seq";
CREATE SEQUENCE "pay_notify_log_seq" CREATE SEQUENCE "pay_notify_log_seq"
INCREMENT 1 INCREMENT 1
MAXVALUE 9223372036854775807 MAXVALUE 9223372036854775807
CACHE 1; CACHE 1;
@ -236,7 +236,7 @@ CACHE 1;
-- Sequence structure for pay_notify_task_seq -- Sequence structure for pay_notify_task_seq
-- ---------------------------- -- ----------------------------
DROP SEQUENCE IF EXISTS "pay_notify_task_seq"; DROP SEQUENCE IF EXISTS "pay_notify_task_seq";
CREATE SEQUENCE "pay_notify_task_seq" CREATE SEQUENCE "pay_notify_task_seq"
INCREMENT 1 INCREMENT 1
MAXVALUE 9223372036854775807 MAXVALUE 9223372036854775807
CACHE 1; CACHE 1;
@ -245,7 +245,7 @@ CACHE 1;
-- Sequence structure for pay_order_extension_seq -- Sequence structure for pay_order_extension_seq
-- ---------------------------- -- ----------------------------
DROP SEQUENCE IF EXISTS "pay_order_extension_seq"; DROP SEQUENCE IF EXISTS "pay_order_extension_seq";
CREATE SEQUENCE "pay_order_extension_seq" CREATE SEQUENCE "pay_order_extension_seq"
INCREMENT 1 INCREMENT 1
MAXVALUE 9223372036854775807 MAXVALUE 9223372036854775807
CACHE 1; CACHE 1;
@ -254,7 +254,7 @@ CACHE 1;
-- Sequence structure for pay_order_seq -- Sequence structure for pay_order_seq
-- ---------------------------- -- ----------------------------
DROP SEQUENCE IF EXISTS "pay_order_seq"; DROP SEQUENCE IF EXISTS "pay_order_seq";
CREATE SEQUENCE "pay_order_seq" CREATE SEQUENCE "pay_order_seq"
INCREMENT 1 INCREMENT 1
MAXVALUE 9223372036854775807 MAXVALUE 9223372036854775807
CACHE 1; CACHE 1;
@ -263,7 +263,7 @@ CACHE 1;
-- Sequence structure for pay_refund_seq -- Sequence structure for pay_refund_seq
-- ---------------------------- -- ----------------------------
DROP SEQUENCE IF EXISTS "pay_refund_seq"; DROP SEQUENCE IF EXISTS "pay_refund_seq";
CREATE SEQUENCE "pay_refund_seq" CREATE SEQUENCE "pay_refund_seq"
INCREMENT 1 INCREMENT 1
MAXVALUE 9223372036854775807 MAXVALUE 9223372036854775807
CACHE 1; CACHE 1;
@ -272,7 +272,7 @@ CACHE 1;
-- Sequence structure for system_dept_seq -- Sequence structure for system_dept_seq
-- ---------------------------- -- ----------------------------
DROP SEQUENCE IF EXISTS "system_dept_seq"; DROP SEQUENCE IF EXISTS "system_dept_seq";
CREATE SEQUENCE "system_dept_seq" CREATE SEQUENCE "system_dept_seq"
INCREMENT 1 INCREMENT 1
MAXVALUE 9223372036854775807 MAXVALUE 9223372036854775807
CACHE 1; CACHE 1;
@ -281,7 +281,7 @@ CACHE 1;
-- Sequence structure for system_dict_data_seq -- Sequence structure for system_dict_data_seq
-- ---------------------------- -- ----------------------------
DROP SEQUENCE IF EXISTS "system_dict_data_seq"; DROP SEQUENCE IF EXISTS "system_dict_data_seq";
CREATE SEQUENCE "system_dict_data_seq" CREATE SEQUENCE "system_dict_data_seq"
INCREMENT 1 INCREMENT 1
MAXVALUE 9223372036854775807 MAXVALUE 9223372036854775807
CACHE 1; CACHE 1;
@ -290,7 +290,7 @@ CACHE 1;
-- Sequence structure for system_dict_type_seq -- Sequence structure for system_dict_type_seq
-- ---------------------------- -- ----------------------------
DROP SEQUENCE IF EXISTS "system_dict_type_seq"; DROP SEQUENCE IF EXISTS "system_dict_type_seq";
CREATE SEQUENCE "system_dict_type_seq" CREATE SEQUENCE "system_dict_type_seq"
INCREMENT 1 INCREMENT 1
MAXVALUE 9223372036854775807 MAXVALUE 9223372036854775807
CACHE 1; CACHE 1;
@ -299,7 +299,7 @@ CACHE 1;
-- Sequence structure for system_error_code_seq -- Sequence structure for system_error_code_seq
-- ---------------------------- -- ----------------------------
DROP SEQUENCE IF EXISTS "system_error_code_seq"; DROP SEQUENCE IF EXISTS "system_error_code_seq";
CREATE SEQUENCE "system_error_code_seq" CREATE SEQUENCE "system_error_code_seq"
INCREMENT 1 INCREMENT 1
MAXVALUE 9223372036854775807 MAXVALUE 9223372036854775807
CACHE 1; CACHE 1;
@ -308,7 +308,7 @@ CACHE 1;
-- Sequence structure for system_login_log_seq -- Sequence structure for system_login_log_seq
-- ---------------------------- -- ----------------------------
DROP SEQUENCE IF EXISTS "system_login_log_seq"; DROP SEQUENCE IF EXISTS "system_login_log_seq";
CREATE SEQUENCE "system_login_log_seq" CREATE SEQUENCE "system_login_log_seq"
INCREMENT 1 INCREMENT 1
MAXVALUE 9223372036854775807 MAXVALUE 9223372036854775807
CACHE 1; CACHE 1;
@ -317,7 +317,7 @@ CACHE 1;
-- Sequence structure for system_menu_seq -- Sequence structure for system_menu_seq
-- ---------------------------- -- ----------------------------
DROP SEQUENCE IF EXISTS "system_menu_seq"; DROP SEQUENCE IF EXISTS "system_menu_seq";
CREATE SEQUENCE "system_menu_seq" CREATE SEQUENCE "system_menu_seq"
INCREMENT 1 INCREMENT 1
MAXVALUE 9223372036854775807 MAXVALUE 9223372036854775807
CACHE 1; CACHE 1;
@ -326,7 +326,7 @@ CACHE 1;
-- Sequence structure for system_notice_seq -- Sequence structure for system_notice_seq
-- ---------------------------- -- ----------------------------
DROP SEQUENCE IF EXISTS "system_notice_seq"; DROP SEQUENCE IF EXISTS "system_notice_seq";
CREATE SEQUENCE "system_notice_seq" CREATE SEQUENCE "system_notice_seq"
INCREMENT 1 INCREMENT 1
MAXVALUE 9223372036854775807 MAXVALUE 9223372036854775807
CACHE 1; CACHE 1;
@ -335,7 +335,7 @@ CACHE 1;
-- Sequence structure for system_oauth2_access_token_seq -- Sequence structure for system_oauth2_access_token_seq
-- ---------------------------- -- ----------------------------
DROP SEQUENCE IF EXISTS "system_oauth2_access_token_seq"; DROP SEQUENCE IF EXISTS "system_oauth2_access_token_seq";
CREATE SEQUENCE "system_oauth2_access_token_seq" CREATE SEQUENCE "system_oauth2_access_token_seq"
INCREMENT 1 INCREMENT 1
MINVALUE 1 MINVALUE 1
MAXVALUE 9223372036854775807 MAXVALUE 9223372036854775807
@ -346,7 +346,7 @@ CACHE 1;
-- Sequence structure for system_oauth2_approve_seq -- Sequence structure for system_oauth2_approve_seq
-- ---------------------------- -- ----------------------------
DROP SEQUENCE IF EXISTS "system_oauth2_approve_seq"; DROP SEQUENCE IF EXISTS "system_oauth2_approve_seq";
CREATE SEQUENCE "system_oauth2_approve_seq" CREATE SEQUENCE "system_oauth2_approve_seq"
INCREMENT 1 INCREMENT 1
MINVALUE 1 MINVALUE 1
MAXVALUE 9223372036854775807 MAXVALUE 9223372036854775807
@ -357,7 +357,7 @@ CACHE 1;
-- Sequence structure for system_oauth2_client_seq -- Sequence structure for system_oauth2_client_seq
-- ---------------------------- -- ----------------------------
DROP SEQUENCE IF EXISTS "system_oauth2_client_seq"; DROP SEQUENCE IF EXISTS "system_oauth2_client_seq";
CREATE SEQUENCE "system_oauth2_client_seq" CREATE SEQUENCE "system_oauth2_client_seq"
INCREMENT 1 INCREMENT 1
MINVALUE 1 MINVALUE 1
MAXVALUE 9223372036854775807 MAXVALUE 9223372036854775807
@ -368,7 +368,7 @@ CACHE 1;
-- Sequence structure for system_oauth2_code_seq -- Sequence structure for system_oauth2_code_seq
-- ---------------------------- -- ----------------------------
DROP SEQUENCE IF EXISTS "system_oauth2_code_seq"; DROP SEQUENCE IF EXISTS "system_oauth2_code_seq";
CREATE SEQUENCE "system_oauth2_code_seq" CREATE SEQUENCE "system_oauth2_code_seq"
INCREMENT 1 INCREMENT 1
MINVALUE 1 MINVALUE 1
MAXVALUE 9223372036854775807 MAXVALUE 9223372036854775807
@ -379,7 +379,7 @@ CACHE 1;
-- Sequence structure for system_oauth2_refresh_token_seq -- Sequence structure for system_oauth2_refresh_token_seq
-- ---------------------------- -- ----------------------------
DROP SEQUENCE IF EXISTS "system_oauth2_refresh_token_seq"; DROP SEQUENCE IF EXISTS "system_oauth2_refresh_token_seq";
CREATE SEQUENCE "system_oauth2_refresh_token_seq" CREATE SEQUENCE "system_oauth2_refresh_token_seq"
INCREMENT 1 INCREMENT 1
MINVALUE 1 MINVALUE 1
MAXVALUE 9223372036854775807 MAXVALUE 9223372036854775807
@ -390,7 +390,7 @@ CACHE 1;
-- Sequence structure for system_operate_log_seq -- Sequence structure for system_operate_log_seq
-- ---------------------------- -- ----------------------------
DROP SEQUENCE IF EXISTS "system_operate_log_seq"; DROP SEQUENCE IF EXISTS "system_operate_log_seq";
CREATE SEQUENCE "system_operate_log_seq" CREATE SEQUENCE "system_operate_log_seq"
INCREMENT 1 INCREMENT 1
MAXVALUE 9223372036854775807 MAXVALUE 9223372036854775807
CACHE 1; CACHE 1;
@ -399,7 +399,7 @@ CACHE 1;
-- Sequence structure for system_post_seq -- Sequence structure for system_post_seq
-- ---------------------------- -- ----------------------------
DROP SEQUENCE IF EXISTS "system_post_seq"; DROP SEQUENCE IF EXISTS "system_post_seq";
CREATE SEQUENCE "system_post_seq" CREATE SEQUENCE "system_post_seq"
INCREMENT 1 INCREMENT 1
MAXVALUE 9223372036854775807 MAXVALUE 9223372036854775807
CACHE 1; CACHE 1;
@ -408,7 +408,7 @@ CACHE 1;
-- Sequence structure for system_role_menu_seq -- Sequence structure for system_role_menu_seq
-- ---------------------------- -- ----------------------------
DROP SEQUENCE IF EXISTS "system_role_menu_seq"; DROP SEQUENCE IF EXISTS "system_role_menu_seq";
CREATE SEQUENCE "system_role_menu_seq" CREATE SEQUENCE "system_role_menu_seq"
INCREMENT 1 INCREMENT 1
MAXVALUE 9223372036854775807 MAXVALUE 9223372036854775807
CACHE 1; CACHE 1;
@ -417,7 +417,7 @@ CACHE 1;
-- Sequence structure for system_role_seq -- Sequence structure for system_role_seq
-- ---------------------------- -- ----------------------------
DROP SEQUENCE IF EXISTS "system_role_seq"; DROP SEQUENCE IF EXISTS "system_role_seq";
CREATE SEQUENCE "system_role_seq" CREATE SEQUENCE "system_role_seq"
INCREMENT 1 INCREMENT 1
MAXVALUE 9223372036854775807 MAXVALUE 9223372036854775807
CACHE 1; CACHE 1;
@ -426,7 +426,7 @@ CACHE 1;
-- Sequence structure for system_sensitive_word_seq -- Sequence structure for system_sensitive_word_seq
-- ---------------------------- -- ----------------------------
DROP SEQUENCE IF EXISTS "system_sensitive_word_seq"; DROP SEQUENCE IF EXISTS "system_sensitive_word_seq";
CREATE SEQUENCE "system_sensitive_word_seq" CREATE SEQUENCE "system_sensitive_word_seq"
INCREMENT 1 INCREMENT 1
MAXVALUE 9223372036854775807 MAXVALUE 9223372036854775807
CACHE 1; CACHE 1;
@ -435,7 +435,7 @@ CACHE 1;
-- Sequence structure for system_sms_channel_seq -- Sequence structure for system_sms_channel_seq
-- ---------------------------- -- ----------------------------
DROP SEQUENCE IF EXISTS "system_sms_channel_seq"; DROP SEQUENCE IF EXISTS "system_sms_channel_seq";
CREATE SEQUENCE "system_sms_channel_seq" CREATE SEQUENCE "system_sms_channel_seq"
INCREMENT 1 INCREMENT 1
MAXVALUE 9223372036854775807 MAXVALUE 9223372036854775807
CACHE 1; CACHE 1;
@ -444,7 +444,7 @@ CACHE 1;
-- Sequence structure for system_sms_code_seq -- Sequence structure for system_sms_code_seq
-- ---------------------------- -- ----------------------------
DROP SEQUENCE IF EXISTS "system_sms_code_seq"; DROP SEQUENCE IF EXISTS "system_sms_code_seq";
CREATE SEQUENCE "system_sms_code_seq" CREATE SEQUENCE "system_sms_code_seq"
INCREMENT 1 INCREMENT 1
MAXVALUE 9223372036854775807 MAXVALUE 9223372036854775807
CACHE 1; CACHE 1;
@ -453,7 +453,7 @@ CACHE 1;
-- Sequence structure for system_sms_log_seq -- Sequence structure for system_sms_log_seq
-- ---------------------------- -- ----------------------------
DROP SEQUENCE IF EXISTS "system_sms_log_seq"; DROP SEQUENCE IF EXISTS "system_sms_log_seq";
CREATE SEQUENCE "system_sms_log_seq" CREATE SEQUENCE "system_sms_log_seq"
INCREMENT 1 INCREMENT 1
MAXVALUE 9223372036854775807 MAXVALUE 9223372036854775807
CACHE 1; CACHE 1;
@ -462,7 +462,7 @@ CACHE 1;
-- Sequence structure for system_sms_template_seq -- Sequence structure for system_sms_template_seq
-- ---------------------------- -- ----------------------------
DROP SEQUENCE IF EXISTS "system_sms_template_seq"; DROP SEQUENCE IF EXISTS "system_sms_template_seq";
CREATE SEQUENCE "system_sms_template_seq" CREATE SEQUENCE "system_sms_template_seq"
INCREMENT 1 INCREMENT 1
MAXVALUE 9223372036854775807 MAXVALUE 9223372036854775807
CACHE 1; CACHE 1;
@ -471,7 +471,7 @@ CACHE 1;
-- Sequence structure for system_social_user_bind_seq -- Sequence structure for system_social_user_bind_seq
-- ---------------------------- -- ----------------------------
DROP SEQUENCE IF EXISTS "system_social_user_bind_seq"; DROP SEQUENCE IF EXISTS "system_social_user_bind_seq";
CREATE SEQUENCE "system_social_user_bind_seq" CREATE SEQUENCE "system_social_user_bind_seq"
INCREMENT 1 INCREMENT 1
MAXVALUE 9223372036854775807 MAXVALUE 9223372036854775807
CACHE 1; CACHE 1;
@ -480,7 +480,7 @@ CACHE 1;
-- Sequence structure for system_social_user_seq -- Sequence structure for system_social_user_seq
-- ---------------------------- -- ----------------------------
DROP SEQUENCE IF EXISTS "system_social_user_seq"; DROP SEQUENCE IF EXISTS "system_social_user_seq";
CREATE SEQUENCE "system_social_user_seq" CREATE SEQUENCE "system_social_user_seq"
INCREMENT 1 INCREMENT 1
MAXVALUE 9223372036854775807 MAXVALUE 9223372036854775807
CACHE 1; CACHE 1;
@ -489,7 +489,7 @@ CACHE 1;
-- Sequence structure for system_tenant_package_seq -- Sequence structure for system_tenant_package_seq
-- ---------------------------- -- ----------------------------
DROP SEQUENCE IF EXISTS "system_tenant_package_seq"; DROP SEQUENCE IF EXISTS "system_tenant_package_seq";
CREATE SEQUENCE "system_tenant_package_seq" CREATE SEQUENCE "system_tenant_package_seq"
INCREMENT 1 INCREMENT 1
MAXVALUE 9223372036854775807 MAXVALUE 9223372036854775807
CACHE 1; CACHE 1;
@ -498,7 +498,7 @@ CACHE 1;
-- Sequence structure for system_tenant_seq -- Sequence structure for system_tenant_seq
-- ---------------------------- -- ----------------------------
DROP SEQUENCE IF EXISTS "system_tenant_seq"; DROP SEQUENCE IF EXISTS "system_tenant_seq";
CREATE SEQUENCE "system_tenant_seq" CREATE SEQUENCE "system_tenant_seq"
INCREMENT 1 INCREMENT 1
MAXVALUE 9223372036854775807 MAXVALUE 9223372036854775807
CACHE 1; CACHE 1;
@ -507,7 +507,7 @@ CACHE 1;
-- Sequence structure for system_user_post_seq -- Sequence structure for system_user_post_seq
-- ---------------------------- -- ----------------------------
DROP SEQUENCE IF EXISTS "system_user_post_seq"; DROP SEQUENCE IF EXISTS "system_user_post_seq";
CREATE SEQUENCE "system_user_post_seq" CREATE SEQUENCE "system_user_post_seq"
INCREMENT 1 INCREMENT 1
MAXVALUE 9223372036854775807 MAXVALUE 9223372036854775807
CACHE 1; CACHE 1;
@ -516,7 +516,7 @@ CACHE 1;
-- Sequence structure for system_user_role_seq -- Sequence structure for system_user_role_seq
-- ---------------------------- -- ----------------------------
DROP SEQUENCE IF EXISTS "system_user_role_seq"; DROP SEQUENCE IF EXISTS "system_user_role_seq";
CREATE SEQUENCE "system_user_role_seq" CREATE SEQUENCE "system_user_role_seq"
INCREMENT 1 INCREMENT 1
MAXVALUE 9223372036854775807 MAXVALUE 9223372036854775807
CACHE 1; CACHE 1;
@ -525,7 +525,7 @@ CACHE 1;
-- Sequence structure for system_user_seq -- Sequence structure for system_user_seq
-- ---------------------------- -- ----------------------------
DROP SEQUENCE IF EXISTS "system_user_seq"; DROP SEQUENCE IF EXISTS "system_user_seq";
CREATE SEQUENCE "system_user_seq" CREATE SEQUENCE "system_user_seq"
INCREMENT 1 INCREMENT 1
MAXVALUE 9223372036854775807 MAXVALUE 9223372036854775807
CACHE 1; CACHE 1;
@ -2267,7 +2267,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 (62, 0, '', '0', 'infra_api_error_log_process_status', 0, 'primary', '', NULL, '', '2021-02-26 07:07:19', '1', '2022-02-16 20:14:17', 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 (62, 0, '', '0', 'infra_api_error_log_process_status', 0, 'primary', '', NULL, '', '2021-02-26 07:07:19', '1', '2022-02-16 20:14:17', 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 (63, 1, '', '1', 'infra_api_error_log_process_status', 0, 'success', '', NULL, '', '2021-02-26 07:07:26', '1', '2022-02-16 20:14:08', 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 (63, 1, '', '1', 'infra_api_error_log_process_status', 0, 'success', '', NULL, '', '2021-02-26 07:07:26', '1', '2022-02-16 20:14:08', 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 (64, 2, '', '2', 'infra_api_error_log_process_status', 0, 'danger', '', NULL, '', '2021-02-26 07:07:34', '1', '2022-02-16 20:14:14', 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 (64, 2, '', '2', 'infra_api_error_log_process_status', 0, 'danger', '', NULL, '', '2021-02-26 07:07:34', '1', '2022-02-16 20:14:14', 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 (65, 1, '', 'YUN_PIAN', 'system_sms_channel_code', 0, 'success', '', NULL, '1', '2021-04-05 01:05:14', '1', '2022-02-16 10:09:55', 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 (66, 2, '', 'ALIYUN', 'system_sms_channel_code', 0, 'primary', '', NULL, '1', '2021-04-05 01:05:26', '1', '2022-02-16 10:09:52', 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 (66, 2, '', 'ALIYUN', 'system_sms_channel_code', 0, 'primary', '', NULL, '1', '2021-04-05 01:05:26', '1', '2022-02-16 10:09:52', 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 (67, 1, '', '1', 'system_sms_template_type', 0, 'warning', '', NULL, '1', '2021-04-05 21:50:57', '1', '2022-02-16 12:48:30', 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 (67, 1, '', '1', 'system_sms_template_type', 0, 'warning', '', NULL, '1', '2021-04-05 21:50:57', '1', '2022-02-16 12:48:30', 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 (68, 2, '', '2', 'system_sms_template_type', 0, 'primary', '', NULL, '1', '2021-04-05 21:51:08', '1', '2022-02-16 12:48:27', 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 (68, 2, '', '2', 'system_sms_template_type', 0, 'primary', '', NULL, '1', '2021-04-05 21:51:08', '1', '2022-02-16 12:48:27', 0);
@ -2358,38 +2357,58 @@ COMMIT;
-- Table structure for system_dict_type -- Table structure for system_dict_type
-- ---------------------------- -- ----------------------------
DROP TABLE IF EXISTS "system_dict_type"; DROP TABLE IF EXISTS "system_dict_type";
CREATE TABLE "system_dict_type" ( CREATE TABLE "system_dict_type"(
"id" int8 NOT NULL, "id" int8 NOT NULL,
"name" varchar(100) COLLATE "pg_catalog"."default" NOT NULL, "name" varchar(100) COLLATE "pg_catalog"."default" NOT NULL,
"type" varchar(100) COLLATE "pg_catalog"."default" NOT NULL, "type" varchar(100) COLLATE "pg_catalog"."default" NOT NULL,
"status" int2 NOT NULL, "status" int2 NOT NULL,
"remark" varchar(500) COLLATE "pg_catalog"."default", "remark" varchar(500) COLLATE "pg_catalog"."default",
"creator" varchar(64) COLLATE "pg_catalog"."default", "creator" varchar(64) COLLATE "pg_catalog"."default",
"create_time" timestamp(6) NOT NULL, "create_time" timestamp(6) NOT NULL,
"updater" varchar(64) COLLATE "pg_catalog"."default", "updater" varchar(64) COLLATE "pg_catalog"."default",
"update_time" timestamp(6) NOT NULL, "update_time" timestamp(6) NOT NULL,
"deleted" int2 NOT NULL DEFAULT 0 "deleted_time" timestamp(6),
"deleted" int2 NOT NULL DEFAULT 0
) )
; ;
COMMENT ON COLUMN "system_dict_type"."id" IS ''; COMMENT
COMMENT ON COLUMN "system_dict_type"."name" IS ''; ON COLUMN "system_dict_type"."id" IS '';
COMMENT ON COLUMN "system_dict_type"."type" IS ''; COMMENT
COMMENT ON COLUMN "system_dict_type"."status" IS '0 1'; ON COLUMN "system_dict_type"."name" IS '';
COMMENT ON COLUMN "system_dict_type"."remark" IS ''; COMMENT
COMMENT ON COLUMN "system_dict_type"."creator" IS ''; ON COLUMN "system_dict_type"."type" IS '';
COMMENT ON COLUMN "system_dict_type"."create_time" IS ''; COMMENT
COMMENT ON COLUMN "system_dict_type"."updater" IS ''; ON COLUMN "system_dict_type"."status" IS '0 1';
COMMENT ON COLUMN "system_dict_type"."update_time" IS ''; COMMENT
COMMENT ON COLUMN "system_dict_type"."deleted" IS ''; ON COLUMN "system_dict_type"."remark" IS '';
COMMENT ON TABLE "system_dict_type" IS ''; COMMENT
ON COLUMN "system_dict_type"."creator" IS '';
COMMENT
ON COLUMN "system_dict_type"."create_time" IS '';
COMMENT
ON COLUMN "system_dict_type"."updater" IS '';
COMMENT
ON COLUMN "system_dict_type"."update_time" IS '';
COMMENT
ON COLUMN "system_dict_type"."deleted_time" IS '';
COMMENT
ON COLUMN "system_dict_type"."deleted" IS '';
COMMENT
ON TABLE "system_dict_type" IS '';
-- ---------------------------- -- ----------------------------
-- Records of system_dict_type -- Records of system_dict_type
-- ---------------------------- -- ----------------------------
BEGIN; BEGIN;
INSERT INTO "system_dict_type" ("id", "name", "type", "status", "remark", "creator", "create_time", "updater", "update_time", "deleted") VALUES (1, '', 'system_user_sex', 0, NULL, 'admin', '2021-01-05 17:03:48', '', '2022-02-01 16:30:31', 0); INSERT INTO "system_dict_type" ("id", "name", "type", "status", "remark", "creator", "create_time", "updater",
INSERT INTO "system_dict_type" ("id", "name", "type", "status", "remark", "creator", "create_time", "updater", "update_time", "deleted") VALUES (6, '', 'infra_config_type', 0, NULL, 'admin', '2021-01-05 17:03:48', '', '2022-02-01 16:36:54', 0); "update_time", "deleted")
INSERT INTO "system_dict_type" ("id", "name", "type", "status", "remark", "creator", "create_time", "updater", "update_time", "deleted") VALUES (7, '', 'system_notice_type', 0, NULL, 'admin', '2021-01-05 17:03:48', '', '2022-02-01 16:35:26', 0); VALUES (1, '', 'system_user_sex', 0, NULL, 'admin', '2021-01-05 17:03:48', '', '2022-02-01 16:30:31', 0);
INSERT INTO "system_dict_type" ("id", "name", "type", "status", "remark", "creator", "create_time", "updater",
"update_time", "deleted")
VALUES (6, '', 'infra_config_type', 0, NULL, 'admin', '2021-01-05 17:03:48', '', '2022-02-01 16:36:54', 0);
INSERT INTO "system_dict_type" ("id", "name", "type", "status", "remark", "creator", "create_time", "updater",
"update_time", "deleted")
VALUES (7, '', 'system_notice_type', 0, NULL, 'admin', '2021-01-05 17:03:48', '', '2022-02-01 16:35:26', 0);
INSERT INTO "system_dict_type" ("id", "name", "type", "status", "remark", "creator", "create_time", "updater", "update_time", "deleted") VALUES (9, '', 'system_operate_type', 0, NULL, 'admin', '2021-01-05 17:03:48', '1', '2022-02-16 09:32:21', 0); INSERT INTO "system_dict_type" ("id", "name", "type", "status", "remark", "creator", "create_time", "updater", "update_time", "deleted") VALUES (9, '', 'system_operate_type', 0, NULL, 'admin', '2021-01-05 17:03:48', '1', '2022-02-16 09:32:21', 0);
INSERT INTO "system_dict_type" ("id", "name", "type", "status", "remark", "creator", "create_time", "updater", "update_time", "deleted") VALUES (10, '', 'common_status', 0, NULL, 'admin', '2021-01-05 17:03:48', '', '2022-02-01 16:21:28', 0); INSERT INTO "system_dict_type" ("id", "name", "type", "status", "remark", "creator", "create_time", "updater", "update_time", "deleted") VALUES (10, '', 'common_status', 0, NULL, 'admin', '2021-01-05 17:03:48', '', '2022-02-01 16:21:28', 0);
INSERT INTO "system_dict_type" ("id", "name", "type", "status", "remark", "creator", "create_time", "updater", "update_time", "deleted") VALUES (11, 'Boolean ', 'infra_boolean_string', 0, 'boolean ', '', '2021-01-19 03:20:08', '', '2022-02-01 16:37:10', 0); INSERT INTO "system_dict_type" ("id", "name", "type", "status", "remark", "creator", "create_time", "updater", "update_time", "deleted") VALUES (11, 'Boolean ', 'infra_boolean_string', 0, 'boolean ', '', '2021-01-19 03:20:08', '', '2022-02-01 16:37:10', 0);
@ -3519,7 +3538,6 @@ COMMENT ON TABLE "system_sms_channel" IS '短信渠道';
-- Records of system_sms_channel -- Records of system_sms_channel
-- ---------------------------- -- ----------------------------
BEGIN; BEGIN;
INSERT INTO "system_sms_channel" ("id", "signature", "code", "status", "remark", "api_key", "api_secret", "callback_url", "creator", "create_time", "updater", "update_time", "deleted") VALUES (1, '', 'YUN_PIAN', 0, '', '1555a14277cb8a608cf45a9e6a80d510', NULL, 'http://vdwapu.natappfree.cc/admin-api/system/sms/callback/yunpian', '', '2021-03-31 06:12:20', '1', '2022-02-23 16:48:44', 0);
INSERT INTO "system_sms_channel" ("id", "signature", "code", "status", "remark", "api_key", "api_secret", "callback_url", "creator", "create_time", "updater", "update_time", "deleted") VALUES (2, 'Ballcat', 'ALIYUN', 0, '', 'LTAI5tCnKso2uG3kJ5gRav88', 'fGJ5SNXL7P1NHNRmJ7DJaMJGPyE55C', NULL, '', '2021-03-31 11:53:10', '1', '2021-04-14 00:08:37', 0); INSERT INTO "system_sms_channel" ("id", "signature", "code", "status", "remark", "api_key", "api_secret", "callback_url", "creator", "create_time", "updater", "update_time", "deleted") VALUES (2, 'Ballcat', 'ALIYUN', 0, '', 'LTAI5tCnKso2uG3kJ5gRav88', 'fGJ5SNXL7P1NHNRmJ7DJaMJGPyE55C', NULL, '', '2021-03-31 11:53:10', '1', '2021-04-14 00:08:37', 0);
INSERT INTO "system_sms_channel" ("id", "signature", "code", "status", "remark", "api_key", "api_secret", "callback_url", "creator", "create_time", "updater", "update_time", "deleted") VALUES (4, '', 'DEBUG_DING_TALK', 0, '123', '696b5d8ead48071237e4aa5861ff08dbadb2b4ded1c688a7b7c9afc615579859', 'SEC5c4e5ff888bc8a9923ae47f59e7ccd30af1f14d93c55b4e2c9cb094e35aeed67', NULL, '1', '2021-04-13 00:23:14', '1', '2022-03-27 20:29:49', 0); INSERT INTO "system_sms_channel" ("id", "signature", "code", "status", "remark", "api_key", "api_secret", "callback_url", "creator", "create_time", "updater", "update_time", "deleted") VALUES (4, '', 'DEBUG_DING_TALK', 0, '123', '696b5d8ead48071237e4aa5861ff08dbadb2b4ded1c688a7b7c9afc615579859', 'SEC5c4e5ff888bc8a9923ae47f59e7ccd30af1f14d93c55b4e2c9cb094e35aeed67', NULL, '1', '2021-04-13 00:23:14', '1', '2022-03-27 20:29:49', 0);
INSERT INTO "system_sms_channel" ("id", "signature", "code", "status", "remark", "api_key", "api_secret", "callback_url", "creator", "create_time", "updater", "update_time", "deleted") VALUES (6, '', 'DEBUG_DING_TALK', 0, NULL, '696b5d8ead48071237e4aa5861ff08dbadb2b4ded1c688a7b7c9afc615579859', 'SEC5c4e5ff888bc8a9923ae47f59e7ccd30af1f14d93c55b4e2c9cb094e35aeed67', NULL, '1', '2022-04-10 23:07:59', '1', '2022-04-10 23:07:59', 0); INSERT INTO "system_sms_channel" ("id", "signature", "code", "status", "remark", "api_key", "api_secret", "callback_url", "creator", "create_time", "updater", "update_time", "deleted") VALUES (6, '', 'DEBUG_DING_TALK', 0, NULL, '696b5d8ead48071237e4aa5861ff08dbadb2b4ded1c688a7b7c9afc615579859', 'SEC5c4e5ff888bc8a9923ae47f59e7ccd30af1f14d93c55b4e2c9cb094e35aeed67', NULL, '1', '2022-04-10 23:07:59', '1', '2022-04-10 23:07:59', 0);

@ -5545,11 +5545,7 @@ GO
INSERT INTO [dbo].[system_dict_data] ([id], [sort], [label], [value], [dict_type], [status], [color_type], [css_class], [remark], [creator], [create_time], [updater], [update_time], [deleted]) VALUES (N'63', N'1', N'', N'1', N'infra_api_error_log_process_status', N'0', N'success', N'', NULL, N'', N'2021-02-26 07:07:26.0000000', N'1', N'2022-02-16 20:14:08.0000000', N'0') INSERT INTO [dbo].[system_dict_data] ([id], [sort], [label], [value], [dict_type], [status], [color_type], [css_class], [remark], [creator], [create_time], [updater], [update_time], [deleted]) VALUES (N'63', N'1', N'', N'1', N'infra_api_error_log_process_status', N'0', N'success', N'', NULL, N'', N'2021-02-26 07:07:26.0000000', N'1', N'2022-02-16 20:14:08.0000000', N'0')
GO GO
INSERT INTO [dbo].[system_dict_data] ([id], [sort], [label], [value], [dict_type], [status], [color_type], [css_class], [remark], [creator], [create_time], [updater], [update_time], [deleted]) VALUES (N'64', N'2', N'', N'2', N'infra_api_error_log_process_status', N'0', N'danger', N'', NULL, N'', N'2021-02-26 07:07:34.0000000', N'1', N'2022-02-16 20:14:14.0000000', N'0')
GO
INSERT INTO [dbo].[system_dict_data] ([id], [sort], [label], [value], [dict_type], [status], [color_type], [css_class], [remark], [creator], [create_time], [updater], [update_time], [deleted]) VALUES (N'65', N'1', N'', N'YUN_PIAN', N'system_sms_channel_code', N'0', N'success', N'', NULL, N'1', N'2021-04-05 01:05:14.0000000', N'1', N'2022-02-16 10:09:55.0000000', N'0')
GO
INSERT INTO [dbo].[system_dict_data] ([id], [sort], [label], [value], [dict_type], [status], [color_type], [css_class], [remark], [creator], [create_time], [updater], [update_time], [deleted]) VALUES (N'66', N'2', N'', N'ALIYUN', N'system_sms_channel_code', N'0', N'primary', N'', NULL, N'1', N'2021-04-05 01:05:26.0000000', N'1', N'2022-02-16 10:09:52.0000000', N'0') INSERT INTO [dbo].[system_dict_data] ([id], [sort], [label], [value], [dict_type], [status], [color_type], [css_class], [remark], [creator], [create_time], [updater], [update_time], [deleted]) VALUES (N'66', N'2', N'', N'ALIYUN', N'system_sms_channel_code', N'0', N'primary', N'', NULL, N'1', N'2021-04-05 01:05:26.0000000', N'1', N'2022-02-16 10:09:52.0000000', N'0')
GO GO
@ -5817,18 +5813,51 @@ IF EXISTS (SELECT * FROM sys.all_objects WHERE object_id = OBJECT_ID(N'[dbo].[sy
DROP TABLE [dbo].[system_dict_type] DROP TABLE [dbo].[system_dict_type]
GO GO
CREATE TABLE [dbo].[system_dict_type] ( CREATE TABLE [dbo].[system_dict_type]
[id] bigint IDENTITY(1,1) NOT NULL, (
[name] nvarchar(100) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL, [
[type] nvarchar(100) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL, id]
[status] tinyint NOT NULL, bigint
[remark] nvarchar(500) COLLATE SQL_Latin1_General_CP1_CI_AS NULL, IDENTITY
[creator] nvarchar(64) COLLATE SQL_Latin1_General_CP1_CI_AS NULL, (
[create_time] datetime2(7) NOT NULL, 1,
[updater] nvarchar(64) COLLATE SQL_Latin1_General_CP1_CI_AS NULL, 1
[update_time] datetime2(7) NOT NULL, ) NOT NULL,
[deleted] bit DEFAULT 0 NOT NULL [name] nvarchar
) (
100
) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
[type] nvarchar
(
100
) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
[status] tinyint NOT NULL,
[remark] nvarchar
(
500
) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[creator] nvarchar
(
64
) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[create_time] datetime2
(
7
) NOT NULL,
[updater] nvarchar
(
64
) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[update_time] datetime2
(
7
) NOT NULL,
[deleted_time] datetime2
(
7
),
[deleted] bit DEFAULT 0 NOT NULL
)
GO GO
ALTER TABLE [dbo].[system_dict_type] SET (LOCK_ESCALATION = TABLE) ALTER TABLE [dbo].[system_dict_type] SET (LOCK_ESCALATION = TABLE)
@ -5886,26 +5915,29 @@ GO
EXEC sp_addextendedproperty EXEC sp_addextendedproperty
'MS_Description', N'', 'MS_Description', N'',
'SCHEMA', N'dbo', 'SCHEMA', N'dbo',
'TABLE', N'system_dict_type', 'TABLE', N'system_dict_type',
'COLUMN', N'updater' 'COLUMN', N'updater'
GO GO
EXEC sp_addextendedproperty
EXEC sp_addextendedproperty 'MS_Description', N'',
'MS_Description', N'', 'SCHEMA', N'dbo',
'SCHEMA', N'dbo', 'TABLE', N'system_dict_type',
'TABLE', N'system_dict_type', 'COLUMN', N'update_time'
'COLUMN', N'update_time' GO
GO EXEC sp_addextendedproperty
'MS_Description', N'',
EXEC sp_addextendedproperty 'SCHEMA', N'dbo',
'MS_Description', N'', 'TABLE', N'system_dict_type',
'SCHEMA', N'dbo', 'COLUMN', N'deleted_time'
'TABLE', N'system_dict_type', GO
'COLUMN', N'deleted' EXEC sp_addextendedproperty
GO 'MS_Description', N'',
'SCHEMA', N'dbo',
EXEC sp_addextendedproperty 'TABLE', N'system_dict_type',
'MS_Description', N'', 'COLUMN', N'deleted'
GO
EXEC sp_addextendedproperty
'MS_Description', N'',
'SCHEMA', N'dbo', 'SCHEMA', N'dbo',
'TABLE', N'system_dict_type' 'TABLE', N'system_dict_type'
GO GO
@ -9623,9 +9655,6 @@ GO
SET IDENTITY_INSERT [dbo].[system_sms_channel] ON SET IDENTITY_INSERT [dbo].[system_sms_channel] ON
GO GO
INSERT INTO [dbo].[system_sms_channel] ([id], [signature], [code], [status], [remark], [api_key], [api_secret], [callback_url], [creator], [create_time], [updater], [update_time], [deleted]) VALUES (N'1', N'', N'YUN_PIAN', N'0', N'', N'1555a14277cb8a608cf45a9e6a80d510', NULL, N'http://vdwapu.natappfree.cc/admin-api/system/sms/callback/yunpian', N'', N'2021-03-31 06:12:20.0000000', N'1', N'2022-02-23 16:48:44.0000000', N'0')
GO
INSERT INTO [dbo].[system_sms_channel] ([id], [signature], [code], [status], [remark], [api_key], [api_secret], [callback_url], [creator], [create_time], [updater], [update_time], [deleted]) VALUES (N'2', N'Ballcat', N'ALIYUN', N'0', N'', N'LTAI5tCnKso2uG3kJ5gRav88', N'fGJ5SNXL7P1NHNRmJ7DJaMJGPyE55C', NULL, N'', N'2021-03-31 11:53:10.0000000', N'1', N'2021-04-14 00:08:37.0000000', N'0') INSERT INTO [dbo].[system_sms_channel] ([id], [signature], [code], [status], [remark], [api_key], [api_secret], [callback_url], [creator], [create_time], [updater], [update_time], [deleted]) VALUES (N'2', N'Ballcat', N'ALIYUN', N'0', N'', N'LTAI5tCnKso2uG3kJ5gRav88', N'fGJ5SNXL7P1NHNRmJ7DJaMJGPyE55C', NULL, N'', N'2021-03-31 11:53:10.0000000', N'1', N'2021-04-14 00:08:37.0000000', N'0')
GO GO
@ -11348,7 +11377,7 @@ GO
-- Primary Key structure for table QRTZ_CALENDARS -- Primary Key structure for table QRTZ_CALENDARS
-- ---------------------------- -- ----------------------------
ALTER TABLE [dbo].[QRTZ_CALENDARS] ADD CONSTRAINT [PK_QRTZ_CALENDARS] PRIMARY KEY CLUSTERED ([SCHED_NAME], [CALENDAR_NAME]) ALTER TABLE [dbo].[QRTZ_CALENDARS] ADD CONSTRAINT [PK_QRTZ_CALENDARS] PRIMARY KEY CLUSTERED ([SCHED_NAME], [CALENDAR_NAME])
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY] ON [PRIMARY]
GO GO
@ -11369,7 +11398,7 @@ GO
-- Primary Key structure for table QRTZ_CRON_TRIGGERS -- Primary Key structure for table QRTZ_CRON_TRIGGERS
-- ---------------------------- -- ----------------------------
ALTER TABLE [dbo].[QRTZ_CRON_TRIGGERS] ADD CONSTRAINT [PK_QRTZ_CRON_TRIGGERS] PRIMARY KEY CLUSTERED ([SCHED_NAME], [TRIGGER_NAME], [TRIGGER_GROUP]) ALTER TABLE [dbo].[QRTZ_CRON_TRIGGERS] ADD CONSTRAINT [PK_QRTZ_CRON_TRIGGERS] PRIMARY KEY CLUSTERED ([SCHED_NAME], [TRIGGER_NAME], [TRIGGER_GROUP])
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY] ON [PRIMARY]
GO GO
@ -11378,7 +11407,7 @@ GO
-- Primary Key structure for table QRTZ_FIRED_TRIGGERS -- Primary Key structure for table QRTZ_FIRED_TRIGGERS
-- ---------------------------- -- ----------------------------
ALTER TABLE [dbo].[QRTZ_FIRED_TRIGGERS] ADD CONSTRAINT [PK_QRTZ_FIRED_TRIGGERS] PRIMARY KEY CLUSTERED ([SCHED_NAME], [ENTRY_ID]) ALTER TABLE [dbo].[QRTZ_FIRED_TRIGGERS] ADD CONSTRAINT [PK_QRTZ_FIRED_TRIGGERS] PRIMARY KEY CLUSTERED ([SCHED_NAME], [ENTRY_ID])
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY] ON [PRIMARY]
GO GO
@ -11387,7 +11416,7 @@ GO
-- Primary Key structure for table QRTZ_JOB_DETAILS -- Primary Key structure for table QRTZ_JOB_DETAILS
-- ---------------------------- -- ----------------------------
ALTER TABLE [dbo].[QRTZ_JOB_DETAILS] ADD CONSTRAINT [PK_QRTZ_JOB_DETAILS] PRIMARY KEY CLUSTERED ([SCHED_NAME], [JOB_NAME], [JOB_GROUP]) ALTER TABLE [dbo].[QRTZ_JOB_DETAILS] ADD CONSTRAINT [PK_QRTZ_JOB_DETAILS] PRIMARY KEY CLUSTERED ([SCHED_NAME], [JOB_NAME], [JOB_GROUP])
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY] ON [PRIMARY]
GO GO
@ -11396,7 +11425,7 @@ GO
-- Primary Key structure for table QRTZ_LOCKS -- Primary Key structure for table QRTZ_LOCKS
-- ---------------------------- -- ----------------------------
ALTER TABLE [dbo].[QRTZ_LOCKS] ADD CONSTRAINT [PK_QRTZ_LOCKS] PRIMARY KEY CLUSTERED ([SCHED_NAME], [LOCK_NAME]) ALTER TABLE [dbo].[QRTZ_LOCKS] ADD CONSTRAINT [PK_QRTZ_LOCKS] PRIMARY KEY CLUSTERED ([SCHED_NAME], [LOCK_NAME])
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY] ON [PRIMARY]
GO GO
@ -11405,7 +11434,7 @@ GO
-- Primary Key structure for table QRTZ_PAUSED_TRIGGER_GRPS -- Primary Key structure for table QRTZ_PAUSED_TRIGGER_GRPS
-- ---------------------------- -- ----------------------------
ALTER TABLE [dbo].[QRTZ_PAUSED_TRIGGER_GRPS] ADD CONSTRAINT [PK_QRTZ_PAUSED_TRIGGER_GRPS] PRIMARY KEY CLUSTERED ([SCHED_NAME], [TRIGGER_GROUP]) ALTER TABLE [dbo].[QRTZ_PAUSED_TRIGGER_GRPS] ADD CONSTRAINT [PK_QRTZ_PAUSED_TRIGGER_GRPS] PRIMARY KEY CLUSTERED ([SCHED_NAME], [TRIGGER_GROUP])
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY] ON [PRIMARY]
GO GO
@ -11414,7 +11443,7 @@ GO
-- Primary Key structure for table QRTZ_SCHEDULER_STATE -- Primary Key structure for table QRTZ_SCHEDULER_STATE
-- ---------------------------- -- ----------------------------
ALTER TABLE [dbo].[QRTZ_SCHEDULER_STATE] ADD CONSTRAINT [PK_QRTZ_SCHEDULER_STATE] PRIMARY KEY CLUSTERED ([SCHED_NAME], [INSTANCE_NAME]) ALTER TABLE [dbo].[QRTZ_SCHEDULER_STATE] ADD CONSTRAINT [PK_QRTZ_SCHEDULER_STATE] PRIMARY KEY CLUSTERED ([SCHED_NAME], [INSTANCE_NAME])
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY] ON [PRIMARY]
GO GO
@ -11435,7 +11464,7 @@ GO
-- Primary Key structure for table QRTZ_SIMPLE_TRIGGERS -- Primary Key structure for table QRTZ_SIMPLE_TRIGGERS
-- ---------------------------- -- ----------------------------
ALTER TABLE [dbo].[QRTZ_SIMPLE_TRIGGERS] ADD CONSTRAINT [PK_QRTZ_SIMPLE_TRIGGERS] PRIMARY KEY CLUSTERED ([SCHED_NAME], [TRIGGER_NAME], [TRIGGER_GROUP]) ALTER TABLE [dbo].[QRTZ_SIMPLE_TRIGGERS] ADD CONSTRAINT [PK_QRTZ_SIMPLE_TRIGGERS] PRIMARY KEY CLUSTERED ([SCHED_NAME], [TRIGGER_NAME], [TRIGGER_GROUP])
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY] ON [PRIMARY]
GO GO
@ -11456,7 +11485,7 @@ GO
-- Primary Key structure for table QRTZ_SIMPROP_TRIGGERS -- Primary Key structure for table QRTZ_SIMPROP_TRIGGERS
-- ---------------------------- -- ----------------------------
ALTER TABLE [dbo].[QRTZ_SIMPROP_TRIGGERS] ADD CONSTRAINT [PK_QRTZ_SIMPROP_TRIGGERS] PRIMARY KEY CLUSTERED ([SCHED_NAME], [TRIGGER_NAME], [TRIGGER_GROUP]) ALTER TABLE [dbo].[QRTZ_SIMPROP_TRIGGERS] ADD CONSTRAINT [PK_QRTZ_SIMPROP_TRIGGERS] PRIMARY KEY CLUSTERED ([SCHED_NAME], [TRIGGER_NAME], [TRIGGER_GROUP])
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY] ON [PRIMARY]
GO GO
@ -11477,7 +11506,7 @@ GO
-- Primary Key structure for table QRTZ_TRIGGERS -- Primary Key structure for table QRTZ_TRIGGERS
-- ---------------------------- -- ----------------------------
ALTER TABLE [dbo].[QRTZ_TRIGGERS] ADD CONSTRAINT [PK_QRTZ_TRIGGERS] PRIMARY KEY CLUSTERED ([SCHED_NAME], [TRIGGER_NAME], [TRIGGER_GROUP]) ALTER TABLE [dbo].[QRTZ_TRIGGERS] ADD CONSTRAINT [PK_QRTZ_TRIGGERS] PRIMARY KEY CLUSTERED ([SCHED_NAME], [TRIGGER_NAME], [TRIGGER_GROUP])
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY] ON [PRIMARY]
GO GO
@ -11493,7 +11522,7 @@ GO
-- Primary Key structure for table bpm_form -- Primary Key structure for table bpm_form
-- ---------------------------- -- ----------------------------
ALTER TABLE [dbo].[bpm_form] ADD CONSTRAINT [PK__bpm_form__3213E83F86C2B27F] PRIMARY KEY CLUSTERED ([id]) ALTER TABLE [dbo].[bpm_form] ADD CONSTRAINT [PK__bpm_form__3213E83F86C2B27F] PRIMARY KEY CLUSTERED ([id])
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY] ON [PRIMARY]
GO GO
@ -11509,7 +11538,7 @@ GO
-- Primary Key structure for table bpm_oa_leave -- Primary Key structure for table bpm_oa_leave
-- ---------------------------- -- ----------------------------
ALTER TABLE [dbo].[bpm_oa_leave] ADD CONSTRAINT [PK__bpm_oa_l__3213E83F3569F596] PRIMARY KEY CLUSTERED ([id]) ALTER TABLE [dbo].[bpm_oa_leave] ADD CONSTRAINT [PK__bpm_oa_l__3213E83F3569F596] PRIMARY KEY CLUSTERED ([id])
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY] ON [PRIMARY]
GO GO
@ -11525,7 +11554,7 @@ GO
-- Primary Key structure for table bpm_process_definition_ext -- Primary Key structure for table bpm_process_definition_ext
-- ---------------------------- -- ----------------------------
ALTER TABLE [dbo].[bpm_process_definition_ext] ADD CONSTRAINT [PK__bpm_proc__3213E83F0A8AB015] PRIMARY KEY CLUSTERED ([id]) ALTER TABLE [dbo].[bpm_process_definition_ext] ADD CONSTRAINT [PK__bpm_proc__3213E83F0A8AB015] PRIMARY KEY CLUSTERED ([id])
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY] ON [PRIMARY]
GO GO
@ -11541,7 +11570,7 @@ GO
-- Primary Key structure for table bpm_process_instance_ext -- Primary Key structure for table bpm_process_instance_ext
-- ---------------------------- -- ----------------------------
ALTER TABLE [dbo].[bpm_process_instance_ext] ADD CONSTRAINT [PK__bpm_proc__3213E83FFD88328F] PRIMARY KEY CLUSTERED ([id]) ALTER TABLE [dbo].[bpm_process_instance_ext] ADD CONSTRAINT [PK__bpm_proc__3213E83FFD88328F] PRIMARY KEY CLUSTERED ([id])
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY] ON [PRIMARY]
GO GO
@ -11557,7 +11586,7 @@ GO
-- Primary Key structure for table bpm_task_assign_rule -- Primary Key structure for table bpm_task_assign_rule
-- ---------------------------- -- ----------------------------
ALTER TABLE [dbo].[bpm_task_assign_rule] ADD CONSTRAINT [PK__bpm_task__3213E83F474371C5] PRIMARY KEY CLUSTERED ([id]) ALTER TABLE [dbo].[bpm_task_assign_rule] ADD CONSTRAINT [PK__bpm_task__3213E83F474371C5] PRIMARY KEY CLUSTERED ([id])
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY] ON [PRIMARY]
GO GO
@ -11573,7 +11602,7 @@ GO
-- Primary Key structure for table bpm_task_ext -- Primary Key structure for table bpm_task_ext
-- ---------------------------- -- ----------------------------
ALTER TABLE [dbo].[bpm_task_ext] ADD CONSTRAINT [PK__bpm_task__3213E83FD8AFE1F9] PRIMARY KEY CLUSTERED ([id]) ALTER TABLE [dbo].[bpm_task_ext] ADD CONSTRAINT [PK__bpm_task__3213E83FD8AFE1F9] PRIMARY KEY CLUSTERED ([id])
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY] ON [PRIMARY]
GO GO
@ -11589,7 +11618,7 @@ GO
-- Primary Key structure for table bpm_user_group -- Primary Key structure for table bpm_user_group
-- ---------------------------- -- ----------------------------
ALTER TABLE [dbo].[bpm_user_group] ADD CONSTRAINT [PK__bpm_user__3213E83F25E4725B] PRIMARY KEY CLUSTERED ([id]) ALTER TABLE [dbo].[bpm_user_group] ADD CONSTRAINT [PK__bpm_user__3213E83F25E4725B] PRIMARY KEY CLUSTERED ([id])
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY] ON [PRIMARY]
GO GO
@ -11605,7 +11634,7 @@ GO
-- Primary Key structure for table infra_api_access_log -- Primary Key structure for table infra_api_access_log
-- ---------------------------- -- ----------------------------
ALTER TABLE [dbo].[infra_api_access_log] ADD CONSTRAINT [PK__infra_ap__3213E83F04F27A05] PRIMARY KEY CLUSTERED ([id]) ALTER TABLE [dbo].[infra_api_access_log] ADD CONSTRAINT [PK__infra_ap__3213E83F04F27A05] PRIMARY KEY CLUSTERED ([id])
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY] ON [PRIMARY]
GO GO
@ -11621,7 +11650,7 @@ GO
-- Primary Key structure for table infra_api_error_log -- Primary Key structure for table infra_api_error_log
-- ---------------------------- -- ----------------------------
ALTER TABLE [dbo].[infra_api_error_log] ADD CONSTRAINT [PK__infra_ap__3213E83FCA2446D4] PRIMARY KEY CLUSTERED ([id]) ALTER TABLE [dbo].[infra_api_error_log] ADD CONSTRAINT [PK__infra_ap__3213E83FCA2446D4] PRIMARY KEY CLUSTERED ([id])
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY] ON [PRIMARY]
GO GO
@ -11637,7 +11666,7 @@ GO
-- Primary Key structure for table infra_codegen_column -- Primary Key structure for table infra_codegen_column
-- ---------------------------- -- ----------------------------
ALTER TABLE [dbo].[infra_codegen_column] ADD CONSTRAINT [PK__infra_co__3213E83FA9EC5005] PRIMARY KEY CLUSTERED ([id]) ALTER TABLE [dbo].[infra_codegen_column] ADD CONSTRAINT [PK__infra_co__3213E83FA9EC5005] PRIMARY KEY CLUSTERED ([id])
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY] ON [PRIMARY]
GO GO
@ -11653,7 +11682,7 @@ GO
-- Primary Key structure for table infra_codegen_table -- Primary Key structure for table infra_codegen_table
-- ---------------------------- -- ----------------------------
ALTER TABLE [dbo].[infra_codegen_table] ADD CONSTRAINT [PK__infra_co__3213E83F555031D0] PRIMARY KEY CLUSTERED ([id]) ALTER TABLE [dbo].[infra_codegen_table] ADD CONSTRAINT [PK__infra_co__3213E83F555031D0] PRIMARY KEY CLUSTERED ([id])
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY] ON [PRIMARY]
GO GO
@ -11662,7 +11691,7 @@ GO
-- Primary Key structure for table infra_config -- Primary Key structure for table infra_config
-- ---------------------------- -- ----------------------------
ALTER TABLE [dbo].[infra_config] ADD CONSTRAINT [PK__infra_co__3213E83FF4C71E85] PRIMARY KEY CLUSTERED ([id]) ALTER TABLE [dbo].[infra_config] ADD CONSTRAINT [PK__infra_co__3213E83FF4C71E85] PRIMARY KEY CLUSTERED ([id])
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY] ON [PRIMARY]
GO GO
@ -11678,7 +11707,7 @@ GO
-- Primary Key structure for table infra_data_source_config -- Primary Key structure for table infra_data_source_config
-- ---------------------------- -- ----------------------------
ALTER TABLE [dbo].[infra_data_source_config] ADD CONSTRAINT [PK__infra_da__3213E83F02D21AEB] PRIMARY KEY CLUSTERED ([id]) ALTER TABLE [dbo].[infra_data_source_config] ADD CONSTRAINT [PK__infra_da__3213E83F02D21AEB] PRIMARY KEY CLUSTERED ([id])
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY] ON [PRIMARY]
GO GO
@ -11701,7 +11730,7 @@ GO
-- Primary Key structure for table infra_file_config -- Primary Key structure for table infra_file_config
-- ---------------------------- -- ----------------------------
ALTER TABLE [dbo].[infra_file_config] ADD CONSTRAINT [PK__infra_fi__3213E83F8A7903EA] PRIMARY KEY CLUSTERED ([id]) ALTER TABLE [dbo].[infra_file_config] ADD CONSTRAINT [PK__infra_fi__3213E83F8A7903EA] PRIMARY KEY CLUSTERED ([id])
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY] ON [PRIMARY]
GO GO
@ -11717,7 +11746,7 @@ GO
-- Primary Key structure for table infra_file_content -- Primary Key structure for table infra_file_content
-- ---------------------------- -- ----------------------------
ALTER TABLE [dbo].[infra_file_content] ADD CONSTRAINT [PK__infra_fi__3213E83F033E6045] PRIMARY KEY CLUSTERED ([id]) ALTER TABLE [dbo].[infra_file_content] ADD CONSTRAINT [PK__infra_fi__3213E83F033E6045] PRIMARY KEY CLUSTERED ([id])
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY] ON [PRIMARY]
GO GO
@ -11733,7 +11762,7 @@ GO
-- Primary Key structure for table infra_job -- Primary Key structure for table infra_job
-- ---------------------------- -- ----------------------------
ALTER TABLE [dbo].[infra_job] ADD CONSTRAINT [PK__infra_jo__3213E83F3C7DE10C] PRIMARY KEY CLUSTERED ([id]) ALTER TABLE [dbo].[infra_job] ADD CONSTRAINT [PK__infra_jo__3213E83F3C7DE10C] PRIMARY KEY CLUSTERED ([id])
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY] ON [PRIMARY]
GO GO
@ -11749,7 +11778,7 @@ GO
-- Primary Key structure for table infra_job_log -- Primary Key structure for table infra_job_log
-- ---------------------------- -- ----------------------------
ALTER TABLE [dbo].[infra_job_log] ADD CONSTRAINT [PK__infra_jo__3213E83F4CA8F353] PRIMARY KEY CLUSTERED ([id]) ALTER TABLE [dbo].[infra_job_log] ADD CONSTRAINT [PK__infra_jo__3213E83F4CA8F353] PRIMARY KEY CLUSTERED ([id])
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY] ON [PRIMARY]
GO GO
@ -11772,7 +11801,7 @@ GO
-- Primary Key structure for table member_user -- Primary Key structure for table member_user
-- ---------------------------- -- ----------------------------
ALTER TABLE [dbo].[member_user] ADD CONSTRAINT [PK__member_u__3213E83F0A9AEC0B] PRIMARY KEY CLUSTERED ([id]) ALTER TABLE [dbo].[member_user] ADD CONSTRAINT [PK__member_u__3213E83F0A9AEC0B] PRIMARY KEY CLUSTERED ([id])
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY] ON [PRIMARY]
GO GO
@ -11788,7 +11817,7 @@ GO
-- Primary Key structure for table pay_app -- Primary Key structure for table pay_app
-- ---------------------------- -- ----------------------------
ALTER TABLE [dbo].[pay_app] ADD CONSTRAINT [PK__pay_app__3213E83FB26E0A6B] PRIMARY KEY CLUSTERED ([id]) ALTER TABLE [dbo].[pay_app] ADD CONSTRAINT [PK__pay_app__3213E83FB26E0A6B] PRIMARY KEY CLUSTERED ([id])
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY] ON [PRIMARY]
GO GO
@ -11804,7 +11833,7 @@ GO
-- Primary Key structure for table pay_channel -- Primary Key structure for table pay_channel
-- ---------------------------- -- ----------------------------
ALTER TABLE [dbo].[pay_channel] ADD CONSTRAINT [PK__pay_chan__3213E83F2556A7FC] PRIMARY KEY CLUSTERED ([id]) ALTER TABLE [dbo].[pay_channel] ADD CONSTRAINT [PK__pay_chan__3213E83F2556A7FC] PRIMARY KEY CLUSTERED ([id])
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY] ON [PRIMARY]
GO GO
@ -11820,7 +11849,7 @@ GO
-- Primary Key structure for table pay_merchant -- Primary Key structure for table pay_merchant
-- ---------------------------- -- ----------------------------
ALTER TABLE [dbo].[pay_merchant] ADD CONSTRAINT [PK__pay_merc__3213E83F010D02B8] PRIMARY KEY CLUSTERED ([id]) ALTER TABLE [dbo].[pay_merchant] ADD CONSTRAINT [PK__pay_merc__3213E83F010D02B8] PRIMARY KEY CLUSTERED ([id])
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY] ON [PRIMARY]
GO GO
@ -11836,7 +11865,7 @@ GO
-- Primary Key structure for table pay_notify_log -- Primary Key structure for table pay_notify_log
-- ---------------------------- -- ----------------------------
ALTER TABLE [dbo].[pay_notify_log] ADD CONSTRAINT [PK__pay_noti__3213E83F5F4B3447] PRIMARY KEY CLUSTERED ([id]) ALTER TABLE [dbo].[pay_notify_log] ADD CONSTRAINT [PK__pay_noti__3213E83F5F4B3447] PRIMARY KEY CLUSTERED ([id])
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY] ON [PRIMARY]
GO GO
@ -11852,7 +11881,7 @@ GO
-- Primary Key structure for table pay_notify_task -- Primary Key structure for table pay_notify_task
-- ---------------------------- -- ----------------------------
ALTER TABLE [dbo].[pay_notify_task] ADD CONSTRAINT [PK__pay_noti__3213E83FB9215103] PRIMARY KEY CLUSTERED ([id]) ALTER TABLE [dbo].[pay_notify_task] ADD CONSTRAINT [PK__pay_noti__3213E83FB9215103] PRIMARY KEY CLUSTERED ([id])
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY] ON [PRIMARY]
GO GO
@ -11868,7 +11897,7 @@ GO
-- Primary Key structure for table pay_order -- Primary Key structure for table pay_order
-- ---------------------------- -- ----------------------------
ALTER TABLE [dbo].[pay_order] ADD CONSTRAINT [PK__pay_orde__3213E83F34C95271] PRIMARY KEY CLUSTERED ([id]) ALTER TABLE [dbo].[pay_order] ADD CONSTRAINT [PK__pay_orde__3213E83F34C95271] PRIMARY KEY CLUSTERED ([id])
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY] ON [PRIMARY]
GO GO
@ -11884,7 +11913,7 @@ GO
-- Primary Key structure for table pay_order_extension -- Primary Key structure for table pay_order_extension
-- ---------------------------- -- ----------------------------
ALTER TABLE [dbo].[pay_order_extension] ADD CONSTRAINT [PK__pay_orde__3213E83F5ACB776F] PRIMARY KEY CLUSTERED ([id]) ALTER TABLE [dbo].[pay_order_extension] ADD CONSTRAINT [PK__pay_orde__3213E83F5ACB776F] PRIMARY KEY CLUSTERED ([id])
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY] ON [PRIMARY]
GO GO
@ -11900,7 +11929,7 @@ GO
-- Primary Key structure for table pay_refund -- Primary Key structure for table pay_refund
-- ---------------------------- -- ----------------------------
ALTER TABLE [dbo].[pay_refund] ADD CONSTRAINT [PK__pay_refu__3213E83FBE1B54AC] PRIMARY KEY CLUSTERED ([id]) ALTER TABLE [dbo].[pay_refund] ADD CONSTRAINT [PK__pay_refu__3213E83FBE1B54AC] PRIMARY KEY CLUSTERED ([id])
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY] ON [PRIMARY]
GO GO
@ -11916,7 +11945,7 @@ GO
-- Primary Key structure for table system_dept -- Primary Key structure for table system_dept
-- ---------------------------- -- ----------------------------
ALTER TABLE [dbo].[system_dept] ADD CONSTRAINT [PK__system_d__3213E83FFA72847C] PRIMARY KEY CLUSTERED ([id]) ALTER TABLE [dbo].[system_dept] ADD CONSTRAINT [PK__system_d__3213E83FFA72847C] PRIMARY KEY CLUSTERED ([id])
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY] ON [PRIMARY]
GO GO
@ -11932,7 +11961,7 @@ GO
-- Primary Key structure for table system_dict_data -- Primary Key structure for table system_dict_data
-- ---------------------------- -- ----------------------------
ALTER TABLE [dbo].[system_dict_data] ADD CONSTRAINT [PK__system_d__3213E83F20407597] PRIMARY KEY CLUSTERED ([id]) ALTER TABLE [dbo].[system_dict_data] ADD CONSTRAINT [PK__system_d__3213E83F20407597] PRIMARY KEY CLUSTERED ([id])
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY] ON [PRIMARY]
GO GO
@ -11948,7 +11977,7 @@ GO
-- Primary Key structure for table system_dict_type -- Primary Key structure for table system_dict_type
-- ---------------------------- -- ----------------------------
ALTER TABLE [dbo].[system_dict_type] ADD CONSTRAINT [PK__system_d__3213E83F7C36B1FD] PRIMARY KEY CLUSTERED ([id]) ALTER TABLE [dbo].[system_dict_type] ADD CONSTRAINT [PK__system_d__3213E83F7C36B1FD] PRIMARY KEY CLUSTERED ([id])
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY] ON [PRIMARY]
GO GO
@ -11964,7 +11993,7 @@ GO
-- Primary Key structure for table system_error_code -- Primary Key structure for table system_error_code
-- ---------------------------- -- ----------------------------
ALTER TABLE [dbo].[system_error_code] ADD CONSTRAINT [PK__system_e__3213E83F68B8DFD0] PRIMARY KEY CLUSTERED ([id]) ALTER TABLE [dbo].[system_error_code] ADD CONSTRAINT [PK__system_e__3213E83F68B8DFD0] PRIMARY KEY CLUSTERED ([id])
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY] ON [PRIMARY]
GO GO
@ -11980,7 +12009,7 @@ GO
-- Primary Key structure for table system_login_log -- Primary Key structure for table system_login_log
-- ---------------------------- -- ----------------------------
ALTER TABLE [dbo].[system_login_log] ADD CONSTRAINT [PK__system_l__3213E83F717953E9] PRIMARY KEY CLUSTERED ([id]) ALTER TABLE [dbo].[system_login_log] ADD CONSTRAINT [PK__system_l__3213E83F717953E9] PRIMARY KEY CLUSTERED ([id])
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY] ON [PRIMARY]
GO GO
@ -11996,7 +12025,7 @@ GO
-- Primary Key structure for table system_menu -- Primary Key structure for table system_menu
-- ---------------------------- -- ----------------------------
ALTER TABLE [dbo].[system_menu] ADD CONSTRAINT [PK__system_m__3213E83F14175801] PRIMARY KEY CLUSTERED ([id]) ALTER TABLE [dbo].[system_menu] ADD CONSTRAINT [PK__system_m__3213E83F14175801] PRIMARY KEY CLUSTERED ([id])
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY] ON [PRIMARY]
GO GO
@ -12012,7 +12041,7 @@ GO
-- Primary Key structure for table system_notice -- Primary Key structure for table system_notice
-- ---------------------------- -- ----------------------------
ALTER TABLE [dbo].[system_notice] ADD CONSTRAINT [PK__system_n__3213E83FA158BA8D] PRIMARY KEY CLUSTERED ([id]) ALTER TABLE [dbo].[system_notice] ADD CONSTRAINT [PK__system_n__3213E83FA158BA8D] PRIMARY KEY CLUSTERED ([id])
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY] ON [PRIMARY]
GO GO
@ -12035,7 +12064,7 @@ GO
-- Primary Key structure for table system_oauth2_approve -- Primary Key structure for table system_oauth2_approve
-- ---------------------------- -- ----------------------------
ALTER TABLE [dbo].[system_oauth2_approve] ADD CONSTRAINT [PK__system_o__3213E83F7CC08ED6] PRIMARY KEY CLUSTERED ([id]) ALTER TABLE [dbo].[system_oauth2_approve] ADD CONSTRAINT [PK__system_o__3213E83F7CC08ED6] PRIMARY KEY CLUSTERED ([id])
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY] ON [PRIMARY]
GO GO
@ -12058,7 +12087,7 @@ GO
-- Primary Key structure for table system_oauth2_code -- Primary Key structure for table system_oauth2_code
-- ---------------------------- -- ----------------------------
ALTER TABLE [dbo].[system_oauth2_code] ADD CONSTRAINT [PK__system_o__3213E83F38C13543] PRIMARY KEY CLUSTERED ([id]) ALTER TABLE [dbo].[system_oauth2_code] ADD CONSTRAINT [PK__system_o__3213E83F38C13543] PRIMARY KEY CLUSTERED ([id])
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY] ON [PRIMARY]
GO GO
@ -12074,7 +12103,7 @@ GO
-- Primary Key structure for table system_oauth2_refresh_token -- Primary Key structure for table system_oauth2_refresh_token
-- ---------------------------- -- ----------------------------
ALTER TABLE [dbo].[system_oauth2_refresh_token] ADD CONSTRAINT [PK__system_o__3213E83FCFB541CC] PRIMARY KEY CLUSTERED ([id]) ALTER TABLE [dbo].[system_oauth2_refresh_token] ADD CONSTRAINT [PK__system_o__3213E83FCFB541CC] PRIMARY KEY CLUSTERED ([id])
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY] ON [PRIMARY]
GO GO
@ -12090,7 +12119,7 @@ GO
-- Primary Key structure for table system_operate_log -- Primary Key structure for table system_operate_log
-- ---------------------------- -- ----------------------------
ALTER TABLE [dbo].[system_operate_log] ADD CONSTRAINT [PK__system_o__3213E83F85EC81FD] PRIMARY KEY CLUSTERED ([id]) ALTER TABLE [dbo].[system_operate_log] ADD CONSTRAINT [PK__system_o__3213E83F85EC81FD] PRIMARY KEY CLUSTERED ([id])
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY] ON [PRIMARY]
GO GO
@ -12106,7 +12135,7 @@ GO
-- Primary Key structure for table system_post -- Primary Key structure for table system_post
-- ---------------------------- -- ----------------------------
ALTER TABLE [dbo].[system_post] ADD CONSTRAINT [PK__system_p__3213E83FBC098F34] PRIMARY KEY CLUSTERED ([id]) ALTER TABLE [dbo].[system_post] ADD CONSTRAINT [PK__system_p__3213E83FBC098F34] PRIMARY KEY CLUSTERED ([id])
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY] ON [PRIMARY]
GO GO
@ -12122,7 +12151,7 @@ GO
-- Primary Key structure for table system_role -- Primary Key structure for table system_role
-- ---------------------------- -- ----------------------------
ALTER TABLE [dbo].[system_role] ADD CONSTRAINT [PK__system_r__3213E83F209B43F2] PRIMARY KEY CLUSTERED ([id]) ALTER TABLE [dbo].[system_role] ADD CONSTRAINT [PK__system_r__3213E83F209B43F2] PRIMARY KEY CLUSTERED ([id])
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY] ON [PRIMARY]
GO GO
@ -12138,7 +12167,7 @@ GO
-- Primary Key structure for table system_role_menu -- Primary Key structure for table system_role_menu
-- ---------------------------- -- ----------------------------
ALTER TABLE [dbo].[system_role_menu] ADD CONSTRAINT [PK__system_r__3213E83F6F1E4A9B] PRIMARY KEY CLUSTERED ([id]) ALTER TABLE [dbo].[system_role_menu] ADD CONSTRAINT [PK__system_r__3213E83F6F1E4A9B] PRIMARY KEY CLUSTERED ([id])
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY] ON [PRIMARY]
GO GO
@ -12154,7 +12183,7 @@ GO
-- Primary Key structure for table system_sensitive_word -- Primary Key structure for table system_sensitive_word
-- ---------------------------- -- ----------------------------
ALTER TABLE [dbo].[system_sensitive_word] ADD CONSTRAINT [PK__system_s__3213E83FFFD8E555] PRIMARY KEY CLUSTERED ([id]) ALTER TABLE [dbo].[system_sensitive_word] ADD CONSTRAINT [PK__system_s__3213E83FFFD8E555] PRIMARY KEY CLUSTERED ([id])
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY] ON [PRIMARY]
GO GO
@ -12170,7 +12199,7 @@ GO
-- Primary Key structure for table system_sms_channel -- Primary Key structure for table system_sms_channel
-- ---------------------------- -- ----------------------------
ALTER TABLE [dbo].[system_sms_channel] ADD CONSTRAINT [PK__system_s__3213E83FA96B966E] PRIMARY KEY CLUSTERED ([id]) ALTER TABLE [dbo].[system_sms_channel] ADD CONSTRAINT [PK__system_s__3213E83FA96B966E] PRIMARY KEY CLUSTERED ([id])
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY] ON [PRIMARY]
GO GO
@ -12186,7 +12215,7 @@ GO
-- Primary Key structure for table system_sms_code -- Primary Key structure for table system_sms_code
-- ---------------------------- -- ----------------------------
ALTER TABLE [dbo].[system_sms_code] ADD CONSTRAINT [PK__system_s__3213E83F825CBCB9] PRIMARY KEY CLUSTERED ([id]) ALTER TABLE [dbo].[system_sms_code] ADD CONSTRAINT [PK__system_s__3213E83F825CBCB9] PRIMARY KEY CLUSTERED ([id])
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY] ON [PRIMARY]
GO GO
@ -12202,7 +12231,7 @@ GO
-- Primary Key structure for table system_sms_log -- Primary Key structure for table system_sms_log
-- ---------------------------- -- ----------------------------
ALTER TABLE [dbo].[system_sms_log] ADD CONSTRAINT [PK__system_s__3213E83F5F1968A9] PRIMARY KEY CLUSTERED ([id]) ALTER TABLE [dbo].[system_sms_log] ADD CONSTRAINT [PK__system_s__3213E83F5F1968A9] PRIMARY KEY CLUSTERED ([id])
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY] ON [PRIMARY]
GO GO
@ -12218,7 +12247,7 @@ GO
-- Primary Key structure for table system_sms_template -- Primary Key structure for table system_sms_template
-- ---------------------------- -- ----------------------------
ALTER TABLE [dbo].[system_sms_template] ADD CONSTRAINT [PK__system_s__3213E83F5C91CA37] PRIMARY KEY CLUSTERED ([id]) ALTER TABLE [dbo].[system_sms_template] ADD CONSTRAINT [PK__system_s__3213E83F5C91CA37] PRIMARY KEY CLUSTERED ([id])
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY] ON [PRIMARY]
GO GO
@ -12234,7 +12263,7 @@ GO
-- Primary Key structure for table system_social_user -- Primary Key structure for table system_social_user
-- ---------------------------- -- ----------------------------
ALTER TABLE [dbo].[system_social_user] ADD CONSTRAINT [PK__system_s__3213E83F6EF3863C] PRIMARY KEY CLUSTERED ([id]) ALTER TABLE [dbo].[system_social_user] ADD CONSTRAINT [PK__system_s__3213E83F6EF3863C] PRIMARY KEY CLUSTERED ([id])
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY] ON [PRIMARY]
GO GO
@ -12250,7 +12279,7 @@ GO
-- Primary Key structure for table system_social_user_bind -- Primary Key structure for table system_social_user_bind
-- ---------------------------- -- ----------------------------
ALTER TABLE [dbo].[system_social_user_bind] ADD CONSTRAINT [PK__system_s__3213E83F21F44049] PRIMARY KEY CLUSTERED ([id]) ALTER TABLE [dbo].[system_social_user_bind] ADD CONSTRAINT [PK__system_s__3213E83F21F44049] PRIMARY KEY CLUSTERED ([id])
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY] ON [PRIMARY]
GO GO
@ -12266,7 +12295,7 @@ GO
-- Primary Key structure for table system_tenant -- Primary Key structure for table system_tenant
-- ---------------------------- -- ----------------------------
ALTER TABLE [dbo].[system_tenant] ADD CONSTRAINT [PK__system_t__3213E83FAF444092] PRIMARY KEY CLUSTERED ([id]) ALTER TABLE [dbo].[system_tenant] ADD CONSTRAINT [PK__system_t__3213E83FAF444092] PRIMARY KEY CLUSTERED ([id])
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY] ON [PRIMARY]
GO GO
@ -12282,7 +12311,7 @@ GO
-- Primary Key structure for table system_tenant_package -- Primary Key structure for table system_tenant_package
-- ---------------------------- -- ----------------------------
ALTER TABLE [dbo].[system_tenant_package] ADD CONSTRAINT [PK__system_t__3213E83FA2213DB5] PRIMARY KEY CLUSTERED ([id]) ALTER TABLE [dbo].[system_tenant_package] ADD CONSTRAINT [PK__system_t__3213E83FA2213DB5] PRIMARY KEY CLUSTERED ([id])
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY] ON [PRIMARY]
GO GO
@ -12298,7 +12327,7 @@ GO
-- Primary Key structure for table system_user_post -- Primary Key structure for table system_user_post
-- ---------------------------- -- ----------------------------
ALTER TABLE [dbo].[system_user_post] ADD CONSTRAINT [PK__system_u__3213E83F56DD4107] PRIMARY KEY CLUSTERED ([id]) ALTER TABLE [dbo].[system_user_post] ADD CONSTRAINT [PK__system_u__3213E83F56DD4107] PRIMARY KEY CLUSTERED ([id])
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY] ON [PRIMARY]
GO GO
@ -12314,7 +12343,7 @@ GO
-- Primary Key structure for table system_user_role -- Primary Key structure for table system_user_role
-- ---------------------------- -- ----------------------------
ALTER TABLE [dbo].[system_user_role] ADD CONSTRAINT [PK__system_u__3213E83F3593F652] PRIMARY KEY CLUSTERED ([id]) ALTER TABLE [dbo].[system_user_role] ADD CONSTRAINT [PK__system_u__3213E83F3593F652] PRIMARY KEY CLUSTERED ([id])
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY] ON [PRIMARY]
GO GO
@ -12330,7 +12359,7 @@ GO
-- Primary Key structure for table system_users -- Primary Key structure for table system_users
-- ---------------------------- -- ----------------------------
ALTER TABLE [dbo].[system_users] ADD CONSTRAINT [PK__system_u__3213E83F7CF2516E] PRIMARY KEY CLUSTERED ([id]) ALTER TABLE [dbo].[system_users] ADD CONSTRAINT [PK__system_u__3213E83F7CF2516E] PRIMARY KEY CLUSTERED ([id])
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY] ON [PRIMARY]
GO GO

@ -14,57 +14,61 @@
<url>https://github.com/YunaiV/ruoyi-vue-pro</url> <url>https://github.com/YunaiV/ruoyi-vue-pro</url>
<properties> <properties>
<revision>1.6.3-snapshot</revision> <revision>1.6.6-snapshot</revision>
<!-- 统一依赖管理 --> <!-- 统一依赖管理 -->
<spring.boot.version>2.6.10</spring.boot.version> <spring.boot.version>2.7.7</spring.boot.version>
<!-- Web 相关 --> <!-- Web 相关 -->
<knife4j.version>3.0.3</knife4j.version> <knife4j.version>4.0.0</knife4j.version>
<swagger-annotations.version>1.6.6</swagger-annotations.version> <swagger-annotations.version>1.6.8</swagger-annotations.version>
<servlet.versoin>2.5</servlet.versoin> <servlet.versoin>2.5</servlet.versoin>
<!-- DB 相关 --> <!-- DB 相关 -->
<druid.version>1.2.11</druid.version> <druid.version>1.2.15</druid.version>
<mybatis-plus.version>3.5.2</mybatis-plus.version> <mybatis-plus.version>3.5.3.1</mybatis-plus.version>
<mybatis-plus-generator.version>3.5.2</mybatis-plus-generator.version> <mybatis-plus-generator.version>3.5.3.1</mybatis-plus-generator.version>
<dynamic-datasource.version>3.5.0</dynamic-datasource.version> <dynamic-datasource.version>3.6.1</dynamic-datasource.version>
<redisson.version>3.17.4</redisson.version> <redisson.version>3.18.0</redisson.version>
<!-- Config 配置中心相关 -->
<apollo.version>1.9.2</apollo.version>
<!-- 服务保障相关 --> <!-- 服务保障相关 -->
<lock4j.version>2.2.0</lock4j.version> <lock4j.version>2.2.3</lock4j.version>
<resilience4j.version>1.7.1</resilience4j.version> <resilience4j.version>1.7.1</resilience4j.version>
<!-- 监控相关 --> <!-- 监控相关 -->
<skywalking.version>8.7.0</skywalking.version> <skywalking.version>8.12.0</skywalking.version>
<spring-boot-admin.version>2.6.7</spring-boot-admin.version> <spring-boot-admin.version>2.7.10</spring-boot-admin.version>
<opentracing.version>0.31.0</opentracing.version> <opentracing.version>0.33.0</opentracing.version>
<!-- Test 测试相关 --> <!-- Test 测试相关 -->
<podam.version>7.2.6.RELEASE</podam.version> <podam.version>7.2.11.RELEASE</podam.version>
<jedis-mock.version>0.1.16</jedis-mock.version> <jedis-mock.version>1.0.5</jedis-mock.version>
<mockito-inline.version>4.0.0</mockito-inline.version> <mockito-inline.version>4.11.0</mockito-inline.version>
<!-- Bpm 工作流相关 --> <!-- Bpm 工作流相关 -->
<flowable.version>6.7.0</flowable.version> <flowable.version>6.8.0</flowable.version>
<!-- 工具类相关 --> <!-- 工具类相关 -->
<jasypt-spring-boot-starter.version>3.0.4</jasypt-spring-boot-starter.version> <captcha-plus.version>1.0.1</captcha-plus.version>
<lombok.version>1.18.20</lombok.version> <jsoup.version>1.15.3</jsoup.version>
<mapstruct.version>1.4.1.Final</mapstruct.version> <lombok.version>1.18.24</lombok.version>
<hutool.version>5.7.22</hutool.version> <mapstruct.version>1.5.3.Final</mapstruct.version>
<easyexcel.verion>3.1.1</easyexcel.verion> <hutool.version>5.8.11</hutool.version>
<velocity.version>2.2</velocity.version> <easyexcel.verion>3.1.5</easyexcel.verion>
<velocity.version>2.3</velocity.version>
<screw.version>1.0.5</screw.version> <screw.version>1.0.5</screw.version>
<fastjson.version>1.2.83</fastjson.version> <fastjson.version>1.2.83</fastjson.version>
<guava.version>30.1.1-jre</guava.version> <guava.version>31.1-jre</guava.version>
<guice.version>5.1.0</guice.version> <guice.version>5.1.0</guice.version>
<transmittable-thread-local.version>2.12.2</transmittable-thread-local.version> <transmittable-thread-local.version>2.14.2</transmittable-thread-local.version>
<commons-net.version>3.8.0</commons-net.version> <commons-net.version>3.8.0</commons-net.version>
<jsch.version>0.1.55</jsch.version> <jsch.version>0.1.55</jsch.version>
<tika-core.version>2.4.1</tika-core.version> <tika-core.version>2.6.0</tika-core.version>
<netty-all.version>4.1.86.Final</netty-all.version>
<ip2region.version>2.6.6</ip2region.version>
<!-- 三方云服务相关 --> <!-- 三方云服务相关 -->
<minio.version>8.2.2</minio.version> <okio.version>3.0.0</okio.version>
<aliyun-java-sdk-core.version>4.5.25</aliyun-java-sdk-core.version> <okhttp3.version>4.10.0</okhttp3.version>
<aliyun-java-sdk-dysmsapi.version>2.1.0</aliyun-java-sdk-dysmsapi.version> <minio.version>8.5.1</minio.version>
<tencentcloud-sdk-java.version>3.1.471</tencentcloud-sdk-java.version> <aliyun-java-sdk-core.version>4.6.3</aliyun-java-sdk-core.version>
<yunpian-java-sdk.version>1.2.7</yunpian-java-sdk.version> <aliyun-java-sdk-dysmsapi.version>2.2.1</aliyun-java-sdk-dysmsapi.version>
<tencentcloud-sdk-java.version>3.1.676</tencentcloud-sdk-java.version>
<justauth.version>1.4.0</justauth.version> <justauth.version>1.4.0</justauth.version>
<jimureport.version>1.5.2</jimureport.version> <jimureport.version>1.5.6</jimureport.version>
<xercesImpl.version>2.12.2</xercesImpl.version>
<wx-java-mp.version>4.3.0</wx-java-mp.version>
</properties> </properties>
<dependencyManagement> <dependencyManagement>
@ -129,6 +133,21 @@
<artifactId>yudao-spring-boot-starter-biz-error-code</artifactId> <artifactId>yudao-spring-boot-starter-biz-error-code</artifactId>
<version>${revision}</version> <version>${revision}</version>
</dependency> </dependency>
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-spring-boot-starter-biz-ip</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-spring-boot-starter-captcha</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-spring-boot-starter-desensitize</artifactId>
<version>${revision}</version>
</dependency>
<!-- Spring 核心 --> <!-- Spring 核心 -->
<dependency> <dependency>
@ -153,7 +172,7 @@
<dependency> <dependency>
<groupId>com.github.xiaoymin</groupId> <groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId> <artifactId>knife4j-openapi2-spring-boot-starter</artifactId>
<version>${knife4j.version}</version> <version>${knife4j.version}</version>
<exclusions> <exclusions>
<exclusion> <exclusion>
@ -217,17 +236,6 @@
</dependency> </dependency>
<!-- Config 配置中心相关 --> <!-- Config 配置中心相关 -->
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-spring-boot-starter-config</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>com.ctrip.framework.apollo</groupId>
<artifactId>apollo-client</artifactId> <!-- 引入 Apollo Client 库,实现内嵌的配置中心 -->
<version>${apollo.version}</version>
</dependency>
<!-- Job 定时任务相关 --> <!-- Job 定时任务相关 -->
<dependency> <dependency>
@ -399,12 +407,6 @@
<version>${revision}</version> <version>${revision}</version>
</dependency> </dependency>
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId> <!-- 加解密 -->
<version>${jasypt-spring-boot-starter.version}</version>
</dependency>
<dependency> <dependency>
<groupId>cn.iocoder.boot</groupId> <groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-spring-boot-starter-excel</artifactId> <artifactId>yudao-spring-boot-starter-excel</artifactId>
@ -502,13 +504,48 @@
<artifactId>commons-net</artifactId> <!-- 解决 ftp 连接 --> <artifactId>commons-net</artifactId> <!-- 解决 ftp 连接 -->
<version>${commons-net.version}</version> <version>${commons-net.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.jcraft</groupId> <groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId> <!-- 解决 sftp 连接 --> <artifactId>jsch</artifactId> <!-- 解决 sftp 连接 -->
<version>${jsch.version}</version> <version>${jsch.version}</version>
</dependency> </dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>${netty-all.version}</version>
</dependency>
<dependency>
<groupId>com.xingyuv</groupId>
<artifactId>spring-boot-starter-captcha-plus</artifactId>
<version>${captcha-plus.version}</version>
</dependency>
<dependency>
<groupId>org.lionsoul</groupId>
<artifactId>ip2region</artifactId>
<version>${ip2region.version}</version>
</dependency>
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>${jsoup.version}</version>
</dependency>
<!-- 三方云服务相关 --> <!-- 三方云服务相关 -->
<dependency>
<groupId>com.squareup.okio</groupId>
<artifactId>okio</artifactId>
<version>${okio.version}</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>${okhttp3.version}</version>
</dependency>
<dependency> <dependency>
<groupId>cn.iocoder.boot</groupId> <groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-spring-boot-starter-file</artifactId> <artifactId>yudao-spring-boot-starter-file</artifactId>
@ -521,11 +558,6 @@
</dependency> </dependency>
<!-- SMS SDK begin --> <!-- SMS SDK begin -->
<dependency>
<groupId>com.yunpian.sdk</groupId>
<artifactId>yunpian-java-sdk</artifactId>
<version>${yunpian-java-sdk.version}</version>
</dependency>
<dependency> <dependency>
<groupId>com.aliyun</groupId> <groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId> <artifactId>aliyun-java-sdk-core</artifactId>
@ -548,7 +580,7 @@
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.tencentcloudapi</groupId> <groupId>com.tencentcloudapi</groupId>
<artifactId>tencentcloud-sdk-java</artifactId> <artifactId>tencentcloud-sdk-java-sms</artifactId>
<version>${tencentcloud-sdk-java.version}</version> <version>${tencentcloud-sdk-java.version}</version>
</dependency> </dependency>
<!-- SMS SDK end --> <!-- SMS SDK end -->
@ -559,11 +591,34 @@
<version>${justauth.version}</version> <version>${justauth.version}</version>
</dependency> </dependency>
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>wx-java-mp-spring-boot-starter</artifactId>
<version>${wx-java-mp.version}</version>
</dependency>
<!-- 积木报表--> <!-- 积木报表-->
<dependency> <dependency>
<groupId>org.jeecgframework.jimureport</groupId> <groupId>org.jeecgframework.jimureport</groupId>
<artifactId>jimureport-spring-boot-starter</artifactId> <artifactId>jimureport-spring-boot-starter</artifactId>
<version>${jimureport.version}</version> <version>${jimureport.version}</version>
<exclusions>
<exclusion>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>xerces</groupId>
<artifactId>xercesImpl</artifactId>
<version>${xercesImpl.version}</version>
</dependency>
<!-- SpringBoot Websocket -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
<version>${spring.boot.version}</version>
</dependency> </dependency>
</dependencies> </dependencies>
</dependencyManagement> </dependencyManagement>

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!-- 由于方便大家拷贝,使用不使用 yudao 作为 Maven parent -->
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-example</artifactId>
<version>1.0.0-snapshot</version>
<packaging>pom</packaging>
<modules>
<module>yudao-sso-demo-by-code</module>
<module>yudao-sso-demo-by-password</module>
</modules>
<name>${project.artifactId}</name>
<description>提供各种示例例如说SSO 单点登录</description>
<url>https://github.com/YunaiV/ruoyi-vue-pro</url>
</project>

@ -0,0 +1,65 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!-- 由于方便大家拷贝,使用不使用 yudao 作为 Maven parent -->
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-sso-demo-by-code</artifactId>
<version>1.0.0-snapshot</version>
<packaging>jar</packaging>
<name>${project.artifactId}</name>
<description>基于授权码模式,如何实现 SSO 单点登录?</description>
<url>https://github.com/YunaiV/ruoyi-vue-pro</url>
<properties>
<!-- Maven 相关 -->
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- 统一依赖管理 -->
<spring.boot.version>2.7.7</spring.boot.version>
</properties>
<dependencyManagement>
<dependencies>
<!-- 统一依赖管理 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring.boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- Web 相关 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.11</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
</project>

@ -0,0 +1,13 @@
package cn.iocoder.yudao.ssodemo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SSODemoApplication {
public static void main(String[] args) {
SpringApplication.run(SSODemoApplication.class, args);
}
}

@ -0,0 +1,157 @@
package cn.iocoder.yudao.ssodemo.client;
import cn.iocoder.yudao.ssodemo.client.dto.CommonResult;
import cn.iocoder.yudao.ssodemo.client.dto.oauth2.OAuth2AccessTokenRespDTO;
import cn.iocoder.yudao.ssodemo.client.dto.oauth2.OAuth2CheckTokenRespDTO;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import org.springframework.util.Base64Utils;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import java.nio.charset.StandardCharsets;
/**
* OAuth 2.0
*
* OAuth2OpenController
*/
@Component
public class OAuth2Client {
private static final String BASE_URL = "http://127.0.0.1:48080/admin-api/system/oauth2";
/**
*
*
* 使 1使
*/
public static final Long TENANT_ID = 1L;
private static final String CLIENT_ID = "yudao-sso-demo-by-code";
private static final String CLIENT_SECRET = "test";
// @Resource // 可优化,注册一个 RestTemplate Bean然后注入
private final RestTemplate restTemplate = new RestTemplate();
/**
* 使 code 访
*
* @param code
* @param redirectUri URI
* @return 访
*/
public CommonResult<OAuth2AccessTokenRespDTO> postAccessToken(String code, String redirectUri) {
// 1.1 构建请求头
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
headers.set("tenant-id", TENANT_ID.toString());
addClientHeader(headers);
// 1.2 构建请求参数
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
body.add("grant_type", "authorization_code");
body.add("code", code);
body.add("redirect_uri", redirectUri);
// body.add("state", ""); // 选填;填了会校验
// 2. 执行请求
ResponseEntity<CommonResult<OAuth2AccessTokenRespDTO>> exchange = restTemplate.exchange(
BASE_URL + "/token",
HttpMethod.POST,
new HttpEntity<>(body, headers),
new ParameterizedTypeReference<CommonResult<OAuth2AccessTokenRespDTO>>() {}); // 解决 CommonResult 的泛型丢失
Assert.isTrue(exchange.getStatusCode().is2xxSuccessful(), "响应必须是 200 成功");
return exchange.getBody();
}
/**
* 访
*
* @param token 访
* @return 访
*/
public CommonResult<OAuth2CheckTokenRespDTO> checkToken(String token) {
// 1.1 构建请求头
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
headers.set("tenant-id", TENANT_ID.toString());
addClientHeader(headers);
// 1.2 构建请求参数
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
body.add("token", token);
// 2. 执行请求
ResponseEntity<CommonResult<OAuth2CheckTokenRespDTO>> exchange = restTemplate.exchange(
BASE_URL + "/check-token",
HttpMethod.POST,
new HttpEntity<>(body, headers),
new ParameterizedTypeReference<CommonResult<OAuth2CheckTokenRespDTO>>() {}); // 解决 CommonResult 的泛型丢失
Assert.isTrue(exchange.getStatusCode().is2xxSuccessful(), "响应必须是 200 成功");
return exchange.getBody();
}
/**
* 使访
*
* @param refreshToken
* @return 访
*/
public CommonResult<OAuth2AccessTokenRespDTO> refreshToken(String refreshToken) {
// 1.1 构建请求头
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
headers.set("tenant-id", TENANT_ID.toString());
addClientHeader(headers);
// 1.2 构建请求参数
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
body.add("grant_type", "refresh_token");
body.add("refresh_token", refreshToken);
// 2. 执行请求
ResponseEntity<CommonResult<OAuth2AccessTokenRespDTO>> exchange = restTemplate.exchange(
BASE_URL + "/token",
HttpMethod.POST,
new HttpEntity<>(body, headers),
new ParameterizedTypeReference<CommonResult<OAuth2AccessTokenRespDTO>>() {}); // 解决 CommonResult 的泛型丢失
Assert.isTrue(exchange.getStatusCode().is2xxSuccessful(), "响应必须是 200 成功");
return exchange.getBody();
}
/**
* 访
*
* @param token 访
* @return
*/
public CommonResult<Boolean> revokeToken(String token) {
// 1.1 构建请求头
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
headers.set("tenant-id", TENANT_ID.toString());
addClientHeader(headers);
// 1.2 构建请求参数
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
body.add("token", token);
// 2. 执行请求
ResponseEntity<CommonResult<Boolean>> exchange = restTemplate.exchange(
BASE_URL + "/token",
HttpMethod.DELETE,
new HttpEntity<>(body, headers),
new ParameterizedTypeReference<CommonResult<Boolean>>() {}); // 解决 CommonResult 的泛型丢失
Assert.isTrue(exchange.getStatusCode().is2xxSuccessful(), "响应必须是 200 成功");
return exchange.getBody();
}
private static void addClientHeader(HttpHeaders headers) {
// client 拼接,需要 BASE64 编码
String client = CLIENT_ID + ":" + CLIENT_SECRET;
client = Base64Utils.encodeToString(client.getBytes(StandardCharsets.UTF_8));
headers.add("Authorization", "Basic " + client);
}
}

@ -0,0 +1,73 @@
package cn.iocoder.yudao.ssodemo.client;
import cn.iocoder.yudao.ssodemo.client.dto.CommonResult;
import cn.iocoder.yudao.ssodemo.client.dto.user.UserInfoRespDTO;
import cn.iocoder.yudao.ssodemo.client.dto.user.UserUpdateReqDTO;
import cn.iocoder.yudao.ssodemo.framework.core.LoginUser;
import cn.iocoder.yudao.ssodemo.framework.core.util.SecurityUtils;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
/**
* User
*
* OAuth2UserController
*/
@Component
public class UserClient {
private static final String BASE_URL = "http://127.0.0.1:48080/admin-api//system/oauth2/user";
// @Resource // 可优化,注册一个 RestTemplate Bean然后注入
private final RestTemplate restTemplate = new RestTemplate();
public CommonResult<UserInfoRespDTO> getUser() {
// 1.1 构建请求头
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
headers.set("tenant-id", OAuth2Client.TENANT_ID.toString());
addTokenHeader(headers);
// 1.2 构建请求参数
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
// 2. 执行请求
ResponseEntity<CommonResult<UserInfoRespDTO>> exchange = restTemplate.exchange(
BASE_URL + "/get",
HttpMethod.GET,
new HttpEntity<>(body, headers),
new ParameterizedTypeReference<CommonResult<UserInfoRespDTO>>() {}); // 解决 CommonResult 的泛型丢失
Assert.isTrue(exchange.getStatusCode().is2xxSuccessful(), "响应必须是 200 成功");
return exchange.getBody();
}
public CommonResult<Boolean> updateUser(UserUpdateReqDTO updateReqDTO) {
// 1.1 构建请求头
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.set("tenant-id", OAuth2Client.TENANT_ID.toString());
addTokenHeader(headers);
// 1.2 构建请求参数
// 使用 updateReqDTO 即可
// 2. 执行请求
ResponseEntity<CommonResult<Boolean>> exchange = restTemplate.exchange(
BASE_URL + "/update",
HttpMethod.PUT,
new HttpEntity<>(updateReqDTO, headers),
new ParameterizedTypeReference<CommonResult<Boolean>>() {}); // 解决 CommonResult 的泛型丢失
Assert.isTrue(exchange.getStatusCode().is2xxSuccessful(), "响应必须是 200 成功");
return exchange.getBody();
}
private static void addTokenHeader(HttpHeaders headers) {
LoginUser loginUser = SecurityUtils.getLoginUser();
Assert.notNull(loginUser, "登录用户不能为空");
headers.add("Authorization", "Bearer " + loginUser.getAccessToken());
}
}

@ -0,0 +1,28 @@
package cn.iocoder.yudao.ssodemo.client.dto;
import lombok.Data;
import java.io.Serializable;
/**
*
*
* @param <T>
*/
@Data
public class CommonResult<T> implements Serializable {
/**
*
*/
private Integer code;
/**
*
*/
private T data;
/**
*
*/
private String msg;
}

@ -0,0 +1,45 @@
package cn.iocoder.yudao.ssodemo.client.dto.oauth2;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 访 Response DTO
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class OAuth2AccessTokenRespDTO {
/**
* 访
*/
@JsonProperty("access_token")
private String accessToken;
/**
*
*/
@JsonProperty("refresh_token")
private String refreshToken;
/**
*
*/
@JsonProperty("token_type")
private String tokenType;
/**
*
*/
@JsonProperty("expires_in")
private Long expiresIn;
/**
* 使
*/
private String scope;
}

@ -0,0 +1,59 @@
package cn.iocoder.yudao.ssodemo.client.dto.oauth2;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
/**
* Response DTO
*
* @author
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class OAuth2CheckTokenRespDTO {
/**
*
*/
@JsonProperty("user_id")
private Long userId;
/**
*
*/
@JsonProperty("user_type")
private Integer userType;
/**
*
*/
@JsonProperty("tenant_id")
private Long tenantId;
/**
*
*/
@JsonProperty("client_id")
private String clientId;
/**
*
*/
private List<String> scopes;
/**
* 访
*/
@JsonProperty("access_token")
private String accessToken;
/**
*
*
* / 1000
*/
private Long exp;
}

@ -0,0 +1,97 @@
package cn.iocoder.yudao.ssodemo.client.dto.user;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
/**
* Response dto
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class UserInfoRespDTO {
/**
*
*/
private Long id;
/**
*
*/
private String username;
/**
*
*/
private String nickname;
/**
*
*/
private String email;
/**
*
*/
private String mobile;
/**
*
*/
private Integer sex;
/**
*
*/
private String avatar;
/**
*
*/
private Dept dept;
/**
*
*/
private List<Post> posts;
/**
*
*/
@Data
public static class Dept {
/**
*
*/
private Long id;
/**
*
*/
private String name;
}
/**
*
*/
@Data
public static class Post {
/**
*
*/
private Long id;
/**
*
*/
private String name;
}
}

@ -0,0 +1,35 @@
package cn.iocoder.yudao.ssodemo.client.dto.user;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* Request DTO
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class UserUpdateReqDTO {
/**
*
*/
private String nickname;
/**
*
*/
private String email;
/**
*
*/
private String mobile;
/**
*
*/
private Integer sex;
}

@ -0,0 +1,63 @@
package cn.iocoder.yudao.ssodemo.controller;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.ssodemo.client.OAuth2Client;
import cn.iocoder.yudao.ssodemo.client.dto.CommonResult;
import cn.iocoder.yudao.ssodemo.client.dto.oauth2.OAuth2AccessTokenRespDTO;
import cn.iocoder.yudao.ssodemo.framework.core.util.SecurityUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
@RestController
@RequestMapping("/auth")
public class AuthController {
@Resource
private OAuth2Client oauth2Client;
/**
* 使 code 访访
*
* @param code
* @param redirectUri URI
* @return 访 ResponseVO
*/
@PostMapping("/login-by-code")
public CommonResult<OAuth2AccessTokenRespDTO> loginByCode(@RequestParam("code") String code,
@RequestParam("redirectUri") String redirectUri) {
return oauth2Client.postAccessToken(code, redirectUri);
}
/**
* 使访
*
* @param refreshToken
* @return 访 ResponseVO
*/
@PostMapping("/refresh-token")
public CommonResult<OAuth2AccessTokenRespDTO> refreshToken(@RequestParam("refreshToken") String refreshToken) {
return oauth2Client.refreshToken(refreshToken);
}
/**
* 退
*
* @param request
* @return
*/
@PostMapping("/logout")
public CommonResult<Boolean> logout(HttpServletRequest request) {
String token = SecurityUtils.obtainAuthorization(request, "Authorization");
if (StrUtil.isNotBlank(token)) {
return oauth2Client.revokeToken(token);
}
// 返回成功
return new CommonResult<>();
}
}

@ -0,0 +1,40 @@
package cn.iocoder.yudao.ssodemo.controller;
import cn.iocoder.yudao.ssodemo.client.UserClient;
import cn.iocoder.yudao.ssodemo.client.dto.CommonResult;
import cn.iocoder.yudao.ssodemo.client.dto.user.UserInfoRespDTO;
import cn.iocoder.yudao.ssodemo.client.dto.user.UserUpdateReqDTO;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
@RestController
@RequestMapping("/user")
public class UserController {
@Resource
private UserClient userClient;
/**
*
*
* @return ResponseVO
*/
@GetMapping("/get")
public CommonResult<UserInfoRespDTO> getUser() {
return userClient.getUser();
}
/**
*
*
* @param nickname
* @return
*/
@PutMapping("/update")
public CommonResult<Boolean> updateUser(@RequestParam("nickname") String nickname) {
UserUpdateReqDTO updateReqDTO = new UserUpdateReqDTO(nickname, null, null, null);
return userClient.updateUser(updateReqDTO);
}
}

@ -0,0 +1,52 @@
package cn.iocoder.yudao.ssodemo.framework.config;
import cn.iocoder.yudao.ssodemo.framework.core.filter.TokenAuthenticationFilter;
import cn.iocoder.yudao.ssodemo.framework.core.handler.AccessDeniedHandlerImpl;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import javax.annotation.Resource;
@Configuration(proxyBeanMethods = false)
@EnableWebSecurity
public class SecurityConfiguration{
@Resource
private TokenAuthenticationFilter tokenAuthenticationFilter;
@Resource
private AccessDeniedHandlerImpl accessDeniedHandler;
@Resource
private AuthenticationEntryPoint authenticationEntryPoint;
@Bean
protected SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {
// 设置 URL 安全权限
httpSecurity.csrf().disable() // 禁用 CSRF 保护
.authorizeRequests()
// 1. 静态资源,可匿名访问
.antMatchers(HttpMethod.GET, "/*.html", "/**/*.html", "/**/*.css", "/**/*.js").permitAll()
// 2. 登录相关的接口,可匿名访问
.antMatchers("/auth/login-by-code").permitAll()
.antMatchers("/auth/refresh-token").permitAll()
.antMatchers("/auth/logout").permitAll()
// last. 兜底规则,必须认证
.and().authorizeRequests()
.anyRequest().authenticated();
// 设置处理器
httpSecurity.exceptionHandling().accessDeniedHandler(accessDeniedHandler)
.authenticationEntryPoint(authenticationEntryPoint);
// 添加 Token Filter
httpSecurity.addFilterBefore(tokenAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
return httpSecurity.build();
}
}

@ -0,0 +1,37 @@
package cn.iocoder.yudao.ssodemo.framework.core;
import lombok.Data;
import java.util.List;
/**
*
*
* @author
*/
@Data
public class LoginUser {
/**
*
*/
private Long id;
/**
*
*/
private Integer userType;
/**
*
*/
private Long tenantId;
/**
*
*/
private List<String> scopes;
/**
* 访
*/
private String accessToken;
}

@ -0,0 +1,66 @@
package cn.iocoder.yudao.ssodemo.framework.core.filter;
import cn.iocoder.yudao.ssodemo.client.OAuth2Client;
import cn.iocoder.yudao.ssodemo.client.dto.CommonResult;
import cn.iocoder.yudao.ssodemo.client.dto.oauth2.OAuth2CheckTokenRespDTO;
import cn.iocoder.yudao.ssodemo.framework.core.LoginUser;
import cn.iocoder.yudao.ssodemo.framework.core.util.SecurityUtils;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.annotation.Resource;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* Token token
* {@link LoginUser} Spring Security
*
* @author
*/
@Component
public class TokenAuthenticationFilter extends OncePerRequestFilter {
@Resource
private OAuth2Client oauth2Client;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
// 1. 获得访问令牌
String token = SecurityUtils.obtainAuthorization(request, "Authorization");
if (StringUtils.hasText(token)) {
// 2. 基于 token 构建登录用户
LoginUser loginUser = buildLoginUserByToken(token);
// 3. 设置当前用户
if (loginUser != null) {
SecurityUtils.setLoginUser(loginUser, request);
}
}
// 继续过滤链
filterChain.doFilter(request, response);
}
private LoginUser buildLoginUserByToken(String token) {
try {
CommonResult<OAuth2CheckTokenRespDTO> accessTokenResult = oauth2Client.checkToken(token);
OAuth2CheckTokenRespDTO accessToken = accessTokenResult.getData();
if (accessToken == null) {
return null;
}
// 构建登录用户
return new LoginUser().setId(accessToken.getUserId()).setUserType(accessToken.getUserType())
.setTenantId(accessToken.getTenantId()).setScopes(accessToken.getScopes())
.setAccessToken(accessToken.getAccessToken());
} catch (Exception exception) {
// 校验 Token 不通过时,考虑到一些接口是无需登录的,所以直接返回 null 即可
return null;
}
}
}

@ -0,0 +1,44 @@
package cn.iocoder.yudao.ssodemo.framework.core.handler;
import cn.iocoder.yudao.ssodemo.client.dto.CommonResult;
import cn.iocoder.yudao.ssodemo.framework.core.util.SecurityUtils;
import cn.iocoder.yudao.ssodemo.framework.core.util.ServletUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.security.web.access.ExceptionTranslationFilter;
import org.springframework.stereotype.Component;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* 访 URL {@link GlobalErrorCodeConstants#FORBIDDEN}
*
* Spring Security {@link ExceptionTranslationFilter#handleAccessDeniedException(HttpServletRequest, HttpServletResponse, FilterChain, AccessDeniedException)}
*
* @author
*/
@Component
@SuppressWarnings("JavadocReference")
@Slf4j
public class AccessDeniedHandlerImpl implements AccessDeniedHandler {
@Override
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException e)
throws IOException, ServletException {
// 打印 warn 的原因是,不定期合并 warn看看有没恶意破坏
log.warn("[commence][访问 URL({}) 时,用户({}) 权限不够]", request.getRequestURI(),
SecurityUtils.getLoginUserId(), e);
// 返回 403
CommonResult<Object> result = new CommonResult<>();
result.setCode(HttpStatus.FORBIDDEN.value());
result.setMsg("没有该操作权限");
ServletUtils.writeJSON(response, result);
}
}

@ -0,0 +1,36 @@
package cn.iocoder.yudao.ssodemo.framework.core.handler;
import cn.iocoder.yudao.ssodemo.client.dto.CommonResult;
import cn.iocoder.yudao.ssodemo.framework.core.util.ServletUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.access.ExceptionTranslationFilter;
import org.springframework.stereotype.Component;
import javax.servlet.FilterChain;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 访 URL {@link GlobalErrorCodeConstants#UNAUTHORIZED} 使
*
* Spring Security {@link ExceptionTranslationFilter#sendStartAuthentication(HttpServletRequest, HttpServletResponse, FilterChain, AuthenticationException)}
*/
@Component
@Slf4j
@SuppressWarnings("JavadocReference") // 忽略文档引用报错
public class AuthenticationEntryPointImpl implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) {
log.debug("[commence][访问 URL({}) 时,没有登录]", request.getRequestURI(), e);
// 返回 401
CommonResult<Object> result = new CommonResult<>();
result.setCode(HttpStatus.UNAUTHORIZED.value());
result.setMsg("账号未登录");
ServletUtils.writeJSON(response, result);
}
}

@ -0,0 +1,103 @@
package cn.iocoder.yudao.ssodemo.framework.core.util;
import cn.iocoder.yudao.ssodemo.framework.core.LoginUser;
import org.springframework.lang.Nullable;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.util.StringUtils;
import javax.servlet.http.HttpServletRequest;
import java.util.Collections;
/**
*
*
* @author
*/
public class SecurityUtils {
public static final String AUTHORIZATION_BEARER = "Bearer";
private SecurityUtils() {}
/**
* Token
*
* @param request
* @param header Token Header
* @return Token
*/
public static String obtainAuthorization(HttpServletRequest request, String header) {
String authorization = request.getHeader(header);
if (!StringUtils.hasText(authorization)) {
return null;
}
int index = authorization.indexOf(AUTHORIZATION_BEARER + " ");
if (index == -1) { // 未找到
return null;
}
return authorization.substring(index + 7).trim();
}
/**
*
*
* @return
*/
public static Authentication getAuthentication() {
SecurityContext context = SecurityContextHolder.getContext();
if (context == null) {
return null;
}
return context.getAuthentication();
}
/**
*
*
* @return
*/
@Nullable
public static LoginUser getLoginUser() {
Authentication authentication = getAuthentication();
if (authentication == null) {
return null;
}
return authentication.getPrincipal() instanceof LoginUser ? (LoginUser) authentication.getPrincipal() : null;
}
/**
*
*
* @return
*/
@Nullable
public static Long getLoginUserId() {
LoginUser loginUser = getLoginUser();
return loginUser != null ? loginUser.getId() : null;
}
/**
*
*
* @param loginUser
* @param request
*/
public static void setLoginUser(LoginUser loginUser, HttpServletRequest request) {
// 创建 Authentication并设置到上下文
Authentication authentication = buildAuthentication(loginUser, request);
SecurityContextHolder.getContext().setAuthentication(authentication);
}
private static Authentication buildAuthentication(LoginUser loginUser, HttpServletRequest request) {
// 创建 UsernamePasswordAuthenticationToken 对象
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(
loginUser, null, Collections.emptyList());
authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
return authenticationToken;
}
}

@ -0,0 +1,28 @@
package cn.iocoder.yudao.ssodemo.framework.core.util;
import cn.hutool.extra.servlet.ServletUtil;
import cn.hutool.json.JSONUtil;
import org.springframework.http.MediaType;
import javax.servlet.http.HttpServletResponse;
/**
*
*
* @author
*/
public class ServletUtils {
/**
* JSON
*
* @param response
* @param object JSON
*/
@SuppressWarnings("deprecation") // 必须使用 APPLICATION_JSON_UTF8_VALUE否则会乱码
public static void writeJSON(HttpServletResponse response, Object object) {
String content = JSONUtil.toJsonStr(object);
ServletUtil.write(response, content, MediaType.APPLICATION_JSON_UTF8_VALUE);
}
}

@ -0,0 +1,61 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>SSO 授权后的回调页</title>
<!-- jQuery操作 dom、发起请求等 -->
<script src="https://lf9-cdn-tos.bytecdntp.com/cdn/expire-1-M/jquery/2.1.2/jquery.min.js" type="application/javascript"></script>
<!-- 工具类 -->
<script type="application/javascript">
(function ($) {
/**
* 获得 URL 的指定参数的值
*
* @param name 参数名
* @returns 参数值
*/
$.getUrlParam = function (name) {
const reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
const r = window.location.search.substr(1).match(reg);
if (r != null) return unescape(r[2]); return null;
}
})(jQuery);
</script>
<script type="application/javascript">
$(function () {
// 获得 code 授权码
const code = $.getUrlParam('code');
if (!code) {
alert('获取不到 code 参数,请排查!')
return;
}
// 提交
const redirectUri = 'http://127.0.0.1:18080/callback.html'; // 需要修改成,你回调的地址,就是在 index.html 拼接的 redirectUri
$.ajax({
url: "http://127.0.0.1:18080/auth/login-by-code?code=" + code
+ '&redirectUri=' + redirectUri,
method: 'POST',
success: function( result ) {
if (result.code !== 0) {
alert('获得访问令牌失败,原因:' + result.msg)
return;
}
alert('获得访问令牌成功!点击确认,跳转回首页')
// 设置到 localStorage 中
localStorage.setItem('ACCESS-TOKEN', result.data.access_token);
localStorage.setItem('REFRESH-TOKEN', result.data.refresh_token);
// 跳转回首页
window.location.href = '/index.html';
}
})
})
</script>
</head>
<body>
正在使用 code 授权码,进行 accessToken 访问令牌的获取
</body>
</html>

@ -0,0 +1,159 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>首页</title>
<!-- jQuery操作 dom、发起请求等 -->
<script src="https://lf9-cdn-tos.bytecdntp.com/cdn/expire-1-M/jquery/2.1.2/jquery.min.js" type="application/javascript"></script>
<script type="application/javascript">
/**
* 跳转单点登录
*/
function ssoLogin() {
const clientId = 'yudao-sso-demo-by-code'; // 可以改写成,你的 clientId
const redirectUri = encodeURIComponent('http://127.0.0.1:18080/callback.html'); // 注意,需要使用 encodeURIComponent 编码地址
const responseType = 'code'; // 1授权码模式对应 code2简化模式对应 token
window.location.href = 'http://127.0.0.1:1024/sso?client_id=' + clientId
+ '&redirect_uri=' + redirectUri
+ '&response_type=' + responseType;
}
/**
* 修改昵称
*/
function updateNickname() {
const nickname = prompt("请输入新的昵称", "");
if (!nickname) {
return;
}
// 更新用户的昵称
const accessToken = localStorage.getItem('ACCESS-TOKEN');
$.ajax({
url: "http://127.0.0.1:18080/user/update?nickname=" + nickname,
method: 'PUT',
headers: {
'Authorization': 'Bearer ' + accessToken
},
success: function (result) {
if (result.code !== 0) {
alert('更新昵称失败,原因:' + result.msg)
return;
}
alert('更新昵称成功!');
$('#nicknameSpan').html(nickname);
}
});
}
/**
* 刷新令牌
*/
function refreshToken() {
const refreshToken = localStorage.getItem('REFRESH-TOKEN');
if (!refreshToken) {
alert("获取不到刷新令牌");
return;
}
$.ajax({
url: "http://127.0.0.1:18080/auth/refresh-token?refreshToken=" + refreshToken,
method: 'POST',
success: function (result) {
if (result.code !== 0) {
alert('刷新访问令牌失败,原因:' + result.msg)
return;
}
alert('更新访问令牌成功!');
$('#accessTokenSpan').html(result.data.access_token);
// 设置到 localStorage 中
localStorage.setItem('ACCESS-TOKEN', result.data.access_token);
localStorage.setItem('REFRESH-TOKEN', result.data.refresh_token);
}
});
}
/**
* 登出,删除访问令牌
*/
function logout() {
const accessToken = localStorage.getItem('ACCESS-TOKEN');
if (!accessToken) {
location.reload();
return;
}
$.ajax({
url: "http://127.0.0.1:18080/auth/logout",
method: 'POST',
headers: {
'Authorization': 'Bearer ' + accessToken
},
success: function (result) {
if (result.code !== 0) {
alert('退出登录失败,原因:' + result.msg)
return;
}
alert('退出登录成功!');
// 删除 localStorage 中
localStorage.removeItem('ACCESS-TOKEN');
localStorage.removeItem('REFRESH-TOKEN');
location.reload();
}
});
}
$(function () {
const accessToken = localStorage.getItem('ACCESS-TOKEN');
// 情况一:未登录
if (!accessToken) {
$('#noLoginDiv').css("display", "block");
return;
}
// 情况二:已登录
$('#yesLoginDiv').css("display", "block");
$('#accessTokenSpan').html(accessToken);
// 获得登录用户的信息
$.ajax({
url: "http://127.0.0.1:18080/user/get",
method: 'GET',
headers: {
'Authorization': 'Bearer ' + accessToken
},
success: function (result) {
if (result.code !== 0) {
alert('获得个人信息失败,原因:' + result.msg)
return;
}
$('#nicknameSpan').html(result.data.nickname);
}
});
})
</script>
</head>
<body>
<!-- 情况一未登录1跳转 ruoyi-vue-pro 的 SSO 登录页 -->
<div id="noLoginDiv" style="display: none">
您未登录,点击 <a href="#" onclick="ssoLogin()">跳转 </a> SSO 单点登录
</div>
<!-- 情况二已登录1展示用户信息2刷新访问令牌3退出登录 -->
<div id="yesLoginDiv" style="display: none">
您已登录!<button onclick="logout()">退出登录</button> <br />
昵称:<span id="nicknameSpan"> 加载中... </span> <button onclick="updateNickname()">修改昵称</button> <br />
访问令牌:<span id="accessTokenSpan"> 加载中... </span> <button onclick="refreshToken()">刷新令牌</button> <br />
</div>
</body>
<style>
body { /** 页面居中 */
border-radius: 20px;
height: 350px;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%,-50%);
}
</style>
</html>

@ -0,0 +1,65 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!-- 由于方便大家拷贝,使用不使用 yudao 作为 Maven parent -->
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-sso-demo-by-password</artifactId>
<version>1.0.0-snapshot</version>
<packaging>jar</packaging>
<name>${project.artifactId}</name>
<description>基于密码模式,如何实现 SSO 单点登录?</description>
<url>https://github.com/YunaiV/ruoyi-vue-pro</url>
<properties>
<!-- Maven 相关 -->
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- 统一依赖管理 -->
<spring.boot.version>2.7.7</spring.boot.version>
</properties>
<dependencyManagement>
<dependencies>
<!-- 统一依赖管理 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring.boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- Web 相关 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.11</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
</project>

@ -0,0 +1,13 @@
package cn.iocoder.yudao.ssodemo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SSODemoApplication {
public static void main(String[] args) {
SpringApplication.run(SSODemoApplication.class, args);
}
}

@ -0,0 +1,127 @@
package cn.iocoder.yudao.ssodemo.client;
import cn.iocoder.yudao.ssodemo.client.dto.CommonResult;
import cn.iocoder.yudao.ssodemo.client.dto.oauth2.OAuth2AccessTokenRespDTO;
import cn.iocoder.yudao.ssodemo.client.dto.oauth2.OAuth2CheckTokenRespDTO;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import org.springframework.util.Base64Utils;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import java.nio.charset.StandardCharsets;
/**
* OAuth 2.0
*
* OAuth2OpenController
*/
@Component
public class OAuth2Client {
private static final String BASE_URL = "http://127.0.0.1:48080/admin-api/system/oauth2";
/**
*
*
* 使 1使
*/
public static final Long TENANT_ID = 1L;
private static final String CLIENT_ID = "yudao-sso-demo-by-password";
private static final String CLIENT_SECRET = "test";
// @Resource // 可优化,注册一个 RestTemplate Bean然后注入
private final RestTemplate restTemplate = new RestTemplate();
/**
* 访
*
* @param token 访
* @return 访
*/
public CommonResult<OAuth2CheckTokenRespDTO> checkToken(String token) {
// 1.1 构建请求头
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
headers.set("tenant-id", TENANT_ID.toString());
addClientHeader(headers);
// 1.2 构建请求参数
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
body.add("token", token);
// 2. 执行请求
ResponseEntity<CommonResult<OAuth2CheckTokenRespDTO>> exchange = restTemplate.exchange(
BASE_URL + "/check-token",
HttpMethod.POST,
new HttpEntity<>(body, headers),
new ParameterizedTypeReference<CommonResult<OAuth2CheckTokenRespDTO>>() {}); // 解决 CommonResult 的泛型丢失
Assert.isTrue(exchange.getStatusCode().is2xxSuccessful(), "响应必须是 200 成功");
return exchange.getBody();
}
/**
* 使访
*
* @param refreshToken
* @return 访
*/
public CommonResult<OAuth2AccessTokenRespDTO> refreshToken(String refreshToken) {
// 1.1 构建请求头
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
headers.set("tenant-id", TENANT_ID.toString());
addClientHeader(headers);
// 1.2 构建请求参数
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
body.add("grant_type", "refresh_token");
body.add("refresh_token", refreshToken);
// 2. 执行请求
ResponseEntity<CommonResult<OAuth2AccessTokenRespDTO>> exchange = restTemplate.exchange(
BASE_URL + "/token",
HttpMethod.POST,
new HttpEntity<>(body, headers),
new ParameterizedTypeReference<CommonResult<OAuth2AccessTokenRespDTO>>() {}); // 解决 CommonResult 的泛型丢失
Assert.isTrue(exchange.getStatusCode().is2xxSuccessful(), "响应必须是 200 成功");
return exchange.getBody();
}
/**
* 访
*
* @param token 访
* @return
*/
public CommonResult<Boolean> revokeToken(String token) {
// 1.1 构建请求头
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
headers.set("tenant-id", TENANT_ID.toString());
addClientHeader(headers);
// 1.2 构建请求参数
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
body.add("token", token);
// 2. 执行请求
ResponseEntity<CommonResult<Boolean>> exchange = restTemplate.exchange(
BASE_URL + "/token",
HttpMethod.DELETE,
new HttpEntity<>(body, headers),
new ParameterizedTypeReference<CommonResult<Boolean>>() {}); // 解决 CommonResult 的泛型丢失
Assert.isTrue(exchange.getStatusCode().is2xxSuccessful(), "响应必须是 200 成功");
return exchange.getBody();
}
private static void addClientHeader(HttpHeaders headers) {
// client 拼接,需要 BASE64 编码
String client = CLIENT_ID + ":" + CLIENT_SECRET;
client = Base64Utils.encodeToString(client.getBytes(StandardCharsets.UTF_8));
headers.add("Authorization", "Basic " + client);
}
}

@ -0,0 +1,73 @@
package cn.iocoder.yudao.ssodemo.client;
import cn.iocoder.yudao.ssodemo.client.dto.CommonResult;
import cn.iocoder.yudao.ssodemo.client.dto.user.UserInfoRespDTO;
import cn.iocoder.yudao.ssodemo.client.dto.user.UserUpdateReqDTO;
import cn.iocoder.yudao.ssodemo.framework.core.LoginUser;
import cn.iocoder.yudao.ssodemo.framework.core.util.SecurityUtils;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
/**
* User
*
* OAuth2UserController
*/
@Component
public class UserClient {
private static final String BASE_URL = "http://127.0.0.1:48080/admin-api//system/oauth2/user";
// @Resource // 可优化,注册一个 RestTemplate Bean然后注入
private final RestTemplate restTemplate = new RestTemplate();
public CommonResult<UserInfoRespDTO> getUser() {
// 1.1 构建请求头
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
headers.set("tenant-id", OAuth2Client.TENANT_ID.toString());
addTokenHeader(headers);
// 1.2 构建请求参数
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
// 2. 执行请求
ResponseEntity<CommonResult<UserInfoRespDTO>> exchange = restTemplate.exchange(
BASE_URL + "/get",
HttpMethod.GET,
new HttpEntity<>(body, headers),
new ParameterizedTypeReference<CommonResult<UserInfoRespDTO>>() {}); // 解决 CommonResult 的泛型丢失
Assert.isTrue(exchange.getStatusCode().is2xxSuccessful(), "响应必须是 200 成功");
return exchange.getBody();
}
public CommonResult<Boolean> updateUser(UserUpdateReqDTO updateReqDTO) {
// 1.1 构建请求头
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.set("tenant-id", OAuth2Client.TENANT_ID.toString());
addTokenHeader(headers);
// 1.2 构建请求参数
// 使用 updateReqDTO 即可
// 2. 执行请求
ResponseEntity<CommonResult<Boolean>> exchange = restTemplate.exchange(
BASE_URL + "/update",
HttpMethod.PUT,
new HttpEntity<>(updateReqDTO, headers),
new ParameterizedTypeReference<CommonResult<Boolean>>() {}); // 解决 CommonResult 的泛型丢失
Assert.isTrue(exchange.getStatusCode().is2xxSuccessful(), "响应必须是 200 成功");
return exchange.getBody();
}
private static void addTokenHeader(HttpHeaders headers) {
LoginUser loginUser = SecurityUtils.getLoginUser();
Assert.notNull(loginUser, "登录用户不能为空");
headers.add("Authorization", "Bearer " + loginUser.getAccessToken());
}
}

@ -0,0 +1,28 @@
package cn.iocoder.yudao.ssodemo.client.dto;
import lombok.Data;
import java.io.Serializable;
/**
*
*
* @param <T>
*/
@Data
public class CommonResult<T> implements Serializable {
/**
*
*/
private Integer code;
/**
*
*/
private T data;
/**
*
*/
private String msg;
}

@ -0,0 +1,45 @@
package cn.iocoder.yudao.ssodemo.client.dto.oauth2;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 访 Response DTO
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class OAuth2AccessTokenRespDTO {
/**
* 访
*/
@JsonProperty("access_token")
private String accessToken;
/**
*
*/
@JsonProperty("refresh_token")
private String refreshToken;
/**
*
*/
@JsonProperty("token_type")
private String tokenType;
/**
*
*/
@JsonProperty("expires_in")
private Long expiresIn;
/**
* 使
*/
private String scope;
}

@ -0,0 +1,59 @@
package cn.iocoder.yudao.ssodemo.client.dto.oauth2;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
/**
* Response DTO
*
* @author
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class OAuth2CheckTokenRespDTO {
/**
*
*/
@JsonProperty("user_id")
private Long userId;
/**
*
*/
@JsonProperty("user_type")
private Integer userType;
/**
*
*/
@JsonProperty("tenant_id")
private Long tenantId;
/**
*
*/
@JsonProperty("client_id")
private String clientId;
/**
*
*/
private List<String> scopes;
/**
* 访
*/
@JsonProperty("access_token")
private String accessToken;
/**
*
*
* / 1000
*/
private Long exp;
}

@ -0,0 +1,97 @@
package cn.iocoder.yudao.ssodemo.client.dto.user;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
/**
* Response dto
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class UserInfoRespDTO {
/**
*
*/
private Long id;
/**
*
*/
private String username;
/**
*
*/
private String nickname;
/**
*
*/
private String email;
/**
*
*/
private String mobile;
/**
*
*/
private Integer sex;
/**
*
*/
private String avatar;
/**
*
*/
private Dept dept;
/**
*
*/
private List<Post> posts;
/**
*
*/
@Data
public static class Dept {
/**
*
*/
private Long id;
/**
*
*/
private String name;
}
/**
*
*/
@Data
public static class Post {
/**
*
*/
private Long id;
/**
*
*/
private String name;
}
}

@ -0,0 +1,35 @@
package cn.iocoder.yudao.ssodemo.client.dto.user;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* Request DTO
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class UserUpdateReqDTO {
/**
*
*/
private String nickname;
/**
*
*/
private String email;
/**
*
*/
private String mobile;
/**
*
*/
private Integer sex;
}

@ -0,0 +1,50 @@
package cn.iocoder.yudao.ssodemo.controller;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.ssodemo.client.OAuth2Client;
import cn.iocoder.yudao.ssodemo.client.dto.CommonResult;
import cn.iocoder.yudao.ssodemo.client.dto.oauth2.OAuth2AccessTokenRespDTO;
import cn.iocoder.yudao.ssodemo.framework.core.util.SecurityUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
@RestController
@RequestMapping("/auth")
public class AuthController {
@Resource
private OAuth2Client oauth2Client;
/**
* 使访
*
* @param refreshToken
* @return 访 ResponseVO
*/
@PostMapping("/refresh-token")
public CommonResult<OAuth2AccessTokenRespDTO> refreshToken(@RequestParam("refreshToken") String refreshToken) {
return oauth2Client.refreshToken(refreshToken);
}
/**
* 退
*
* @param request
* @return
*/
@PostMapping("/logout")
public CommonResult<Boolean> logout(HttpServletRequest request) {
String token = SecurityUtils.obtainAuthorization(request, "Authorization");
if (StrUtil.isNotBlank(token)) {
return oauth2Client.revokeToken(token);
}
// 返回成功
return new CommonResult<>();
}
}

@ -0,0 +1,40 @@
package cn.iocoder.yudao.ssodemo.controller;
import cn.iocoder.yudao.ssodemo.client.UserClient;
import cn.iocoder.yudao.ssodemo.client.dto.CommonResult;
import cn.iocoder.yudao.ssodemo.client.dto.user.UserInfoRespDTO;
import cn.iocoder.yudao.ssodemo.client.dto.user.UserUpdateReqDTO;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
@RestController
@RequestMapping("/user")
public class UserController {
@Resource
private UserClient userClient;
/**
*
*
* @return ResponseVO
*/
@GetMapping("/get")
public CommonResult<UserInfoRespDTO> getUser() {
return userClient.getUser();
}
/**
*
*
* @param nickname
* @return
*/
@PutMapping("/update")
public CommonResult<Boolean> updateUser(@RequestParam("nickname") String nickname) {
UserUpdateReqDTO updateReqDTO = new UserUpdateReqDTO(nickname, null, null, null);
return userClient.updateUser(updateReqDTO);
}
}

@ -0,0 +1,52 @@
package cn.iocoder.yudao.ssodemo.framework.config;
import cn.iocoder.yudao.ssodemo.framework.core.filter.TokenAuthenticationFilter;
import cn.iocoder.yudao.ssodemo.framework.core.handler.AccessDeniedHandlerImpl;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import javax.annotation.Resource;
@Configuration(proxyBeanMethods = false)
@EnableWebSecurity
public class SecurityConfiguration {
@Resource
private TokenAuthenticationFilter tokenAuthenticationFilter;
@Resource
private AccessDeniedHandlerImpl accessDeniedHandler;
@Resource
private AuthenticationEntryPoint authenticationEntryPoint;
@Bean
protected SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {
// 设置 URL 安全权限
httpSecurity.csrf().disable() // 禁用 CSRF 保护
.authorizeRequests()
// 1. 静态资源,可匿名访问
.antMatchers(HttpMethod.GET, "/*.html", "/**/*.html", "/**/*.css", "/**/*.js").permitAll()
// 2. 登录相关的接口,可匿名访问
.antMatchers("/auth/login-by-code").permitAll()
.antMatchers("/auth/refresh-token").permitAll()
.antMatchers("/auth/logout").permitAll()
// last. 兜底规则,必须认证
.and().authorizeRequests()
.anyRequest().authenticated();
// 设置处理器
httpSecurity.exceptionHandling().accessDeniedHandler(accessDeniedHandler)
.authenticationEntryPoint(authenticationEntryPoint);
// 添加 Token Filter
httpSecurity.addFilterBefore(tokenAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
return httpSecurity.build();
}
}

@ -0,0 +1,37 @@
package cn.iocoder.yudao.ssodemo.framework.core;
import lombok.Data;
import java.util.List;
/**
*
*
* @author
*/
@Data
public class LoginUser {
/**
*
*/
private Long id;
/**
*
*/
private Integer userType;
/**
*
*/
private Long tenantId;
/**
*
*/
private List<String> scopes;
/**
* 访
*/
private String accessToken;
}

@ -0,0 +1,66 @@
package cn.iocoder.yudao.ssodemo.framework.core.filter;
import cn.iocoder.yudao.ssodemo.client.OAuth2Client;
import cn.iocoder.yudao.ssodemo.client.dto.CommonResult;
import cn.iocoder.yudao.ssodemo.client.dto.oauth2.OAuth2CheckTokenRespDTO;
import cn.iocoder.yudao.ssodemo.framework.core.LoginUser;
import cn.iocoder.yudao.ssodemo.framework.core.util.SecurityUtils;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.annotation.Resource;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* Token token
* {@link LoginUser} Spring Security
*
* @author
*/
@Component
public class TokenAuthenticationFilter extends OncePerRequestFilter {
@Resource
private OAuth2Client oauth2Client;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
// 1. 获得访问令牌
String token = SecurityUtils.obtainAuthorization(request, "Authorization");
if (StringUtils.hasText(token)) {
// 2. 基于 token 构建登录用户
LoginUser loginUser = buildLoginUserByToken(token);
// 3. 设置当前用户
if (loginUser != null) {
SecurityUtils.setLoginUser(loginUser, request);
}
}
// 继续过滤链
filterChain.doFilter(request, response);
}
private LoginUser buildLoginUserByToken(String token) {
try {
CommonResult<OAuth2CheckTokenRespDTO> accessTokenResult = oauth2Client.checkToken(token);
OAuth2CheckTokenRespDTO accessToken = accessTokenResult.getData();
if (accessToken == null) {
return null;
}
// 构建登录用户
return new LoginUser().setId(accessToken.getUserId()).setUserType(accessToken.getUserType())
.setTenantId(accessToken.getTenantId()).setScopes(accessToken.getScopes())
.setAccessToken(accessToken.getAccessToken());
} catch (Exception exception) {
// 校验 Token 不通过时,考虑到一些接口是无需登录的,所以直接返回 null 即可
return null;
}
}
}

@ -0,0 +1,44 @@
package cn.iocoder.yudao.ssodemo.framework.core.handler;
import cn.iocoder.yudao.ssodemo.client.dto.CommonResult;
import cn.iocoder.yudao.ssodemo.framework.core.util.SecurityUtils;
import cn.iocoder.yudao.ssodemo.framework.core.util.ServletUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.security.web.access.ExceptionTranslationFilter;
import org.springframework.stereotype.Component;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* 访 URL {@link GlobalErrorCodeConstants#FORBIDDEN}
*
* Spring Security {@link ExceptionTranslationFilter#handleAccessDeniedException(HttpServletRequest, HttpServletResponse, FilterChain, AccessDeniedException)}
*
* @author
*/
@Component
@SuppressWarnings("JavadocReference")
@Slf4j
public class AccessDeniedHandlerImpl implements AccessDeniedHandler {
@Override
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException e)
throws IOException, ServletException {
// 打印 warn 的原因是,不定期合并 warn看看有没恶意破坏
log.warn("[commence][访问 URL({}) 时,用户({}) 权限不够]", request.getRequestURI(),
SecurityUtils.getLoginUserId(), e);
// 返回 403
CommonResult<Object> result = new CommonResult<>();
result.setCode(HttpStatus.FORBIDDEN.value());
result.setMsg("没有该操作权限");
ServletUtils.writeJSON(response, result);
}
}

@ -0,0 +1,36 @@
package cn.iocoder.yudao.ssodemo.framework.core.handler;
import cn.iocoder.yudao.ssodemo.client.dto.CommonResult;
import cn.iocoder.yudao.ssodemo.framework.core.util.ServletUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.access.ExceptionTranslationFilter;
import org.springframework.stereotype.Component;
import javax.servlet.FilterChain;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 访 URL {@link GlobalErrorCodeConstants#UNAUTHORIZED} 使
*
* Spring Security {@link ExceptionTranslationFilter#sendStartAuthentication(HttpServletRequest, HttpServletResponse, FilterChain, AuthenticationException)}
*/
@Component
@Slf4j
@SuppressWarnings("JavadocReference") // 忽略文档引用报错
public class AuthenticationEntryPointImpl implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) {
log.debug("[commence][访问 URL({}) 时,没有登录]", request.getRequestURI(), e);
// 返回 401
CommonResult<Object> result = new CommonResult<>();
result.setCode(HttpStatus.UNAUTHORIZED.value());
result.setMsg("账号未登录");
ServletUtils.writeJSON(response, result);
}
}

@ -0,0 +1,103 @@
package cn.iocoder.yudao.ssodemo.framework.core.util;
import cn.iocoder.yudao.ssodemo.framework.core.LoginUser;
import org.springframework.lang.Nullable;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.util.StringUtils;
import javax.servlet.http.HttpServletRequest;
import java.util.Collections;
/**
*
*
* @author
*/
public class SecurityUtils {
public static final String AUTHORIZATION_BEARER = "Bearer";
private SecurityUtils() {}
/**
* Token
*
* @param request
* @param header Token Header
* @return Token
*/
public static String obtainAuthorization(HttpServletRequest request, String header) {
String authorization = request.getHeader(header);
if (!StringUtils.hasText(authorization)) {
return null;
}
int index = authorization.indexOf(AUTHORIZATION_BEARER + " ");
if (index == -1) { // 未找到
return null;
}
return authorization.substring(index + 7).trim();
}
/**
*
*
* @return
*/
public static Authentication getAuthentication() {
SecurityContext context = SecurityContextHolder.getContext();
if (context == null) {
return null;
}
return context.getAuthentication();
}
/**
*
*
* @return
*/
@Nullable
public static LoginUser getLoginUser() {
Authentication authentication = getAuthentication();
if (authentication == null) {
return null;
}
return authentication.getPrincipal() instanceof LoginUser ? (LoginUser) authentication.getPrincipal() : null;
}
/**
*
*
* @return
*/
@Nullable
public static Long getLoginUserId() {
LoginUser loginUser = getLoginUser();
return loginUser != null ? loginUser.getId() : null;
}
/**
*
*
* @param loginUser
* @param request
*/
public static void setLoginUser(LoginUser loginUser, HttpServletRequest request) {
// 创建 Authentication并设置到上下文
Authentication authentication = buildAuthentication(loginUser, request);
SecurityContextHolder.getContext().setAuthentication(authentication);
}
private static Authentication buildAuthentication(LoginUser loginUser, HttpServletRequest request) {
// 创建 UsernamePasswordAuthenticationToken 对象
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(
loginUser, null, Collections.emptyList());
authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
return authenticationToken;
}
}

@ -0,0 +1,28 @@
package cn.iocoder.yudao.ssodemo.framework.core.util;
import cn.hutool.extra.servlet.ServletUtil;
import cn.hutool.json.JSONUtil;
import org.springframework.http.MediaType;
import javax.servlet.http.HttpServletResponse;
/**
*
*
* @author
*/
public class ServletUtils {
/**
* JSON
*
* @param response
* @param object JSON
*/
@SuppressWarnings("deprecation") // 必须使用 APPLICATION_JSON_UTF8_VALUE否则会乱码
public static void writeJSON(HttpServletResponse response, Object object) {
String content = JSONUtil.toJsonStr(object);
ServletUtil.write(response, content, MediaType.APPLICATION_JSON_UTF8_VALUE);
}
}

@ -0,0 +1,154 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>首页</title>
<!-- jQuery操作 dom、发起请求等 -->
<script src="https://lf9-cdn-tos.bytecdntp.com/cdn/expire-1-M/jquery/2.1.2/jquery.min.js" type="application/javascript"></script>
<script type="application/javascript">
/**
* 跳转单点登录
*/
function passwordLogin() {
window.location.href = '/login.html'
}
/**
* 修改昵称
*/
function updateNickname() {
const nickname = prompt("请输入新的昵称", "");
if (!nickname) {
return;
}
// 更新用户的昵称
const accessToken = localStorage.getItem('ACCESS-TOKEN');
$.ajax({
url: "http://127.0.0.1:18080/user/update?nickname=" + nickname,
method: 'PUT',
headers: {
'Authorization': 'Bearer ' + accessToken
},
success: function (result) {
if (result.code !== 0) {
alert('更新昵称失败,原因:' + result.msg)
return;
}
alert('更新昵称成功!');
$('#nicknameSpan').html(nickname);
}
});
}
/**
* 刷新令牌
*/
function refreshToken() {
const refreshToken = localStorage.getItem('REFRESH-TOKEN');
if (!refreshToken) {
alert("获取不到刷新令牌");
return;
}
$.ajax({
url: "http://127.0.0.1:18080/auth/refresh-token?refreshToken=" + refreshToken,
method: 'POST',
success: function (result) {
if (result.code !== 0) {
alert('刷新访问令牌失败,原因:' + result.msg)
return;
}
alert('更新访问令牌成功!');
$('#accessTokenSpan').html(result.data.access_token);
// 设置到 localStorage 中
localStorage.setItem('ACCESS-TOKEN', result.data.access_token);
localStorage.setItem('REFRESH-TOKEN', result.data.refresh_token);
}
});
}
/**
* 登出,删除访问令牌
*/
function logout() {
const accessToken = localStorage.getItem('ACCESS-TOKEN');
if (!accessToken) {
location.reload();
return;
}
$.ajax({
url: "http://127.0.0.1:18080/auth/logout",
method: 'POST',
headers: {
'Authorization': 'Bearer ' + accessToken
},
success: function (result) {
if (result.code !== 0) {
alert('退出登录失败,原因:' + result.msg)
return;
}
alert('退出登录成功!');
// 删除 localStorage 中
localStorage.removeItem('ACCESS-TOKEN');
localStorage.removeItem('REFRESH-TOKEN');
location.reload();
}
});
}
$(function () {
const accessToken = localStorage.getItem('ACCESS-TOKEN');
// 情况一:未登录
if (!accessToken) {
$('#noLoginDiv').css("display", "block");
return;
}
// 情况二:已登录
$('#yesLoginDiv').css("display", "block");
$('#accessTokenSpan').html(accessToken);
// 获得登录用户的信息
$.ajax({
url: "http://127.0.0.1:18080/user/get",
method: 'GET',
headers: {
'Authorization': 'Bearer ' + accessToken
},
success: function (result) {
if (result.code !== 0) {
alert('获得个人信息失败,原因:' + result.msg)
return;
}
$('#nicknameSpan').html(result.data.nickname);
}
});
})
</script>
</head>
<body>
<!-- 情况一未登录1跳转 ruoyi-vue-pro 的 SSO 登录页 -->
<div id="noLoginDiv" style="display: none">
您未登录,点击 <a href="#" onclick="passwordLogin()">跳转 </a> 账号密码登录
</div>
<!-- 情况二已登录1展示用户信息2刷新访问令牌3退出登录 -->
<div id="yesLoginDiv" style="display: none">
您已登录!<button onclick="logout()">退出登录</button> <br />
昵称:<span id="nicknameSpan"> 加载中... </span> <button onclick="updateNickname()">修改昵称</button> <br />
访问令牌:<span id="accessTokenSpan"> 加载中... </span> <button onclick="refreshToken()">刷新令牌</button> <br />
</div>
</body>
<style>
body { /** 页面居中 */
border-radius: 20px;
height: 350px;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%,-50%);
}
</style>
</html>

@ -0,0 +1,74 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登录</title>
<!-- jQuery操作 dom、发起请求等 -->
<script src="https://lf9-cdn-tos.bytecdntp.com/cdn/expire-1-M/jquery/2.1.2/jquery.min.js" type="application/javascript"></script>
<script type="application/javascript">
/**
* 账号密码登录
*/
function login() {
const clientId = 'yudao-sso-demo-by-password'; // 可以改写成,你的 clientId
const clientSecret = 'test'; // 可以改写成,你的 clientSecret
const grantType = 'password'; // 密码模式
// 账号 + 密码
const username = $('#username').val();
const password = $('#password').val();
if (username.length === 0 || password.length === 0) {
alert('账号或密码未输入');
return;
}
// 发起请求
$.ajax({
url: "http://127.0.0.1:48080/admin-api/system/oauth2/token?"
// 客户端
+ "client_id=" + clientId
+ "&client_secret=" + clientSecret
// 密码模式的参数
+ "&grant_type=" + grantType
+ "&username=" + username
+ "&password=" + password
+ '&scope=user.read user.write',
method: 'POST',
headers: {
'tenant-id': '1', // 多租户编号,写死
},
success: function (result) {
if (result.code !== 0) {
alert('登录失败,原因:' + result.msg)
return;
}
// 设置到 localStorage 中
localStorage.setItem('ACCESS-TOKEN', result.data.access_token);
localStorage.setItem('REFRESH-TOKEN', result.data.refresh_token);
// 提示登录成功
alert('登录成功!点击确认,跳转回首页');
window.location.href = '/index.html';
}
});
}
</script>
</head>
<body>
账号:<input id="username" value="admin" /> <br />
密码:<input id="password" value="admin123" > <br />
<button style="float: right; margin-top: 5px;" onclick="login()">登录</button>
</body>
<style>
body { /** 页面居中 */
border-radius: 20px;
height: 350px;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%,-50%);
}
</style>
</html>

@ -20,7 +20,6 @@
<module>yudao-spring-boot-starter-file</module> <module>yudao-spring-boot-starter-file</module>
<module>yudao-spring-boot-starter-monitor</module> <module>yudao-spring-boot-starter-monitor</module>
<module>yudao-spring-boot-starter-protection</module> <module>yudao-spring-boot-starter-protection</module>
<module>yudao-spring-boot-starter-config</module>
<module>yudao-spring-boot-starter-job</module> <module>yudao-spring-boot-starter-job</module>
<module>yudao-spring-boot-starter-mq</module> <module>yudao-spring-boot-starter-mq</module>
@ -37,8 +36,12 @@
<module>yudao-spring-boot-starter-biz-tenant</module> <module>yudao-spring-boot-starter-biz-tenant</module>
<module>yudao-spring-boot-starter-biz-data-permission</module> <module>yudao-spring-boot-starter-biz-data-permission</module>
<module>yudao-spring-boot-starter-biz-error-code</module> <module>yudao-spring-boot-starter-biz-error-code</module>
<module>yudao-spring-boot-starter-biz-ip</module>
<module>yudao-spring-boot-starter-flowable</module> <module>yudao-spring-boot-starter-flowable</module>
<module>yudao-spring-boot-starter-captcha</module>
<module>yudao-spring-boot-starter-websocket</module>
<module>yudao-spring-boot-starter-desensitize</module>
</modules> </modules>
<artifactId>yudao-framework</artifactId> <artifactId>yudao-framework</artifactId>

@ -105,6 +105,11 @@
<artifactId>jackson-core</artifactId> <artifactId>jackson-core</artifactId>
<scope>provided</scope> <!-- 设置为 provided只有工具类需要使用到 --> <scope>provided</scope> <!-- 设置为 provided只有工具类需要使用到 -->
</dependency> </dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<scope>provided</scope> <!-- 设置为 provided只有工具类需要使用到 -->
</dependency>
<dependency> <dependency>
<groupId>org.slf4j</groupId> <groupId>org.slf4j</groupId>

@ -20,7 +20,6 @@ public enum CommonStatusEnum implements IntArrayValuable {
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(CommonStatusEnum::getStatus).toArray(); public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(CommonStatusEnum::getStatus).toArray();
/** /**
* *
*/ */

@ -12,7 +12,8 @@ import lombok.Getter;
@AllArgsConstructor @AllArgsConstructor
public enum DocumentEnum { public enum DocumentEnum {
REDIS_INSTALL("https://gitee.com/zhijiantianya/ruoyi-vue-pro/issues/I4VCSJ", "Redis 安装文档"); REDIS_INSTALL("https://gitee.com/zhijiantianya/ruoyi-vue-pro/issues/I4VCSJ", "Redis 安装文档"),
TENANT("https://doc.iocoder.cn", "SaaS 多租户文档");
private final String url; private final String url;
private final String memo; private final String memo;

@ -0,0 +1,40 @@
package cn.iocoder.yudao.framework.common.enums;
import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import java.util.Arrays;
/**
*
*
* @author
*/
@RequiredArgsConstructor
@Getter
public enum TerminalEnum implements IntArrayValuable {
WECHAT_MINI_PROGRAM(10, "微信小程序"),
WECHAT_WAP(11, "微信公众号"),
H5(20, "H5 网页"),
IOS(31, "苹果 App"),
ANDROID(32, "安卓 App"),
;
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(TerminalEnum::getTerminal).toArray();
/**
*
*/
private final Integer terminal;
/**
*
*/
private final String name;
@Override
public int[] array() {
return ARRAYS;
}
}

@ -29,6 +29,7 @@ public interface GlobalErrorCodeConstants {
// ========== 服务端错误段 ========== // ========== 服务端错误段 ==========
ErrorCode INTERNAL_SERVER_ERROR = new ErrorCode(500, "系统异常"); ErrorCode INTERNAL_SERVER_ERROR = new ErrorCode(500, "系统异常");
ErrorCode NOT_IMPLEMENTED = new ErrorCode(501, "功能未实现/未开启");
// ========== 自定义错误段 ========== // ========== 自定义错误段 ==========
ErrorCode REPEATED_REQUESTS = new ErrorCode(900, "重复请求,请稍后重试"); // 重复请求 ErrorCode REPEATED_REQUESTS = new ErrorCode(900, "重复请求,请稍后重试"); // 重复请求

@ -1,6 +1,7 @@
package cn.iocoder.yudao.framework.common.util.collection; package cn.iocoder.yudao.framework.common.util.collection;
import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.collection.IterUtil;
import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.ArrayUtil;
import java.util.Collection; import java.util.Collection;
@ -44,7 +45,7 @@ public class ArrayUtils {
if (CollectionUtil.isEmpty(from)) { if (CollectionUtil.isEmpty(from)) {
return (T[]) (new Object[0]); return (T[]) (new Object[0]);
} }
return ArrayUtil.toArray(from, (Class<T>) CollectionUtil.getElementType(from.iterator())); return ArrayUtil.toArray(from, (Class<T>) IterUtil.getElementType(from.iterator()));
} }
public static <T> T get(T[] array, int index) { public static <T> T get(T[] array, int index) {

@ -173,6 +173,23 @@ public class CollectionUtils {
return valueFunc.apply(t); return valueFunc.apply(t);
} }
public static <T, V extends Comparable<? super V>> V getMinValue(List<T> from, Function<T, V> valueFunc) {
if (CollUtil.isEmpty(from)) {
return null;
}
assert from.size() > 0; // 断言,避免告警
T t = from.stream().min(Comparator.comparing(valueFunc)).get();
return valueFunc.apply(t);
}
public static <T, V extends Comparable<? super V>> V getSumValue(List<T> from, Function<T, V> valueFunc, BinaryOperator<V> accumulator) {
if (CollUtil.isEmpty(from)) {
return null;
}
assert from.size() > 0; // 断言,避免告警
return from.stream().map(valueFunc).reduce(accumulator).get();
}
public static <T> void addIfNotNull(Collection<T> coll, T item) { public static <T> void addIfNotNull(Collection<T> coll, T item) {
if (item == null) { if (item == null) {
return; return;

@ -11,6 +11,7 @@ import java.util.Set;
*/ */
public class SetUtils { public class SetUtils {
@SafeVarargs
public static <T> Set<T> asSet(T... objs) { public static <T> Set<T> asSet(T... objs) {
return new HashSet<>(Arrays.asList(objs)); return new HashSet<>(Arrays.asList(objs));
} }

@ -1,8 +1,8 @@
package cn.iocoder.yudao.framework.common.util.date; package cn.iocoder.yudao.framework.common.util.date;
import cn.hutool.core.date.DateUtil; import cn.hutool.core.date.LocalDateTimeUtil;
import java.time.Duration; import java.time.*;
import java.util.Calendar; import java.util.Calendar;
import java.util.Date; import java.util.Date;
@ -25,6 +25,37 @@ public class DateUtils {
public static final String FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND = "yyyy-MM-dd HH:mm:ss"; public static final String FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND = "yyyy-MM-dd HH:mm:ss";
public static final String FORMAT_HOUR_MINUTE_SECOND = "HH:mm:ss";
/**
* LocalDateTime Date
*
* @param date LocalDateTime
* @return LocalDateTime
*/
public static Date of(LocalDateTime date) {
// 将此日期时间与时区相结合以创建 ZonedDateTime
ZonedDateTime zonedDateTime = date.atZone(ZoneId.systemDefault());
// 本地时间线 LocalDateTime 到即时时间线 Instant 时间戳
Instant instant = zonedDateTime.toInstant();
// UTC时间(世界协调时间,UTC + 00:00)转北京(北京,UTC + 8:00)时间
return Date.from(instant);
}
/**
* Date LocalDateTime
*
* @param date Date
* @return LocalDateTime
*/
public static LocalDateTime of(Date date) {
// 转为时间戳
Instant instant = date.toInstant();
// UTC时间(世界协调时间,UTC + 00:00)转北京(北京,UTC + 8:00)时间
return LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
}
@Deprecated
public static Date addTime(Duration duration) { public static Date addTime(Duration duration) {
return new Date(System.currentTimeMillis() + duration.toMillis()); return new Date(System.currentTimeMillis() + duration.toMillis());
} }
@ -33,6 +64,11 @@ public class DateUtils {
return System.currentTimeMillis() > time.getTime(); return System.currentTimeMillis() > time.getTime();
} }
public static boolean isExpired(LocalDateTime time) {
LocalDateTime now = LocalDateTime.now();
return now.isAfter(time);
}
public static long diff(Date endTime, Date startTime) { public static long diff(Date endTime, Date startTime) {
return endTime.getTime() - startTime.getTime(); return endTime.getTime() - startTime.getTime();
} }
@ -40,9 +76,9 @@ public class DateUtils {
/** /**
* *
* *
* @param year * @param year
* @param mouth * @param mouth
* @param day * @param day
* @return * @return
*/ */
public static Date buildTime(int year, int mouth, int day) { public static Date buildTime(int year, int mouth, int day) {
@ -52,12 +88,12 @@ public class DateUtils {
/** /**
* *
* *
* @param year * @param year
* @param mouth * @param mouth
* @param day * @param day
* @param hour * @param hour
* @param minute * @param minute
* @param second * @param second
* @return * @return
*/ */
public static Date buildTime(int year, int mouth, int day, public static Date buildTime(int year, int mouth, int day,
@ -83,12 +119,14 @@ public class DateUtils {
return a.compareTo(b) > 0 ? a : b; return a.compareTo(b) > 0 ? a : b;
} }
public static boolean beforeNow(Date date) { public static LocalDateTime max(LocalDateTime a, LocalDateTime b) {
return date.getTime() < System.currentTimeMillis(); if (a == null) {
} return b;
}
public static boolean afterNow(Date date) { if (b == null) {
return date.getTime() >= System.currentTimeMillis(); return a;
}
return a.isAfter(b) ? a : b;
} }
/** /**
@ -128,11 +166,8 @@ public class DateUtils {
* @param date * @param date
* @return * @return
*/ */
public static boolean isToday(Date date) { public static boolean isToday(LocalDateTime date) {
if (date == null) { return LocalDateTimeUtil.isSameDay(date, LocalDateTime.now());
return false;
}
return DateUtil.isSameDay(date, new Date());
} }
} }

@ -0,0 +1,63 @@
package cn.iocoder.yudao.framework.common.util.date;
import cn.hutool.core.date.LocalDateTimeUtil;
import java.time.Duration;
import java.time.LocalDateTime;
/**
* {@link java.time.LocalDateTime}
*
* @author
*/
public class LocalDateTimeUtils {
/**
* LocalDateTime DB
*/
public static LocalDateTime EMPTY = buildTime(1970, 1, 1);
public static LocalDateTime addTime(Duration duration) {
return LocalDateTime.now().plus(duration);
}
public static boolean beforeNow(LocalDateTime date) {
return date.isBefore(LocalDateTime.now());
}
public static boolean afterNow(LocalDateTime date) {
return date.isAfter(LocalDateTime.now());
}
/**
*
*
* @param year
* @param mouth
* @param day
* @return
*/
public static LocalDateTime buildTime(int year, int mouth, int day) {
return LocalDateTime.of(year, mouth, day, 0, 0, 0);
}
public static LocalDateTime[] buildBetweenTime(int year1, int mouth1, int day1,
int year2, int mouth2, int day2) {
return new LocalDateTime[]{buildTime(year1, mouth1, day1), buildTime(year2, mouth2, day2)};
}
/**
*
*
* @param startTime
* @param endTime
* @return
*/
public static boolean isBetween(LocalDateTime startTime, LocalDateTime endTime) {
if (startTime == null || endTime == null) {
return false;
}
return LocalDateTimeUtil.isIn(LocalDateTime.now(), startTime, endTime);
}
}

@ -7,6 +7,7 @@ import com.fasterxml.jackson.core.type.TypeReference;
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.datatype.jsr310.JavaTimeModule;
import lombok.SneakyThrows; import lombok.SneakyThrows;
import lombok.experimental.UtilityClass; import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -28,6 +29,7 @@ public class JsonUtils {
static { static {
objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
objectMapper.registerModules(new JavaTimeModule()); // 解决 LocalDateTime 的序列化
} }
/** /**

@ -1,12 +1,10 @@
package cn.iocoder.yudao.framework.common.util.object; package cn.iocoder.yudao.framework.common.util.object;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ReflectUtil; import cn.hutool.core.util.ReflectUtil;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.Arrays; import java.util.Arrays;
import java.util.Objects;
import java.util.function.Consumer; import java.util.function.Consumer;
/** /**
@ -47,6 +45,7 @@ public class ObjectUtils {
return obj1.compareTo(obj2) > 0 ? obj1 : obj2; return obj1.compareTo(obj2) > 0 ? obj1 : obj2;
} }
@SafeVarargs
public static <T> T defaultIfNull(T... array) { public static <T> T defaultIfNull(T... array) {
for (T item : array) { for (T item : array) {
if (item != null) { if (item != null) {
@ -56,6 +55,7 @@ public class ObjectUtils {
return null; return null;
} }
@SafeVarargs
public static <T> boolean equalsAny(T obj, T... array) { public static <T> boolean equalsAny(T obj, T... array) {
return Arrays.asList(array).contains(obj); return Arrays.asList(array).contains(obj);
} }

@ -3,7 +3,10 @@ package cn.iocoder.yudao.framework.common.util.string;
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 java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
/** /**
* *
@ -37,4 +40,9 @@ public class StrUtils {
return false; return false;
} }
public static List<Long> splitToLong(String value, CharSequence separator) {
long[] longs = StrUtil.splitToLong(value, separator);
return Arrays.stream(longs).boxed().collect(Collectors.toList());
}
} }

@ -1,7 +1,6 @@
package cn.iocoder.yudao.framework.common.util.validation; package cn.iocoder.yudao.framework.common.util.validation;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import javax.validation.ConstraintViolation; import javax.validation.ConstraintViolation;
@ -17,16 +16,15 @@ import java.util.regex.Pattern;
*/ */
public class ValidationUtils { public class ValidationUtils {
private static final Pattern PATTERN_MOBILE = Pattern.compile("^(?:(?:\\+|00)86)?1(?:(?:3[\\d])|(?:4[5-79])|(?:5[0-35-9])|(?:6[5-7])|(?:7[0-8])|(?:8[\\d])|(?:9[189]))\\d{8}$");
private static final Pattern PATTERN_URL = Pattern.compile("^(https?|ftp|file)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]"); private static final Pattern PATTERN_URL = Pattern.compile("^(https?|ftp|file)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]");
private static final Pattern PATTERN_XML_NCNAME = Pattern.compile("[a-zA-Z_][\\-_.0-9_a-zA-Z$]*"); private static final Pattern PATTERN_XML_NCNAME = Pattern.compile("[a-zA-Z_][\\-_.0-9_a-zA-Z$]*");
public static boolean isMobile(String mobile) { public static boolean isMobile(String mobile) {
if (StrUtil.length(mobile) != 11) { return StringUtils.hasText(mobile)
return false; && PATTERN_MOBILE.matcher(mobile).matches();
}
// TODO 芋艿,后面完善手机校验
return true;
} }
public static boolean isURL(String url) { public static boolean isURL(String url) {

@ -1,15 +1,15 @@
package cn.iocoder.yudao.framework.banner.config; package cn.iocoder.yudao.framework.banner.config;
import cn.iocoder.yudao.framework.banner.core.BannerApplicationRunner; import cn.iocoder.yudao.framework.banner.core.BannerApplicationRunner;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/** /**
* Banner * Banner
* *
* @author * @author
*/ */
@Configuration @AutoConfiguration
public class YudaoBannerAutoConfiguration { public class YudaoBannerAutoConfiguration {
@Bean @Bean

@ -1,2 +0,0 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
cn.iocoder.yudao.framework.banner.config.YudaoBannerAutoConfiguration

@ -7,8 +7,8 @@ import cn.iocoder.yudao.framework.datapermission.core.rule.DataPermissionRuleFac
import cn.iocoder.yudao.framework.datapermission.core.rule.DataPermissionRuleFactoryImpl; import cn.iocoder.yudao.framework.datapermission.core.rule.DataPermissionRuleFactoryImpl;
import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils; import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.List; import java.util.List;
@ -17,7 +17,7 @@ import java.util.List;
* *
* @author * @author
*/ */
@Configuration @AutoConfiguration
public class YudaoDataPermissionAutoConfiguration { public class YudaoDataPermissionAutoConfiguration {
@Bean @Bean
@ -27,9 +27,8 @@ public class YudaoDataPermissionAutoConfiguration {
@Bean @Bean
public DataPermissionDatabaseInterceptor dataPermissionDatabaseInterceptor(MybatisPlusInterceptor interceptor, public DataPermissionDatabaseInterceptor dataPermissionDatabaseInterceptor(MybatisPlusInterceptor interceptor,
List<DataPermissionRule> rules) { DataPermissionRuleFactory ruleFactory) {
// 创建 DataPermissionDatabaseInterceptor 拦截器 // 创建 DataPermissionDatabaseInterceptor 拦截器
DataPermissionRuleFactory ruleFactory = dataPermissionRuleFactory(rules);
DataPermissionDatabaseInterceptor inner = new DataPermissionDatabaseInterceptor(ruleFactory); DataPermissionDatabaseInterceptor inner = new DataPermissionDatabaseInterceptor(ruleFactory);
// 添加到 interceptor 中 // 添加到 interceptor 中
// 需要加在首个,主要是为了在分页插件前面。这个是 MyBatis Plus 的规定 // 需要加在首个,主要是为了在分页插件前面。这个是 MyBatis Plus 的规定

@ -4,10 +4,10 @@ import cn.iocoder.yudao.framework.datapermission.core.rule.dept.DeptDataPermissi
import cn.iocoder.yudao.framework.datapermission.core.rule.dept.DeptDataPermissionRuleCustomizer; import cn.iocoder.yudao.framework.datapermission.core.rule.dept.DeptDataPermissionRuleCustomizer;
import cn.iocoder.yudao.framework.security.core.LoginUser; import cn.iocoder.yudao.framework.security.core.LoginUser;
import cn.iocoder.yudao.module.system.api.permission.PermissionApi; import cn.iocoder.yudao.module.system.api.permission.PermissionApi;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.List; import java.util.List;
@ -16,7 +16,7 @@ import java.util.List;
* *
* @author * @author
*/ */
@Configuration @AutoConfiguration
@ConditionalOnClass(LoginUser.class) @ConditionalOnClass(LoginUser.class)
@ConditionalOnBean(value = {PermissionApi.class, DeptDataPermissionRuleCustomizer.class}) @ConditionalOnBean(value = {PermissionApi.class, DeptDataPermissionRuleCustomizer.class})
public class YudaoDeptDataPermissionAutoConfiguration { public class YudaoDeptDataPermissionAutoConfiguration {

@ -18,7 +18,6 @@ import net.sf.jsqlparser.expression.operators.conditional.OrExpression;
import net.sf.jsqlparser.expression.operators.relational.ExistsExpression; import net.sf.jsqlparser.expression.operators.relational.ExistsExpression;
import net.sf.jsqlparser.expression.operators.relational.ExpressionList; import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
import net.sf.jsqlparser.expression.operators.relational.InExpression; import net.sf.jsqlparser.expression.operators.relational.InExpression;
import net.sf.jsqlparser.expression.operators.relational.ItemsList;
import net.sf.jsqlparser.schema.Table; import net.sf.jsqlparser.schema.Table;
import net.sf.jsqlparser.statement.delete.Delete; import net.sf.jsqlparser.statement.delete.Delete;
import net.sf.jsqlparser.statement.select.*; import net.sf.jsqlparser.statement.select.*;
@ -37,7 +36,7 @@ import java.util.concurrent.ConcurrentHashMap;
/** /**
* {@link DataPermissionRule} SQL * {@link DataPermissionRule} SQL
* SQL {@link #builderExpression(Expression, Table)} * SQL {@link #builderExpression(Expression, List)}
* *
* {@link com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor} * {@link com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor}
* MyBatis Plus Review * MyBatis Plus Review
@ -53,8 +52,7 @@ public class DataPermissionDatabaseInterceptor extends JsqlParserSupport impleme
private final MappedStatementCache mappedStatementCache = new MappedStatementCache(); private final MappedStatementCache mappedStatementCache = new MappedStatementCache();
@Override // SELECT 场景 @Override // SELECT 场景
public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
// 获得 Mapper 对应的数据权限的规则 // 获得 Mapper 对应的数据权限的规则
List<DataPermissionRule> rules = ruleFactory.getDataPermissionRule(ms.getId()); List<DataPermissionRule> rules = ruleFactory.getDataPermissionRule(ms.getId());
if (mappedStatementCache.noRewritable(ms, rules)) { // 如果无需重写,则跳过 if (mappedStatementCache.noRewritable(ms, rules)) { // 如果无需重写,则跳过
@ -68,12 +66,14 @@ public class DataPermissionDatabaseInterceptor extends JsqlParserSupport impleme
// 处理 SQL // 处理 SQL
mpBs.sql(parserSingle(mpBs.sql(), null)); mpBs.sql(parserSingle(mpBs.sql(), null));
} finally { } finally {
// 添加是否需要重写的缓存
addMappedStatementCache(ms); addMappedStatementCache(ms);
// 清空上下文
ContextHolder.clear(); ContextHolder.clear();
} }
} }
@Override // 只处理 UPDATE / DELETE 场景,不处理 INSERT 场景 @Override // 只处理 UPDATE / DELETE 场景,不处理 INSERT 场景(因为 INSERT 不需要数据权限)
public void beforePrepare(StatementHandler sh, Connection connection, Integer transactionTimeout) { public void beforePrepare(StatementHandler sh, Connection connection, Integer transactionTimeout) {
PluginUtils.MPStatementHandler mpSh = PluginUtils.mpStatementHandler(sh); PluginUtils.MPStatementHandler mpSh = PluginUtils.mpStatementHandler(sh);
MappedStatement ms = mpSh.mappedStatement(); MappedStatement ms = mpSh.mappedStatement();
@ -92,7 +92,9 @@ public class DataPermissionDatabaseInterceptor extends JsqlParserSupport impleme
// 处理 SQL // 处理 SQL
mpBs.sql(parserMulti(mpBs.sql(), null)); mpBs.sql(parserMulti(mpBs.sql(), null));
} finally { } finally {
// 添加是否需要重写的缓存
addMappedStatementCache(ms); addMappedStatementCache(ms);
// 清空上下文
ContextHolder.clear(); ContextHolder.clear();
} }
} }
@ -107,24 +109,6 @@ public class DataPermissionDatabaseInterceptor extends JsqlParserSupport impleme
} }
} }
protected void processSelectBody(SelectBody selectBody) {
if (selectBody == null) {
return;
}
if (selectBody instanceof PlainSelect) {
processPlainSelect((PlainSelect) selectBody);
} else if (selectBody instanceof WithItem) {
WithItem withItem = (WithItem) selectBody;
processSelectBody(withItem.getSubSelect().getSelectBody());
} else {
SetOperationList operationList = (SetOperationList) selectBody;
List<SelectBody> selectBodys = operationList.getSelects();
if (CollectionUtils.isNotEmpty(selectBodys)) {
selectBodys.forEach(this::processSelectBody);
}
}
}
/** /**
* update * update
*/ */
@ -142,28 +126,77 @@ public class DataPermissionDatabaseInterceptor extends JsqlParserSupport impleme
delete.setWhere(this.builderExpression(delete.getWhere(), delete.getTable())); delete.setWhere(this.builderExpression(delete.getWhere(), delete.getTable()));
} }
// ========== 和 TenantLineInnerInterceptor 一致的逻辑 ==========
protected void processSelectBody(SelectBody selectBody) {
if (selectBody == null) {
return;
}
if (selectBody instanceof PlainSelect) {
processPlainSelect((PlainSelect) selectBody);
} else if (selectBody instanceof WithItem) {
WithItem withItem = (WithItem) selectBody;
processSelectBody(withItem.getSubSelect().getSelectBody());
} else {
SetOperationList operationList = (SetOperationList) selectBody;
List<SelectBody> selectBodyList = operationList.getSelects();
if (CollectionUtils.isNotEmpty(selectBodyList)) {
selectBodyList.forEach(this::processSelectBody);
}
}
}
/** /**
* PlainSelect * PlainSelect
*/ */
protected void processPlainSelect(PlainSelect plainSelect) { protected void processPlainSelect(PlainSelect plainSelect) {
FromItem fromItem = plainSelect.getFromItem();
Expression where = plainSelect.getWhere();
processWhereSubSelect(where);
if (fromItem instanceof Table) {
Table fromTable = (Table) fromItem;
plainSelect.setWhere(builderExpression(where, fromTable));
} else {
processFromItem(fromItem);
}
//#3087 github //#3087 github
List<SelectItem> selectItems = plainSelect.getSelectItems(); List<SelectItem> selectItems = plainSelect.getSelectItems();
if (CollectionUtils.isNotEmpty(selectItems)) { if (CollectionUtils.isNotEmpty(selectItems)) {
selectItems.forEach(this::processSelectItem); selectItems.forEach(this::processSelectItem);
} }
// 处理 where 中的子查询
Expression where = plainSelect.getWhere();
processWhereSubSelect(where);
// 处理 fromItem
FromItem fromItem = plainSelect.getFromItem();
List<Table> list = processFromItem(fromItem);
List<Table> mainTables = new ArrayList<>(list);
// 处理 join
List<Join> joins = plainSelect.getJoins(); List<Join> joins = plainSelect.getJoins();
if (CollectionUtils.isNotEmpty(joins)) { if (CollectionUtils.isNotEmpty(joins)) {
processJoins(joins); mainTables = processJoins(mainTables, joins);
}
// 当有 mainTable 时,进行 where 条件追加
if (CollectionUtils.isNotEmpty(mainTables)) {
plainSelect.setWhere(builderExpression(where, mainTables));
}
}
private List<Table> processFromItem(FromItem fromItem) {
// 处理括号括起来的表达式
while (fromItem instanceof ParenthesisFromItem) {
fromItem = ((ParenthesisFromItem) fromItem).getFromItem();
}
List<Table> mainTables = new ArrayList<>();
// 无 join 时的处理逻辑
if (fromItem instanceof Table) {
Table fromTable = (Table) fromItem;
mainTables.add(fromTable);
} else if (fromItem instanceof SubJoin) {
// SubJoin 类型则还需要添加上 where 条件
List<Table> tables = processSubJoin((SubJoin) fromItem);
mainTables.addAll(tables);
} else {
// 处理下 fromItem
processOtherFromItem(fromItem);
} }
return mainTables;
} }
/** /**
@ -191,7 +224,7 @@ public class DataPermissionDatabaseInterceptor extends JsqlParserSupport impleme
return; return;
} }
if (where instanceof FromItem) { if (where instanceof FromItem) {
processFromItem((FromItem) where); processOtherFromItem((FromItem) where);
return; return;
} }
if (where.toString().indexOf("SELECT") > 0) { if (where.toString().indexOf("SELECT") > 0) {
@ -204,9 +237,9 @@ public class DataPermissionDatabaseInterceptor extends JsqlParserSupport impleme
} else if (where instanceof InExpression) { } else if (where instanceof InExpression) {
// in // in
InExpression expression = (InExpression) where; InExpression expression = (InExpression) where;
ItemsList itemsList = expression.getRightItemsList(); Expression inExpression = expression.getRightExpression();
if (itemsList instanceof SubSelect) { if (inExpression instanceof SubSelect) {
processSelectBody(((SubSelect) itemsList).getSelectBody()); processSelectBody(((SubSelect) inExpression).getSelectBody());
} }
} else if (where instanceof ExistsExpression) { } else if (where instanceof ExistsExpression) {
// exists // exists
@ -239,7 +272,7 @@ public class DataPermissionDatabaseInterceptor extends JsqlParserSupport impleme
* <p>: 1. select fun(args..) 2. select fun1(fun2(args..),args..)<p> * <p>: 1. select fun(args..) 2. select fun1(fun2(args..),args..)<p>
* <p> fixed gitee pulls/141</p> * <p> fixed gitee pulls/141</p>
* *
* @param function * @param function
*/ */
protected void processFunction(Function function) { protected void processFunction(Function function) {
ExpressionList parameters = function.getParameters(); ExpressionList parameters = function.getParameters();
@ -257,22 +290,19 @@ public class DataPermissionDatabaseInterceptor extends JsqlParserSupport impleme
/** /**
* *
*/ */
protected void processFromItem(FromItem fromItem) { protected void processOtherFromItem(FromItem fromItem) {
if (fromItem instanceof SubJoin) { // 去除括号
SubJoin subJoin = (SubJoin) fromItem; while (fromItem instanceof ParenthesisFromItem) {
if (subJoin.getJoinList() != null) { fromItem = ((ParenthesisFromItem) fromItem).getFromItem();
processJoins(subJoin.getJoinList()); }
}
if (subJoin.getLeft() != null) { if (fromItem instanceof SubSelect) {
processFromItem(subJoin.getLeft());
}
} else if (fromItem instanceof SubSelect) {
SubSelect subSelect = (SubSelect) fromItem; SubSelect subSelect = (SubSelect) fromItem;
if (subSelect.getSelectBody() != null) { if (subSelect.getSelectBody() != null) {
processSelectBody(subSelect.getSelectBody()); processSelectBody(subSelect.getSelectBody());
} }
} else if (fromItem instanceof ValuesList) { } else if (fromItem instanceof ValuesList) {
logger.debug("Perform a subquery, if you do not give us feedback"); logger.debug("Perform a subQuery, if you do not give us feedback");
} else if (fromItem instanceof LateralSubSelect) { } else if (fromItem instanceof LateralSubSelect) {
LateralSubSelect lateralSubSelect = (LateralSubSelect) fromItem; LateralSubSelect lateralSubSelect = (LateralSubSelect) fromItem;
if (lateralSubSelect.getSubSelect() != null) { if (lateralSubSelect.getSubSelect() != null) {
@ -284,75 +314,176 @@ public class DataPermissionDatabaseInterceptor extends JsqlParserSupport impleme
} }
} }
/**
* sub join
*
* @param subJoin subJoin
* @return Table subJoin
*/
private List<Table> processSubJoin(SubJoin subJoin) {
List<Table> mainTables = new ArrayList<>();
if (subJoin.getJoinList() != null) {
List<Table> list = processFromItem(subJoin.getLeft());
mainTables.addAll(list);
mainTables = processJoins(mainTables, subJoin.getJoinList());
}
return mainTables;
}
/** /**
* joins * joins
* *
* @param joins join * @param mainTables null
* @param joins join
* @return List<Table> Table
*/ */
private void processJoins(List<Join> joins) { private List<Table> processJoins(List<Table> mainTables, List<Join> joins) {
// join 表达式中最终的主表
Table mainTable = null;
// 当前 join 的左表
Table leftTable = null;
if (mainTables == null) {
mainTables = new ArrayList<>();
} else if (mainTables.size() == 1) {
mainTable = mainTables.get(0);
leftTable = mainTable;
}
//对于 on 表达式写在最后的 join需要记录下前面多个 on 的表名 //对于 on 表达式写在最后的 join需要记录下前面多个 on 的表名
Deque<Table> tables = new LinkedList<>(); Deque<List<Table>> onTableDeque = new LinkedList<>();
for (Join join : joins) { for (Join join : joins) {
// 处理 on 表达式 // 处理 on 表达式
FromItem fromItem = join.getRightItem(); FromItem joinItem = join.getRightItem();
if (fromItem instanceof Table) {
Table fromTable = (Table) fromItem; // 获取当前 join 的表subJoint 可以看作是一张表
List<Table> joinTables = null;
if (joinItem instanceof Table) {
joinTables = new ArrayList<>();
joinTables.add((Table) joinItem);
} else if (joinItem instanceof SubJoin) {
joinTables = processSubJoin((SubJoin) joinItem);
}
if (joinTables != null) {
// 如果是隐式内连接
if (join.isSimple()) {
mainTables.addAll(joinTables);
continue;
}
// 当前表是否忽略
Table joinTable = joinTables.get(0);
List<Table> onTables = null;
// 如果不要忽略,且是右连接,则记录下当前表
if (join.isRight()) {
mainTable = joinTable;
if (leftTable != null) {
onTables = Collections.singletonList(leftTable);
}
} else if (join.isLeft()) {
onTables = Collections.singletonList(joinTable);
} else if (join.isInner()) {
if (mainTable == null) {
onTables = Collections.singletonList(joinTable);
} else {
onTables = Arrays.asList(mainTable, joinTable);
}
mainTable = null;
}
mainTables = new ArrayList<>();
if (mainTable != null) {
mainTables.add(mainTable);
}
// 获取 join 尾缀的 on 表达式列表 // 获取 join 尾缀的 on 表达式列表
Collection<Expression> originOnExpressions = join.getOnExpressions(); Collection<Expression> originOnExpressions = join.getOnExpressions();
// 正常 join on 表达式只有一个,立刻处理 // 正常 join on 表达式只有一个,立刻处理
if (originOnExpressions.size() == 1) { if (originOnExpressions.size() == 1 && onTables != null) {
processJoin(join); List<Expression> onExpressions = new LinkedList<>();
onExpressions.add(builderExpression(originOnExpressions.iterator().next(), onTables));
join.setOnExpressions(onExpressions);
leftTable = joinTable;
continue; continue;
} }
tables.push(fromTable); // 表名压栈,忽略的表压入 null以便后续不处理
onTableDeque.push(onTables);
// 尾缀多个 on 表达式的时候统一处理 // 尾缀多个 on 表达式的时候统一处理
if (originOnExpressions.size() > 1) { if (originOnExpressions.size() > 1) {
Collection<Expression> onExpressions = new LinkedList<>(); Collection<Expression> onExpressions = new LinkedList<>();
for (Expression originOnExpression : originOnExpressions) { for (Expression originOnExpression : originOnExpressions) {
Table currentTable = tables.poll(); List<Table> currentTableList = onTableDeque.poll();
onExpressions.add(builderExpression(originOnExpression, currentTable)); if (CollectionUtils.isEmpty(currentTableList)) {
onExpressions.add(originOnExpression);
} else {
onExpressions.add(builderExpression(originOnExpression, currentTableList));
}
} }
join.setOnExpressions(onExpressions); join.setOnExpressions(onExpressions);
} }
leftTable = joinTable;
} else { } else {
// 处理右边连接的子表达式 processOtherFromItem(joinItem);
processFromItem(fromItem); leftTable = null;
} }
} }
return mainTables;
} }
// ========== 和 TenantLineInnerInterceptor 存在差异的逻辑:关键,实现权限条件的拼接 ==========
/** /**
* *
*
* @param currentExpression where
* @param table
*/ */
protected void processJoin(Join join) { protected Expression builderExpression(Expression currentExpression, Table table) {
if (join.getRightItem() instanceof Table) { return this.builderExpression(currentExpression, Collections.singletonList(table));
Table fromTable = (Table) join.getRightItem();
Expression originOnExpression = CollUtil.getFirst(join.getOnExpressions());
originOnExpression = builderExpression(originOnExpression, fromTable);
join.setOnExpressions(CollUtil.newArrayList(originOnExpression));
}
} }
/** /**
* *
*
* @param currentExpression where
* @param tables
*/ */
protected Expression builderExpression(Expression currentExpression, Table table) { protected Expression builderExpression(Expression currentExpression, List<Table> tables) {
// 获得 Table 对应的数据权限条件 // 没有表需要处理直接返回
Expression equalsTo = buildDataPermissionExpression(table); if (CollectionUtils.isEmpty(tables)) {
if (equalsTo == null) { // 如果没条件,则返回 currentExpression 默认
return currentExpression; return currentExpression;
} }
// 表达式为空,则直接返回 equalsTo // 第一步,获得 Table 对应的数据权限条件
Expression dataPermissionExpression = null;
for (Table table : tables) {
// 构建每个表的权限 Expression 条件
Expression expression = buildDataPermissionExpression(table);
if (expression == null) {
continue;
}
// 合并到 dataPermissionExpression 中
dataPermissionExpression = dataPermissionExpression == null ? expression
: new AndExpression(dataPermissionExpression, expression);
}
// 第二步,合并多个 Expression 条件
if (dataPermissionExpression == null) {
return currentExpression;
}
if (currentExpression == null) { if (currentExpression == null) {
return equalsTo; return dataPermissionExpression;
} }
// 如果表达式为 Or则需要 (currentExpression) AND equalsTo // 如果表达式为 Or则需要 (currentExpression) AND dataPermissionExpression
if (currentExpression instanceof OrExpression) { if (currentExpression instanceof OrExpression) {
return new AndExpression(new Parenthesis(currentExpression), equalsTo); return new AndExpression(new Parenthesis(currentExpression), dataPermissionExpression);
} }
// 如果表达式为 And则直接返回 currentExpression AND equalsTo // ② 如果表达式为 And则直接返回 where AND dataPermissionExpression
return new AndExpression(currentExpression, equalsTo); return new AndExpression(currentExpression, dataPermissionExpression);
} }
/** /**

@ -7,6 +7,7 @@ import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.framework.common.util.json.JsonUtils; import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
import cn.iocoder.yudao.framework.datapermission.core.rule.DataPermissionRule; import cn.iocoder.yudao.framework.datapermission.core.rule.DataPermissionRule;
import cn.iocoder.yudao.framework.expression.OrExpressionX;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils; import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils;
import cn.iocoder.yudao.framework.security.core.LoginUser; import cn.iocoder.yudao.framework.security.core.LoginUser;
@ -20,7 +21,6 @@ import net.sf.jsqlparser.expression.Alias;
import net.sf.jsqlparser.expression.Expression; import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.LongValue; import net.sf.jsqlparser.expression.LongValue;
import net.sf.jsqlparser.expression.NullValue; import net.sf.jsqlparser.expression.NullValue;
import net.sf.jsqlparser.expression.operators.conditional.OrExpression;
import net.sf.jsqlparser.expression.operators.relational.EqualsTo; import net.sf.jsqlparser.expression.operators.relational.EqualsTo;
import net.sf.jsqlparser.expression.operators.relational.ExpressionList; import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
import net.sf.jsqlparser.expression.operators.relational.InExpression; import net.sf.jsqlparser.expression.operators.relational.InExpression;
@ -143,8 +143,8 @@ public class DeptDataPermissionRule implements DataPermissionRule {
if (userExpression == null) { if (userExpression == null) {
return deptExpression; return deptExpression;
} }
// 目前,如果有指定部门 + 可查看自己,采用 OR 条件。即WHERE dept_id IN ? OR user_id = ? // 目前,如果有指定部门 + 可查看自己,采用 OR 条件。即WHERE (dept_id IN ? OR user_id = ?)
return new OrExpression(deptExpression, userExpression); return new OrExpressionX(deptExpression, userExpression);
} }
private Expression buildDeptExpression(String tableName, Alias tableAlias, Set<Long> deptIds) { private Expression buildDeptExpression(String tableName, Alias tableAlias, Set<Long> deptIds) {

@ -1,3 +0,0 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
cn.iocoder.yudao.framework.datapermission.config.YudaoDataPermissionAutoConfiguration,\
cn.iocoder.yudao.framework.datapermission.config.YudaoDeptDataPermissionAutoConfiguration

@ -0,0 +1,2 @@
cn.iocoder.yudao.framework.datapermission.config.YudaoDataPermissionAutoConfiguration
cn.iocoder.yudao.framework.datapermission.config.YudaoDeptDataPermissionAutoConfiguration

@ -87,7 +87,7 @@ public class DataPermissionDatabaseInterceptorTest extends BaseMockitoUnitTest {
interceptor.beforeQuery(null, mappedStatement, null, null, null, boundSql); interceptor.beforeQuery(null, mappedStatement, null, null, null, boundSql);
// 断言 // 断言
verify(mpBs, times(1)).sql( verify(mpBs, times(1)).sql(
eq("SELECT * FROM t_user WHERE id = 1 AND dept_id = 100")); eq("SELECT * FROM t_user WHERE id = 1 AND t_user.dept_id = 100"));
// 断言缓存 // 断言缓存
assertTrue(interceptor.getMappedStatementCache().getNoRewritableMappedStatements().isEmpty()); assertTrue(interceptor.getMappedStatementCache().getNoRewritableMappedStatements().isEmpty());
} }

@ -46,7 +46,7 @@ public class DataPermissionDatabaseInterceptorTest2 extends BaseMockitoUnitTest
@Override @Override
public Set<String> getTableNames() { public Set<String> getTableNames() {
return asSet("entity", "entity1", "entity2", "t1", "t2", // 支持 MyBatis Plus 的单元测试 return asSet("entity", "entity1", "entity2", "entity3", "t1", "t2", "sys_dict_item", // 支持 MyBatis Plus 的单元测试
"t_user", "t_role"); // 满足自己的单元测试 "t_user", "t_role"); // 满足自己的单元测试
} }
@ -84,30 +84,30 @@ public class DataPermissionDatabaseInterceptorTest2 extends BaseMockitoUnitTest
@Test @Test
void delete() { void delete() {
assertSql("delete from entity where id = ?", assertSql("delete from entity where id = ?",
"DELETE FROM entity WHERE id = ? AND tenant_id = 1"); "DELETE FROM entity WHERE id = ? AND entity.tenant_id = 1");
} }
@Test @Test
void update() { void update() {
assertSql("update entity set name = ? where id = ?", assertSql("update entity set name = ? where id = ?",
"UPDATE entity SET name = ? WHERE id = ? AND tenant_id = 1"); "UPDATE entity SET name = ? WHERE id = ? AND entity.tenant_id = 1");
} }
@Test @Test
void selectSingle() { void selectSingle() {
// 单表 // 单表
assertSql("select * from entity where id = ?", assertSql("select * from entity where id = ?",
"SELECT * FROM entity WHERE id = ? AND tenant_id = 1"); "SELECT * FROM entity WHERE id = ? AND entity.tenant_id = 1");
assertSql("select * from entity where id = ? or name = ?", assertSql("select * from entity where id = ? or name = ?",
"SELECT * FROM entity WHERE (id = ? OR name = ?) AND tenant_id = 1"); "SELECT * FROM entity WHERE (id = ? OR name = ?) AND entity.tenant_id = 1");
assertSql("SELECT * FROM entity WHERE (id = ? OR name = ?)", assertSql("SELECT * FROM entity WHERE (id = ? OR name = ?)",
"SELECT * FROM entity WHERE (id = ? OR name = ?) AND tenant_id = 1"); "SELECT * FROM entity WHERE (id = ? OR name = ?) AND entity.tenant_id = 1");
/* not */ /* not */
assertSql("SELECT * FROM entity WHERE not (id = ? OR name = ?)", assertSql("SELECT * FROM entity WHERE not (id = ? OR name = ?)",
"SELECT * FROM entity WHERE NOT (id = ? OR name = ?) AND tenant_id = 1"); "SELECT * FROM entity WHERE NOT (id = ? OR name = ?) AND entity.tenant_id = 1");
} }
@Test @Test
@ -167,10 +167,12 @@ public class DataPermissionDatabaseInterceptorTest2 extends BaseMockitoUnitTest
assertSql("SELECT * FROM entity e WHERE e.id >= (select e1.id from entity1 e1 where e1.id = ?)", assertSql("SELECT * FROM entity e WHERE e.id >= (select e1.id from entity1 e1 where e1.id = ?)",
"SELECT * FROM entity e WHERE e.id >= (SELECT e1.id FROM entity1 e1 WHERE e1.id = ? AND e1.tenant_id = 1) AND e.tenant_id = 1"); "SELECT * FROM entity e WHERE e.id >= (SELECT e1.id FROM entity1 e1 WHERE e1.id = ? AND e1.tenant_id = 1) AND e.tenant_id = 1");
/* <= */ /* <= */
assertSql("SELECT * FROM entity e WHERE e.id <= (select e1.id from entity1 e1 where e1.id = ?)", assertSql("SELECT * FROM entity e WHERE e.id <= (select e1.id from entity1 e1 where e1.id = ?)",
"SELECT * FROM entity e WHERE e.id <= (SELECT e1.id FROM entity1 e1 WHERE e1.id = ? AND e1.tenant_id = 1) AND e.tenant_id = 1"); "SELECT * FROM entity e WHERE e.id <= (SELECT e1.id FROM entity1 e1 WHERE e1.id = ? AND e1.tenant_id = 1) AND e.tenant_id = 1");
/* <> */ /* <> */
assertSql("SELECT * FROM entity e WHERE e.id <> (select e1.id from entity1 e1 where e1.id = ?)", assertSql("SELECT * FROM entity e WHERE e.id <> (select e1.id from entity1 e1 where e1.id = ?)",
"SELECT * FROM entity e WHERE e.id <> (SELECT e1.id FROM entity1 e1 WHERE e1.id = ? AND e1.tenant_id = 1) AND e.tenant_id = 1"); "SELECT * FROM entity e WHERE e.id <> (SELECT e1.id FROM entity1 e1 WHERE e1.id = ? AND e1.tenant_id = 1) AND e.tenant_id = 1");
@ -204,6 +206,14 @@ public class DataPermissionDatabaseInterceptorTest2 extends BaseMockitoUnitTest
"SELECT * FROM entity e " + "SELECT * FROM entity e " +
"LEFT JOIN entity1 e1 ON e1.id = e.id AND e1.tenant_id = 1 " + "LEFT JOIN entity1 e1 ON e1.id = e.id AND e1.tenant_id = 1 " +
"WHERE (e.id = ? OR e.name = ?) AND e.tenant_id = 1"); "WHERE (e.id = ? OR e.name = ?) AND e.tenant_id = 1");
assertSql("SELECT * FROM entity e " +
"left join entity1 e1 on e1.id = e.id " +
"left join entity2 e2 on e1.id = e2.id",
"SELECT * FROM entity e " +
"LEFT JOIN entity1 e1 ON e1.id = e.id AND e1.tenant_id = 1 " +
"LEFT JOIN entity2 e2 ON e1.id = e2.id AND e2.tenant_id = 1 " +
"WHERE e.tenant_id = 1");
} }
@Test @Test
@ -212,17 +222,125 @@ public class DataPermissionDatabaseInterceptorTest2 extends BaseMockitoUnitTest
assertSql("SELECT * FROM entity e " + assertSql("SELECT * FROM entity e " +
"right join entity1 e1 on e1.id = e.id", "right join entity1 e1 on e1.id = e.id",
"SELECT * FROM entity e " + "SELECT * FROM entity e " +
"RIGHT JOIN entity1 e1 ON e1.id = e.id AND e1.tenant_id = 1 " + "RIGHT JOIN entity1 e1 ON e1.id = e.id AND e.tenant_id = 1 " +
"WHERE e.tenant_id = 1"); "WHERE e1.tenant_id = 1");
assertSql("SELECT * FROM with_as_1 e " +
"right join entity1 e1 on e1.id = e.id",
"SELECT * FROM with_as_1 e " +
"RIGHT JOIN entity1 e1 ON e1.id = e.id " +
"WHERE e1.tenant_id = 1");
assertSql("SELECT * FROM entity e " + assertSql("SELECT * FROM entity e " +
"right join entity1 e1 on e1.id = e.id " + "right join entity1 e1 on e1.id = e.id " +
"WHERE e.id = ? OR e.name = ?", "WHERE e.id = ? OR e.name = ?",
"SELECT * FROM entity e " + "SELECT * FROM entity e " +
"RIGHT JOIN entity1 e1 ON e1.id = e.id AND e1.tenant_id = 1 " + "RIGHT JOIN entity1 e1 ON e1.id = e.id AND e.tenant_id = 1 " +
"WHERE (e.id = ? OR e.name = ?) AND e.tenant_id = 1"); "WHERE (e.id = ? OR e.name = ?) AND e1.tenant_id = 1");
assertSql("SELECT * FROM entity e " +
"right join entity1 e1 on e1.id = e.id " +
"right join entity2 e2 on e1.id = e2.id ",
"SELECT * FROM entity e " +
"RIGHT JOIN entity1 e1 ON e1.id = e.id AND e.tenant_id = 1 " +
"RIGHT JOIN entity2 e2 ON e1.id = e2.id AND e1.tenant_id = 1 " +
"WHERE e2.tenant_id = 1");
}
@Test
void selectMixJoin() {
assertSql("SELECT * FROM entity e " +
"right join entity1 e1 on e1.id = e.id " +
"left join entity2 e2 on e1.id = e2.id",
"SELECT * FROM entity e " +
"RIGHT JOIN entity1 e1 ON e1.id = e.id AND e.tenant_id = 1 " +
"LEFT JOIN entity2 e2 ON e1.id = e2.id AND e2.tenant_id = 1 " +
"WHERE e1.tenant_id = 1");
assertSql("SELECT * FROM entity e " +
"left join entity1 e1 on e1.id = e.id " +
"right join entity2 e2 on e1.id = e2.id",
"SELECT * FROM entity e " +
"LEFT JOIN entity1 e1 ON e1.id = e.id AND e1.tenant_id = 1 " +
"RIGHT JOIN entity2 e2 ON e1.id = e2.id AND e1.tenant_id = 1 " +
"WHERE e2.tenant_id = 1");
assertSql("SELECT * FROM entity e " +
"left join entity1 e1 on e1.id = e.id " +
"inner join entity2 e2 on e1.id = e2.id",
"SELECT * FROM entity e " +
"LEFT JOIN entity1 e1 ON e1.id = e.id AND e1.tenant_id = 1 " +
"INNER JOIN entity2 e2 ON e1.id = e2.id AND e.tenant_id = 1 AND e2.tenant_id = 1");
} }
@Test
void selectJoinSubSelect() {
assertSql("select * from (select * from entity) e1 " +
"left join entity2 e2 on e1.id = e2.id",
"SELECT * FROM (SELECT * FROM entity WHERE entity.tenant_id = 1) e1 " +
"LEFT JOIN entity2 e2 ON e1.id = e2.id AND e2.tenant_id = 1");
assertSql("select * from entity1 e1 " +
"left join (select * from entity2) e2 " +
"on e1.id = e2.id",
"SELECT * FROM entity1 e1 " +
"LEFT JOIN (SELECT * FROM entity2 WHERE entity2.tenant_id = 1) e2 " +
"ON e1.id = e2.id " +
"WHERE e1.tenant_id = 1");
}
@Test
void selectSubJoin() {
assertSql("select * FROM " +
"(entity1 e1 right JOIN entity2 e2 ON e1.id = e2.id)",
"SELECT * FROM " +
"(entity1 e1 RIGHT JOIN entity2 e2 ON e1.id = e2.id AND e1.tenant_id = 1) " +
"WHERE e2.tenant_id = 1");
assertSql("select * FROM " +
"(entity1 e1 LEFT JOIN entity2 e2 ON e1.id = e2.id)",
"SELECT * FROM " +
"(entity1 e1 LEFT JOIN entity2 e2 ON e1.id = e2.id AND e2.tenant_id = 1) " +
"WHERE e1.tenant_id = 1");
assertSql("select * FROM " +
"(entity1 e1 LEFT JOIN entity2 e2 ON e1.id = e2.id) " +
"right join entity3 e3 on e1.id = e3.id",
"SELECT * FROM " +
"(entity1 e1 LEFT JOIN entity2 e2 ON e1.id = e2.id AND e2.tenant_id = 1) " +
"RIGHT JOIN entity3 e3 ON e1.id = e3.id AND e1.tenant_id = 1 " +
"WHERE e3.tenant_id = 1");
assertSql("select * FROM entity e " +
"LEFT JOIN (entity1 e1 right join entity2 e2 ON e1.id = e2.id) " +
"on e.id = e2.id",
"SELECT * FROM entity e " +
"LEFT JOIN (entity1 e1 RIGHT JOIN entity2 e2 ON e1.id = e2.id AND e1.tenant_id = 1) " +
"ON e.id = e2.id AND e2.tenant_id = 1 " +
"WHERE e.tenant_id = 1");
assertSql("select * FROM entity e " +
"LEFT JOIN (entity1 e1 left join entity2 e2 ON e1.id = e2.id) " +
"on e.id = e2.id",
"SELECT * FROM entity e " +
"LEFT JOIN (entity1 e1 LEFT JOIN entity2 e2 ON e1.id = e2.id AND e2.tenant_id = 1) " +
"ON e.id = e2.id AND e1.tenant_id = 1 " +
"WHERE e.tenant_id = 1");
assertSql("select * FROM entity e " +
"RIGHT JOIN (entity1 e1 left join entity2 e2 ON e1.id = e2.id) " +
"on e.id = e2.id",
"SELECT * FROM entity e " +
"RIGHT JOIN (entity1 e1 LEFT JOIN entity2 e2 ON e1.id = e2.id AND e2.tenant_id = 1) " +
"ON e.id = e2.id AND e.tenant_id = 1 " +
"WHERE e1.tenant_id = 1");
}
@Test @Test
void selectLeftJoinMultipleTrailingOn() { void selectLeftJoinMultipleTrailingOn() {
// 多个 on 尾缀的 // 多个 on 尾缀的
@ -256,51 +374,97 @@ public class DataPermissionDatabaseInterceptorTest2 extends BaseMockitoUnitTest
"inner join entity1 e1 on e1.id = e.id " + "inner join entity1 e1 on e1.id = e.id " +
"WHERE e.id = ? OR e.name = ?", "WHERE e.id = ? OR e.name = ?",
"SELECT * FROM entity e " + "SELECT * FROM entity e " +
"INNER JOIN entity1 e1 ON e1.id = e.id AND e1.tenant_id = 1 " + "INNER JOIN entity1 e1 ON e1.id = e.id AND e.tenant_id = 1 AND e1.tenant_id = 1 " +
"WHERE (e.id = ? OR e.name = ?) AND e.tenant_id = 1"); "WHERE e.id = ? OR e.name = ?");
assertSql("SELECT * FROM entity e " + assertSql("SELECT * FROM entity e " +
"inner join entity1 e1 on e1.id = e.id " + "inner join entity1 e1 on e1.id = e.id " +
"WHERE (e.id = ? OR e.name = ?)", "WHERE (e.id = ? OR e.name = ?)",
"SELECT * FROM entity e " + "SELECT * FROM entity e " +
"INNER JOIN entity1 e1 ON e1.id = e.id AND e1.tenant_id = 1 " + "INNER JOIN entity1 e1 ON e1.id = e.id AND e.tenant_id = 1 AND e1.tenant_id = 1 " +
"WHERE (e.id = ? OR e.name = ?) AND e.tenant_id = 1"); "WHERE (e.id = ? OR e.name = ?)");
// 隐式内连接
assertSql("SELECT * FROM entity,entity1 " +
"WHERE entity.id = entity1.id",
"SELECT * FROM entity, entity1 " +
"WHERE entity.id = entity1.id AND entity.tenant_id = 1 AND entity1.tenant_id = 1");
// 隐式内连接
assertSql("SELECT * FROM entity a, with_as_entity1 b " +
"WHERE a.id = b.id",
"SELECT * FROM entity a, with_as_entity1 b " +
"WHERE a.id = b.id AND a.tenant_id = 1");
assertSql("SELECT * FROM with_as_entity a, with_as_entity1 b " +
"WHERE a.id = b.id",
"SELECT * FROM with_as_entity a, with_as_entity1 b " +
"WHERE a.id = b.id");
// SubJoin with 隐式内连接
assertSql("SELECT * FROM (entity,entity1) " +
"WHERE entity.id = entity1.id",
"SELECT * FROM (entity, entity1) " +
"WHERE entity.id = entity1.id " +
"AND entity.tenant_id = 1 AND entity1.tenant_id = 1");
assertSql("SELECT * FROM ((entity,entity1),entity2) " +
"WHERE entity.id = entity1.id and entity.id = entity2.id",
"SELECT * FROM ((entity, entity1), entity2) " +
"WHERE entity.id = entity1.id AND entity.id = entity2.id " +
"AND entity.tenant_id = 1 AND entity1.tenant_id = 1 AND entity2.tenant_id = 1");
assertSql("SELECT * FROM (entity,(entity1,entity2)) " +
"WHERE entity.id = entity1.id and entity.id = entity2.id",
"SELECT * FROM (entity, (entity1, entity2)) " +
"WHERE entity.id = entity1.id AND entity.id = entity2.id " +
"AND entity.tenant_id = 1 AND entity1.tenant_id = 1 AND entity2.tenant_id = 1");
// 沙雕的括号写法
assertSql("SELECT * FROM (((entity,entity1))) " +
"WHERE entity.id = entity1.id",
"SELECT * FROM (((entity, entity1))) " +
"WHERE entity.id = entity1.id " +
"AND entity.tenant_id = 1 AND entity1.tenant_id = 1");
// 垃圾 inner join todo
// assertSql("SELECT * FROM entity,entity1 " +
// "WHERE entity.id = entity1.id",
// "SELECT * FROM entity e " +
// "INNER JOIN entity1 e1 ON e1.id = e.id AND e1.tenant_id = 1 " +
// "WHERE (e.id = ? OR e.name = ?) AND e.tenant_id = 1");
} }
@Test @Test
void selectWithAs() { void selectWithAs() {
assertSql("with with_as_A as (select * from entity) select * from with_as_A", assertSql("with with_as_A as (select * from entity) select * from with_as_A",
"WITH with_as_A AS (SELECT * FROM entity WHERE tenant_id = 1) SELECT * FROM with_as_A"); "WITH with_as_A AS (SELECT * FROM entity WHERE entity.tenant_id = 1) SELECT * FROM with_as_A");
}
@Test
void selectIgnoreTable() {
assertSql(" SELECT dict.dict_code, item.item_text AS \"text\", item.item_value AS \"value\" FROM sys_dict_item item INNER JOIN sys_dict dict ON dict.id = item.dict_id WHERE dict.dict_code IN (1, 2, 3) AND item.item_value IN (1, 2, 3)",
"SELECT dict.dict_code, item.item_text AS \"text\", item.item_value AS \"value\" FROM sys_dict_item item INNER JOIN sys_dict dict ON dict.id = item.dict_id AND item.tenant_id = 1 WHERE dict.dict_code IN (1, 2, 3) AND item.item_value IN (1, 2, 3)");
} }
private void assertSql(String sql, String targetSql) { private void assertSql(String sql, String targetSql) {
assertEquals(targetSql, interceptor.parserSingle(sql, null)); assertEquals(targetSql, interceptor.parserSingle(sql, null));
} }
// ========== 额外的测试 ========== // ========== 额外的测试 ==========
@Test @Test
public void testSelectSingle() { public void testSelectSingle() {
// 单表 // 单表
assertSql("select * from t_user where id = ?", assertSql("select * from t_user where id = ?",
"SELECT * FROM t_user WHERE id = ? AND tenant_id = 1 AND dept_id IN (10, 20)"); "SELECT * FROM t_user WHERE id = ? AND t_user.tenant_id = 1 AND t_user.dept_id IN (10, 20)");
assertSql("select * from t_user where id = ? or name = ?", assertSql("select * from t_user where id = ? or name = ?",
"SELECT * FROM t_user WHERE (id = ? OR name = ?) AND tenant_id = 1 AND dept_id IN (10, 20)"); "SELECT * FROM t_user WHERE (id = ? OR name = ?) AND t_user.tenant_id = 1 AND t_user.dept_id IN (10, 20)");
assertSql("SELECT * FROM t_user WHERE (id = ? OR name = ?)", assertSql("SELECT * FROM t_user WHERE (id = ? OR name = ?)",
"SELECT * FROM t_user WHERE (id = ? OR name = ?) AND tenant_id = 1 AND dept_id IN (10, 20)"); "SELECT * FROM t_user WHERE (id = ? OR name = ?) AND t_user.tenant_id = 1 AND t_user.dept_id IN (10, 20)");
/* not */ /* not */
assertSql("SELECT * FROM t_user WHERE not (id = ? OR name = ?)", assertSql("SELECT * FROM t_user WHERE not (id = ? OR name = ?)",
"SELECT * FROM t_user WHERE NOT (id = ? OR name = ?) AND tenant_id = 1 AND dept_id IN (10, 20)"); "SELECT * FROM t_user WHERE NOT (id = ? OR name = ?) AND t_user.tenant_id = 1 AND t_user.dept_id IN (10, 20)");
} }
@Test @Test
@ -329,16 +493,16 @@ public class DataPermissionDatabaseInterceptorTest2 extends BaseMockitoUnitTest
"right join t_role e1 on e1.id = e.id " + "right join t_role e1 on e1.id = e.id " +
"WHERE e.id = ? OR e.name = ?", "WHERE e.id = ? OR e.name = ?",
"SELECT * FROM t_user e " + "SELECT * FROM t_user e " +
"RIGHT JOIN t_role e1 ON e1.id = e.id AND e1.tenant_id = 1 " + "RIGHT JOIN t_role e1 ON e1.id = e.id AND e.tenant_id = 1 AND e.dept_id IN (10, 20) " +
"WHERE (e.id = ? OR e.name = ?) AND e.tenant_id = 1 AND e.dept_id IN (10, 20)"); "WHERE (e.id = ? OR e.name = ?) AND e1.tenant_id = 1");
// 条件 e.id = ? OR e.name = ? 带括号 // 条件 e.id = ? OR e.name = ? 带括号
assertSql("SELECT * FROM t_user e " + assertSql("SELECT * FROM t_user e " +
"right join t_role e1 on e1.id = e.id " + "right join t_role e1 on e1.id = e.id " +
"WHERE (e.id = ? OR e.name = ?)", "WHERE (e.id = ? OR e.name = ?)",
"SELECT * FROM t_user e " + "SELECT * FROM t_user e " +
"RIGHT JOIN t_role e1 ON e1.id = e.id AND e1.tenant_id = 1 " + "RIGHT JOIN t_role e1 ON e1.id = e.id AND e.tenant_id = 1 AND e.dept_id IN (10, 20) " +
"WHERE (e.id = ? OR e.name = ?) AND e.tenant_id = 1 AND e.dept_id IN (10, 20)"); "WHERE (e.id = ? OR e.name = ?) AND e1.tenant_id = 1");
} }
@Test @Test
@ -348,23 +512,22 @@ public class DataPermissionDatabaseInterceptorTest2 extends BaseMockitoUnitTest
"inner join entity1 e1 on e1.id = e.id " + "inner join entity1 e1 on e1.id = e.id " +
"WHERE e.id = ? OR e.name = ?", "WHERE e.id = ? OR e.name = ?",
"SELECT * FROM t_user e " + "SELECT * FROM t_user e " +
"INNER JOIN entity1 e1 ON e1.id = e.id AND e1.tenant_id = 1 " + "INNER JOIN entity1 e1 ON e1.id = e.id AND e.tenant_id = 1 AND e.dept_id IN (10, 20) AND e1.tenant_id = 1 " +
"WHERE (e.id = ? OR e.name = ?) AND e.tenant_id = 1 AND e.dept_id IN (10, 20)"); "WHERE e.id = ? OR e.name = ?");
// 条件 e.id = ? OR e.name = ? 带括号 // 条件 e.id = ? OR e.name = ? 带括号
assertSql("SELECT * FROM t_user e " + assertSql("SELECT * FROM t_user e " +
"inner join t_role e1 on e1.id = e.id " + "inner join entity1 e1 on e1.id = e.id " +
"WHERE (e.id = ? OR e.name = ?)", "WHERE (e.id = ? OR e.name = ?)",
"SELECT * FROM t_user e " + "SELECT * FROM t_user e " +
"INNER JOIN t_role e1 ON e1.id = e.id AND e1.tenant_id = 1 " + "INNER JOIN entity1 e1 ON e1.id = e.id AND e.tenant_id = 1 AND e.dept_id IN (10, 20) AND e1.tenant_id = 1 " +
"WHERE (e.id = ? OR e.name = ?) AND e.tenant_id = 1 AND e.dept_id IN (10, 20)"); "WHERE (e.id = ? OR e.name = ?)");
// 垃圾 inner join todo // 没有 On 的 inner join
// assertSql("SELECT * FROM entity,entity1 " + assertSql("SELECT * FROM entity,entity1 " +
// "WHERE entity.id = entity1.id", "WHERE entity.id = entity1.id",
// "SELECT * FROM entity e " + "SELECT * FROM entity, entity1 " +
// "INNER JOIN entity1 e1 ON e1.id = e.id AND e1.tenant_id = 1 " + "WHERE entity.id = entity1.id AND entity.tenant_id = 1 AND entity1.tenant_id = 1");
// "WHERE (e.id = ? OR e.name = ?) AND e.tenant_id = 1");
} }
} }

@ -227,7 +227,7 @@ class DeptDataPermissionRuleTest extends BaseMockitoUnitTest {
// 调用 // 调用
Expression expression = rule.getExpression(tableName, tableAlias); Expression expression = rule.getExpression(tableName, tableAlias);
// 断言 // 断言
assertEquals("u.dept_id IN (10, 20) OR u.id = 1", expression.toString()); assertEquals("(u.dept_id IN (10, 20) OR u.id = 1)", expression.toString());
assertSame(deptDataPermission, loginUser.getContext(DeptDataPermissionRule.CONTEXT_KEY, DeptDataPermissionRespDTO.class)); assertSame(deptDataPermission, loginUser.getContext(DeptDataPermissionRule.CONTEXT_KEY, DeptDataPermissionRespDTO.class));
} }
} }

@ -2,10 +2,10 @@ package cn.iocoder.yudao.framework.dict.config;
import cn.iocoder.yudao.framework.dict.core.util.DictFrameworkUtils; import cn.iocoder.yudao.framework.dict.core.util.DictFrameworkUtils;
import cn.iocoder.yudao.module.system.api.dict.DictDataApi; import cn.iocoder.yudao.module.system.api.dict.DictDataApi;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration @AutoConfiguration
public class YudaoDictAutoConfiguration { public class YudaoDictAutoConfiguration {
@Bean @Bean

@ -27,7 +27,7 @@ public class DictFrameworkUtils {
/** /**
* {@link #getDictDataLabel(String, String)} * {@link #getDictDataLabel(String, String)}
*/ */
private static final LoadingCache<KeyValue<String, String>, DictDataRespDTO> getDictDataCache = CacheUtils.buildAsyncReloadingCache( private static final LoadingCache<KeyValue<String, String>, DictDataRespDTO> GET_DICT_DATA_CACHE = CacheUtils.buildAsyncReloadingCache(
Duration.ofMinutes(1L), // 过期时间 1 分钟 Duration.ofMinutes(1L), // 过期时间 1 分钟
new CacheLoader<KeyValue<String, String>, DictDataRespDTO>() { new CacheLoader<KeyValue<String, String>, DictDataRespDTO>() {
@ -41,7 +41,7 @@ public class DictFrameworkUtils {
/** /**
* {@link #parseDictDataValue(String, String)} * {@link #parseDictDataValue(String, String)}
*/ */
private static final LoadingCache<KeyValue<String, String>, DictDataRespDTO> parseDictDataCache = CacheUtils.buildAsyncReloadingCache( private static final LoadingCache<KeyValue<String, String>, DictDataRespDTO> PARSE_DICT_DATA_CACHE = CacheUtils.buildAsyncReloadingCache(
Duration.ofMinutes(1L), // 过期时间 1 分钟 Duration.ofMinutes(1L), // 过期时间 1 分钟
new CacheLoader<KeyValue<String, String>, DictDataRespDTO>() { new CacheLoader<KeyValue<String, String>, DictDataRespDTO>() {
@ -59,12 +59,12 @@ public class DictFrameworkUtils {
@SneakyThrows @SneakyThrows
public static String getDictDataLabel(String dictType, String value) { public static String getDictDataLabel(String dictType, String value) {
return getDictDataCache.get(new KeyValue<>(dictType, value)).getLabel(); return GET_DICT_DATA_CACHE.get(new KeyValue<>(dictType, value)).getLabel();
} }
@SneakyThrows @SneakyThrows
public static String parseDictDataValue(String dictType, String label) { public static String parseDictDataValue(String dictType, String label) {
return parseDictDataCache.get(new KeyValue<>(dictType, label)).getValue(); return PARSE_DICT_DATA_CACHE.get(new KeyValue<>(dictType, label)).getValue();
} }
} }

@ -1,2 +0,0 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
cn.iocoder.yudao.framework.dict.config.YudaoDictAutoConfiguration

@ -6,10 +6,10 @@ import cn.iocoder.yudao.framework.errorcode.core.loader.ErrorCodeLoader;
import cn.iocoder.yudao.framework.errorcode.core.loader.ErrorCodeLoaderImpl; import cn.iocoder.yudao.framework.errorcode.core.loader.ErrorCodeLoaderImpl;
import cn.iocoder.yudao.module.system.api.errorcode.ErrorCodeApi; import cn.iocoder.yudao.module.system.api.errorcode.ErrorCodeApi;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.EnableScheduling;
/** /**
@ -17,7 +17,7 @@ import org.springframework.scheduling.annotation.EnableScheduling;
* *
* @author * @author
*/ */
@Configuration @AutoConfiguration
@ConditionalOnProperty(prefix = "yudao.error-code", value = "enable", matchIfMissing = true) // 允许使用 yudao.error-code.enable=false 禁用访问日志 @ConditionalOnProperty(prefix = "yudao.error-code", value = "enable", matchIfMissing = true) // 允许使用 yudao.error-code.enable=false 禁用访问日志
@EnableConfigurationProperties(ErrorCodeProperties.class) @EnableConfigurationProperties(ErrorCodeProperties.class)
@EnableScheduling // 开启调度任务的功能,因为 ErrorCodeRemoteLoader 通过定时刷新错误码 @EnableScheduling // 开启调度任务的功能,因为 ErrorCodeRemoteLoader 通过定时刷新错误码

@ -10,7 +10,7 @@ import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.event.EventListener; import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Scheduled; import org.springframework.scheduling.annotation.Scheduled;
import java.util.Date; import java.time.LocalDateTime;
import java.util.List; import java.util.List;
/** /**
@ -41,7 +41,7 @@ public class ErrorCodeLoaderImpl implements ErrorCodeLoader {
/** /**
* *
*/ */
private Date maxUpdateTime; private LocalDateTime maxUpdateTime;
@EventListener(ApplicationReadyEvent.class) @EventListener(ApplicationReadyEvent.class)
public void loadErrorCodes() { public void loadErrorCodes() {

@ -1,2 +0,0 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
cn.iocoder.yudao.framework.errorcode.config.YudaoErrorCodeConfiguration

@ -0,0 +1,58 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>yudao-framework</artifactId>
<groupId>cn.iocoder.boot</groupId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>yudao-spring-boot-starter-biz-ip</artifactId>
<packaging>jar</packaging>
<name>${project.artifactId}</name>
<description>IP 拓展,支持如下功能:
1. IP 功能:查询 IP 对应的城市信息
基于 https://gitee.com/lionsoul/ip2region 实现
2. 城市功能:查询城市编码对应的城市信息
基于 https://github.com/modood/Administrative-divisions-of-China 实现
</description>
<url>https://github.com/YunaiV/ruoyi-vue-pro</url>
<properties>
<ip2region.version>2.6.6</ip2region.version>
</properties>
<dependencies>
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-common</artifactId>
</dependency>
<!-- IP地址检索 -->
<dependency>
<groupId>org.lionsoul</groupId>
<artifactId>ip2region</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<scope>provided</scope> <!-- 设置为 provided只有工具类需要使用到 -->
</dependency>
<!-- Test 测试相关 -->
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

@ -0,0 +1,55 @@
package cn.iocoder.yudao.framework.ip.core;
import cn.iocoder.yudao.framework.ip.core.enums.AreaTypeEnum;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
/**
*
*
* resources/area.csv
*
* @author
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Area {
/**
* -
*/
public static final Integer ID_GLOBAL = 0;
/**
* -
*/
public static final Integer ID_CHINA = 1;
/**
*
*/
private Integer id;
/**
*
*/
private String name;
/**
*
*
* {@link AreaTypeEnum}
*/
private Integer type;
/**
*
*/
private Area parent;
/**
*
*/
private List<Area> children;
}

@ -0,0 +1,39 @@
package cn.iocoder.yudao.framework.ip.core.enums;
import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
/**
*
*
* @author
*/
@AllArgsConstructor
@Getter
public enum AreaTypeEnum implements IntArrayValuable {
COUNTRY(1, "国家"),
PROVINCE(2, "省份"),
CITY(3, "城市"),
DISTRICT(4, "地区"), // 县、镇、区等
;
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(AreaTypeEnum::getType).toArray();
/**
*
*/
private final Integer type;
/**
*
*/
private final String name;
@Override
public int[] array() {
return ARRAYS;
}
}

@ -0,0 +1,119 @@
package cn.iocoder.yudao.framework.ip.core.utils;
import cn.hutool.core.io.resource.ResourceUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.text.csv.CsvRow;
import cn.hutool.core.text.csv.CsvUtil;
import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
import cn.iocoder.yudao.framework.ip.core.Area;
import cn.iocoder.yudao.framework.ip.core.enums.AreaTypeEnum;
import lombok.extern.slf4j.Slf4j;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
*
*
* @author
*/
@Slf4j
public class AreaUtils {
/**
* SEARCHER
*/
@SuppressWarnings("InstantiationOfUtilityClass")
private final static AreaUtils INSTANCE = new AreaUtils();
/**
* Area 访
*/
private static Map<Integer, Area> areas;
private AreaUtils() {
long now = System.currentTimeMillis();
areas = new HashMap<>();
areas.put(Area.ID_GLOBAL, new Area(Area.ID_GLOBAL, "全球", 0,
null, new ArrayList<>()));
// 从 csv 中加载数据
List<CsvRow> rows = CsvUtil.getReader().read(ResourceUtil.getUtf8Reader("area.csv")).getRows();
rows.remove(0); // 删除 header
for (CsvRow row : rows) {
// 创建 Area 对象
Area area = new Area(Integer.valueOf(row.get(0)), row.get(1), Integer.valueOf(row.get(2)),
null, new ArrayList<>());
// 添加到 areas 中
areas.put(area.getId(), area);
}
// 构建父子关系:因为 Area 中没有 parentId 字段,所以需要重复读取
for (CsvRow row : rows) {
Area area = areas.get(Integer.valueOf(row.get(0))); // 自己
Area parent = areas.get(Integer.valueOf(row.get(3))); // 父
Assert.isTrue(area != parent, "{}:父子节点相同", area.getName());
area.setParent(parent);
parent.getChildren().add(area);
}
log.info("启动加载 AreaUtils 成功,耗时 ({}) 毫秒", System.currentTimeMillis() - now);
}
/**
*
*
* @param id
* @return
*/
public static Area getArea(Integer id) {
return areas.get(id);
}
/**
*
*
* @param id
* @return
*/
public static String format(Integer id) {
return format(id, " ");
}
/**
*
*
*
* 1. id =
* 2. id =
* 3. id =
* 4. id =
*
*
* @param id
* @param separator
* @return
*/
public static String format(Integer id, String separator) {
// 获得区域
Area area = areas.get(id);
if (area == null) {
return null;
}
// 格式化
StringBuilder sb = new StringBuilder();
for (int i = 0; i < AreaTypeEnum.values().length; i++) { // 避免死循环
sb.insert(0, area.getName());
// “递归”父节点
area = area.getParent();
if (area == null
|| ObjectUtils.equalsAny(area.getId(), Area.ID_GLOBAL, Area.ID_CHINA)) { // 跳过父节点为中国的情况
break;
}
sb.insert(0, separator);
}
return sb.toString();
}
}

@ -0,0 +1,87 @@
package cn.iocoder.yudao.framework.ip.core.utils;
import cn.hutool.core.io.resource.ResourceUtil;
import cn.iocoder.yudao.framework.ip.core.Area;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.lionsoul.ip2region.xdb.Searcher;
import java.io.IOException;
/**
* IP
*
* IP ip2region.xdb <a href="https://gitee.com/zhijiantianya/ip2region"/>
*
* @author wanglhup
*/
@Slf4j
public class IPUtils {
/**
* SEARCHER
*/
@SuppressWarnings("InstantiationOfUtilityClass")
private final static IPUtils INSTANCE = new IPUtils();
/**
* IP
*/
private static Searcher SEARCHER;
/**
*
*/
private IPUtils() {
try {
long now = System.currentTimeMillis();
byte[] bytes = ResourceUtil.readBytes("ip2region.xdb");
SEARCHER = Searcher.newWithBuffer(bytes);
log.info("启动加载 IPUtils 成功,耗时 ({}) 毫秒", System.currentTimeMillis() - now);
} catch (IOException e) {
log.error("启动加载 IPUtils 失败", e);
}
}
/**
* IP
*
* @param ip IP 127.0.0.1
* @return id
*/
@SneakyThrows
public static Integer getAreaId(String ip) {
return Integer.parseInt(SEARCHER.search(ip));
}
/**
* IP
*
* @param ip IP {@link Searcher#checkIP(String)}
* @return
*/
@SneakyThrows
public static Integer getAreaId(long ip) {
return Integer.parseInt(SEARCHER.search(ip));
}
/**
* IP
*
* @param ip IP 127.0.0.1
* @return
*/
public static Area getArea(String ip) {
return AreaUtils.getArea(getAreaId(ip));
}
/**
* IP
*
* @param ip IP {@link Searcher#checkIP(String)}
* @return
*/
public static Area getArea(long ip) {
return AreaUtils.getArea(getAreaId(ip));
}
}

@ -0,0 +1,11 @@
/**
* IP
*
* 1. IP IP
* https://gitee.com/lionsoul/ip2region 实现
* 2.
* https://github.com/modood/Administrative-divisions-of-China 实现
*
* @author
*/
package cn.iocoder.yudao.framework.ip;

@ -0,0 +1,36 @@
package cn.iocoder.yudao.framework.ip.core.utils;
import cn.iocoder.yudao.framework.ip.core.Area;
import cn.iocoder.yudao.framework.ip.core.enums.AreaTypeEnum;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
/**
* {@link AreaUtils}
*
* @author
*/
public class AreaUtilsTest {
@Test
public void testGetArea() {
// 调用:北京
Area area = AreaUtils.getArea(110100);
// 断言
assertEquals(area.getId(), 110100);
assertEquals(area.getName(), "北京市");
assertEquals(area.getType(), AreaTypeEnum.CITY.getType());
assertEquals(area.getParent().getId(), 110000);
assertEquals(area.getChildren().size(), 16);
}
@Test
public void testFormat() {
assertEquals(AreaUtils.format(110105), "北京 北京市 朝阳区");
assertEquals(AreaUtils.format(1), "中国");
assertEquals(AreaUtils.format(2), "蒙古");
}
}

@ -0,0 +1,47 @@
package cn.iocoder.yudao.framework.ip.core.utils;
import cn.iocoder.yudao.framework.ip.core.Area;
import org.junit.jupiter.api.Test;
import org.lionsoul.ip2region.xdb.Searcher;
import static org.junit.jupiter.api.Assertions.assertEquals;
/**
* {@link IPUtils}
*
* @author wanglhup
*/
public class IPUtilsTest {
@Test
public void testGetAreaId_string() {
// 120.202.4.0|120.202.4.255|420600
Integer areaId = IPUtils.getAreaId("120.202.4.50");
assertEquals(420600, areaId);
}
@Test
public void testGetAreaId_long() throws Exception {
// 120.203.123.0|120.203.133.255|360900
long ip = Searcher.checkIP("120.203.123.250");
Integer areaId = IPUtils.getAreaId(ip);
assertEquals(360900, areaId);
}
@Test
public void testGetArea_string() {
// 120.202.4.0|120.202.4.255|420600
Area area = IPUtils.getArea("120.202.4.50");
assertEquals("襄阳市", area.getName());
}
@Test
public void testGetArea_long() throws Exception {
// 120.203.123.0|120.203.133.255|360900
long ip = Searcher.checkIP("120.203.123.252");
Area area = IPUtils.getArea(ip);
assertEquals("宜春市", area.getName());
}
}

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

Loading…
Cancel
Save