Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1736b5d991 | ||
|
|
fad3b80fae | ||
|
|
c5555cff1f | ||
|
|
ebc0964988 | ||
|
|
069b9892c6 |
5
.vscode/settings.json
vendored
5
.vscode/settings.json
vendored
@ -1,5 +0,0 @@
|
|||||||
{
|
|
||||||
"editor.codeLens": true,
|
|
||||||
"java.test.editor.enableShortcuts": true,
|
|
||||||
"testing.gutterEnabled": true
|
|
||||||
}
|
|
||||||
@ -1,579 +0,0 @@
|
|||||||
# WholeProcessPlatform Backend 业务模块开发技术规范
|
|
||||||
|
|
||||||
## 1. 文档目的
|
|
||||||
|
|
||||||
本文档用于统一 `d:\shuili\WholeProcessPlatform\backend` 项目中业务模块的开发方式,重点覆盖:
|
|
||||||
|
|
||||||
- 模块目录与分层设计规范
|
|
||||||
- Controller、Service、Mapper、VO、Domain 的职责边界
|
|
||||||
- 基于 `Spring Boot 4.0.3 + Java 21 + MyBatis/MyBatis-Plus` 的编码约束
|
|
||||||
- 当前项目已形成的事实标准
|
|
||||||
- 新增业务模块、旧系统迁移模块、字典/基础数据模块的推荐实现方式
|
|
||||||
- SQL、异常、接口返回、分页、文档、测试、性能与安全要求
|
|
||||||
|
|
||||||
本文档适用于本项目所有新增或改造的业务模块,尤其适用于 `env` 目录下的生态环境类业务。
|
|
||||||
|
|
||||||
## 2. 技术基线
|
|
||||||
|
|
||||||
根据项目当前 `pom.xml`,本项目业务开发技术基线如下:
|
|
||||||
|
|
||||||
- JDK:21
|
|
||||||
- Spring Boot:4.0.3
|
|
||||||
- Spring Web:MVC
|
|
||||||
- Spring Security:已引入
|
|
||||||
- Springdoc OpenAPI:3.0.2
|
|
||||||
- MyBatis:3.5.16
|
|
||||||
- MyBatis Spring Boot Starter:4.0.1
|
|
||||||
- MyBatis-Plus:3.5.16,使用 `mybatis-plus-spring-boot4-starter`
|
|
||||||
- 数据库驱动:MySQL、Oracle、达梦
|
|
||||||
- 工具库:Hutool、Lombok、Guava、POI
|
|
||||||
|
|
||||||
## 3. 外部参考原则
|
|
||||||
|
|
||||||
本文档参考了当前主流的 Spring Boot 4 / 现代 Spring 开发建议,并结合项目现状做了落地约束,核心依据如下:
|
|
||||||
|
|
||||||
- Spring Boot 官方文档强调代码结构、配置类组织、依赖注入、外部化配置、日志、Web、Data、Validation、Actuator 等能力应作为应用开发基础。
|
|
||||||
- Springdoc 官方文档建议使用 `springdoc-openapi-starter-webmvc-ui` 作为 OpenAPI/Swagger UI 集成方式,并通过注解与配置文件维持接口文档。
|
|
||||||
- MyBatis Spring Boot Starter 官方文档强调在 Boot 4 体系中使用官方 starter、自动扫描 Mapper、使用配置项统一管理 MyBatis 行为。
|
|
||||||
- MyBatis-Plus 官方文档明确支持 Spring Boot 4,推荐使用 Boot 4 对应 starter,并采用 `BaseMapper`、`ServiceImpl`、分页对象等标准方式实现常规 CRUD。
|
|
||||||
|
|
||||||
说明:
|
|
||||||
|
|
||||||
- 本规范不是照搬互联网通用模板,而是“以本项目实际代码为准,吸收外部最佳实践后形成的可执行规范”。
|
|
||||||
- 若通用建议与现有项目框架存在冲突,优先保证现有项目兼容性,再逐步演进。
|
|
||||||
|
|
||||||
## 4. 当前项目模块结构总结
|
|
||||||
|
|
||||||
`env` 模块已经形成两类主流实现风格。
|
|
||||||
|
|
||||||
### 4.1 基础资料型模块
|
|
||||||
|
|
||||||
典型文件:
|
|
||||||
|
|
||||||
- `controller/SdCountryBController.java`
|
|
||||||
- `service/ISdCountryBService.java`
|
|
||||||
- `service/impl/SdCountryBServiceImpl.java`
|
|
||||||
- `mapper/SdCountryBMapper.java`
|
|
||||||
- `domain/SdCountryB.java`
|
|
||||||
|
|
||||||
特征:
|
|
||||||
|
|
||||||
- 面向单表或轻量多表的增删改查
|
|
||||||
- Service 通常继承 `ServiceImpl<Mapper, Domain>`
|
|
||||||
- 使用 `BaseMapper` 和 MyBatis-Plus `lambdaQuery()`
|
|
||||||
- Controller 以分页查询、列表查询、详情查询为主
|
|
||||||
|
|
||||||
适用场景:
|
|
||||||
|
|
||||||
- 字典表
|
|
||||||
- 基础资料表
|
|
||||||
- 标准后台管理页面
|
|
||||||
|
|
||||||
### 4.2 业务查询/迁移型模块
|
|
||||||
|
|
||||||
典型文件:
|
|
||||||
|
|
||||||
- `controller/SdWTMonitorController.java`
|
|
||||||
- `service/SdWtMonitorService.java`
|
|
||||||
- `service/impl/SdWtMonitorServiceImpl.java`
|
|
||||||
- `service/AlongListService.java`
|
|
||||||
- `service/impl/AlongListServiceImpl.java`
|
|
||||||
- `mapper/AlongDetailMapper.java`
|
|
||||||
- `mapper/SdWtMonitorMapper.java`
|
|
||||||
- `entity/vo/*`
|
|
||||||
|
|
||||||
特征:
|
|
||||||
|
|
||||||
- 来自旧系统迁移的复杂业务查询较多
|
|
||||||
- Controller 聚合多个业务接口
|
|
||||||
- Service 接口与实现手写,通常不继承 `ServiceImpl`
|
|
||||||
- 同时存在注解 SQL、动态 SQL、MyBatis-Plus 分页
|
|
||||||
- 使用 `DataSourceRequest`、`DataSourceResult` 适配旧平台 Kendo/DevExtreme 风格
|
|
||||||
|
|
||||||
适用场景:
|
|
||||||
|
|
||||||
- 旧系统模块迁移
|
|
||||||
- 复杂统计、图表、对比分析、联表明细
|
|
||||||
- 需要兼容旧平台入参与返回结构的接口
|
|
||||||
|
|
||||||
## 5. 模块分层规范
|
|
||||||
|
|
||||||
### 5.1 Controller 层职责
|
|
||||||
|
|
||||||
Controller 仅负责:
|
|
||||||
|
|
||||||
- 暴露路由
|
|
||||||
- 参数接收
|
|
||||||
- 基础空值校验
|
|
||||||
- 调用 Service
|
|
||||||
- 统一包装 `ResponseResult`
|
|
||||||
|
|
||||||
Controller 禁止:
|
|
||||||
|
|
||||||
- 拼接 SQL
|
|
||||||
- 大段业务判断
|
|
||||||
- 循环组装复杂结果
|
|
||||||
- 直接操作 Mapper
|
|
||||||
|
|
||||||
当前项目推荐写法:
|
|
||||||
|
|
||||||
- 类上使用 `@RestController`
|
|
||||||
- 类上使用 `@RequestMapping`
|
|
||||||
- 类上使用 `@Tag`
|
|
||||||
- 方法上使用 `@Operation`
|
|
||||||
- 返回值统一为 `ResponseResult`
|
|
||||||
|
|
||||||
示例风格:
|
|
||||||
|
|
||||||
- 业务聚合 Controller:`SdWTMonitorController`
|
|
||||||
- 管理型 Controller:`SdCountryBController`
|
|
||||||
|
|
||||||
### 5.2 Service 层职责
|
|
||||||
|
|
||||||
Service 层负责:
|
|
||||||
|
|
||||||
- 业务编排
|
|
||||||
- 参数解析
|
|
||||||
- 分页对象生成
|
|
||||||
- 调用 Mapper
|
|
||||||
- Java 层补充计算
|
|
||||||
- 返回对象组装
|
|
||||||
|
|
||||||
Service 层应根据模块类型选择实现方式:
|
|
||||||
|
|
||||||
- 基础 CRUD:优先 `IxxxService + ServiceImpl`
|
|
||||||
- 复杂业务查询:优先 `XxxService + XxxServiceImpl`
|
|
||||||
- 旧系统迁移模块:优先显式定义业务接口,避免泛化成通用 CRUD Service
|
|
||||||
|
|
||||||
### 5.3 Mapper 层职责
|
|
||||||
|
|
||||||
Mapper 层负责:
|
|
||||||
|
|
||||||
- 数据查询与数据写入
|
|
||||||
- 注解 SQL 或 XML SQL
|
|
||||||
- 复杂 join、exists、聚合、分页 SQL
|
|
||||||
|
|
||||||
Mapper 层禁止:
|
|
||||||
|
|
||||||
- 放业务语义不清的万能 SQL
|
|
||||||
- 将参数语义不明确地混在同一个方法中
|
|
||||||
- 为了省事直接将前端字段名等同于数据库字段名而不做映射说明
|
|
||||||
|
|
||||||
### 5.4 VO / DTO / Domain 职责
|
|
||||||
|
|
||||||
当前项目已存在三类对象:
|
|
||||||
|
|
||||||
- `domain`:数据库实体,主要服务于 MyBatis-Plus CRUD
|
|
||||||
- `entity/vo`:前端返回对象、业务查询对象
|
|
||||||
- `common`:分页、过滤、排序、结果包装对象
|
|
||||||
|
|
||||||
规范要求:
|
|
||||||
|
|
||||||
- 单表管理页优先使用 `domain`
|
|
||||||
- 复杂查询、聚合结果、旧接口兼容结构必须使用独立 VO
|
|
||||||
- 不允许复用 `domain` 直接承接复杂联表查询结果
|
|
||||||
- 前端字段名与数据库字段名不一致时,SQL 必须用旧字段名作为别名返回
|
|
||||||
|
|
||||||
## 6. 推荐目录规范
|
|
||||||
|
|
||||||
新增业务模块建议按如下目录落位:
|
|
||||||
|
|
||||||
```text
|
|
||||||
src/main/java/com/yfd/platform/<module>/
|
|
||||||
controller/
|
|
||||||
service/
|
|
||||||
service/impl/
|
|
||||||
mapper/
|
|
||||||
domain/
|
|
||||||
entity/vo/
|
|
||||||
```
|
|
||||||
|
|
||||||
命名建议:
|
|
||||||
|
|
||||||
- Controller:`XxxController`
|
|
||||||
- Service:`XxxService`
|
|
||||||
- ServiceImpl:`XxxServiceImpl`
|
|
||||||
- Mapper:`XxxMapper`
|
|
||||||
- 管理类 Service:`IXxxService`
|
|
||||||
- 管理类 ServiceImpl:`XxxServiceImpl extends ServiceImpl`
|
|
||||||
- Domain:与表/业务实体对应
|
|
||||||
- VO:以业务含义命名,如 `SdYearListVO`、`WtFishVo`
|
|
||||||
|
|
||||||
## 7. 接口设计规范
|
|
||||||
|
|
||||||
### 7.1 返回结构规范
|
|
||||||
|
|
||||||
本项目统一返回对象为 `ResponseResult`,必须使用:
|
|
||||||
|
|
||||||
- `ResponseResult.success()`
|
|
||||||
- `ResponseResult.successData(data)`
|
|
||||||
- `ResponseResult.error(msg)`
|
|
||||||
|
|
||||||
禁止:
|
|
||||||
|
|
||||||
- Controller 直接返回裸对象
|
|
||||||
- 不同模块返回结构不一致
|
|
||||||
- 同类接口同时混用 `Map`、实体、裸数组作为顶层响应
|
|
||||||
|
|
||||||
### 7.2 异常规范
|
|
||||||
|
|
||||||
业务异常统一使用 `BizException`。
|
|
||||||
|
|
||||||
适用场景:
|
|
||||||
|
|
||||||
- 必填参数缺失
|
|
||||||
- 业务前置条件不满足
|
|
||||||
- 站点、工程、字典等基础数据不存在
|
|
||||||
- 旧接口兼容校验失败
|
|
||||||
|
|
||||||
推荐写法:
|
|
||||||
|
|
||||||
```java
|
|
||||||
if (StrUtil.isBlank(stcd)) {
|
|
||||||
throw new BizException("站点编码不能为空.");
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
禁止:
|
|
||||||
|
|
||||||
- `throw new RuntimeException(...)`
|
|
||||||
- Controller 静默吞异常
|
|
||||||
- Service 返回 `null` 表示明确错误
|
|
||||||
|
|
||||||
### 7.3 参数接收规范
|
|
||||||
|
|
||||||
当前项目主要有两类接口:
|
|
||||||
|
|
||||||
- Kendo/DevExtreme 风格:`@RequestBody DataSourceRequest`
|
|
||||||
- 标准后台管理风格:`@RequestParam` + 分页参数
|
|
||||||
|
|
||||||
规范要求:
|
|
||||||
|
|
||||||
- 旧平台迁移接口优先保留 `DataSourceRequest`
|
|
||||||
- 后台管理接口优先使用显式参数
|
|
||||||
- 不允许将大量业务字段塞入 `Map<String, Object>` 作为常规入参
|
|
||||||
- `Map<String, Object>` 仅用于动态字段更新、非结构化补丁写入等少数场景
|
|
||||||
|
|
||||||
## 8. 分页与筛选规范
|
|
||||||
|
|
||||||
### 8.1 `DataSourceRequest` 适用范围
|
|
||||||
|
|
||||||
`DataSourceRequest` 是本项目重要的兼容层对象,适用于:
|
|
||||||
|
|
||||||
- 迁移旧平台 Kendo Grid 接口
|
|
||||||
- 需要复杂 filter/group/sort/select 的业务页面
|
|
||||||
- 旧接口需要兼容前端请求结构时
|
|
||||||
|
|
||||||
规范要求:
|
|
||||||
|
|
||||||
- 迁移旧接口时优先从 `DataSourceRequest` 中提取明确字段
|
|
||||||
- 尽量封装公共提取逻辑,如使用 `QgcQueryWrapperUtil.getFilterFieldValue(...)`
|
|
||||||
- 对必要参数要先做空值校验
|
|
||||||
|
|
||||||
### 8.2 `DataSourceResult` 规范
|
|
||||||
|
|
||||||
使用 `DataSourceResult` 时应设置:
|
|
||||||
|
|
||||||
- `data`
|
|
||||||
- `total`
|
|
||||||
- `aggregates`
|
|
||||||
|
|
||||||
推荐:
|
|
||||||
|
|
||||||
- 无聚合时设置空 `HashMap<>`
|
|
||||||
- 无数据时返回空列表而不是 `null`
|
|
||||||
|
|
||||||
## 9. 依赖注入规范
|
|
||||||
|
|
||||||
现状:
|
|
||||||
|
|
||||||
- 项目中大量使用 `@Resource` 字段注入
|
|
||||||
|
|
||||||
建议:
|
|
||||||
|
|
||||||
- 存量代码允许继续使用 `@Resource`
|
|
||||||
- 新增业务模块优先使用构造器注入
|
|
||||||
- 若为了保持模块风格一致,可在同一文件中延续现有注入方式
|
|
||||||
|
|
||||||
统一要求:
|
|
||||||
|
|
||||||
- 不允许通过 `SpringContextHolder` 主动取 Bean 代替正常依赖注入,除非是历史兼容场景且无法重构
|
|
||||||
|
|
||||||
## 10. SQL 与数据访问规范
|
|
||||||
|
|
||||||
### 10.1 选型原则
|
|
||||||
|
|
||||||
优先级如下:
|
|
||||||
|
|
||||||
1. 单表 CRUD、简单条件分页:MyBatis-Plus
|
|
||||||
2. 明确的小型查询:Mapper 注解 SQL
|
|
||||||
3. 复杂迁移查询、动态列、旧 SQL 兼容:`MicroservicDynamicSQLMapper`
|
|
||||||
4. 复杂 XML 已有现成资产且迁移成本高:可保留 XML
|
|
||||||
|
|
||||||
### 10.2 MyBatis-Plus 适用规范
|
|
||||||
|
|
||||||
适用于:
|
|
||||||
|
|
||||||
- 基础字典
|
|
||||||
- 台账管理
|
|
||||||
- 后台标准分页列表
|
|
||||||
|
|
||||||
要求:
|
|
||||||
|
|
||||||
- 使用 `lambdaQuery()`、`lambdaUpdate()`
|
|
||||||
- 条件判断写在链式条件中
|
|
||||||
- 避免大量手写 SQL 替代简单 CRUD
|
|
||||||
|
|
||||||
### 10.3 动态 SQL 适用规范
|
|
||||||
|
|
||||||
当前项目已有 `MicroservicDynamicSQLMapper`,适用于:
|
|
||||||
|
|
||||||
- 旧系统 SQL 平移
|
|
||||||
- 表结构拆分后的复杂重写
|
|
||||||
- 返回 VO 列较多且结构动态
|
|
||||||
|
|
||||||
使用规范:
|
|
||||||
|
|
||||||
- 动态 SQL 必须先在 Service 中拼装完整语义,不允许把参数语义留给前端猜测
|
|
||||||
- SQL 返回字段必须使用 VO 字段名别名
|
|
||||||
- 参数统一通过 `Map<String, Object>` 绑定,禁止字符串直接拼接用户输入
|
|
||||||
- 非必要不要在 Service 中写多个层层嵌套的查询,优先压缩为可维护的单条 SQL 或小规模明确查询
|
|
||||||
|
|
||||||
### 10.4 SQL 编写要求
|
|
||||||
|
|
||||||
必须遵循:
|
|
||||||
|
|
||||||
- 过滤条件尽量前置
|
|
||||||
- 明确 `IS_DELETED = 0`
|
|
||||||
- 与旧系统兼容时保留 `USFL`、`MWAY`、`DTIN_TYPE`、`STTP` 等业务条件
|
|
||||||
- 联表字段语义必须先确认再关联
|
|
||||||
- 能用 `EXISTS` 的场景优先评估是否优于无谓 join
|
|
||||||
- 排序字段应稳定,避免前端列表顺序漂移
|
|
||||||
|
|
||||||
禁止:
|
|
||||||
|
|
||||||
- 用错误语义字段强行 join
|
|
||||||
- 在 SQL 中随意猜测旧字段映射
|
|
||||||
- 使用无法参数化的用户输入拼接 SQL
|
|
||||||
|
|
||||||
### 10.5 旧系统迁移专项规则
|
|
||||||
|
|
||||||
迁移模块时必须先做三件事:
|
|
||||||
|
|
||||||
1. 找到旧 Controller/Service/Mapper/XML 主入口
|
|
||||||
2. 梳理旧表关系和字段语义
|
|
||||||
3. 建立旧表到新表的映射说明
|
|
||||||
|
|
||||||
禁止:
|
|
||||||
|
|
||||||
- 未分析旧 SQL 语义就直接按字段名猜测重写
|
|
||||||
- 把旧“横表字段”误当成新“关系表字段”
|
|
||||||
- 为了快速实现,破坏旧接口请求和返回结构
|
|
||||||
|
|
||||||
## 11. 业务模块编码规范
|
|
||||||
|
|
||||||
### 11.1 Controller 编码规范
|
|
||||||
|
|
||||||
- 一个 Controller 只承载同一业务域或同一前端页面聚合能力
|
|
||||||
- 聚合型 Controller 可以包含多个子接口,但应保持前缀一致
|
|
||||||
- 方法名与 `@Operation(summary = "...")` 应表达真实业务语义
|
|
||||||
- 空值校验放在 Controller 或 Service 入口,不能完全依赖底层报错
|
|
||||||
|
|
||||||
### 11.2 Service 编码规范
|
|
||||||
|
|
||||||
- 一个方法只表达一个明确业务能力
|
|
||||||
- 复杂逻辑可拆为少量私有方法,但不要抽象出与旧业务语义脱节的“工具方法泛滥”
|
|
||||||
- 允许在 Service 层做二次排序、月份格式化、标志位组装、列头组装等 Java 后处理
|
|
||||||
- 数据库语义判断优先放 SQL,纯展示逻辑优先放 Java
|
|
||||||
|
|
||||||
### 11.3 VO 编码规范
|
|
||||||
|
|
||||||
- VO 字段必须服务于前端返回,不要无意义堆字段
|
|
||||||
- 对旧接口兼容字段要保持命名稳定
|
|
||||||
- 使用 Lombok 时优先 `@Data` 或 `@Getter/@Setter`
|
|
||||||
- 对外 VO 建议加 `@Schema` 注释
|
|
||||||
|
|
||||||
### 11.4 Domain 编码规范
|
|
||||||
|
|
||||||
- Domain 应与真实表结构对齐
|
|
||||||
- 建议保持字段名、注释、表映射一致
|
|
||||||
- 不要将 VO 字段、临时业务字段塞进 Domain
|
|
||||||
|
|
||||||
## 12. 文档与 OpenAPI 规范
|
|
||||||
|
|
||||||
项目当前已引入 `springdoc-openapi-starter-webmvc-ui`,因此新增接口必须同时维护接口文档。
|
|
||||||
|
|
||||||
要求:
|
|
||||||
|
|
||||||
- Controller 类使用 `@Tag`
|
|
||||||
- 方法使用 `@Operation`
|
|
||||||
- 复杂 VO 使用 `@Schema`
|
|
||||||
- 对外接口要有清晰的 `summary`
|
|
||||||
|
|
||||||
推荐:
|
|
||||||
|
|
||||||
- 对关键参数补充 `description`
|
|
||||||
- 对复杂返回结构单独定义 VO,不返回匿名 `Map`
|
|
||||||
- 将生产环境的 OpenAPI/Swagger UI 访问权限纳入安全控制
|
|
||||||
|
|
||||||
## 13. 配置管理规范
|
|
||||||
|
|
||||||
根据 Spring Boot 官方建议,配置应外部化管理。
|
|
||||||
|
|
||||||
项目要求:
|
|
||||||
|
|
||||||
- 数据源、缓存、安全、文档开关、日志级别等必须放配置文件
|
|
||||||
- 多环境配置使用 profile 管理
|
|
||||||
- 不允许将数据库地址、账号、密码、第三方密钥硬编码进 Java 代码
|
|
||||||
- 与数据库方言相关的行为尽量通过配置或基础层封装统一管理
|
|
||||||
|
|
||||||
## 14. 日志与可观测性规范
|
|
||||||
|
|
||||||
项目已引入 `spring-boot-starter-actuator`,因此新增模块应具备基本可观测性意识。
|
|
||||||
|
|
||||||
要求:
|
|
||||||
|
|
||||||
- 业务异常使用统一异常体系,不在正常分支打 error 日志
|
|
||||||
- 大查询、长耗时任务、批量处理建议记录 info/debug 级别日志
|
|
||||||
- 不记录敏感字段原文
|
|
||||||
- 生产问题定位优先结合 Actuator、日志、SQL 条件进行
|
|
||||||
|
|
||||||
建议:
|
|
||||||
|
|
||||||
- 对复杂迁移接口记录关键参数与结果数量
|
|
||||||
- 对导入、导出、批处理记录耗时
|
|
||||||
|
|
||||||
## 15. 安全规范
|
|
||||||
|
|
||||||
由于项目已引入 Spring Security,新增模块应遵循最小暴露原则。
|
|
||||||
|
|
||||||
要求:
|
|
||||||
|
|
||||||
- Swagger/OpenAPI 文档在生产环境应受控
|
|
||||||
- 任何写接口必须考虑权限控制与审计要求
|
|
||||||
- 参数校验必须前置,避免越权探测和异常信息泄露
|
|
||||||
- 对动态 SQL 特别关注注入风险,所有用户输入都必须通过参数绑定
|
|
||||||
|
|
||||||
## 16. 测试规范
|
|
||||||
|
|
||||||
### 16.1 必测场景
|
|
||||||
|
|
||||||
新增业务模块至少要验证:
|
|
||||||
|
|
||||||
- 正常查询
|
|
||||||
- 必填参数缺失
|
|
||||||
- 空数据返回
|
|
||||||
- 关键筛选条件命中
|
|
||||||
- 排序/分页正确
|
|
||||||
|
|
||||||
### 16.2 测试建议
|
|
||||||
|
|
||||||
- 单表 CRUD 模块:优先补 Service/Mapper 单元或集成测试
|
|
||||||
- 迁移型查询模块:至少保留典型请求体样例和 SQL 验证说明
|
|
||||||
- 高风险接口:建议补接口级集成测试
|
|
||||||
|
|
||||||
### 16.3 不建议
|
|
||||||
|
|
||||||
- 为了补测试而写无价值的样板测试
|
|
||||||
- 完全重复实现逻辑本身的测试
|
|
||||||
|
|
||||||
## 17. 性能规范
|
|
||||||
|
|
||||||
### 17.1 查询性能
|
|
||||||
|
|
||||||
- 优先明确主表与过滤条件
|
|
||||||
- 少用无必要的多层嵌套子查询
|
|
||||||
- 大表统计优先关注时间条件、站点条件、逻辑删除条件是否下推
|
|
||||||
- `ROWNUM = 1`、`FETCH FIRST 1 ROWS ONLY` 等默认值查询必须确保排序稳定
|
|
||||||
|
|
||||||
### 17.2 Java 21 使用建议
|
|
||||||
|
|
||||||
本项目使用 Java 21,但业务模块默认仍以同步 MVC 为主。
|
|
||||||
|
|
||||||
建议:
|
|
||||||
|
|
||||||
- 普通查询接口保持同步风格,避免过早引入响应式复杂度
|
|
||||||
- CPU 密集或 I/O 密集的异步能力需经过明确评估后再引入
|
|
||||||
- 语言特性应以可读性优先,避免为了“新语法”牺牲团队可维护性
|
|
||||||
|
|
||||||
## 18. 新增业务模块推荐模板
|
|
||||||
|
|
||||||
### 18.1 基础管理模块模板
|
|
||||||
|
|
||||||
- `domain/Xxx.java`
|
|
||||||
- `mapper/XxxMapper.java`
|
|
||||||
- `service/IXxxService.java`
|
|
||||||
- `service/impl/XxxServiceImpl.java`
|
|
||||||
- `controller/XxxController.java`
|
|
||||||
|
|
||||||
适用:
|
|
||||||
|
|
||||||
- 国家、流域、字典、基础表管理
|
|
||||||
|
|
||||||
### 18.2 复杂查询模块模板
|
|
||||||
|
|
||||||
- `entity/vo/XxxVO.java`
|
|
||||||
- `mapper/XxxMapper.java`
|
|
||||||
- `service/XxxService.java`
|
|
||||||
- `service/impl/XxxServiceImpl.java`
|
|
||||||
- `controller/XxxController.java`
|
|
||||||
|
|
||||||
适用:
|
|
||||||
|
|
||||||
- 旧平台迁移
|
|
||||||
- 统计分析
|
|
||||||
- 图表联查
|
|
||||||
- 多表业务判断
|
|
||||||
|
|
||||||
## 19. 开发禁止项
|
|
||||||
|
|
||||||
以下行为在新增业务模块中原则上禁止:
|
|
||||||
|
|
||||||
- Controller 直接操作 Mapper
|
|
||||||
- 直接返回裸 `Map` 作为通用接口响应
|
|
||||||
- 大量复制旧 SQL 但不校验字段语义
|
|
||||||
- 将前端字段名直接拼成 SQL 片段
|
|
||||||
- 业务异常使用 `RuntimeException`
|
|
||||||
- 多个接口返回结构风格不统一
|
|
||||||
- 在 Service 中堆积无法复用、语义不清的“万能工具方法”
|
|
||||||
- 未确认表语义就擅自把旧表字段映射到新表字段
|
|
||||||
- 对外接口无 `@Operation` 文档说明
|
|
||||||
|
|
||||||
## 20. 迁移模块专项检查清单
|
|
||||||
|
|
||||||
新增或改造迁移模块时,提交前必须自检:
|
|
||||||
|
|
||||||
- 是否定位了旧入口 Controller/Service/Mapper/XML
|
|
||||||
- 是否梳理了旧表职责与表关系
|
|
||||||
- 是否建立了旧表到新表的映射说明
|
|
||||||
- 是否保持了旧接口路径、入参名、返回字段的兼容性
|
|
||||||
- 是否校验了关键 SQL 的过滤条件、排序条件和时间口径
|
|
||||||
- 是否补充了空值、默认值、无数据场景处理
|
|
||||||
- 是否检查了 `IS_DELETED`、`USFL`、`MWAY`、`DTIN_TYPE` 等业务条件
|
|
||||||
- 是否校验了 `ResponseResult`、`DataSourceResult`、VO 返回结构
|
|
||||||
- 是否完成最基本的诊断或测试验证
|
|
||||||
|
|
||||||
## 21. 推荐落地原则
|
|
||||||
|
|
||||||
本项目业务模块开发建议遵循以下顺序:
|
|
||||||
|
|
||||||
1. 先确认业务语义与表关系
|
|
||||||
2. 再确定模块属于 CRUD 型还是迁移查询型
|
|
||||||
3. 再选择 MyBatis-Plus、注解 SQL 或动态 SQL
|
|
||||||
4. 再定义 VO/Domain/Service/Controller 落位
|
|
||||||
5. 最后补异常、文档、校验、测试与性能检查
|
|
||||||
|
|
||||||
一句话原则:
|
|
||||||
|
|
||||||
以项目现有架构为主线,以 Spring Boot 4.0 现代实践为约束,以“业务语义正确、接口兼容、SQL 可维护、结构可复用”为最终标准。
|
|
||||||
|
|
||||||
## 22. 附录:外部参考资料
|
|
||||||
|
|
||||||
- Spring Boot Documentation Overview
|
|
||||||
- https://docs.spring.io/spring-boot/documentation.html
|
|
||||||
- springdoc OpenAPI Getting Started
|
|
||||||
- https://springdoc.org/getting-started.html
|
|
||||||
- MyBatis-Plus Quick Start
|
|
||||||
- https://baomidou.com/en/getting-started/
|
|
||||||
- MyBatis Spring Boot Starter Reference
|
|
||||||
- https://mybatis.org/spring-boot-starter/mybatis-spring-boot-autoconfigure/
|
|
||||||
110
backend/platform-common/pom.xml
Normal file
110
backend/platform-common/pom.xml
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
<?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>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>com.yfd</groupId>
|
||||||
|
<artifactId>platform</artifactId>
|
||||||
|
<version>1.0</version>
|
||||||
|
<relativePath>../pom.xml</relativePath>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<artifactId>platform-common</artifactId>
|
||||||
|
<version>1.0</version>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<name>Platform Common</name>
|
||||||
|
<description>Platform Common Module</description>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<!-- Spring Boot Starter -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Spring Boot Quartz -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-quartz</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Spring Boot Security -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-security</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Lombok -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Hutool -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.hutool</groupId>
|
||||||
|
<artifactId>hutool-all</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Apache Commons -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-lang3</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>commons-codec</groupId>
|
||||||
|
<artifactId>commons-codec</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- POI -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.poi</groupId>
|
||||||
|
<artifactId>poi</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.poi</groupId>
|
||||||
|
<artifactId>poi-ooxml</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- IP2Region -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.lionsoul</groupId>
|
||||||
|
<artifactId>ip2region</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- UserAgentUtils -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>eu.bitwalker</groupId>
|
||||||
|
<artifactId>UserAgentUtils</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- MyBatis-Plus Generator -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.baomidou</groupId>
|
||||||
|
<artifactId>mybatis-plus-generator</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Freemarker (for MyBatis-Plus Generator) -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.freemarker</groupId>
|
||||||
|
<artifactId>freemarker</artifactId>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<skip>true</skip>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
||||||
@ -0,0 +1,48 @@
|
|||||||
|
package com.yfd.platform.common.request;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 统一请求参数结构
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class RequestParams {
|
||||||
|
/**
|
||||||
|
* 分页参数
|
||||||
|
*/
|
||||||
|
private PageParams page;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 排序参数
|
||||||
|
*/
|
||||||
|
private SortParams sort;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 筛选条件
|
||||||
|
*/
|
||||||
|
private Map<String, Object> filter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 业务参数
|
||||||
|
*/
|
||||||
|
private Map<String, Object> params;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页参数类
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public static class PageParams {
|
||||||
|
private int pageSize;
|
||||||
|
private int pageNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 排序参数类
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public static class SortParams {
|
||||||
|
private String field;
|
||||||
|
private String direction;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,60 @@
|
|||||||
|
package com.yfd.platform.common.response;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 统一返回结构
|
||||||
|
*/
|
||||||
|
public class ResponseResult extends HashMap<String, Object> {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public ResponseResult() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ResponseResult unlogin() {
|
||||||
|
return message("401", "未登录");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ResponseResult error() {
|
||||||
|
return error("操作失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ResponseResult success() {
|
||||||
|
return success("操作成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ResponseResult error(String msg) {
|
||||||
|
ResponseResult json = new ResponseResult();
|
||||||
|
json.put((String)"code", "1");//错误
|
||||||
|
json.put((String)"msg", msg);
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ResponseResult message(String code, String msg) {
|
||||||
|
ResponseResult json = new ResponseResult();
|
||||||
|
json.put((String)"code", code);
|
||||||
|
json.put((String)"msg", msg);
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ResponseResult success(String msg) {
|
||||||
|
ResponseResult json = new ResponseResult();
|
||||||
|
json.put((String)"code", "0");//正常
|
||||||
|
json.put((String)"msg", msg);
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ResponseResult successData(Object obj) {
|
||||||
|
ResponseResult json = new ResponseResult();
|
||||||
|
json.put((String)"code", "0");//正常
|
||||||
|
json.put((String)"msg", "操作成功");
|
||||||
|
json.put("data", obj);
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public ResponseResult put(String key, Object value) {
|
||||||
|
super.put(key, value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019-2020 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.yfd.platform.common.utils;
|
||||||
|
|
||||||
|
import com.yfd.platform.common.utils.SpringContextHolder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author: liaojinlong
|
||||||
|
* @date: 2020/6/9 17:02
|
||||||
|
* @since: 1.0
|
||||||
|
* @see {@link SpringContextHolder}
|
||||||
|
* 针对某些初始化方法,在SpringContextHolder 初始化前时,<br>
|
||||||
|
* 可提交一个 提交回调任务。<br>
|
||||||
|
* 在SpringContextHolder 初始化后,进行回调使用
|
||||||
|
*/
|
||||||
|
|
||||||
|
public interface CallBack {
|
||||||
|
/**
|
||||||
|
* 回调执行方法
|
||||||
|
*/
|
||||||
|
void executor();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 本回调任务名称
|
||||||
|
* @return /
|
||||||
|
*/
|
||||||
|
default String getCallBackName() {
|
||||||
|
return Thread.currentThread().getId() + ":" + this.getClass().getName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,75 @@
|
|||||||
|
package com.yfd.platform.common.utils;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
|
||||||
|
import com.baomidou.mybatisplus.generator.config.OutputFile;
|
||||||
|
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
|
||||||
|
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Scanner;
|
||||||
|
|
||||||
|
// 演示例子,执行 main 方法控制台输入模块表名回车自动生成对应项目目录中
|
||||||
|
public class CodeGenerator {
|
||||||
|
|
||||||
|
public static String scanner(String tip) {
|
||||||
|
Scanner scanner = new Scanner(System.in);
|
||||||
|
StringBuilder help = new StringBuilder();
|
||||||
|
help.append("请输入" + tip + ":");
|
||||||
|
System.out.println(help.toString());
|
||||||
|
if (scanner.hasNext()) {
|
||||||
|
String ipt = scanner.next();
|
||||||
|
if (ipt != null && !ipt.trim().isEmpty()) {
|
||||||
|
return ipt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new RuntimeException("请输入正确的" + tip + "!");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
String projectPath = System.getProperty("user.dir");
|
||||||
|
String module = scanner("模块名称");
|
||||||
|
|
||||||
|
Map<OutputFile, String> pathInfo = new HashMap<>();
|
||||||
|
pathInfo.put(OutputFile.entity, projectPath + "/src/main/java/com/yfd/platform/" + module + "/domain");
|
||||||
|
pathInfo.put(OutputFile.mapper, projectPath + "/src/main/java/com/yfd/platform/" + module + "/mapper");
|
||||||
|
pathInfo.put(OutputFile.controller, projectPath + "/src/main/java/com/yfd/platform/" + module + "/controller");
|
||||||
|
pathInfo.put(OutputFile.serviceImpl, projectPath + "/src/main/java/com/yfd/platform/" + module + "/service/impl");
|
||||||
|
pathInfo.put(OutputFile.service, projectPath + "/src/main/java/com/yfd/platform/" + module + "/service");
|
||||||
|
pathInfo.put(OutputFile.xml, projectPath + "/src/main/resources/mapper/" + module);
|
||||||
|
|
||||||
|
FastAutoGenerator.create(
|
||||||
|
"jdbc:mysql://43.143.220.7:3306/frameworkdb2023?useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&autoReconnect=true&failOverReadOnly=false&allowMultiQueries=true&serverTimezone=Asia/Shanghai",
|
||||||
|
"root",
|
||||||
|
"zhengg7QkXa<gRqqQ2023")
|
||||||
|
.globalConfig(builder -> {
|
||||||
|
builder.author("TangWei")
|
||||||
|
.disableOpenDir()
|
||||||
|
.outputDir(projectPath + "/src/main/java");
|
||||||
|
})
|
||||||
|
.packageConfig(builder -> {
|
||||||
|
builder.parent("com.yfd.platform")
|
||||||
|
.moduleName(module)
|
||||||
|
.pathInfo(pathInfo);
|
||||||
|
})
|
||||||
|
.strategyConfig(builder -> {
|
||||||
|
builder.addInclude(scanner("表名,多个英文逗号分割").split(","))
|
||||||
|
.entityBuilder()
|
||||||
|
.enableLombok()
|
||||||
|
.naming(NamingStrategy.underline_to_camel)
|
||||||
|
.columnNaming(NamingStrategy.underline_to_camel)
|
||||||
|
.controllerBuilder()
|
||||||
|
.enableRestStyle()
|
||||||
|
.mapperBuilder()
|
||||||
|
.formatMapperFileName("%sMapper")
|
||||||
|
.serviceBuilder()
|
||||||
|
.formatServiceFileName("%sService")
|
||||||
|
.formatServiceImplFileName("%sServiceImpl")
|
||||||
|
.controllerBuilder()
|
||||||
|
.formatFileName("%sController");
|
||||||
|
})
|
||||||
|
.templateEngine(new FreemarkerTemplateEngine())
|
||||||
|
.execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -1,8 +1,5 @@
|
|||||||
package com.yfd.platform.utils;
|
package com.yfd.platform.common.utils;
|
||||||
|
|
||||||
import org.jasypt.encryption.pbe.PooledPBEStringEncryptor;
|
|
||||||
import org.jasypt.encryption.pbe.config.SimpleStringPBEConfig;
|
|
||||||
import org.jasypt.util.text.BasicTextEncryptor;
|
|
||||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||||
|
|
||||||
public class EncryptConfigUtil {
|
public class EncryptConfigUtil {
|
||||||
@ -0,0 +1,100 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019-2020 Zheng Jie
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.yfd.platform.common.utils;
|
||||||
|
|
||||||
|
import javax.crypto.Cipher;
|
||||||
|
import javax.crypto.SecretKey;
|
||||||
|
import javax.crypto.SecretKeyFactory;
|
||||||
|
import javax.crypto.spec.DESKeySpec;
|
||||||
|
import javax.crypto.spec.IvParameterSpec;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加密
|
||||||
|
* @author
|
||||||
|
* @date 2018-11-23
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class EncryptUtils {
|
||||||
|
|
||||||
|
private static final String STR_PARAM = "Passw0rd";
|
||||||
|
|
||||||
|
private static Cipher cipher;
|
||||||
|
|
||||||
|
private static final IvParameterSpec IV = new IvParameterSpec(STR_PARAM.getBytes(StandardCharsets.UTF_8));
|
||||||
|
|
||||||
|
private static DESKeySpec getDesKeySpec(String source) throws Exception {
|
||||||
|
if (source == null || source.length() == 0){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
|
||||||
|
String strKey = "Passw0rd";
|
||||||
|
return new DESKeySpec(strKey.getBytes(StandardCharsets.UTF_8));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对称加密
|
||||||
|
*/
|
||||||
|
public static String desEncrypt(String source) throws Exception {
|
||||||
|
DESKeySpec desKeySpec = getDesKeySpec(source);
|
||||||
|
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
|
||||||
|
SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
|
||||||
|
cipher.init(Cipher.ENCRYPT_MODE, secretKey, IV);
|
||||||
|
return byte2hex(
|
||||||
|
cipher.doFinal(source.getBytes(StandardCharsets.UTF_8))).toUpperCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对称解密
|
||||||
|
*/
|
||||||
|
public static String desDecrypt(String source) throws Exception {
|
||||||
|
byte[] src = hex2byte(source.getBytes(StandardCharsets.UTF_8));
|
||||||
|
DESKeySpec desKeySpec = getDesKeySpec(source);
|
||||||
|
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
|
||||||
|
SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
|
||||||
|
cipher.init(Cipher.DECRYPT_MODE, secretKey, IV);
|
||||||
|
byte[] retByte = cipher.doFinal(src);
|
||||||
|
return new String(retByte);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String byte2hex(byte[] inStr) {
|
||||||
|
String stmp;
|
||||||
|
StringBuilder out = new StringBuilder(inStr.length * 2);
|
||||||
|
for (byte b : inStr) {
|
||||||
|
stmp = Integer.toHexString(b & 0xFF);
|
||||||
|
if (stmp.length() == 1) {
|
||||||
|
// 如果是0至F的单位字符串,则添加0
|
||||||
|
out.append("0").append(stmp);
|
||||||
|
} else {
|
||||||
|
out.append(stmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static byte[] hex2byte(byte[] b) {
|
||||||
|
int size = 2;
|
||||||
|
if ((b.length % size) != 0){
|
||||||
|
throw new IllegalArgumentException("长度不是偶数");
|
||||||
|
}
|
||||||
|
byte[] b2 = new byte[b.length / 2];
|
||||||
|
for (int n = 0; n < b.length; n += size) {
|
||||||
|
String item = new String(b, n, 2);
|
||||||
|
b2[n / 2] = (byte) Integer.parseInt(item, 16);
|
||||||
|
}
|
||||||
|
return b2;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,395 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019-2020 Zheng Jie
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.yfd.platform.common.utils;
|
||||||
|
|
||||||
|
import cn.hutool.core.date.DateUtil;
|
||||||
|
import cn.hutool.core.io.IoUtil;
|
||||||
|
import cn.hutool.core.util.IdUtil;
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import cn.hutool.poi.excel.BigExcelWriter;
|
||||||
|
import cn.hutool.poi.excel.ExcelUtil;
|
||||||
|
import com.yfd.platform.exception.BadRequestException;
|
||||||
|
import jakarta.servlet.ServletOutputStream;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
import org.apache.poi.util.IOUtils;
|
||||||
|
import org.apache.poi.xssf.streaming.SXSSFSheet;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.net.URLDecoder;
|
||||||
|
import java.security.MessageDigest;
|
||||||
|
import java.text.DecimalFormat;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* File工具类,扩展 hutool 工具包
|
||||||
|
*
|
||||||
|
* @author
|
||||||
|
* @date 2018-12-27
|
||||||
|
*/
|
||||||
|
public class FileUtil extends cn.hutool.core.io.FileUtil {
|
||||||
|
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(FileUtil.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 系统临时目录
|
||||||
|
* <br>
|
||||||
|
* windows 包含路径分割符,但Linux 不包含,
|
||||||
|
* 在windows \\==\ 前提下,
|
||||||
|
* 为安全起见 同意拼装 路径分割符,
|
||||||
|
* <pre>
|
||||||
|
* java.io.tmpdir
|
||||||
|
* windows : C:\Users/xxx\AppData\Local\Temp\
|
||||||
|
* linux: /temp
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
|
public static final String SYS_TEM_DIR = System.getProperty("java.io.tmpdir") + File.separator;
|
||||||
|
/**
|
||||||
|
* 定义GB的计算常量
|
||||||
|
*/
|
||||||
|
private static final int GB = 1024 * 1024 * 1024;
|
||||||
|
/**
|
||||||
|
* 定义MB的计算常量
|
||||||
|
*/
|
||||||
|
private static final int MB = 1024 * 1024;
|
||||||
|
/**
|
||||||
|
* 定义KB的计算常量
|
||||||
|
*/
|
||||||
|
private static final int KB = 1024;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 格式化小数
|
||||||
|
*/
|
||||||
|
private static final DecimalFormat DF = new DecimalFormat("0.00");
|
||||||
|
|
||||||
|
public static final String IMAGE = "image";
|
||||||
|
public static final String TXT = "document";
|
||||||
|
public static final String MUSIC = "music";
|
||||||
|
public static final String VIDEO = "video";
|
||||||
|
public static final String OTHER = "other";
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MultipartFile转File
|
||||||
|
*/
|
||||||
|
public static File toFile(MultipartFile multipartFile) {
|
||||||
|
// 获取文件名
|
||||||
|
String fileName = multipartFile.getOriginalFilename();
|
||||||
|
// 获取文件后缀
|
||||||
|
String prefix = "." + getExtensionName(fileName);
|
||||||
|
File file = null;
|
||||||
|
try {
|
||||||
|
// 用uuid作为文件名,防止生成的临时文件重复
|
||||||
|
file = File.createTempFile(IdUtil.simpleUUID(), prefix);
|
||||||
|
// MultipartFile to File
|
||||||
|
multipartFile.transferTo(file);
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取文件扩展名,不带 .
|
||||||
|
*/
|
||||||
|
public static String getExtensionName(String filename) {
|
||||||
|
if ((filename != null) && (filename.length() > 0)) {
|
||||||
|
int dot = filename.lastIndexOf('.');
|
||||||
|
if ((dot > -1) && (dot < (filename.length() - 1))) {
|
||||||
|
return filename.substring(dot + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Java文件操作 获取不带扩展名的文件名
|
||||||
|
*/
|
||||||
|
public static String getFileNameNoEx(String filename) {
|
||||||
|
if ((filename != null) && (filename.length() > 0)) {
|
||||||
|
int dot = filename.lastIndexOf('.');
|
||||||
|
if ((dot > -1) && (dot < (filename.length()))) {
|
||||||
|
return filename.substring(0, dot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件大小转换
|
||||||
|
*/
|
||||||
|
public static String getSize(long size) {
|
||||||
|
String resultSize;
|
||||||
|
if (size / GB >= 1) {
|
||||||
|
//如果当前Byte的值大于等于1GB
|
||||||
|
resultSize = DF.format(size / (float) GB) + "GB ";
|
||||||
|
} else if (size / MB >= 1) {
|
||||||
|
//如果当前Byte的值大于等于1MB
|
||||||
|
resultSize = DF.format(size / (float) MB) + "MB ";
|
||||||
|
} else if (size / KB >= 1) {
|
||||||
|
//如果当前Byte的值大于等于1KB
|
||||||
|
resultSize = DF.format(size / (float) KB) + "KB ";
|
||||||
|
} else {
|
||||||
|
resultSize = size + "B ";
|
||||||
|
}
|
||||||
|
return resultSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* inputStream 转 File
|
||||||
|
*/
|
||||||
|
static File inputStreamToFile(InputStream ins, String name) throws Exception {
|
||||||
|
File file = new File(SYS_TEM_DIR + name);
|
||||||
|
if (file.exists()) {
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
OutputStream os = new FileOutputStream(file);
|
||||||
|
int bytesRead;
|
||||||
|
int len = 8192;
|
||||||
|
byte[] buffer = new byte[len];
|
||||||
|
while ((bytesRead = ins.read(buffer, 0, len)) != -1) {
|
||||||
|
os.write(buffer, 0, bytesRead);
|
||||||
|
}
|
||||||
|
os.close();
|
||||||
|
ins.close();
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将文件名解析成文件的上传路径
|
||||||
|
*/
|
||||||
|
public static File upload(MultipartFile file, String filePath) {
|
||||||
|
Date date = new Date();
|
||||||
|
SimpleDateFormat format = new SimpleDateFormat("yyyyMMddhhmmssS");
|
||||||
|
String name = getFileNameNoEx(file.getOriginalFilename());
|
||||||
|
String suffix = getExtensionName(file.getOriginalFilename());
|
||||||
|
String nowStr = "-" + format.format(date);
|
||||||
|
try {
|
||||||
|
String fileName = name + "." + suffix;
|
||||||
|
String path = filePath +File.separator + fileName;
|
||||||
|
// getCanonicalFile 可解析正确各种路径
|
||||||
|
File dest = new File(path).getCanonicalFile();
|
||||||
|
// 检测是否存在目录
|
||||||
|
if (!dest.getParentFile().exists()) {
|
||||||
|
if (!dest.getParentFile().mkdirs()) {
|
||||||
|
System.out.println("was not successful.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 文件写入
|
||||||
|
file.transferTo(dest);
|
||||||
|
return dest;
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将文件名解析成文件的上传路径
|
||||||
|
* file 上传的文件
|
||||||
|
* filePath 存储路径
|
||||||
|
* tofilename 保存文件名称
|
||||||
|
|
||||||
|
*/
|
||||||
|
public static File upload(MultipartFile file, String filePath,String tofilename) {
|
||||||
|
try {
|
||||||
|
String filename = filePath + File.separator + tofilename;
|
||||||
|
File dest = new File(filename).getCanonicalFile();
|
||||||
|
// 检测是否存在目录
|
||||||
|
if (!dest.getParentFile().exists()) {
|
||||||
|
if (!dest.getParentFile().mkdirs()) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 文件写入
|
||||||
|
file.transferTo(dest);
|
||||||
|
return dest;
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出excel
|
||||||
|
*/
|
||||||
|
public static void downloadExcel(List<Map<String, Object>> list, HttpServletResponse response) throws IOException {
|
||||||
|
String tempPath = SYS_TEM_DIR + IdUtil.fastSimpleUUID() + ".xlsx";
|
||||||
|
String filename = "record"+cn.hutool.core.date.DateUtil.format(DateUtil.date(), "yyyyMMddHHmmss");
|
||||||
|
File file = new File(tempPath);
|
||||||
|
BigExcelWriter writer = ExcelUtil.getBigWriter(file);
|
||||||
|
// 一次性写出内容,使用默认样式,强制输出标题
|
||||||
|
writer.write(list, true);
|
||||||
|
SXSSFSheet sheet = (SXSSFSheet)writer.getSheet();
|
||||||
|
//上面需要强转SXSSFSheet 不然没有trackAllColumnsForAutoSizing方法
|
||||||
|
sheet.trackAllColumnsForAutoSizing();
|
||||||
|
//列宽自适应
|
||||||
|
writer.autoSizeColumnAll();
|
||||||
|
//response为HttpServletResponse对象
|
||||||
|
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
|
||||||
|
//test.xls是弹出下载对话框的文件名,不能为中文,中文请自行编码
|
||||||
|
response.setHeader("Content-Disposition", "attachment;filename="+filename+".xlsx");
|
||||||
|
ServletOutputStream out = response.getOutputStream();
|
||||||
|
// 终止后删除临时文件
|
||||||
|
file.deleteOnExit();
|
||||||
|
writer.flush(out, true);
|
||||||
|
//此处记得关闭输出Servlet流
|
||||||
|
IoUtil.close(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getFileType(String type) {
|
||||||
|
String documents = "txt doc pdf ppt pps xlsx xls docx";
|
||||||
|
String music = "mp3 wav wma mpa ram ra aac aif m4a";
|
||||||
|
String video = "avi mpg mpe mpeg asf wmv mov qt rm mp4 flv m4v webm ogv ogg";
|
||||||
|
String image = "bmp dib pcp dif wmf gif jpg tif eps psd cdr iff tga pcd mpt png jpeg";
|
||||||
|
if (image.contains(type)) {
|
||||||
|
return IMAGE;
|
||||||
|
} else if (documents.contains(type)) {
|
||||||
|
return TXT;
|
||||||
|
} else if (music.contains(type)) {
|
||||||
|
return MUSIC;
|
||||||
|
} else if (video.contains(type)) {
|
||||||
|
return VIDEO;
|
||||||
|
} else {
|
||||||
|
return OTHER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void checkSize(long maxSize, long size) {
|
||||||
|
// 1M
|
||||||
|
int len = 1024 * 1024;
|
||||||
|
if (size > (maxSize * len)) {
|
||||||
|
throw new BadRequestException("文件超出规定大小");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断两个文件是否相同
|
||||||
|
*/
|
||||||
|
public static boolean check(File file1, File file2) {
|
||||||
|
String img1Md5 = getMd5(file1);
|
||||||
|
String img2Md5 = getMd5(file2);
|
||||||
|
return img1Md5.equals(img2Md5);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断两个文件是否相同
|
||||||
|
*/
|
||||||
|
public static boolean check(String file1Md5, String file2Md5) {
|
||||||
|
return file1Md5.equals(file2Md5);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static byte[] getByte(File file) {
|
||||||
|
// 得到文件长度
|
||||||
|
byte[] b = new byte[(int) file.length()];
|
||||||
|
try {
|
||||||
|
InputStream in = new FileInputStream(file);
|
||||||
|
try {
|
||||||
|
System.out.println(in.read(b));
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
log.error(e.getMessage(), e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getMd5(byte[] bytes) {
|
||||||
|
// 16进制字符
|
||||||
|
char[] hexDigits = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
|
||||||
|
try {
|
||||||
|
MessageDigest mdTemp = MessageDigest.getInstance("MD5");
|
||||||
|
mdTemp.update(bytes);
|
||||||
|
byte[] md = mdTemp.digest();
|
||||||
|
int j = md.length;
|
||||||
|
char[] str = new char[j * 2];
|
||||||
|
int k = 0;
|
||||||
|
// 移位 输出字符串
|
||||||
|
for (byte byte0 : md) {
|
||||||
|
str[k++] = hexDigits[byte0 >>> 4 & 0xf];
|
||||||
|
str[k++] = hexDigits[byte0 & 0xf];
|
||||||
|
}
|
||||||
|
return new String(str);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 下载文件
|
||||||
|
*
|
||||||
|
* @param request /
|
||||||
|
* @param response /
|
||||||
|
* @param file /
|
||||||
|
*/
|
||||||
|
public static void downloadFile(HttpServletRequest request, HttpServletResponse response, File file, boolean deleteOnExit) {
|
||||||
|
response.setCharacterEncoding(request.getCharacterEncoding());
|
||||||
|
response.setContentType("application/octet-stream");
|
||||||
|
FileInputStream fis = null;
|
||||||
|
try {
|
||||||
|
fis = new FileInputStream(file);
|
||||||
|
response.setHeader("Content-Disposition", "attachment; filename=" + file.getName());
|
||||||
|
IOUtils.copy(fis, response.getOutputStream());
|
||||||
|
response.flushBuffer();
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error(e.getMessage(), e);
|
||||||
|
} finally {
|
||||||
|
if (fis != null) {
|
||||||
|
try {
|
||||||
|
fis.close();
|
||||||
|
if (deleteOnExit) {
|
||||||
|
file.deleteOnExit();
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 预览PDF文件
|
||||||
|
*
|
||||||
|
* @param filepath /
|
||||||
|
* @param response /
|
||||||
|
*/
|
||||||
|
public static void viewPDF(String filepath, HttpServletResponse response) throws IOException {
|
||||||
|
File file=new File(filepath);
|
||||||
|
String originFileName=file.getName(); //中文编码
|
||||||
|
response.setCharacterEncoding("UTF-8");
|
||||||
|
String showName= StrUtil.isNotBlank(originFileName)?originFileName:file.getName();
|
||||||
|
showName= URLDecoder.decode(showName,"UTF-8");
|
||||||
|
response.setHeader("Content-Disposition","inline;fileName="+new String(showName.getBytes(), "ISO8859-1")+";fileName*=UTF-8''"+ new String(showName.getBytes(), "ISO8859-1"));
|
||||||
|
FileInputStream fis = new FileInputStream(file);
|
||||||
|
response.setHeader("content-type", "application/pdf");
|
||||||
|
response.setContentType("application/pdf; charset=utf-8");
|
||||||
|
IOUtils.copy(fis, response.getOutputStream());
|
||||||
|
fis.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getMd5(File file) {
|
||||||
|
return getMd5(getByte(file));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,152 @@
|
|||||||
|
package com.yfd.platform.common.utils;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class ObjectConverterUtil {
|
||||||
|
|
||||||
|
// 日期时间格式
|
||||||
|
private static final DateTimeFormatter DATE_TIME_FORMATTER =
|
||||||
|
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将 List<Map> 中的大写字段名转换为与实体类一致的小写格式
|
||||||
|
* 适用于 Oracle 数据库查询结果转换
|
||||||
|
* 时间类型字段会转换为字符串格式
|
||||||
|
*
|
||||||
|
* @param entityClass 实体类 Class 对象
|
||||||
|
* @param sourceList 源数据列表(字段名为大写)
|
||||||
|
* @return 转换后的列表(字段名与实体类一致)
|
||||||
|
*/
|
||||||
|
public static <T> List<Map<String, Object>> convertMapFieldsToEntityFormat(
|
||||||
|
Class<T> entityClass,
|
||||||
|
List<Map<String, Object>> sourceList) {
|
||||||
|
|
||||||
|
if (sourceList == null || sourceList.isEmpty()) {
|
||||||
|
return sourceList;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取实体类的所有字段及类型
|
||||||
|
Map<String, Field> fieldMap = new HashMap<>();
|
||||||
|
for (Field field : entityClass.getDeclaredFields()) {
|
||||||
|
fieldMap.put(field.getName(), field);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 转换每个 Map
|
||||||
|
return sourceList.stream().map(sourceMap -> {
|
||||||
|
Map<String, Object> targetMap = new HashMap<>();
|
||||||
|
|
||||||
|
for (Map.Entry<String, Object> entry : sourceMap.entrySet()) {
|
||||||
|
String dbColumnName = entry.getKey(); // 数据库列名(大写)
|
||||||
|
Object value = entry.getValue();
|
||||||
|
|
||||||
|
// 将大写列名转为小写
|
||||||
|
String lowerCaseName = dbColumnName.toLowerCase();
|
||||||
|
|
||||||
|
// 如果实体类中有对应的字段
|
||||||
|
if (fieldMap.containsKey(lowerCaseName)) {
|
||||||
|
Field field = fieldMap.get(lowerCaseName);
|
||||||
|
String fieldType = field.getType().getSimpleName();
|
||||||
|
|
||||||
|
// 处理时间类型,转换为字符串
|
||||||
|
if ("Timestamp".equals(fieldType) || "Date".equals(fieldType) ||
|
||||||
|
"LocalDateTime".equals(fieldType)) {
|
||||||
|
targetMap.put(lowerCaseName, formatDateTimeValue(value));
|
||||||
|
} else {
|
||||||
|
targetMap.put(lowerCaseName, value);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 如果实体类中没有对应字段,保留原列名(转小写)
|
||||||
|
targetMap.put(lowerCaseName, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return targetMap;
|
||||||
|
}).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通用方法:将单个 Map 的大写字段转换为实体类格式
|
||||||
|
* 时间类型字段会转换为字符串格式
|
||||||
|
*
|
||||||
|
* @param entityClass 实体类 Class 对象
|
||||||
|
* @param sourceMap 源 Map(字段名为大写)
|
||||||
|
* @return 转换后的 Map(字段名与实体类一致)
|
||||||
|
*/
|
||||||
|
public static <T> Map<String, Object> convertSingleMapFieldsToEntityFormat(
|
||||||
|
Class<T> entityClass,
|
||||||
|
Map<String, Object> sourceMap) {
|
||||||
|
|
||||||
|
if (sourceMap == null) {
|
||||||
|
return sourceMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取实体类的所有字段及类型
|
||||||
|
Map<String, Field> fieldMap = new HashMap<>();
|
||||||
|
for (Field field : entityClass.getDeclaredFields()) {
|
||||||
|
fieldMap.put(field.getName(), field);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, Object> targetMap = new HashMap<>();
|
||||||
|
|
||||||
|
for (Map.Entry<String, Object> entry : sourceMap.entrySet()) {
|
||||||
|
String dbColumnName = entry.getKey();
|
||||||
|
Object value = entry.getValue();
|
||||||
|
|
||||||
|
// 将大写列名转为小写
|
||||||
|
String lowerCaseName = dbColumnName.toLowerCase();
|
||||||
|
|
||||||
|
// 验证字段是否存在于实体类中
|
||||||
|
if (fieldMap.containsKey(lowerCaseName)) {
|
||||||
|
Field field = fieldMap.get(lowerCaseName);
|
||||||
|
String fieldType = field.getType().getSimpleName();
|
||||||
|
|
||||||
|
// 处理时间类型,转换为字符串
|
||||||
|
if ("Timestamp".equals(fieldType) || "Date".equals(fieldType) ||
|
||||||
|
"LocalDateTime".equals(fieldType)) {
|
||||||
|
targetMap.put(lowerCaseName, formatDateTimeValue(value));
|
||||||
|
} else {
|
||||||
|
targetMap.put(lowerCaseName, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return targetMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 格式化时间类型值为字符串
|
||||||
|
*
|
||||||
|
* @param value 时间值(可能是 Timestamp、Date 或 LocalDateTime)
|
||||||
|
* @return 格式化后的字符串,如果为 null 则返回 null
|
||||||
|
*/
|
||||||
|
private static String formatDateTimeValue(Object value) {
|
||||||
|
if (value == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value instanceof Timestamp) {
|
||||||
|
LocalDateTime localDateTime = ((Timestamp) value).toLocalDateTime();
|
||||||
|
return localDateTime.format(DATE_TIME_FORMATTER);
|
||||||
|
} else if (value instanceof Date) {
|
||||||
|
// 包括 java.sql.Date 和 java.util.Date
|
||||||
|
LocalDateTime localDateTime = ((Date) value).toInstant()
|
||||||
|
.atZone(java.time.ZoneId.systemDefault())
|
||||||
|
.toLocalDateTime();
|
||||||
|
return localDateTime.format(DATE_TIME_FORMATTER);
|
||||||
|
} else if (value instanceof LocalDateTime) {
|
||||||
|
return ((LocalDateTime) value).format(DATE_TIME_FORMATTER);
|
||||||
|
} else {
|
||||||
|
// 其他类型直接转字符串
|
||||||
|
return value.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,29 @@
|
|||||||
|
package com.yfd.platform.common.utils;
|
||||||
|
|
||||||
|
import org.springframework.core.io.ClassPathResource;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.util.Properties;
|
||||||
|
/******************************
|
||||||
|
* 用途说明:
|
||||||
|
* 作者姓名: pcj
|
||||||
|
* 创建时间: 2022/9/20 14:31
|
||||||
|
******************************/
|
||||||
|
public class PropertiesUtils {
|
||||||
|
public final static String RESOURCE_PATH = "application.properties";
|
||||||
|
|
||||||
|
public final static Properties properties = new Properties();
|
||||||
|
|
||||||
|
public static String getPropertyField(String parameter) {
|
||||||
|
//对应resources目录下的资源路径
|
||||||
|
ClassPathResource resource = new ClassPathResource(RESOURCE_PATH);
|
||||||
|
try {
|
||||||
|
properties.load(new InputStreamReader(resource.getInputStream(), "gbk"));
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
return properties.getProperty(parameter);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019-2020 Zheng Jie
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.yfd.platform.common.utils;
|
||||||
|
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import org.springframework.web.context.request.RequestContextHolder;
|
||||||
|
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取 HttpServletRequest
|
||||||
|
* @author
|
||||||
|
* @date 2018-11-24
|
||||||
|
*/
|
||||||
|
public class RequestHolder {
|
||||||
|
|
||||||
|
public static HttpServletRequest getHttpServletRequest() {
|
||||||
|
return ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,190 @@
|
|||||||
|
package com.yfd.platform.common.utils;
|
||||||
|
|
||||||
|
import org.apache.commons.codec.binary.Base64;
|
||||||
|
|
||||||
|
import javax.crypto.Cipher;
|
||||||
|
import java.security.*;
|
||||||
|
import java.security.interfaces.RSAPrivateKey;
|
||||||
|
import java.security.interfaces.RSAPublicKey;
|
||||||
|
import java.security.spec.PKCS8EncodedKeySpec;
|
||||||
|
import java.security.spec.X509EncodedKeySpec;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author https://www.cnblogs.com/nihaorz/p/10690643.html
|
||||||
|
* @description Rsa 工具类,公钥私钥生成,加解密
|
||||||
|
* @date 2020-05-18
|
||||||
|
**/
|
||||||
|
public class RsaUtils {
|
||||||
|
|
||||||
|
private static final String SRC = "123456";
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
System.out.println("\n");
|
||||||
|
// RsaKeyPair keyPair = generateKeyPair();
|
||||||
|
String publicKey = "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANL378k3RiZHWx5AfJqdH9xRNBmD9wGD2iRe41HdTNF8RUhNnHit5NpMNtGL0NPTSSpPjjI1kJfVorRvaQerUgkCAwEAAQ==";
|
||||||
|
String privateKey = "MIIBUwIBADANBgkqhkiG9w0BAQEFAASCAT0wggE5AgEAAkEA0vfvyTdGJkdbHkB8\n" +
|
||||||
|
"mp0f3FE0GYP3AYPaJF7jUd1M0XxFSE2ceK3k2kw20YvQ09NJKk+OMjWQl9WitG9p\n" +
|
||||||
|
"B6tSCQIDAQABAkA2SimBrWC2/wvauBuYqjCFwLvYiRYqZKThUS3MZlebXJiLB+Ue\n" +
|
||||||
|
"/gUifAAKIg1avttUZsHBHrop4qfJCwAI0+YRAiEA+W3NK/RaXtnRqmoUUkb59zsZ\n" +
|
||||||
|
"UBLpvZgQPfj1MhyHDz0CIQDYhsAhPJ3mgS64NbUZmGWuuNKp5coY2GIj/zYDMJp6\n" +
|
||||||
|
"vQIgUueLFXv/eZ1ekgz2Oi67MNCk5jeTF2BurZqNLR3MSmUCIFT3Q6uHMtsB9Eha\n" +
|
||||||
|
"4u7hS31tj1UWE+D+ADzp59MGnoftAiBeHT7gDMuqeJHPL4b+kC+gzV4FGTfhR9q3\n" +
|
||||||
|
"tTbklZkD2A==";
|
||||||
|
RsaKeyPair keyPair =new RsaKeyPair(publicKey, privateKey);
|
||||||
|
System.out.println("私钥:" + keyPair.getPrivateKey());
|
||||||
|
System.out.println("\n");
|
||||||
|
test1(keyPair);
|
||||||
|
System.out.println("\n");
|
||||||
|
// test2(keyPair);
|
||||||
|
System.out.println("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 公钥加密私钥解密
|
||||||
|
*/
|
||||||
|
private static void test1(RsaKeyPair keyPair) throws Exception {
|
||||||
|
System.out.println("***************** 公钥加密私钥解密开始 *****************");
|
||||||
|
String text1 = encryptByPublicKey(keyPair.getPublicKey(), RsaUtils.SRC);
|
||||||
|
String text2 = decryptByPrivateKey(keyPair.getPrivateKey(), text1);
|
||||||
|
System.out.println("加密前:" + RsaUtils.SRC);
|
||||||
|
System.out.println("加密后:" + text1);
|
||||||
|
System.out.println("解密后:" + text2);
|
||||||
|
if (RsaUtils.SRC.equals(text2)) {
|
||||||
|
System.out.println("解密字符串和原始字符串一致,解密成功");
|
||||||
|
} else {
|
||||||
|
System.out.println("解密字符串和原始字符串不一致,解密失败");
|
||||||
|
}
|
||||||
|
System.out.println("***************** 公钥加密私钥解密结束 *****************");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 私钥加密公钥解密
|
||||||
|
* @throws Exception /
|
||||||
|
*/
|
||||||
|
private static void test2(RsaKeyPair keyPair) throws Exception {
|
||||||
|
System.out.println("***************** 私钥加密公钥解密开始 *****************");
|
||||||
|
String text1 = encryptByPrivateKey(keyPair.getPrivateKey(), RsaUtils.SRC);
|
||||||
|
String text2 = decryptByPublicKey(keyPair.getPublicKey(), text1);
|
||||||
|
System.out.println("加密前:" + RsaUtils.SRC);
|
||||||
|
System.out.println("加密后:" + text1);
|
||||||
|
System.out.println("解密后:" + text2);
|
||||||
|
if (RsaUtils.SRC.equals(text2)) {
|
||||||
|
System.out.println("解密字符串和原始字符串一致,解密成功");
|
||||||
|
} else {
|
||||||
|
System.out.println("解密字符串和原始字符串不一致,解密失败");
|
||||||
|
}
|
||||||
|
System.out.println("***************** 私钥加密公钥解密结束 *****************");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 公钥解密
|
||||||
|
*
|
||||||
|
* @param publicKeyText 公钥
|
||||||
|
* @param text 待解密的信息
|
||||||
|
* @return /
|
||||||
|
* @throws Exception /
|
||||||
|
*/
|
||||||
|
public static String decryptByPublicKey(String publicKeyText, String text) throws Exception {
|
||||||
|
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(Base64.decodeBase64(publicKeyText));
|
||||||
|
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
|
||||||
|
PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
|
||||||
|
Cipher cipher = Cipher.getInstance("RSA");
|
||||||
|
cipher.init(Cipher.DECRYPT_MODE, publicKey);
|
||||||
|
byte[] result = cipher.doFinal(Base64.decodeBase64(text));
|
||||||
|
return new String(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 私钥加密
|
||||||
|
*
|
||||||
|
* @param privateKeyText 私钥
|
||||||
|
* @param text 待加密的信息
|
||||||
|
* @return /
|
||||||
|
* @throws Exception /
|
||||||
|
*/
|
||||||
|
public static String encryptByPrivateKey(String privateKeyText, String text) throws Exception {
|
||||||
|
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKeyText));
|
||||||
|
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
|
||||||
|
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
|
||||||
|
Cipher cipher = Cipher.getInstance("RSA");
|
||||||
|
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
|
||||||
|
byte[] result = cipher.doFinal(text.getBytes());
|
||||||
|
return Base64.encodeBase64String(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 私钥解密
|
||||||
|
*
|
||||||
|
* @param privateKeyText 私钥
|
||||||
|
* @param text 待解密的文本
|
||||||
|
* @return /
|
||||||
|
* @throws Exception /
|
||||||
|
*/
|
||||||
|
public static String decryptByPrivateKey(String privateKeyText, String text) throws Exception {
|
||||||
|
PKCS8EncodedKeySpec pkcs8EncodedKeySpec5 = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKeyText));
|
||||||
|
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
|
||||||
|
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec5);
|
||||||
|
Cipher cipher = Cipher.getInstance("RSA");
|
||||||
|
cipher.init(Cipher.DECRYPT_MODE, privateKey);
|
||||||
|
byte[] result = cipher.doFinal(Base64.decodeBase64(text));
|
||||||
|
return new String(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 公钥加密
|
||||||
|
*
|
||||||
|
* @param publicKeyText 公钥
|
||||||
|
* @param text 待加密的文本
|
||||||
|
* @return /
|
||||||
|
*/
|
||||||
|
public static String encryptByPublicKey(String publicKeyText, String text) throws Exception {
|
||||||
|
X509EncodedKeySpec x509EncodedKeySpec2 = new X509EncodedKeySpec(Base64.decodeBase64(publicKeyText));
|
||||||
|
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
|
||||||
|
PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec2);
|
||||||
|
Cipher cipher = Cipher.getInstance("RSA");
|
||||||
|
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
|
||||||
|
byte[] result = cipher.doFinal(text.getBytes());
|
||||||
|
return Base64.encodeBase64String(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构建RSA密钥对
|
||||||
|
*
|
||||||
|
* @return /
|
||||||
|
* @throws NoSuchAlgorithmException /
|
||||||
|
*/
|
||||||
|
public static RsaKeyPair generateKeyPair() throws NoSuchAlgorithmException {
|
||||||
|
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
|
||||||
|
keyPairGenerator.initialize(1024);
|
||||||
|
KeyPair keyPair = keyPairGenerator.generateKeyPair();
|
||||||
|
RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
|
||||||
|
RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
|
||||||
|
String publicKeyString = Base64.encodeBase64String(rsaPublicKey.getEncoded());
|
||||||
|
String privateKeyString = Base64.encodeBase64String(rsaPrivateKey.getEncoded());
|
||||||
|
return new RsaKeyPair(publicKeyString, privateKeyString);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RSA密钥对对象
|
||||||
|
*/
|
||||||
|
public static class RsaKeyPair {
|
||||||
|
|
||||||
|
private final String publicKey;
|
||||||
|
private final String privateKey;
|
||||||
|
|
||||||
|
public RsaKeyPair(String publicKey, String privateKey) {
|
||||||
|
this.publicKey = publicKey;
|
||||||
|
this.privateKey = privateKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPublicKey() {
|
||||||
|
return publicKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPrivateKey() {
|
||||||
|
return privateKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,145 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019-2020 Zheng Jie
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.yfd.platform.common.utils;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.BeansException;
|
||||||
|
import org.springframework.beans.factory.DisposableBean;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.context.ApplicationContextAware;
|
||||||
|
import org.springframework.core.env.Environment;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
/**
|
||||||
|
* @author Jie
|
||||||
|
* @date 2019-01-07
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
public class SpringContextHolder implements ApplicationContextAware, DisposableBean {
|
||||||
|
|
||||||
|
private static ApplicationContext applicationContext = null;
|
||||||
|
private static final List<CallBack> CALL_BACKS = new ArrayList<>();
|
||||||
|
private static boolean addCallback = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 针对 某些初始化方法,在SpringContextHolder 未初始化时 提交回调方法。
|
||||||
|
* 在SpringContextHolder 初始化后,进行回调使用
|
||||||
|
*
|
||||||
|
* @param callBack 回调函数
|
||||||
|
*/
|
||||||
|
public synchronized static void addCallBacks(CallBack callBack) {
|
||||||
|
if (addCallback) {
|
||||||
|
SpringContextHolder.CALL_BACKS.add(callBack);
|
||||||
|
} else {
|
||||||
|
log.warn("CallBack:{} 已无法添加!立即执行", callBack.getCallBackName());
|
||||||
|
callBack.executor();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从静态变量applicationContext中取得Bean, 自动转型为所赋值对象的类型.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public static <T> T getBean(String name) {
|
||||||
|
assertContextInjected();
|
||||||
|
return (T) applicationContext.getBean(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从静态变量applicationContext中取得Bean, 自动转型为所赋值对象的类型.
|
||||||
|
*/
|
||||||
|
public static <T> T getBean(Class<T> requiredType) {
|
||||||
|
assertContextInjected();
|
||||||
|
return applicationContext.getBean(requiredType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取SpringBoot 配置信息
|
||||||
|
*
|
||||||
|
* @param property 属性key
|
||||||
|
* @param defaultValue 默认值
|
||||||
|
* @param requiredType 返回类型
|
||||||
|
* @return /
|
||||||
|
*/
|
||||||
|
public static <T> T getProperties(String property, T defaultValue, Class<T> requiredType) {
|
||||||
|
T result = defaultValue;
|
||||||
|
try {
|
||||||
|
result = getBean(Environment.class).getProperty(property, requiredType);
|
||||||
|
} catch (Exception ignored) {}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取SpringBoot 配置信息
|
||||||
|
*
|
||||||
|
* @param property 属性key
|
||||||
|
* @return /
|
||||||
|
*/
|
||||||
|
public static String getProperties(String property) {
|
||||||
|
return getProperties(property, null, String.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取SpringBoot 配置信息
|
||||||
|
*
|
||||||
|
* @param property 属性key
|
||||||
|
* @param requiredType 返回类型
|
||||||
|
* @return /
|
||||||
|
*/
|
||||||
|
public static <T> T getProperties(String property, Class<T> requiredType) {
|
||||||
|
return getProperties(property, null, requiredType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查ApplicationContext不为空.
|
||||||
|
*/
|
||||||
|
private static void assertContextInjected() {
|
||||||
|
if (applicationContext == null) {
|
||||||
|
throw new IllegalStateException("applicaitonContext属性未注入, 请在applicationContext" +
|
||||||
|
".xml中定义SpringContextHolder或在SpringBoot启动类中注册SpringContextHolder.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清除SpringContextHolder中的ApplicationContext为Null.
|
||||||
|
*/
|
||||||
|
private static void clearHolder() {
|
||||||
|
log.debug("清除SpringContextHolder中的ApplicationContext:"
|
||||||
|
+ applicationContext);
|
||||||
|
applicationContext = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void destroy() {
|
||||||
|
SpringContextHolder.clearHolder();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||||
|
if (SpringContextHolder.applicationContext != null) {
|
||||||
|
log.warn("SpringContextHolder中的ApplicationContext被覆盖, 原有ApplicationContext为:" + SpringContextHolder.applicationContext);
|
||||||
|
}
|
||||||
|
SpringContextHolder.applicationContext = applicationContext;
|
||||||
|
if (addCallback) {
|
||||||
|
for (CallBack callBack : SpringContextHolder.CALL_BACKS) {
|
||||||
|
callBack.executor();
|
||||||
|
}
|
||||||
|
CALL_BACKS.clear();
|
||||||
|
}
|
||||||
|
SpringContextHolder.addCallback = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,306 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019-2020 Zheng Jie
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.yfd.platform.common.utils;
|
||||||
|
|
||||||
|
|
||||||
|
import cn.hutool.http.HttpUtil;
|
||||||
|
import cn.hutool.json.JSONObject;
|
||||||
|
import cn.hutool.json.JSONUtil;
|
||||||
|
import com.yfd.platform.constant.Constant;
|
||||||
|
import eu.bitwalker.useragentutils.Browser;
|
||||||
|
import eu.bitwalker.useragentutils.UserAgent;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import lombok.SneakyThrows;
|
||||||
|
import org.lionsoul.ip2region.DataBlock;
|
||||||
|
import org.lionsoul.ip2region.DbConfig;
|
||||||
|
import org.lionsoul.ip2region.DbSearcher;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.core.io.ClassPathResource;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.net.NetworkInterface;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.Enumeration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author
|
||||||
|
* 字符串工具类, 继承org.apache.commons.lang3.StringUtils类
|
||||||
|
*/
|
||||||
|
public class StringUtils extends org.apache.commons.lang3.StringUtils {
|
||||||
|
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(StringUtils.class);
|
||||||
|
private static boolean ipLocal = false;
|
||||||
|
private static File file ;
|
||||||
|
private static DbConfig config;
|
||||||
|
private static final char SEPARATOR = '_';
|
||||||
|
private static final String UNKNOWN = "unknown";
|
||||||
|
|
||||||
|
static {
|
||||||
|
SpringContextHolder.addCallBacks(() -> {
|
||||||
|
StringUtils.ipLocal = SpringContextHolder.getProperties("ip.local-parsing", false, Boolean.class);
|
||||||
|
if (ipLocal) {
|
||||||
|
/*
|
||||||
|
* 此文件为独享 ,不必关闭
|
||||||
|
*/
|
||||||
|
String path = "ip2region/ip2region.db";
|
||||||
|
String name = "ip2region.db";
|
||||||
|
try {
|
||||||
|
config = new DbConfig();
|
||||||
|
file = FileUtil.inputStreamToFile(new ClassPathResource(path).getInputStream(), name);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 驼峰命名法工具
|
||||||
|
*
|
||||||
|
* @return toCamelCase(" hello_world ") == "helloWorld"
|
||||||
|
* toCapitalizeCamelCase("hello_world") == "HelloWorld"
|
||||||
|
* toUnderScoreCase("helloWorld") = "hello_world"
|
||||||
|
*/
|
||||||
|
public static String toCamelCase(String s) {
|
||||||
|
if (s == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
s = s.toLowerCase();
|
||||||
|
|
||||||
|
StringBuilder sb = new StringBuilder(s.length());
|
||||||
|
boolean upperCase = false;
|
||||||
|
for (int i = 0; i < s.length(); i++) {
|
||||||
|
char c = s.charAt(i);
|
||||||
|
|
||||||
|
if (c == SEPARATOR) {
|
||||||
|
upperCase = true;
|
||||||
|
} else if (upperCase) {
|
||||||
|
sb.append(Character.toUpperCase(c));
|
||||||
|
upperCase = false;
|
||||||
|
} else {
|
||||||
|
sb.append(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 驼峰命名法工具
|
||||||
|
*
|
||||||
|
* @return toCamelCase(" hello_world ") == "helloWorld"
|
||||||
|
* toCapitalizeCamelCase("hello_world") == "HelloWorld"
|
||||||
|
* toUnderScoreCase("helloWorld") = "hello_world"
|
||||||
|
*/
|
||||||
|
public static String toCapitalizeCamelCase(String s) {
|
||||||
|
if (s == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
s = toCamelCase(s);
|
||||||
|
return s.substring(0, 1).toUpperCase() + s.substring(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 驼峰命名法工具
|
||||||
|
*
|
||||||
|
* @return toCamelCase(" hello_world ") == "helloWorld"
|
||||||
|
* toCapitalizeCamelCase("hello_world") == "HelloWorld"
|
||||||
|
* toUnderScoreCase("helloWorld") = "hello_world"
|
||||||
|
*/
|
||||||
|
static String toUnderScoreCase(String s) {
|
||||||
|
if (s == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
boolean upperCase = false;
|
||||||
|
for (int i = 0; i < s.length(); i++) {
|
||||||
|
char c = s.charAt(i);
|
||||||
|
|
||||||
|
boolean nextUpperCase = true;
|
||||||
|
|
||||||
|
if (i < (s.length() - 1)) {
|
||||||
|
nextUpperCase = Character.isUpperCase(s.charAt(i + 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((i > 0) && Character.isUpperCase(c)) {
|
||||||
|
if (!upperCase || !nextUpperCase) {
|
||||||
|
sb.append(SEPARATOR);
|
||||||
|
}
|
||||||
|
upperCase = true;
|
||||||
|
} else {
|
||||||
|
upperCase = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
sb.append(Character.toLowerCase(c));
|
||||||
|
}
|
||||||
|
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取ip地址
|
||||||
|
*/
|
||||||
|
public static String getIp(HttpServletRequest request) {
|
||||||
|
String ip = request.getHeader("x-forwarded-for");
|
||||||
|
if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
|
||||||
|
ip = request.getHeader("Proxy-Client-IP");
|
||||||
|
}
|
||||||
|
if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
|
||||||
|
ip = request.getHeader("WL-Proxy-Client-IP");
|
||||||
|
}
|
||||||
|
if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
|
||||||
|
ip = request.getRemoteAddr();
|
||||||
|
}
|
||||||
|
String comma = ",";
|
||||||
|
String localhost = "127.0.0.1";
|
||||||
|
if (ip.contains(comma)) {
|
||||||
|
ip = ip.split(",")[0];
|
||||||
|
}
|
||||||
|
if (localhost.equals(ip)) {
|
||||||
|
// 获取本机真正的ip地址
|
||||||
|
try {
|
||||||
|
ip = InetAddress.getLocalHost().getHostAddress();
|
||||||
|
} catch (UnknownHostException e) {
|
||||||
|
log.error(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ip;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据ip获取详细地址
|
||||||
|
*/
|
||||||
|
@SneakyThrows
|
||||||
|
public static String getCityInfo(String ip) {
|
||||||
|
if (ipLocal) {
|
||||||
|
return getLocalCityInfo(ip);
|
||||||
|
} else {
|
||||||
|
return getHttpCityInfo(ip);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据ip获取详细地址
|
||||||
|
*/
|
||||||
|
public static String getHttpCityInfo(String ip) {
|
||||||
|
String host = "202.108.22.5";
|
||||||
|
//超时应该在3钞以上
|
||||||
|
int timeOut = 3000;
|
||||||
|
boolean status = false;
|
||||||
|
try {
|
||||||
|
status = InetAddress.getByName(host).isReachable(timeOut);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
String api ="";
|
||||||
|
if (status){
|
||||||
|
api = HttpUtil.get(String.format(Constant.Url.IP_URL, ip));
|
||||||
|
}else {
|
||||||
|
api = "{\"ip\":\"127.0.0.1\",\"pro\":\"\",\"proCode\":\"999999\",\"city\":\"\",\"cityCode\":\"0\",\"region\":\"\",\"regionCode\":\"0\",\"addr\":\" 局域网\",\"regionNames\":\"\",\"err\":\"noprovince\"}";
|
||||||
|
}
|
||||||
|
JSONObject object = JSONUtil.parseObj(api);
|
||||||
|
return object.get("addr", String.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据ip获取详细地址
|
||||||
|
*/
|
||||||
|
public static String getLocalCityInfo(String ip) {
|
||||||
|
try {
|
||||||
|
DataBlock dataBlock = new DbSearcher(config, file.getPath())
|
||||||
|
.binarySearch(ip);
|
||||||
|
String region = dataBlock.getRegion();
|
||||||
|
String address = region.replace("0|", "");
|
||||||
|
char symbol = '|';
|
||||||
|
if (address.charAt(address.length() - 1) == symbol) {
|
||||||
|
address = address.substring(0, address.length() - 1);
|
||||||
|
}
|
||||||
|
return address.equals(Constant.REGION) ? "内网IP" : address;
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getBrowser(HttpServletRequest request) {
|
||||||
|
UserAgent userAgent = UserAgent.parseUserAgentString(request.getHeader("User-Agent"));
|
||||||
|
Browser browser = userAgent.getBrowser();
|
||||||
|
return browser.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得当天是周几
|
||||||
|
*/
|
||||||
|
public static String getWeekDay() {
|
||||||
|
String[] weekDays = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
|
||||||
|
Calendar cal = Calendar.getInstance();
|
||||||
|
cal.setTime(new Date());
|
||||||
|
|
||||||
|
int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
|
||||||
|
if (w < 0) {
|
||||||
|
w = 0;
|
||||||
|
}
|
||||||
|
return weekDays[w];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取当前机器的IP
|
||||||
|
*
|
||||||
|
* @return /
|
||||||
|
*/
|
||||||
|
public static String getLocalIp() {
|
||||||
|
try {
|
||||||
|
InetAddress candidateAddress = null;
|
||||||
|
// 遍历所有的网络接口
|
||||||
|
for (Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces(); interfaces.hasMoreElements();) {
|
||||||
|
NetworkInterface anInterface = interfaces.nextElement();
|
||||||
|
// 在所有的接口下再遍历IP
|
||||||
|
for (Enumeration<InetAddress> inetAddresses = anInterface.getInetAddresses(); inetAddresses.hasMoreElements();) {
|
||||||
|
InetAddress inetAddr = inetAddresses.nextElement();
|
||||||
|
// 排除loopback类型地址
|
||||||
|
if (!inetAddr.isLoopbackAddress()) {
|
||||||
|
if (inetAddr.isSiteLocalAddress()) {
|
||||||
|
// 如果是site-local地址,就是它了
|
||||||
|
return inetAddr.getHostAddress();
|
||||||
|
} else if (candidateAddress == null) {
|
||||||
|
// site-local类型的地址未被发现,先记录候选地址
|
||||||
|
candidateAddress = inetAddr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (candidateAddress != null) {
|
||||||
|
return candidateAddress.getHostAddress();
|
||||||
|
}
|
||||||
|
// 如果没有发现 non-loopback地址.只能用最次选的方案
|
||||||
|
InetAddress jdkSuppliedAddress = InetAddress.getLocalHost();
|
||||||
|
if (jdkSuppliedAddress == null) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return jdkSuppliedAddress.getHostAddress();
|
||||||
|
} catch (Exception e) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -13,7 +13,7 @@ public class Constant {
|
|||||||
public static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
|
public static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
|
||||||
|
|
||||||
public static final String CODE_KEY = "code-key-";
|
public static final String CODE_KEY = "code-key-";
|
||||||
public static final long CODE_EXPIRATION_TIME = 1000 * 60 * 2;
|
public static final long CODE_EXPIRATION_TIME = 1000 * 60;
|
||||||
/**
|
/**
|
||||||
* 用于IP定位转换
|
* 用于IP定位转换
|
||||||
*/
|
*/
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.yfd.platform.exception;
|
package com.yfd.platform.system.exception;
|
||||||
|
|
||||||
import cn.hutool.json.JSONObject;
|
import cn.hutool.json.JSONObject;
|
||||||
import cn.hutool.json.JSONUtil;
|
import cn.hutool.json.JSONUtil;
|
||||||
@ -1,16 +1,13 @@
|
|||||||
package com.yfd.platform.exception;
|
package com.yfd.platform.system.exception;
|
||||||
|
|
||||||
import cn.hutool.json.JSONObject;
|
import cn.hutool.json.JSONObject;
|
||||||
import cn.hutool.json.JSONUtil;
|
import cn.hutool.json.JSONUtil;
|
||||||
import com.yfd.platform.config.ResponseResult;
|
|
||||||
import org.springframework.http.HttpStatus;
|
|
||||||
import org.springframework.http.ResponseEntity;
|
|
||||||
import org.springframework.security.web.AuthenticationEntryPoint;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import jakarta.servlet.ServletException;
|
import jakarta.servlet.ServletException;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
import org.springframework.security.web.AuthenticationEntryPoint;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@Component
|
@Component
|
||||||
public class AuthenticationException implements AuthenticationEntryPoint {
|
public class AuthenticationException implements AuthenticationEntryPoint {
|
||||||
@ -13,7 +13,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package com.yfd.platform.exception;
|
package com.yfd.platform.system.exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 统一关于错误配置信息 异常
|
* 统一关于错误配置信息 异常
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.yfd.platform.exception;
|
package com.yfd.platform.system.exception;
|
||||||
|
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
@ -13,7 +13,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package com.yfd.platform.exception;
|
package com.yfd.platform.system.exception;
|
||||||
|
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
@ -13,7 +13,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package com.yfd.platform.exception;
|
package com.yfd.platform.system.exception;
|
||||||
|
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
134
backend/platform-system/pom.xml
Normal file
134
backend/platform-system/pom.xml
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
<?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>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>com.yfd</groupId>
|
||||||
|
<artifactId>platform</artifactId>
|
||||||
|
<version>1.0</version>
|
||||||
|
<relativePath>../pom.xml</relativePath>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<artifactId>platform-system</artifactId>
|
||||||
|
<version>1.0</version>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<name>Platform System</name>
|
||||||
|
<description>Platform System Module</description>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<!-- Common Module -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.yfd</groupId>
|
||||||
|
<artifactId>platform-common</artifactId>
|
||||||
|
<version>1.0</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Spring Boot Starter -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Spring Boot Web -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Spring Boot WebSocket -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-websocket</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- MyBatis Plus -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.baomidou</groupId>
|
||||||
|
<artifactId>mybatis-plus-spring-boot4-starter</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Spring Security -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-security</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- AspectJ -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.aspectj</groupId>
|
||||||
|
<artifactId>aspectjweaver</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Druid -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba</groupId>
|
||||||
|
<artifactId>druid</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Easy Captcha -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.whvcse</groupId>
|
||||||
|
<artifactId>easy-captcha</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.openjdk.nashorn</groupId>
|
||||||
|
<artifactId>nashorn-core</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<!-- SpringDoc OpenAPI -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springdoc</groupId>
|
||||||
|
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Lombok -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.baomidou</groupId>
|
||||||
|
<artifactId>mybatis-plus-jsqlparser</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba.fastjson2</groupId>
|
||||||
|
<artifactId>fastjson2</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Oracle JDBC Driver -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.oracle.database.jdbc</groupId>
|
||||||
|
<artifactId>ojdbc8</artifactId>
|
||||||
|
<scope>runtime</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.oracle.database.nls</groupId>
|
||||||
|
<artifactId>orai18n</artifactId>
|
||||||
|
<scope>runtime</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<!-- <build>-->
|
||||||
|
<!-- <plugins>-->
|
||||||
|
<!-- <plugin>-->
|
||||||
|
<!-- <groupId>org.springframework.boot</groupId>-->
|
||||||
|
<!-- <artifactId>spring-boot-maven-plugin</artifactId>-->
|
||||||
|
<!-- <configuration>-->
|
||||||
|
<!-- <mainClass>com.yfd.platform.system.PlatformApplication</mainClass>-->
|
||||||
|
<!-- </configuration>-->
|
||||||
|
<!-- </plugin>-->
|
||||||
|
<!-- </plugins>-->
|
||||||
|
<!-- </build>-->
|
||||||
|
|
||||||
|
</project>
|
||||||
@ -16,7 +16,6 @@
|
|||||||
package com.yfd.platform.aspect;
|
package com.yfd.platform.aspect;
|
||||||
|
|
||||||
import com.yfd.platform.system.domain.SysLog;
|
import com.yfd.platform.system.domain.SysLog;
|
||||||
import com.yfd.platform.system.mapper.SysUserMapper;
|
|
||||||
import com.yfd.platform.system.service.ISysLogService;
|
import com.yfd.platform.system.service.ISysLogService;
|
||||||
import com.yfd.platform.system.service.IUserService;
|
import com.yfd.platform.system.service.IUserService;
|
||||||
import com.yfd.platform.utils.RequestHolder;
|
import com.yfd.platform.utils.RequestHolder;
|
||||||
@ -15,14 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package com.yfd.platform.config;
|
package com.yfd.platform.config;
|
||||||
|
|
||||||
import cn.hutool.core.date.DateField;
|
|
||||||
import cn.hutool.core.date.DateUtil;
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.yfd.platform.qgc_env.wq.entity.ao.JobBaseAo;
|
|
||||||
import com.yfd.platform.qgc_env.wq.service.EnvWqDataService;
|
|
||||||
import com.yfd.platform.qgc_job.service.IDwJobService;
|
|
||||||
import com.yfd.platform.qgc_job.service.IEqJobService;
|
|
||||||
import com.yfd.platform.qgc_job.service.IFhJobService;
|
|
||||||
import com.yfd.platform.system.domain.QuartzJob;
|
import com.yfd.platform.system.domain.QuartzJob;
|
||||||
import com.yfd.platform.system.mapper.QuartzJobMapper;
|
import com.yfd.platform.system.mapper.QuartzJobMapper;
|
||||||
import com.yfd.platform.utils.QuartzManage;
|
import com.yfd.platform.utils.QuartzManage;
|
||||||
@ -49,10 +42,6 @@ public class JobRunner implements ApplicationRunner {
|
|||||||
private static final Logger log = LoggerFactory.getLogger(JobRunner.class);
|
private static final Logger log = LoggerFactory.getLogger(JobRunner.class);
|
||||||
private final QuartzJobMapper quartzJobMapper;
|
private final QuartzJobMapper quartzJobMapper;
|
||||||
private final QuartzManage quartzManage;
|
private final QuartzManage quartzManage;
|
||||||
private final EnvWqDataService envWqDataService;
|
|
||||||
private final IEqJobService eqJobService;
|
|
||||||
private final IDwJobService dwJobService;
|
|
||||||
private final IFhJobService fhJobService;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 项目启动时重新激活启用的定时任务
|
* 项目启动时重新激活启用的定时任务
|
||||||
@ -66,25 +55,5 @@ public class JobRunner implements ApplicationRunner {
|
|||||||
quartzJobMapper.selectList(new LambdaQueryWrapper<QuartzJob>().eq(QuartzJob::getStatus, "1"));
|
quartzJobMapper.selectList(new LambdaQueryWrapper<QuartzJob>().eq(QuartzJob::getStatus, "1"));
|
||||||
quartzJobs.forEach(quartzManage::addJob);
|
quartzJobs.forEach(quartzManage::addJob);
|
||||||
log.info("--------------------定时任务注入完成---------------------");
|
log.info("--------------------定时任务注入完成---------------------");
|
||||||
JobBaseAo ao = new JobBaseAo();
|
|
||||||
//如果没有传递时间,则默认为上个月的开始到现在
|
|
||||||
if (null == ao.getEndTime()){
|
|
||||||
ao.setEndTime(DateUtil.date());
|
|
||||||
}
|
|
||||||
if (null == ao.getStartTime()){
|
|
||||||
ao.setStartTime(DateUtil.beginOfYear(DateUtil.offset(ao.getEndTime(), DateField.YEAR,-1)));
|
|
||||||
}
|
|
||||||
envWqDataService.wqLastData(ao);
|
|
||||||
log.info("--------------------wq最新一条数据---------------------");
|
|
||||||
eqJobService.eqAnchorPointLastDate(ao);
|
|
||||||
log.info("--------------------eq最新一条数据---------------------");
|
|
||||||
eqJobService.eqAnchorPointLastDate(ao);
|
|
||||||
log.info("--------------------eq最新一条数据---------------------");
|
|
||||||
dwJobService.wtLastData(ao);
|
|
||||||
log.info("--------------------wt最新一条数据---------------------");
|
|
||||||
dwJobService.wtvtPointData(ao);
|
|
||||||
log.info("--------------------wt最新一条数据---------------------");
|
|
||||||
fhJobService.zqLastData(ao);
|
|
||||||
log.info("--------------------fh最新一条数据---------------------");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2,23 +2,18 @@ package com.yfd.platform.config;
|
|||||||
|
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import cn.hutool.json.JSONUtil;
|
||||||
import cn.hutool.jwt.JWT;
|
import cn.hutool.jwt.JWT;
|
||||||
import cn.hutool.jwt.JWTUtil;
|
import cn.hutool.jwt.JWTUtil;
|
||||||
import com.alibaba.fastjson.JSON;
|
//import com.alibaba.fastjson.JSON;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
||||||
import com.yfd.platform.component.ServerSendEventServer;
|
|
||||||
import com.yfd.platform.constant.Constant;
|
import com.yfd.platform.constant.Constant;
|
||||||
import com.yfd.platform.system.domain.LoginUser;
|
import com.yfd.platform.system.domain.LoginUser;
|
||||||
import com.yfd.platform.system.domain.Message;
|
|
||||||
import com.yfd.platform.system.service.IMessageService;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||||
import org.springframework.security.core.context.SecurityContextHolder;
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.web.filter.OncePerRequestFilter;
|
import org.springframework.web.filter.OncePerRequestFilter;
|
||||||
|
|
||||||
import jakarta.annotation.Resource;
|
|
||||||
import jakarta.servlet.FilterChain;
|
import jakarta.servlet.FilterChain;
|
||||||
import jakarta.servlet.ServletException;
|
import jakarta.servlet.ServletException;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
@ -26,7 +21,6 @@ import jakarta.servlet.http.HttpServletResponse;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
@Slf4j
|
|
||||||
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
|
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
@ -38,9 +32,6 @@ public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
|
|||||||
FilterChain filterChain) throws ServletException, IOException {
|
FilterChain filterChain) throws ServletException, IOException {
|
||||||
//获取token
|
//获取token
|
||||||
String uri = httpServletRequest.getRequestURI();
|
String uri = httpServletRequest.getRequestURI();
|
||||||
if(uri.contains("/data/fishDraft/importZip")){
|
|
||||||
log.info("请求地址:{}", uri);
|
|
||||||
}
|
|
||||||
String token = httpServletRequest.getHeader("token");
|
String token = httpServletRequest.getHeader("token");
|
||||||
if (StrUtil.isEmpty(token) || "/user/login".equals(uri)) {
|
if (StrUtil.isEmpty(token) || "/user/login".equals(uri)) {
|
||||||
filterChain.doFilter(httpServletRequest, httpServletResponse);
|
filterChain.doFilter(httpServletRequest, httpServletResponse);
|
||||||
@ -66,7 +57,7 @@ public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
|
|||||||
//从cachekey中获取用户信息
|
//从cachekey中获取用户信息
|
||||||
String cachekey = "login:" + userid;
|
String cachekey = "login:" + userid;
|
||||||
String jsonstr = webConfig.loginuserCache().get(cachekey);
|
String jsonstr = webConfig.loginuserCache().get(cachekey);
|
||||||
LoginUser loginUser = JSON.parseObject(jsonstr, LoginUser.class);
|
LoginUser loginUser = JSONUtil.toBean(jsonstr, LoginUser.class);
|
||||||
if (ObjectUtil.isEmpty(loginUser)) {
|
if (ObjectUtil.isEmpty(loginUser)) {
|
||||||
httpServletResponse.sendError(HttpServletResponse.SC_FORBIDDEN,
|
httpServletResponse.sendError(HttpServletResponse.SC_FORBIDDEN,
|
||||||
"登录用户已失效!");
|
"登录用户已失效!");
|
||||||
@ -1,20 +1,14 @@
|
|||||||
package com.yfd.platform.config;
|
package com.yfd.platform.config;
|
||||||
|
|
||||||
import cn.hutool.cache.Cache;
|
|
||||||
import cn.hutool.cache.impl.CacheObj;
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.yfd.platform.component.ServerSendEventServer;
|
import com.yfd.platform.component.ServerSendEventServer;
|
||||||
import com.yfd.platform.constant.Constant;
|
import com.yfd.platform.constant.Constant;
|
||||||
import com.yfd.platform.system.domain.Message;
|
import com.yfd.platform.system.domain.Message;
|
||||||
import com.yfd.platform.system.domain.SysUser;
|
|
||||||
import com.yfd.platform.system.service.IMessageService;
|
import com.yfd.platform.system.service.IMessageService;
|
||||||
import com.yfd.platform.system.service.IUserService;
|
import com.yfd.platform.system.service.IUserService;
|
||||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
|
||||||
import org.springframework.security.core.context.SecurityContextHolder;
|
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import java.util.Iterator;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author TangWei
|
* @author TangWei
|
||||||
@ -28,9 +28,7 @@ public class MybitsPlusConfig {
|
|||||||
public MybatisPlusInterceptor mybatisPlusInterceptor() {
|
public MybatisPlusInterceptor mybatisPlusInterceptor() {
|
||||||
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
|
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
|
||||||
// 添加分页拦截器,指定数据库类型为 Oracle
|
// 添加分页拦截器,指定数据库类型为 Oracle
|
||||||
// interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.ORACLE));
|
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.ORACLE));
|
||||||
// 添加分页拦截器,指定数据库类型为 Oracle
|
|
||||||
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.DM));
|
|
||||||
return interceptor;
|
return interceptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -0,0 +1,44 @@
|
|||||||
|
package com.yfd.platform.config;
|
||||||
|
|
||||||
|
import jakarta.servlet.Filter;
|
||||||
|
import jakarta.servlet.FilterChain;
|
||||||
|
import jakarta.servlet.RequestDispatcher;
|
||||||
|
import jakarta.servlet.ServletException;
|
||||||
|
import jakarta.servlet.ServletRequest;
|
||||||
|
import jakarta.servlet.ServletResponse;
|
||||||
|
import jakarta.servlet.annotation.WebFilter;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将以 /prod-api/ 开头的请求转发到去掉前缀的真实后端接口路径。
|
||||||
|
* 例如:/prod-api/user/code -> /user/code
|
||||||
|
* 这样可以兼容前端生产环境仍使用 /prod-api 作为网关前缀的情况。
|
||||||
|
*/
|
||||||
|
@WebFilter(urlPatterns = "/prod-api/*", filterName = "prodApiPrefixFilter")
|
||||||
|
public class ProdApiPrefixFilter implements Filter {
|
||||||
|
|
||||||
|
private static final String PREFIX = "/prod-api";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
|
||||||
|
if (!(req instanceof HttpServletRequest) || !(res instanceof HttpServletResponse)) {
|
||||||
|
chain.doFilter(req, res);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
HttpServletRequest request = (HttpServletRequest) req;
|
||||||
|
String uri = request.getRequestURI();
|
||||||
|
|
||||||
|
// 仅拦截 /prod-api/* 的接口请求并进行内部 forward
|
||||||
|
if (uri.startsWith(PREFIX + "/")) {
|
||||||
|
String forwardUri = uri.substring(PREFIX.length());
|
||||||
|
RequestDispatcher dispatcher = request.getRequestDispatcher(forwardUri);
|
||||||
|
dispatcher.forward(req, res);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
chain.doFilter(req, res);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,8 +1,8 @@
|
|||||||
package com.yfd.platform.config;
|
package com.yfd.platform.config;
|
||||||
|
|
||||||
import com.yfd.platform.config.bean.LoginProperties;
|
import com.yfd.platform.config.bean.LoginProperties;
|
||||||
import com.yfd.platform.exception.AccessDeniedHandExcetion;
|
import com.yfd.platform.system.exception.AccessDeniedHandExcetion;
|
||||||
import com.yfd.platform.exception.AuthenticationException;
|
import com.yfd.platform.system.exception.AuthenticationException;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
@ -39,9 +39,6 @@ public class SecurityConfig {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter;
|
private JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter;
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private RegisterAccessTokenFilter registerAccessTokenFilter;
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private AuthenticationException authenticationException;
|
private AuthenticationException authenticationException;
|
||||||
|
|
||||||
@ -56,34 +53,6 @@ public class SecurityConfig {
|
|||||||
.authorizeHttpRequests(auth -> auth
|
.authorizeHttpRequests(auth -> auth
|
||||||
.requestMatchers("/user/login").anonymous()
|
.requestMatchers("/user/login").anonymous()
|
||||||
.requestMatchers("/user/code").permitAll()
|
.requestMatchers("/user/code").permitAll()
|
||||||
.requestMatchers("/sms/resetPassword").permitAll()
|
|
||||||
.requestMatchers("/data/fishDraft/previewFile").permitAll()
|
|
||||||
.requestMatchers("/tempFile/**").permitAll()
|
|
||||||
.requestMatchers("/system/user/auditUser").permitAll()
|
|
||||||
.requestMatchers("/register/accessToken").permitAll()
|
|
||||||
.requestMatchers("/eng/**").permitAll()
|
|
||||||
.requestMatchers("/eq/**").permitAll()
|
|
||||||
.requestMatchers("/env/**").permitAll()
|
|
||||||
.requestMatchers("/warn/**").permitAll()
|
|
||||||
.requestMatchers("/threedroamb/**").permitAll()
|
|
||||||
.requestMatchers("/overview/**").permitAll()
|
|
||||||
.requestMatchers("/wt/**").permitAll()
|
|
||||||
.requestMatchers("/fb/**").permitAll()
|
|
||||||
.requestMatchers("/zq/**").permitAll()
|
|
||||||
.requestMatchers("/wq/**").permitAll()
|
|
||||||
.requestMatchers("/wte/**").permitAll()
|
|
||||||
.requestMatchers("/vd/**").permitAll()
|
|
||||||
.requestMatchers("/vap/**").permitAll()
|
|
||||||
.requestMatchers("/fp/**").permitAll()
|
|
||||||
.requestMatchers("/fpr/**").permitAll()
|
|
||||||
.requestMatchers("/fh/**").permitAll()
|
|
||||||
.requestMatchers("/data/**").permitAll()
|
|
||||||
.requestMatchers("/mapLayer/**").permitAll()
|
|
||||||
.requestMatchers("/mapmodule/**").permitAll()
|
|
||||||
.requestMatchers("/mapLegend/**").permitAll()
|
|
||||||
.requestMatchers("/base/msalongb/**").permitAll()
|
|
||||||
.requestMatchers("/base/msalongdetb/**").permitAll()
|
|
||||||
.requestMatchers("/sms/**").permitAll()
|
|
||||||
.requestMatchers(HttpMethod.GET, "/").permitAll()
|
.requestMatchers(HttpMethod.GET, "/").permitAll()
|
||||||
.requestMatchers(HttpMethod.GET,
|
.requestMatchers(HttpMethod.GET,
|
||||||
"/*.html",
|
"/*.html",
|
||||||
@ -109,7 +78,6 @@ public class SecurityConfig {
|
|||||||
)
|
)
|
||||||
.cors(cors -> {});
|
.cors(cors -> {});
|
||||||
|
|
||||||
http.addFilterBefore(registerAccessTokenFilter, UsernamePasswordAuthenticationFilter.class);
|
|
||||||
http.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
|
http.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
|
||||||
|
|
||||||
http.exceptionHandling(ex -> ex
|
http.exceptionHandling(ex -> ex
|
||||||
@ -0,0 +1,49 @@
|
|||||||
|
package com.yfd.platform.config;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springdoc.core.models.GroupedOpenApi;
|
||||||
|
import io.swagger.v3.oas.models.OpenAPI;
|
||||||
|
import io.swagger.v3.oas.models.info.Info;
|
||||||
|
import io.swagger.v3.oas.models.info.Contact;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Springdoc OpenAPI 配置
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
public class SwaggerConfig {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public OpenAPI projectOpenAPI() {
|
||||||
|
return new OpenAPI()
|
||||||
|
.info(new Info()
|
||||||
|
.title("项目API 接口文档")
|
||||||
|
.version("3.0")
|
||||||
|
.description("")
|
||||||
|
.contact(new Contact().name("郑顺利").email("13910913995@163.com"))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public GroupedOpenApi groupWebsiteApi() {
|
||||||
|
return GroupedOpenApi.builder()
|
||||||
|
.group("1. 平台模块")
|
||||||
|
.packagesToScan("com.yfd.platform.modules.platformdb.controller")
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public GroupedOpenApi groupQuartzApi() {
|
||||||
|
return GroupedOpenApi.builder()
|
||||||
|
.group("2. 定时任务")
|
||||||
|
.packagesToScan("com.yfd.platform.modules.quartz.controller")
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public GroupedOpenApi groupSystemApi() {
|
||||||
|
return GroupedOpenApi.builder()
|
||||||
|
.group("3. 系统管理")
|
||||||
|
.packagesToScan("com.yfd.platform.system.controller")
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -4,48 +4,24 @@ import cn.hutool.cache.Cache;
|
|||||||
import cn.hutool.cache.CacheUtil;
|
import cn.hutool.cache.CacheUtil;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
|
||||||
import org.springframework.web.cors.CorsConfiguration;
|
import org.springframework.web.cors.CorsConfiguration;
|
||||||
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
|
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
|
||||||
import org.springframework.web.filter.CorsFilter;
|
import org.springframework.web.filter.CorsFilter;
|
||||||
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
||||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||||
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
public class WebConfig implements WebMvcConfigurer {
|
public class WebConfig implements WebMvcConfigurer {
|
||||||
@Resource
|
@Resource
|
||||||
private FileSpaceProperties fileSpaceProperties;
|
private FileSpaceProperties fileSpaceProperties;
|
||||||
|
|
||||||
@Value("${app.zip-import.temp-dir}")
|
|
||||||
private String platformPath;
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private StringRedisTemplate stringRedisTemplate;
|
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public Cache<String, String> loginuserCache() {
|
public Cache<String, String> loginuserCache() {
|
||||||
return CacheUtil.newLRUCache(200);
|
return CacheUtil.newLRUCache(200);//用户登录缓存数 缺省200
|
||||||
}
|
|
||||||
|
|
||||||
public void putLoginCache(String key, String value, long timeoutSeconds) {
|
|
||||||
stringRedisTemplate.opsForValue().set(key, value, timeoutSeconds, TimeUnit.SECONDS);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void putLoginCache(String key, String value) {
|
|
||||||
stringRedisTemplate.opsForValue().set(key, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getLoginCache(String key) {
|
|
||||||
return stringRedisTemplate.opsForValue().get(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removeLoginCache(String key) {
|
|
||||||
stringRedisTemplate.delete(key);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@ -78,8 +54,7 @@ public class WebConfig implements WebMvcConfigurer {
|
|||||||
|
|
||||||
String systemUrl = "file:" + fileSpaceProperties.getSystem().replace("\\", "/")+"user\\";
|
String systemUrl = "file:" + fileSpaceProperties.getSystem().replace("\\", "/")+"user\\";
|
||||||
registry.addResourceHandler("/avatar/**").addResourceLocations(systemUrl).setCachePeriod(0);
|
registry.addResourceHandler("/avatar/**").addResourceLocations(systemUrl).setCachePeriod(0);
|
||||||
String platformUrl = "file:" + platformPath.replace("\\", "/");
|
|
||||||
registry.addResourceHandler("/tempFile/**").addResourceLocations(platformUrl).setCachePeriod(0);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -18,7 +18,7 @@ package com.yfd.platform.config.bean;
|
|||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import com.wf.captcha.*;
|
import com.wf.captcha.*;
|
||||||
import com.wf.captcha.base.Captcha;
|
import com.wf.captcha.base.Captcha;
|
||||||
import com.yfd.platform.exception.BadConfigurationException;
|
import com.yfd.platform.system.exception.BadConfigurationException;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
@ -17,7 +17,7 @@ package com.yfd.platform.config.thread;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
import com.yfd.platform.utils.SpringContextHolder;
|
import com.yfd.platform.common.utils.SpringContextHolder;
|
||||||
|
|
||||||
import java.util.concurrent.ArrayBlockingQueue;
|
import java.util.concurrent.ArrayBlockingQueue;
|
||||||
import java.util.concurrent.ThreadPoolExecutor;
|
import java.util.concurrent.ThreadPoolExecutor;
|
||||||
@ -0,0 +1,42 @@
|
|||||||
|
package com.yfd.platform.constant;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author TangWei
|
||||||
|
* @Date: 2023/3/3 17:40
|
||||||
|
* @Description: 常量类
|
||||||
|
*/
|
||||||
|
public class Constant {
|
||||||
|
|
||||||
|
public static final String LOGIN = "login:";
|
||||||
|
public static final String TOKEN = "token:";
|
||||||
|
public static final String USER_ID = "userid";
|
||||||
|
public static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
|
||||||
|
|
||||||
|
public static final String CODE_KEY = "code-key-";
|
||||||
|
public static final long CODE_EXPIRATION_TIME = 1000 * 60;
|
||||||
|
/**
|
||||||
|
* 用于IP定位转换
|
||||||
|
*/
|
||||||
|
public static final String REGION = "内网IP|内网IP";
|
||||||
|
/**
|
||||||
|
* win 系统
|
||||||
|
*/
|
||||||
|
public static final String WIN = "win";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mac 系统
|
||||||
|
*/
|
||||||
|
public static final String MAC = "mac";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 常用接口
|
||||||
|
*/
|
||||||
|
public static class Url {
|
||||||
|
|
||||||
|
// IP归属地查询
|
||||||
|
// public static final String IP_URL = "http://whois.pconline.com
|
||||||
|
// .cn/ipJson.jsp?ip=%s&json=true";
|
||||||
|
public static final String IP_URL = "http://whois.pconline.com" +
|
||||||
|
".cn/ipJson.jsp?ip=%s&json=true";
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,7 +1,6 @@
|
|||||||
package com.yfd.platform.system.controller;
|
package com.yfd.platform.system.controller;
|
||||||
|
|
||||||
import com.yfd.platform.config.ResponseResult;
|
import com.yfd.platform.common.response.ResponseResult;
|
||||||
import com.yfd.platform.datasource.DataSource;
|
|
||||||
import com.yfd.platform.datasource.DataSourceAspect;
|
import com.yfd.platform.datasource.DataSourceAspect;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
@ -5,23 +5,22 @@ import cn.hutool.core.util.ObjectUtil;
|
|||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.hutool.json.JSONUtil;
|
import cn.hutool.json.JSONUtil;
|
||||||
import cn.hutool.jwt.JWTUtil;
|
import cn.hutool.jwt.JWTUtil;
|
||||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
||||||
import com.wf.captcha.base.Captcha;
|
import com.wf.captcha.base.Captcha;
|
||||||
|
import com.yfd.platform.common.response.ResponseResult;
|
||||||
|
import com.yfd.platform.constant.Constant;
|
||||||
|
import com.yfd.platform.common.utils.RequestHolder;
|
||||||
|
import com.yfd.platform.common.utils.RsaUtils;
|
||||||
|
import com.yfd.platform.common.utils.StringUtils;
|
||||||
import com.yfd.platform.annotation.Log;
|
import com.yfd.platform.annotation.Log;
|
||||||
import com.yfd.platform.config.ResponseResult;
|
|
||||||
import com.yfd.platform.config.WebConfig;
|
import com.yfd.platform.config.WebConfig;
|
||||||
import com.yfd.platform.config.bean.LoginCodeEnum;
|
import com.yfd.platform.config.bean.LoginCodeEnum;
|
||||||
import com.yfd.platform.config.bean.LoginProperties;
|
import com.yfd.platform.config.bean.LoginProperties;
|
||||||
import com.yfd.platform.constant.Constant;
|
|
||||||
import com.yfd.platform.system.domain.LoginUser;
|
import com.yfd.platform.system.domain.LoginUser;
|
||||||
import com.yfd.platform.system.domain.SysLog;
|
import com.yfd.platform.system.domain.SysLog;
|
||||||
import com.yfd.platform.system.domain.SysUser;
|
import com.yfd.platform.system.domain.SysUser;
|
||||||
import com.yfd.platform.system.service.ISysLogService;
|
import com.yfd.platform.system.service.ISysLogService;
|
||||||
import com.yfd.platform.system.service.IUserService;
|
import com.yfd.platform.system.service.IUserService;
|
||||||
import com.yfd.platform.utils.RequestHolder;
|
|
||||||
import com.yfd.platform.utils.RsaUtils;
|
|
||||||
import com.yfd.platform.utils.StringUtils;
|
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@ -68,7 +67,7 @@ public class LoginController {
|
|||||||
@PostMapping("/login")
|
@PostMapping("/login")
|
||||||
@Operation(summary = "登录用户")
|
@Operation(summary = "登录用户")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public ResponseResult login(SysUser user, @RequestHeader(value = "Tenant_id", required = false) String tenantId) throws Exception {
|
public ResponseResult login(SysUser user) throws Exception {
|
||||||
// 密码解密
|
// 密码解密
|
||||||
String password = RsaUtils.decryptByPrivateKey(privateKey,
|
String password = RsaUtils.decryptByPrivateKey(privateKey,
|
||||||
user.getPassword());
|
user.getPassword());
|
||||||
@ -98,26 +97,9 @@ public class LoginController {
|
|||||||
}
|
}
|
||||||
LoginUser loginUser = (LoginUser) authenticate.getPrincipal();
|
LoginUser loginUser = (LoginUser) authenticate.getPrincipal();
|
||||||
Integer status = loginUser.getUser().getStatus();
|
Integer status = loginUser.getUser().getStatus();
|
||||||
String regStatus = loginUser.getUser().getRegStatus();
|
|
||||||
|
|
||||||
if (StrUtil.isNotBlank(tenantId)&&!tenantId.equals(loginUser.getUser().getTenantId())) {
|
|
||||||
return ResponseResult.error("账号不存在或密码错误");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (StrUtil.isNotBlank(regStatus)&&"REJECTED".equals(regStatus)) {
|
|
||||||
return ResponseResult.error("账号审核未通过");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (StrUtil.isNotBlank(regStatus)&&"PENDING".equals(regStatus)) {
|
|
||||||
return ResponseResult.error("账号待审核,请联系管理员");
|
|
||||||
}
|
|
||||||
|
|
||||||
if ("0".equals(status.toString())) {
|
if ("0".equals(status.toString())) {
|
||||||
return ResponseResult.error("账号已停用");
|
return ResponseResult.error("账号已停用");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
HttpServletRequest request = RequestHolder.getHttpServletRequest();
|
HttpServletRequest request = RequestHolder.getHttpServletRequest();
|
||||||
SysLog sysLog = new SysLog();
|
SysLog sysLog = new SysLog();
|
||||||
sysLog.setUsercode(user.getUsername());
|
sysLog.setUsercode(user.getUsername());
|
||||||
@ -208,7 +190,7 @@ public class LoginController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Log(module = "用户登录", value = "更改用户密码")
|
@Log(module = "用户登录", value = "更改用户密码")
|
||||||
@PostMapping("/updatePassword")
|
@GetMapping("/updatePassword")
|
||||||
@Operation(summary = "更改用户密码")
|
@Operation(summary = "更改用户密码")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public ResponseResult updatePassword(@RequestBody SysUser user) throws Exception {
|
public ResponseResult updatePassword(@RequestBody SysUser user) throws Exception {
|
||||||
@ -217,13 +199,9 @@ public class LoginController {
|
|||||||
user.getPassword());
|
user.getPassword());
|
||||||
BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
|
BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
|
||||||
String cryptPassword = passwordEncoder.encode(password);
|
String cryptPassword = passwordEncoder.encode(password);
|
||||||
// 验证新密码和旧密码是否一致
|
UpdateWrapper<SysUser> updateWrapper = new UpdateWrapper<>();
|
||||||
if (passwordEncoder.matches(password, user.getOldPassword())) {
|
updateWrapper.set("password", cryptPassword);
|
||||||
return ResponseResult.error("新密码不能与旧密码相同");
|
updateWrapper.eq("id", user.getId());
|
||||||
}
|
|
||||||
LambdaUpdateWrapper<SysUser> updateWrapper = new LambdaUpdateWrapper<>();
|
|
||||||
updateWrapper.set(SysUser::getPassword, cryptPassword);
|
|
||||||
updateWrapper.eq(SysUser::getId, user.getId());
|
|
||||||
userService.update(updateWrapper);
|
userService.update(updateWrapper);
|
||||||
return ResponseResult.success();
|
return ResponseResult.success();
|
||||||
}
|
}
|
||||||
@ -7,11 +7,9 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.yfd.platform.annotation.Log;
|
import com.yfd.platform.annotation.Log;
|
||||||
import com.yfd.platform.config.MessageConfig;
|
import com.yfd.platform.config.MessageConfig;
|
||||||
import com.yfd.platform.config.ResponseResult;
|
import com.yfd.platform.common.response.ResponseResult;
|
||||||
import com.yfd.platform.config.WebConfig;
|
|
||||||
import com.yfd.platform.system.domain.Message;
|
import com.yfd.platform.system.domain.Message;
|
||||||
import com.yfd.platform.system.service.IMessageService;
|
import com.yfd.platform.system.service.IMessageService;
|
||||||
import com.yfd.platform.system.service.IUserService;
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
@ -5,7 +5,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|||||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.yfd.platform.annotation.Log;
|
import com.yfd.platform.annotation.Log;
|
||||||
import com.yfd.platform.config.ResponseResult;
|
import com.yfd.platform.common.response.ResponseResult;
|
||||||
import com.yfd.platform.system.domain.QuartzJob;
|
import com.yfd.platform.system.domain.QuartzJob;
|
||||||
import com.yfd.platform.system.service.IQuartzJobService;
|
import com.yfd.platform.system.service.IQuartzJobService;
|
||||||
import com.yfd.platform.system.service.impl.UserServiceImpl;
|
import com.yfd.platform.system.service.impl.UserServiceImpl;
|
||||||
@ -2,11 +2,8 @@ package com.yfd.platform.system.controller;
|
|||||||
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.yfd.platform.component.ServerSendEventServer;
|
import com.yfd.platform.component.ServerSendEventServer;
|
||||||
import com.yfd.platform.config.WebConfig;
|
|
||||||
import com.yfd.platform.constant.Constant;
|
|
||||||
import com.yfd.platform.system.domain.Message;
|
import com.yfd.platform.system.domain.Message;
|
||||||
import com.yfd.platform.system.service.IMessageService;
|
import com.yfd.platform.system.service.IMessageService;
|
||||||
import com.yfd.platform.system.service.IUserService;
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
@ -3,8 +3,7 @@ package com.yfd.platform.system.controller;
|
|||||||
|
|
||||||
import cn.hutool.core.util.IdUtil;
|
import cn.hutool.core.util.IdUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.yfd.platform.common.response.ResponseResult;
|
||||||
import com.yfd.platform.config.ResponseResult;
|
|
||||||
import com.yfd.platform.system.domain.SysConfig;
|
import com.yfd.platform.system.domain.SysConfig;
|
||||||
import com.yfd.platform.system.service.ISysConfigService;
|
import com.yfd.platform.system.service.ISysConfigService;
|
||||||
import com.yfd.platform.system.service.IUserService;
|
import com.yfd.platform.system.service.IUserService;
|
||||||
@ -39,22 +38,16 @@ public class SysConfigController {
|
|||||||
@PostMapping("/getOneById")
|
@PostMapping("/getOneById")
|
||||||
@Operation(summary = "根据id查询全局配置详情记录")
|
@Operation(summary = "根据id查询全局配置详情记录")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public SysConfig getOneById(String id,
|
public SysConfig getOneById(String id){
|
||||||
@RequestHeader(value = "Tenant_id", required = false) String tenantId){
|
return configService.getById(id);
|
||||||
LambdaQueryWrapper<SysConfig> queryWrapper = new LambdaQueryWrapper<>();
|
|
||||||
queryWrapper.eq(SysConfig::getId, id)
|
|
||||||
.eq(StrUtil.isNotBlank(tenantId), SysConfig::getTenantId, StrUtil.trim(tenantId));
|
|
||||||
return configService.getOne(queryWrapper);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/addConfig")
|
@PostMapping("/addConfig")
|
||||||
@Operation(summary = "根据id查询全局配置详情记录")
|
@Operation(summary = "根据id查询全局配置详情记录")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public ResponseResult addConfig(@RequestBody SysConfig config,
|
public ResponseResult addConfig(@RequestBody SysConfig config ) throws IOException, UnsupportedAudioFileException {
|
||||||
@RequestHeader(value = "Tenant_id", required = false) String tenantId) throws IOException, UnsupportedAudioFileException {
|
|
||||||
if (StrUtil.isEmpty(config.getId())){
|
if (StrUtil.isEmpty(config.getId())){
|
||||||
config.setId(IdUtil.fastSimpleUUID()); }
|
config.setId(IdUtil.fastSimpleUUID()); }
|
||||||
config.setTenantId(StrUtil.trimToNull(tenantId));
|
|
||||||
config.setLastmodifier(userService.getUsername());
|
config.setLastmodifier(userService.getUsername());
|
||||||
config.setLastmodifydate(new Timestamp(System.currentTimeMillis()));
|
config.setLastmodifydate(new Timestamp(System.currentTimeMillis()));
|
||||||
boolean ok=configService.save(config);
|
boolean ok=configService.save(config);
|
||||||
@ -64,15 +57,7 @@ public class SysConfigController {
|
|||||||
@PostMapping("/updateById")
|
@PostMapping("/updateById")
|
||||||
@Operation(summary = "根据id修改全局配置记录")
|
@Operation(summary = "根据id修改全局配置记录")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public ResponseResult updateById(@RequestBody SysConfig config,
|
public ResponseResult updateById(@RequestBody SysConfig config) throws IOException, UnsupportedAudioFileException {
|
||||||
@RequestHeader(value = "Tenant_id", required = false) String tenantId) throws IOException, UnsupportedAudioFileException {
|
|
||||||
LambdaQueryWrapper<SysConfig> queryWrapper = new LambdaQueryWrapper<>();
|
|
||||||
queryWrapper.eq(SysConfig::getId, config.getId())
|
|
||||||
.eq(StrUtil.isNotBlank(tenantId), SysConfig::getTenantId, StrUtil.trim(tenantId));
|
|
||||||
if (configService.getOne(queryWrapper) == null) {
|
|
||||||
return ResponseResult.error("未找到对应租户的配置记录");
|
|
||||||
}
|
|
||||||
config.setTenantId(StrUtil.trimToNull(tenantId));
|
|
||||||
config.setLastmodifier(userService.getUsername());
|
config.setLastmodifier(userService.getUsername());
|
||||||
config.setLastmodifydate(new Timestamp(System.currentTimeMillis()));
|
config.setLastmodifydate(new Timestamp(System.currentTimeMillis()));
|
||||||
boolean ok=configService.updateById(config);
|
boolean ok=configService.updateById(config);
|
||||||
@ -2,20 +2,15 @@ package com.yfd.platform.system.controller;
|
|||||||
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import com.yfd.platform.annotation.Log;
|
import com.yfd.platform.annotation.Log;
|
||||||
import com.yfd.platform.config.ResponseResult;
|
import com.yfd.platform.common.response.ResponseResult;
|
||||||
import com.yfd.platform.system.domain.SysDictionary;
|
import com.yfd.platform.system.domain.SysDictionary;
|
||||||
import com.yfd.platform.system.domain.SysDictionaryItems;
|
|
||||||
import com.yfd.platform.system.mapper.SysDictionaryItemsMapper;
|
|
||||||
import com.yfd.platform.system.service.ISysDictionaryService;
|
import com.yfd.platform.system.service.ISysDictionaryService;
|
||||||
import com.yfd.platform.system.service.ISysDictionaryItemsService;
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
import org.springframework.util.StringUtils;
|
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
@ -33,9 +28,6 @@ public class SysDictionaryController {
|
|||||||
@Resource
|
@Resource
|
||||||
private ISysDictionaryService sysDictionaryService;
|
private ISysDictionaryService sysDictionaryService;
|
||||||
|
|
||||||
@Resource
|
|
||||||
private ISysDictionaryItemsService sysDictionaryItemsService;
|
|
||||||
|
|
||||||
/**********************************
|
/**********************************
|
||||||
* 用途说明: 获取数据字典列表
|
* 用途说明: 获取数据字典列表
|
||||||
* 参数说明 dictType 字典类型
|
* 参数说明 dictType 字典类型
|
||||||
@ -144,18 +136,4 @@ public class SysDictionaryController {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/getDictItemsByCode")
|
|
||||||
@Operation(summary = "根据字典编号查询字典项列表")
|
|
||||||
public ResponseResult getDictItemsByCode(@RequestParam String dictCode) {
|
|
||||||
if (StrUtil.isBlank(dictCode)) {
|
|
||||||
return ResponseResult.error("字典编号不能为空");
|
|
||||||
}
|
|
||||||
SysDictionary sysDictionary = sysDictionaryService.getByDictCode(dictCode);
|
|
||||||
if (sysDictionary == null) {
|
|
||||||
return ResponseResult.error("未找到对应的字典");
|
|
||||||
}
|
|
||||||
List<SysDictionaryItems> items = sysDictionaryItemsService.listByDictId(sysDictionary.getId());
|
|
||||||
return ResponseResult.successData(items);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -4,9 +4,8 @@ import cn.hutool.core.util.StrUtil;
|
|||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.yfd.platform.annotation.Log;
|
import com.yfd.platform.annotation.Log;
|
||||||
import com.yfd.platform.config.ResponseResult;
|
import com.yfd.platform.common.response.ResponseResult;
|
||||||
import com.yfd.platform.system.domain.SysDictionaryItems;
|
import com.yfd.platform.system.domain.SysDictionaryItems;
|
||||||
import com.yfd.platform.system.mapper.SysDictionaryItemsMapper;
|
|
||||||
import com.yfd.platform.system.service.ISysDictionaryItemsService;
|
import com.yfd.platform.system.service.ISysDictionaryItemsService;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
@ -1,9 +1,8 @@
|
|||||||
package com.yfd.platform.system.controller;
|
package com.yfd.platform.system.controller;
|
||||||
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.yfd.platform.annotation.Log;
|
import com.yfd.platform.annotation.Log;
|
||||||
import com.yfd.platform.config.ResponseResult;
|
import com.yfd.platform.common.response.ResponseResult;
|
||||||
import com.yfd.platform.system.domain.SysLog;
|
import com.yfd.platform.system.domain.SysLog;
|
||||||
import com.yfd.platform.system.service.ISysLogService;
|
import com.yfd.platform.system.service.ISysLogService;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
@ -14,7 +13,6 @@ import jakarta.annotation.Resource;
|
|||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -43,11 +41,10 @@ public class SysLogController {
|
|||||||
@Operation(summary = "分页查询日志信息")
|
@Operation(summary = "分页查询日志信息")
|
||||||
public ResponseResult getLogList(String username, String optType,
|
public ResponseResult getLogList(String username, String optType,
|
||||||
String startDate,
|
String startDate,
|
||||||
String endDate, Page<SysLog> page,
|
String endDate, Page<SysLog> page) {
|
||||||
@RequestHeader(value = "Tenant_id", required = false) String tenantId) {
|
|
||||||
tenantId=null;
|
|
||||||
Page<SysLog> sysLogPage = sysLogService.getLogList(username, optType,
|
Page<SysLog> sysLogPage = sysLogService.getLogList(username, optType,
|
||||||
startDate, endDate, page, StrUtil.trimToNull(tenantId));
|
startDate, endDate, page);
|
||||||
Map<String, Object> map = new HashMap<>();
|
Map<String, Object> map = new HashMap<>();
|
||||||
map.put("list", sysLogPage.getRecords());
|
map.put("list", sysLogPage.getRecords());
|
||||||
map.put("total", sysLogPage.getTotal());
|
map.put("total", sysLogPage.getTotal());
|
||||||
@ -67,11 +64,10 @@ public class SysLogController {
|
|||||||
public void exportExcel(String username, String optType,
|
public void exportExcel(String username, String optType,
|
||||||
String startDate,
|
String startDate,
|
||||||
String endDate, Page<SysLog> page,
|
String endDate, Page<SysLog> page,
|
||||||
HttpServletResponse response,
|
HttpServletResponse response) throws IOException {
|
||||||
@RequestHeader(value = "Tenant_id", required = false) String tenantId) throws IOException {
|
|
||||||
tenantId=null;
|
|
||||||
Page<SysLog> sysLogPage = sysLogService.getLogList(username, optType,
|
Page<SysLog> sysLogPage = sysLogService.getLogList(username, optType,
|
||||||
startDate, endDate, page, StrUtil.trimToNull(tenantId));
|
startDate, endDate, page);
|
||||||
sysLogService.exportExcel(sysLogPage.getRecords(), response);
|
sysLogService.exportExcel(sysLogPage.getRecords(), response);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,19 +1,15 @@
|
|||||||
package com.yfd.platform.system.controller;
|
package com.yfd.platform.system.controller;
|
||||||
|
|
||||||
import cn.hutool.core.util.IdUtil;
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
||||||
import com.yfd.platform.annotation.Log;
|
import com.yfd.platform.annotation.Log;
|
||||||
import com.yfd.platform.config.ResponseResult;
|
import com.yfd.platform.common.response.ResponseResult;
|
||||||
import com.yfd.platform.system.domain.SysMenu;
|
import com.yfd.platform.system.domain.SysMenu;
|
||||||
import com.yfd.platform.system.domain.SysUser;
|
import com.yfd.platform.system.domain.SysUser;
|
||||||
import com.yfd.platform.system.service.ISysMenuService;
|
import com.yfd.platform.system.service.ISysMenuService;
|
||||||
import com.yfd.platform.system.service.IUserService;
|
import com.yfd.platform.system.service.IUserService;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import org.apache.catalina.User;
|
|
||||||
import org.springframework.util.StringUtils;
|
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
@ -23,7 +19,6 @@ import java.io.FileNotFoundException;
|
|||||||
import java.sql.Timestamp;
|
import java.sql.Timestamp;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
@ -59,9 +54,8 @@ public class SysMenuController {
|
|||||||
@ResponseBody
|
@ResponseBody
|
||||||
public List<Map<String, Object>> getMenuButtonTree(String systemcode,
|
public List<Map<String, Object>> getMenuButtonTree(String systemcode,
|
||||||
String name,
|
String name,
|
||||||
String isdisplay,
|
String isdisplay) {
|
||||||
@RequestHeader(value = "Tenant_id", required = false) String tenantId) {
|
return sysMenuService.getMenuButtonTree(systemcode, name, isdisplay);
|
||||||
return sysMenuService.getMenuButtonTree(systemcode, name, isdisplay, StrUtil.trimToNull(tenantId));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************
|
/***********************************
|
||||||
@ -77,9 +71,8 @@ public class SysMenuController {
|
|||||||
@ResponseBody
|
@ResponseBody
|
||||||
public List<Map<String, Object>> getMenuTree(String systemcode,
|
public List<Map<String, Object>> getMenuTree(String systemcode,
|
||||||
String name,
|
String name,
|
||||||
String isdisplay,
|
String isdisplay) {
|
||||||
@RequestHeader(value = "Tenant_id", required = false) String tenantId) {
|
return sysMenuService.getMenuTree(systemcode, name, isdisplay);
|
||||||
return sysMenuService.getMenuTree(systemcode, name, isdisplay, StrUtil.trimToNull(tenantId));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************
|
/***********************************
|
||||||
@ -93,12 +86,11 @@ public class SysMenuController {
|
|||||||
@PostMapping("/permissionAssignment")
|
@PostMapping("/permissionAssignment")
|
||||||
@Operation(summary = "获取分配权限(不含按钮)")
|
@Operation(summary = "获取分配权限(不含按钮)")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public List<Map<String, Object>> permissionAssignment(String code, String roleId,
|
public List<Map<String, Object>> permissionAssignment(String code, String roleId) {
|
||||||
@RequestHeader(value = "Tenant_id", required = false) String tenantId) {
|
|
||||||
if (StrUtil.isBlank(code)) {
|
if (StrUtil.isBlank(code)) {
|
||||||
code = "1";
|
code = "1";
|
||||||
}
|
}
|
||||||
return sysMenuService.permissionAssignment(code, roleId, StrUtil.trimToNull(tenantId));
|
return sysMenuService.permissionAssignment(code,roleId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************
|
/**********************************
|
||||||
@ -109,13 +101,13 @@ public class SysMenuController {
|
|||||||
@GetMapping("/treeRoutes")
|
@GetMapping("/treeRoutes")
|
||||||
@Operation(summary = "获取当前用户菜单结构树")
|
@Operation(summary = "获取当前用户菜单结构树")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public List<Map<String, Object>> getMenuTreeByUser(@RequestHeader(value = "Tenant_id", required = false) String tenantId) {
|
public List<Map<String, Object>> getMenuTreeByUser() {
|
||||||
SysUser userInfo = userService.getUserInfo();
|
SysUser userInfo = userService.getUserInfo();
|
||||||
String id = "";
|
String id = "";
|
||||||
if (0 != userInfo.getUsertype()) {
|
if (0 != userInfo.getUsertype()) {
|
||||||
id = userInfo.getId();
|
id = userInfo.getId();
|
||||||
}
|
}
|
||||||
return sysMenuService.getMenuTree(id, StrUtil.isNotBlank(tenantId) ? StrUtil.trimToNull(tenantId) : userInfo.getTenantId());
|
return sysMenuService.getMenuTree(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************
|
/***********************************
|
||||||
@ -127,12 +119,8 @@ public class SysMenuController {
|
|||||||
@PostMapping("/getOneById")
|
@PostMapping("/getOneById")
|
||||||
@Operation(summary = "根据id查询菜单或按钮详情")
|
@Operation(summary = "根据id查询菜单或按钮详情")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public ResponseResult getOneById(String id,
|
public ResponseResult getOneById(String id) {
|
||||||
@RequestHeader(value = "Tenant_id", required = false) String tenantId) {
|
SysMenu sysMenu = sysMenuService.getById(id);
|
||||||
LambdaQueryWrapper<SysMenu> queryWrapper = new LambdaQueryWrapper<>();
|
|
||||||
queryWrapper.eq(SysMenu::getId, id)
|
|
||||||
.eq(StrUtil.isNotBlank(tenantId), SysMenu::getTenantId, StrUtil.trim(tenantId));
|
|
||||||
SysMenu sysMenu = sysMenuService.getOne(queryWrapper);
|
|
||||||
return ResponseResult.successData(sysMenu);
|
return ResponseResult.successData(sysMenu);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,9 +134,7 @@ public class SysMenuController {
|
|||||||
@PostMapping("/addMenu")
|
@PostMapping("/addMenu")
|
||||||
@Operation(summary = "新增菜单及按钮")
|
@Operation(summary = "新增菜单及按钮")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public ResponseResult addMenu(@RequestBody SysMenu sysMenu,
|
public ResponseResult addMenu(@RequestBody SysMenu sysMenu) {
|
||||||
@RequestHeader(value = "Tenant_id", required = false) String tenantId) {
|
|
||||||
sysMenu.setTenantId(StrUtil.trimToNull(tenantId));
|
|
||||||
boolean isOk = sysMenuService.addMenu(sysMenu);
|
boolean isOk = sysMenuService.addMenu(sysMenu);
|
||||||
if (isOk) {
|
if (isOk) {
|
||||||
return ResponseResult.success();
|
return ResponseResult.success();
|
||||||
@ -167,15 +153,7 @@ public class SysMenuController {
|
|||||||
@PostMapping("/updateById")
|
@PostMapping("/updateById")
|
||||||
@Operation(summary = "修改菜单及按钮")
|
@Operation(summary = "修改菜单及按钮")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public ResponseResult updateById(@RequestBody SysMenu sysMenu,
|
public ResponseResult updateById(@RequestBody SysMenu sysMenu) {
|
||||||
@RequestHeader(value = "Tenant_id", required = false) String tenantId) {
|
|
||||||
LambdaQueryWrapper<SysMenu> queryWrapper = new LambdaQueryWrapper<>();
|
|
||||||
queryWrapper.eq(SysMenu::getId, sysMenu.getId())
|
|
||||||
.eq(StrUtil.isNotBlank(tenantId), SysMenu::getTenantId, StrUtil.trim(tenantId));
|
|
||||||
if (sysMenuService.getOne(queryWrapper) == null) {
|
|
||||||
return ResponseResult.error("未找到对应租户的菜单");
|
|
||||||
}
|
|
||||||
sysMenu.setTenantId(StrUtil.trimToNull(tenantId));
|
|
||||||
sysMenu.setLastmodifier(userService.getUsername());
|
sysMenu.setLastmodifier(userService.getUsername());
|
||||||
sysMenu.setLastmodifydate(new Timestamp(System.currentTimeMillis()));
|
sysMenu.setLastmodifydate(new Timestamp(System.currentTimeMillis()));
|
||||||
boolean isOk = sysMenuService.updateById(sysMenu);
|
boolean isOk = sysMenuService.updateById(sysMenu);
|
||||||
@ -197,14 +175,7 @@ public class SysMenuController {
|
|||||||
@PostMapping("/deleteIcon")
|
@PostMapping("/deleteIcon")
|
||||||
@Operation(summary = "根据id删除单个图标")
|
@Operation(summary = "根据id删除单个图标")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public ResponseResult deleteIcon(@RequestParam String id,
|
public ResponseResult deleteIcon(@RequestParam String id) {
|
||||||
@RequestHeader(value = "Tenant_id", required = false) String tenantId) {
|
|
||||||
LambdaQueryWrapper<SysMenu> queryWrapper = new LambdaQueryWrapper<>();
|
|
||||||
queryWrapper.eq(SysMenu::getId, id)
|
|
||||||
.eq(StrUtil.isNotBlank(tenantId), SysMenu::getTenantId, StrUtil.trim(tenantId));
|
|
||||||
if (sysMenuService.getOne(queryWrapper) == null) {
|
|
||||||
return ResponseResult.error("未找到对应租户的菜单");
|
|
||||||
}
|
|
||||||
boolean ok = sysMenuService.deleteIcon(id);
|
boolean ok = sysMenuService.deleteIcon(id);
|
||||||
if (ok) {
|
if (ok) {
|
||||||
return ResponseResult.success();
|
return ResponseResult.success();
|
||||||
@ -224,11 +195,10 @@ public class SysMenuController {
|
|||||||
@PostMapping("/setIsDisplay")
|
@PostMapping("/setIsDisplay")
|
||||||
@Operation(summary = "更新菜单及按钮是否有效")
|
@Operation(summary = "更新菜单及按钮是否有效")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public ResponseResult setIsDisplay(String id, String isdisplay,
|
public ResponseResult setIsDisplay(String id, String isdisplay) {
|
||||||
@RequestHeader(value = "Tenant_id", required = false) String tenantId) {
|
|
||||||
UpdateWrapper<SysMenu> updateWrapper = new UpdateWrapper<>();
|
UpdateWrapper<SysMenu> updateWrapper = new UpdateWrapper<>();
|
||||||
//根据id 修改是否显示 ,最近修改人,最近修改时间
|
//根据id 修改是否显示 ,最近修改人,最近修改时间
|
||||||
updateWrapper.eq("id", id).eq(StrUtil.isNotBlank(tenantId), "tenant_id", StrUtil.trim(tenantId)).set("isdisplay", isdisplay).set(
|
updateWrapper.eq("id", id).set("isdisplay", isdisplay).set(
|
||||||
"lastmodifier", userService.getUsername()).set(
|
"lastmodifier", userService.getUsername()).set(
|
||||||
"lastmodifydate",
|
"lastmodifydate",
|
||||||
new Timestamp(System.currentTimeMillis()));
|
new Timestamp(System.currentTimeMillis()));
|
||||||
@ -253,15 +223,8 @@ public class SysMenuController {
|
|||||||
@ResponseBody
|
@ResponseBody
|
||||||
public ResponseResult moveOrderno(@RequestParam String parentid,
|
public ResponseResult moveOrderno(@RequestParam String parentid,
|
||||||
@RequestParam String id,
|
@RequestParam String id,
|
||||||
@RequestParam int orderno,
|
@RequestParam int orderno) {
|
||||||
@RequestHeader(value = "Tenant_id", required = false) String tenantId) {
|
boolean ok = sysMenuService.moveOrderno(parentid, id, orderno);
|
||||||
LambdaQueryWrapper<SysMenu> queryWrapper = new LambdaQueryWrapper<>();
|
|
||||||
queryWrapper.eq(SysMenu::getId, id)
|
|
||||||
.eq(StrUtil.isNotBlank(tenantId), SysMenu::getTenantId, StrUtil.trim(tenantId));
|
|
||||||
if (sysMenuService.getOne(queryWrapper) == null) {
|
|
||||||
return ResponseResult.error("未找到对应租户的菜单");
|
|
||||||
}
|
|
||||||
boolean ok = sysMenuService.moveOrderno(parentid, id, orderno, StrUtil.trimToNull(tenantId));
|
|
||||||
if (ok) {
|
if (ok) {
|
||||||
return ResponseResult.success();
|
return ResponseResult.success();
|
||||||
} else {
|
} else {
|
||||||
@ -279,14 +242,7 @@ public class SysMenuController {
|
|||||||
@PostMapping("/deleteById")
|
@PostMapping("/deleteById")
|
||||||
@Operation(summary = "根据id删除菜单或按钮")
|
@Operation(summary = "根据id删除菜单或按钮")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public ResponseResult deleteById(@RequestParam String id,
|
public ResponseResult deleteById(@RequestParam String id) {
|
||||||
@RequestHeader(value = "Tenant_id", required = false) String tenantId) {
|
|
||||||
LambdaQueryWrapper<SysMenu> queryWrapper = new LambdaQueryWrapper<>();
|
|
||||||
queryWrapper.eq(SysMenu::getId, id)
|
|
||||||
.eq(StrUtil.isNotBlank(tenantId), SysMenu::getTenantId, StrUtil.trim(tenantId));
|
|
||||||
if (sysMenuService.getOne(queryWrapper) == null) {
|
|
||||||
return ResponseResult.error("未找到对应租户的菜单");
|
|
||||||
}
|
|
||||||
boolean ok = sysMenuService.deleteById(id);
|
boolean ok = sysMenuService.deleteById(id);
|
||||||
if (ok) {
|
if (ok) {
|
||||||
return ResponseResult.success();
|
return ResponseResult.success();
|
||||||
@ -306,23 +262,13 @@ public class SysMenuController {
|
|||||||
@Operation(summary = "菜单或按钮切换")
|
@Operation(summary = "菜单或按钮切换")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public ResponseResult changeMenuOrder(@RequestParam String fromId,
|
public ResponseResult changeMenuOrder(@RequestParam String fromId,
|
||||||
@RequestParam String toId,
|
@RequestParam String toId) {
|
||||||
@RequestHeader(value = "Tenant_id", required = false) String tenantId) {
|
|
||||||
if (StrUtil.isBlank(fromId) || StrUtil.isBlank(toId)) {
|
if (StrUtil.isBlank(fromId) || StrUtil.isBlank(toId)) {
|
||||||
return ResponseResult.error("参数为空!");
|
return ResponseResult.error("参数为空!");
|
||||||
}
|
}
|
||||||
if (fromId.equals(toId)) {
|
if (fromId.equals(toId)) {
|
||||||
return ResponseResult.error("切换失败!");
|
return ResponseResult.error("切换失败!");
|
||||||
}
|
}
|
||||||
LambdaQueryWrapper<SysMenu> fromWrapper = new LambdaQueryWrapper<>();
|
|
||||||
fromWrapper.eq(SysMenu::getId, fromId)
|
|
||||||
.eq(StrUtil.isNotBlank(tenantId), SysMenu::getTenantId, StrUtil.trim(tenantId));
|
|
||||||
LambdaQueryWrapper<SysMenu> toWrapper = new LambdaQueryWrapper<>();
|
|
||||||
toWrapper.eq(SysMenu::getId, toId)
|
|
||||||
.eq(StrUtil.isNotBlank(tenantId), SysMenu::getTenantId, StrUtil.trim(tenantId));
|
|
||||||
if (sysMenuService.getOne(fromWrapper) == null || sysMenuService.getOne(toWrapper) == null) {
|
|
||||||
return ResponseResult.error("存在不属于当前租户的菜单");
|
|
||||||
}
|
|
||||||
boolean ok = sysMenuService.changeOderNoById(fromId, toId);
|
boolean ok = sysMenuService.changeOderNoById(fromId, toId);
|
||||||
if (ok) {
|
if (ok) {
|
||||||
return ResponseResult.success();
|
return ResponseResult.success();
|
||||||
@ -340,16 +286,9 @@ public class SysMenuController {
|
|||||||
@PostMapping("/uploadIcon")
|
@PostMapping("/uploadIcon")
|
||||||
@Operation(summary = "上传单个图标")
|
@Operation(summary = "上传单个图标")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public ResponseResult uploadIcon(MultipartFile icon, String menuId,
|
public ResponseResult uploadIcon(MultipartFile icon, String menuId) throws FileNotFoundException {
|
||||||
@RequestHeader(value = "Tenant_id", required = false) String tenantId) throws FileNotFoundException {
|
|
||||||
if (StrUtil.isNotBlank(menuId)) {
|
if (StrUtil.isNotBlank(menuId)) {
|
||||||
LambdaQueryWrapper<SysMenu> queryWrapper = new LambdaQueryWrapper<>();
|
SysMenu sysMenu = sysMenuService.getById(menuId);
|
||||||
queryWrapper.eq(SysMenu::getId, menuId)
|
|
||||||
.eq(StrUtil.isNotBlank(tenantId), SysMenu::getTenantId, StrUtil.trim(tenantId));
|
|
||||||
SysMenu sysMenu = sysMenuService.getOne(queryWrapper);
|
|
||||||
if (sysMenu == null) {
|
|
||||||
return ResponseResult.error("未找到对应租户的菜单");
|
|
||||||
}
|
|
||||||
//图片路径
|
//图片路径
|
||||||
String iconname =
|
String iconname =
|
||||||
System.getProperty("user.dir") + "\\src\\main" +
|
System.getProperty("user.dir") + "\\src\\main" +
|
||||||
@ -2,14 +2,10 @@ package com.yfd.platform.system.controller;
|
|||||||
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
||||||
import com.yfd.platform.annotation.Log;
|
import com.yfd.platform.annotation.Log;
|
||||||
import com.yfd.platform.config.ResponseResult;
|
import com.yfd.platform.common.response.ResponseResult;
|
||||||
import com.yfd.platform.system.domain.SysOrganization;
|
import com.yfd.platform.system.domain.SysOrganization;
|
||||||
import com.yfd.platform.system.domain.SysRole;
|
|
||||||
import com.yfd.platform.system.domain.SysUser;
|
|
||||||
import com.yfd.platform.system.mapper.SysRoleMapper;
|
|
||||||
import com.yfd.platform.system.service.ISysOrganizationService;
|
import com.yfd.platform.system.service.ISysOrganizationService;
|
||||||
import com.yfd.platform.system.service.IUserService;
|
import com.yfd.platform.system.service.IUserService;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
@ -20,7 +16,6 @@ import jakarta.annotation.Resource;
|
|||||||
import java.sql.Timestamp;
|
import java.sql.Timestamp;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
@ -51,9 +46,8 @@ public class SysOrganizationController {
|
|||||||
@PostMapping("/getOrgScopeTree")
|
@PostMapping("/getOrgScopeTree")
|
||||||
@Operation(summary = "获取组织范围树结构")
|
@Operation(summary = "获取组织范围树结构")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public List<Map<String, Object>> getOrgScopeTree(String roleId,
|
public List<Map<String, Object>> getOrgScopeTree(String roleId) {
|
||||||
@RequestHeader(value = "Tenant_id", required = false) String tenantId) {
|
return organizationService.getOrgScopeTree(roleId);
|
||||||
return organizationService.getOrgScopeTree(roleId, StrUtil.trimToNull(tenantId));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************
|
/***********************************
|
||||||
@ -65,9 +59,8 @@ public class SysOrganizationController {
|
|||||||
@Operation(summary = "获取组织结构树")
|
@Operation(summary = "获取组织结构树")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public List<Map<String, Object>> getOrgTree(String parentid,
|
public List<Map<String, Object>> getOrgTree(String parentid,
|
||||||
String params,
|
String params) {
|
||||||
@RequestHeader(value = "Tenant_id", required = false) String tenantId) {
|
return organizationService.getOrgTree(parentid, params);
|
||||||
return organizationService.getOrgTree(parentid, params, StrUtil.trimToNull(tenantId));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************
|
/***********************************
|
||||||
@ -79,13 +72,12 @@ public class SysOrganizationController {
|
|||||||
@PostMapping("/getOrganizationById")
|
@PostMapping("/getOrganizationById")
|
||||||
@Operation(summary = "根据企业ID查询组织信息")
|
@Operation(summary = "根据企业ID查询组织信息")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public ResponseResult getOrganizationById(String id, String orgName,
|
public ResponseResult getOrganizationById(String id, String orgName) {
|
||||||
@RequestHeader(value = "Tenant_id", required = false) String tenantId) {
|
|
||||||
if (StrUtil.isBlank(id)) {
|
if (StrUtil.isBlank(id)) {
|
||||||
return ResponseResult.error("查询失败!");
|
return ResponseResult.error("查询失败!");
|
||||||
}
|
}
|
||||||
List<SysOrganization> sysOrganizations =
|
List<SysOrganization> sysOrganizations =
|
||||||
organizationService.getOrganizationById(id, orgName, StrUtil.trimToNull(tenantId));
|
organizationService.getOrganizationById(id, orgName);
|
||||||
return ResponseResult.successData(sysOrganizations);
|
return ResponseResult.successData(sysOrganizations);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,13 +90,8 @@ public class SysOrganizationController {
|
|||||||
@PostMapping("/getOneById")
|
@PostMapping("/getOneById")
|
||||||
@Operation(summary = "根据ID查询组织详情")
|
@Operation(summary = "根据ID查询组织详情")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public ResponseResult getOneById(String id,
|
public ResponseResult getOneById(String id) {
|
||||||
@RequestHeader(value = "Tenant_id", required = false) String tenantId) {
|
SysOrganization sysOrganization = organizationService.getById(id);
|
||||||
LambdaQueryWrapper<SysOrganization> queryWrapper =
|
|
||||||
new LambdaQueryWrapper<>();
|
|
||||||
queryWrapper.eq(SysOrganization::getId, id)
|
|
||||||
.eq(StrUtil.isNotBlank(tenantId), SysOrganization::getTenantId, StrUtil.trim(tenantId));
|
|
||||||
SysOrganization sysOrganization = organizationService.getOne(queryWrapper);
|
|
||||||
return ResponseResult.successData(sysOrganization);
|
return ResponseResult.successData(sysOrganization);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,8 +105,7 @@ public class SysOrganizationController {
|
|||||||
@PostMapping("/addOrg")
|
@PostMapping("/addOrg")
|
||||||
@Operation(summary = "新增系统组织框架")
|
@Operation(summary = "新增系统组织框架")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public ResponseResult addOrg(@RequestBody SysOrganization sysOrganization,
|
public ResponseResult addOrg(@RequestBody SysOrganization sysOrganization) {
|
||||||
@RequestHeader(value = "Tenant_id", required = false) String tenantId) {
|
|
||||||
//判断是否是否填写 有效 否则默认为 1
|
//判断是否是否填写 有效 否则默认为 1
|
||||||
if (StrUtil.isEmpty(sysOrganization.getIsvaild())) {
|
if (StrUtil.isEmpty(sysOrganization.getIsvaild())) {
|
||||||
sysOrganization.setIsvaild("1");
|
sysOrganization.setIsvaild("1");
|
||||||
@ -127,7 +113,6 @@ public class SysOrganizationController {
|
|||||||
if("".equals(sysOrganization.getId())){
|
if("".equals(sysOrganization.getId())){
|
||||||
sysOrganization.setId(null);
|
sysOrganization.setId(null);
|
||||||
}
|
}
|
||||||
sysOrganization.setTenantId(StrUtil.trimToNull(tenantId));
|
|
||||||
//填写 当前用户名称
|
//填写 当前用户名称
|
||||||
sysOrganization.setLastmodifier(userService.getUsername());
|
sysOrganization.setLastmodifier(userService.getUsername());
|
||||||
//填写 当前日期
|
//填写 当前日期
|
||||||
@ -151,16 +136,7 @@ public class SysOrganizationController {
|
|||||||
@PostMapping("/updateById")
|
@PostMapping("/updateById")
|
||||||
@Operation(summary = "修改系统组织框架")
|
@Operation(summary = "修改系统组织框架")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public ResponseResult updateById(@RequestBody SysOrganization sysOrganization,
|
public ResponseResult updateById(@RequestBody SysOrganization sysOrganization) {
|
||||||
@RequestHeader(value = "Tenant_id", required = false) String tenantId) {
|
|
||||||
LambdaQueryWrapper<SysOrganization> queryWrapper =
|
|
||||||
new LambdaQueryWrapper<>();
|
|
||||||
queryWrapper.eq(SysOrganization::getId, sysOrganization.getId())
|
|
||||||
.eq(StrUtil.isNotBlank(tenantId), SysOrganization::getTenantId, StrUtil.trim(tenantId));
|
|
||||||
if (organizationService.getOne(queryWrapper) == null) {
|
|
||||||
return ResponseResult.error("未找到对应租户的组织");
|
|
||||||
}
|
|
||||||
sysOrganization.setTenantId(StrUtil.trimToNull(tenantId));
|
|
||||||
//填写 当前用户名称
|
//填写 当前用户名称
|
||||||
sysOrganization.setLastmodifier(userService.getUsername());
|
sysOrganization.setLastmodifier(userService.getUsername());
|
||||||
//填写 当前日期
|
//填写 当前日期
|
||||||
@ -185,11 +161,10 @@ public class SysOrganizationController {
|
|||||||
@Operation(summary = "设置组织是否有效")
|
@Operation(summary = "设置组织是否有效")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public ResponseResult setIsValid(@RequestParam String id,
|
public ResponseResult setIsValid(@RequestParam String id,
|
||||||
@RequestParam String isvaild,
|
@RequestParam String isvaild) {
|
||||||
@RequestHeader(value = "Tenant_id", required = false) String tenantId) {
|
|
||||||
UpdateWrapper<SysOrganization> updateWrapper = new UpdateWrapper<>();
|
UpdateWrapper<SysOrganization> updateWrapper = new UpdateWrapper<>();
|
||||||
//根据id 修改是否有效,最近修改人,最近修改时间
|
//根据id 修改是否有效,最近修改人,最近修改时间
|
||||||
updateWrapper.eq("id", id).eq(StrUtil.isNotBlank(tenantId), "tenant_id", StrUtil.trim(tenantId)).set("isvaild", isvaild).set("lastmodifier"
|
updateWrapper.eq("id", id).set("isvaild", isvaild).set("lastmodifier"
|
||||||
, userService.getUsername()).set("lastmodifydate",
|
, userService.getUsername()).set("lastmodifydate",
|
||||||
new Timestamp(System.currentTimeMillis()));
|
new Timestamp(System.currentTimeMillis()));
|
||||||
boolean isOk = organizationService.update(updateWrapper);
|
boolean isOk = organizationService.update(updateWrapper);
|
||||||
@ -210,34 +185,21 @@ public class SysOrganizationController {
|
|||||||
@PostMapping("/deleteById")
|
@PostMapping("/deleteById")
|
||||||
@Operation(summary = "根据id删除系统组织框架")
|
@Operation(summary = "根据id删除系统组织框架")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public ResponseResult deleteById(@RequestParam String id,
|
public ResponseResult deleteById(@RequestParam String id) {
|
||||||
@RequestHeader(value = "Tenant_id", required = false) String tenantId) {
|
|
||||||
String[] orgIds = id.split(",");
|
String[] orgIds = id.split(",");
|
||||||
for (String orgId : orgIds) {
|
for (String orgId : orgIds) {
|
||||||
LambdaQueryWrapper<SysOrganization> currentWrapper =
|
|
||||||
new LambdaQueryWrapper<>();
|
|
||||||
currentWrapper.eq(SysOrganization::getId, orgId)
|
|
||||||
.eq(StrUtil.isNotBlank(tenantId), SysOrganization::getTenantId, StrUtil.trim(tenantId));
|
|
||||||
if (organizationService.getOne(currentWrapper) == null) {
|
|
||||||
return ResponseResult.error("存在不属于当前租户的组织");
|
|
||||||
}
|
|
||||||
LambdaQueryWrapper<SysOrganization> queryWrapper =
|
LambdaQueryWrapper<SysOrganization> queryWrapper =
|
||||||
new LambdaQueryWrapper<>();
|
new LambdaQueryWrapper<>();
|
||||||
List<SysOrganization> list =
|
List<SysOrganization> list =
|
||||||
organizationService.list(queryWrapper.eq(SysOrganization::getParentid, orgId)
|
organizationService.list(queryWrapper.eq(SysOrganization::getParentid, orgId));
|
||||||
.eq(StrUtil.isNotBlank(tenantId), SysOrganization::getTenantId, StrUtil.trim(tenantId)));
|
|
||||||
List<String> ids =
|
List<String> ids =
|
||||||
list.stream().map(SysOrganization::getId).collect(Collectors.toList());
|
list.stream().map(SysOrganization::getId).collect(Collectors.toList());
|
||||||
boolean isOk = organizationService.remove(new LambdaQueryWrapper<SysOrganization>()
|
boolean isOk = organizationService.removeById(orgId);
|
||||||
.eq(SysOrganization::getId, orgId)
|
|
||||||
.eq(StrUtil.isNotBlank(tenantId), SysOrganization::getTenantId, StrUtil.trim(tenantId)));
|
|
||||||
if (!isOk) {
|
if (!isOk) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for (String oid : ids) {
|
for (String oid : ids) {
|
||||||
organizationService.remove(new LambdaQueryWrapper<SysOrganization>()
|
organizationService.removeById(oid);
|
||||||
.eq(SysOrganization::getId, oid)
|
|
||||||
.eq(StrUtil.isNotBlank(tenantId), SysOrganization::getTenantId, StrUtil.trim(tenantId)));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ResponseResult.success();
|
return ResponseResult.success();
|
||||||
@ -1,14 +1,10 @@
|
|||||||
package com.yfd.platform.system.controller;
|
package com.yfd.platform.system.controller;
|
||||||
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
||||||
import com.yfd.platform.annotation.Log;
|
import com.yfd.platform.annotation.Log;
|
||||||
import com.yfd.platform.config.ResponseResult;
|
import com.yfd.platform.common.response.ResponseResult;
|
||||||
import com.yfd.platform.system.domain.SysMenu;
|
|
||||||
import com.yfd.platform.system.domain.SysRole;
|
import com.yfd.platform.system.domain.SysRole;
|
||||||
import com.yfd.platform.system.service.ISysMenuService;
|
|
||||||
import com.yfd.platform.system.service.ISysRoleService;
|
import com.yfd.platform.system.service.ISysRoleService;
|
||||||
import com.yfd.platform.system.service.IUserService;
|
import com.yfd.platform.system.service.IUserService;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
@ -18,7 +14,6 @@ import org.springframework.web.bind.annotation.*;
|
|||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import java.sql.Timestamp;
|
import java.sql.Timestamp;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@ -41,9 +36,6 @@ public class SysRoleController {
|
|||||||
@Resource
|
@Resource
|
||||||
private IUserService userService;
|
private IUserService userService;
|
||||||
|
|
||||||
@Resource
|
|
||||||
private ISysMenuService sysMenuService;
|
|
||||||
|
|
||||||
/***********************************
|
/***********************************
|
||||||
* 用途说明:查询所有角色
|
* 用途说明:查询所有角色
|
||||||
* 参数说明
|
* 参数说明
|
||||||
@ -53,9 +45,8 @@ public class SysRoleController {
|
|||||||
@PostMapping("/list")
|
@PostMapping("/list")
|
||||||
@Operation(summary = "查询所有角色")
|
@Operation(summary = "查询所有角色")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public List<SysRole> list(@RequestParam(required = false) String rolename,
|
public List<SysRole> list(@RequestParam(required = false) String rolename) {
|
||||||
@RequestHeader(value = "Tenant_id", required = false) String tenantId) {
|
return roleService.selectRoleList(rolename);
|
||||||
return roleService.selectRoleList(rolename, StrUtil.trimToNull(tenantId));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************
|
/***********************************
|
||||||
@ -67,12 +58,8 @@ public class SysRoleController {
|
|||||||
@PostMapping("/getOneById")
|
@PostMapping("/getOneById")
|
||||||
@Operation(summary = "根据Id获取当个角色")
|
@Operation(summary = "根据Id获取当个角色")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public ResponseResult getOneById(String id,
|
public ResponseResult getOneById(String id) {
|
||||||
@RequestHeader(value = "Tenant_id", required = false) String tenantId) {
|
SysRole sysRole = roleService.getById(id);
|
||||||
LambdaQueryWrapper<SysRole> queryWrapper = new LambdaQueryWrapper<>();
|
|
||||||
queryWrapper.eq(SysRole::getId, id)
|
|
||||||
.eq(StrUtil.isNotBlank(tenantId), SysRole::getTenantId, StrUtil.trim(tenantId));
|
|
||||||
SysRole sysRole = roleService.getOne(queryWrapper);
|
|
||||||
return ResponseResult.successData(sysRole);
|
return ResponseResult.successData(sysRole);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,9 +73,7 @@ public class SysRoleController {
|
|||||||
@PostMapping("/addRole")
|
@PostMapping("/addRole")
|
||||||
@Operation(summary = "新增角色")
|
@Operation(summary = "新增角色")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public ResponseResult addRole(@RequestBody SysRole sysRole,
|
public ResponseResult addRole(@RequestBody SysRole sysRole) {
|
||||||
@RequestHeader(value = "Tenant_id", required = false) String tenantId) {
|
|
||||||
sysRole.setTenantId(StrUtil.trimToNull(tenantId));
|
|
||||||
boolean isOk = roleService.addRole(sysRole);
|
boolean isOk = roleService.addRole(sysRole);
|
||||||
if (isOk) {
|
if (isOk) {
|
||||||
return ResponseResult.success();
|
return ResponseResult.success();
|
||||||
@ -109,11 +94,10 @@ public class SysRoleController {
|
|||||||
@Operation(summary = "分配操作权限")
|
@Operation(summary = "分配操作权限")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public ResponseResult setOptScope(@RequestParam String id,
|
public ResponseResult setOptScope(@RequestParam String id,
|
||||||
@RequestParam String optscope,
|
@RequestParam String optscope) {
|
||||||
@RequestHeader(value = "Tenant_id", required = false) String tenantId) {
|
|
||||||
UpdateWrapper<SysRole> updateWrapper = new UpdateWrapper<>();
|
UpdateWrapper<SysRole> updateWrapper = new UpdateWrapper<>();
|
||||||
//根据id 更新权限,最近修改人,最近修改时间
|
//根据id 更新权限,最近修改人,最近修改时间
|
||||||
updateWrapper.eq("id", id).eq(StrUtil.isNotBlank(tenantId), "tenant_id", StrUtil.trim(tenantId)).set("optscope", optscope).set(
|
updateWrapper.eq("id", id).set("optscope", optscope).set(
|
||||||
"lastmodifier", userService.getUsername()).set(
|
"lastmodifier", userService.getUsername()).set(
|
||||||
"lastmodifydate", LocalDateTime.now());
|
"lastmodifydate", LocalDateTime.now());
|
||||||
boolean ok = roleService.update(updateWrapper);
|
boolean ok = roleService.update(updateWrapper);
|
||||||
@ -135,34 +119,13 @@ public class SysRoleController {
|
|||||||
@PostMapping("/setMenuById")
|
@PostMapping("/setMenuById")
|
||||||
@Operation(summary = "角色菜单权限")
|
@Operation(summary = "角色菜单权限")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public ResponseResult setMenuById(String id, String menuIds,
|
public ResponseResult setMenuById(String id, String menuIds) {
|
||||||
@RequestHeader(value = "Tenant_id", required = false) String tenantId) {
|
|
||||||
if (StrUtil.isBlank(id)) {
|
if (StrUtil.isBlank(id)) {
|
||||||
return ResponseResult.error("参数为空");
|
return ResponseResult.error("参数为空");
|
||||||
}
|
}
|
||||||
LambdaQueryWrapper<SysRole> queryWrapper = new LambdaQueryWrapper<>();
|
|
||||||
queryWrapper.eq(SysRole::getId, id)
|
|
||||||
.eq(StrUtil.isNotBlank(tenantId), SysRole::getTenantId, StrUtil.trim(tenantId));
|
|
||||||
if (roleService.getOne(queryWrapper) == null) {
|
|
||||||
return ResponseResult.error("未找到对应租户的角色");
|
|
||||||
}
|
|
||||||
if (StrUtil.isBlank(menuIds)) {
|
if (StrUtil.isBlank(menuIds)) {
|
||||||
return ResponseResult.success();
|
return ResponseResult.success();
|
||||||
}
|
}
|
||||||
List<String> menuIdList = Arrays.stream(menuIds.split(","))
|
|
||||||
.map(StrUtil::trim)
|
|
||||||
.filter(StrUtil::isNotBlank)
|
|
||||||
.distinct()
|
|
||||||
.toList();
|
|
||||||
if (menuIdList.isEmpty()) {
|
|
||||||
return ResponseResult.success();
|
|
||||||
}
|
|
||||||
long menuCount = sysMenuService.count(new LambdaQueryWrapper<SysMenu>()
|
|
||||||
.in(SysMenu::getId, menuIdList)
|
|
||||||
.eq(StrUtil.isNotBlank(tenantId), SysMenu::getTenantId, StrUtil.trim(tenantId)));
|
|
||||||
if (menuCount != menuIdList.size()) {
|
|
||||||
return ResponseResult.error("存在不属于当前租户的菜单");
|
|
||||||
}
|
|
||||||
boolean ok = roleService.setMenuById(id, menuIds);
|
boolean ok = roleService.setMenuById(id, menuIds);
|
||||||
if (ok) {
|
if (ok) {
|
||||||
return ResponseResult.success();
|
return ResponseResult.success();
|
||||||
@ -184,11 +147,10 @@ public class SysRoleController {
|
|||||||
@Operation(summary = "设置组织范围")
|
@Operation(summary = "设置组织范围")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public ResponseResult setOrgscope(@RequestParam String id,
|
public ResponseResult setOrgscope(@RequestParam String id,
|
||||||
@RequestParam String orgscope,
|
@RequestParam String orgscope) {
|
||||||
@RequestHeader(value = "Tenant_id", required = false) String tenantId) {
|
|
||||||
UpdateWrapper<SysRole> updateWrapper = new UpdateWrapper<>();
|
UpdateWrapper<SysRole> updateWrapper = new UpdateWrapper<>();
|
||||||
//根据id 更新组织范围,最近修改人,最近修改时间
|
//根据id 更新组织范围,最近修改人,最近修改时间
|
||||||
updateWrapper.eq("id", id).eq(StrUtil.isNotBlank(tenantId), "tenant_id", StrUtil.trim(tenantId)).set("orgscope", orgscope).set(
|
updateWrapper.eq("id", id).set("orgscope", orgscope).set(
|
||||||
"lastmodifier", userService.getUsername()).set(
|
"lastmodifier", userService.getUsername()).set(
|
||||||
"lastmodifydate", LocalDateTime.now());
|
"lastmodifydate", LocalDateTime.now());
|
||||||
boolean ok = roleService.update(updateWrapper);
|
boolean ok = roleService.update(updateWrapper);
|
||||||
@ -211,11 +173,10 @@ public class SysRoleController {
|
|||||||
@Operation(summary = "设置业务范围")
|
@Operation(summary = "设置业务范围")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public ResponseResult setBusscope(@RequestParam String id,
|
public ResponseResult setBusscope(@RequestParam String id,
|
||||||
@RequestParam String busscope,
|
@RequestParam String busscope) {
|
||||||
@RequestHeader(value = "Tenant_id", required = false) String tenantId) {
|
|
||||||
UpdateWrapper<SysRole> updateWrapper = new UpdateWrapper<>();
|
UpdateWrapper<SysRole> updateWrapper = new UpdateWrapper<>();
|
||||||
//根据id 更新业务范围,最近修改人,最近修改时间
|
//根据id 更新业务范围,最近修改人,最近修改时间
|
||||||
updateWrapper.eq("id", id).eq(StrUtil.isNotBlank(tenantId), "tenant_id", StrUtil.trim(tenantId)).set("busscope", busscope).set(
|
updateWrapper.eq("id", id).set("busscope", busscope).set(
|
||||||
"lastmodifier", userService.getUsername()).set(
|
"lastmodifier", userService.getUsername()).set(
|
||||||
"lastmodifydate", LocalDateTime.now());
|
"lastmodifydate", LocalDateTime.now());
|
||||||
boolean ok = roleService.update(updateWrapper);
|
boolean ok = roleService.update(updateWrapper);
|
||||||
@ -237,14 +198,7 @@ public class SysRoleController {
|
|||||||
@PostMapping("/setRoleUsers")
|
@PostMapping("/setRoleUsers")
|
||||||
@Operation(summary = "角色添加用户")
|
@Operation(summary = "角色添加用户")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public ResponseResult setRoleUsers(String roleid, String userids,
|
public ResponseResult setRoleUsers(String roleid, String userids) {
|
||||||
@RequestHeader(value = "Tenant_id", required = false) String tenantId) {
|
|
||||||
LambdaQueryWrapper<SysRole> roleWrapper = new LambdaQueryWrapper<>();
|
|
||||||
roleWrapper.eq(SysRole::getId, roleid)
|
|
||||||
.eq(StrUtil.isNotBlank(tenantId), SysRole::getTenantId, StrUtil.trim(tenantId));
|
|
||||||
if (roleService.getOne(roleWrapper) == null) {
|
|
||||||
return ResponseResult.error("未找到对应租户的角色");
|
|
||||||
}
|
|
||||||
boolean isOk = true;
|
boolean isOk = true;
|
||||||
String[] temp = userids.split(",");
|
String[] temp = userids.split(",");
|
||||||
for (String userid : temp) {
|
for (String userid : temp) {
|
||||||
@ -267,14 +221,7 @@ public class SysRoleController {
|
|||||||
@Operation(summary = "删除角色用户")
|
@Operation(summary = "删除角色用户")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public ResponseResult deleteRoleUsers(@RequestParam String roleid,
|
public ResponseResult deleteRoleUsers(@RequestParam String roleid,
|
||||||
@RequestParam String userids,
|
@RequestParam String userids) {
|
||||||
@RequestHeader(value = "Tenant_id", required = false) String tenantId) {
|
|
||||||
LambdaQueryWrapper<SysRole> roleWrapper = new LambdaQueryWrapper<>();
|
|
||||||
roleWrapper.eq(SysRole::getId, roleid)
|
|
||||||
.eq(StrUtil.isNotBlank(tenantId), SysRole::getTenantId, StrUtil.trim(tenantId));
|
|
||||||
if (roleService.getOne(roleWrapper) == null) {
|
|
||||||
return ResponseResult.error("未找到对应租户的角色");
|
|
||||||
}
|
|
||||||
//根据角色id、用户id删除
|
//根据角色id、用户id删除
|
||||||
boolean ok = roleService.deleteRoleUsers(roleid, userids);
|
boolean ok = roleService.deleteRoleUsers(roleid, userids);
|
||||||
if (ok) {
|
if (ok) {
|
||||||
@ -294,11 +241,10 @@ public class SysRoleController {
|
|||||||
@PostMapping("/setIsvaild")
|
@PostMapping("/setIsvaild")
|
||||||
@Operation(summary = "设置角色是否有效")
|
@Operation(summary = "设置角色是否有效")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public ResponseResult setIsvaild(String id, String isvaild,
|
public ResponseResult setIsvaild(String id, String isvaild) {
|
||||||
@RequestHeader(value = "Tenant_id", required = false) String tenantId) {
|
|
||||||
UpdateWrapper<SysRole> updateWrapper = new UpdateWrapper<>();
|
UpdateWrapper<SysRole> updateWrapper = new UpdateWrapper<>();
|
||||||
//根据id 更新业务范围,最近修改人,最近修改时间
|
//根据id 更新业务范围,最近修改人,最近修改时间
|
||||||
updateWrapper.eq("id", id).eq(StrUtil.isNotBlank(tenantId), "tenant_id", StrUtil.trim(tenantId)).set("isvaild", isvaild).set("lastmodifier"
|
updateWrapper.eq("id", id).set("isvaild", isvaild).set("lastmodifier"
|
||||||
, userService.getUsername()).set("lastmodifydate",
|
, userService.getUsername()).set("lastmodifydate",
|
||||||
LocalDateTime.now());
|
LocalDateTime.now());
|
||||||
boolean ok = roleService.update(updateWrapper);
|
boolean ok = roleService.update(updateWrapper);
|
||||||
@ -318,15 +264,7 @@ public class SysRoleController {
|
|||||||
@PostMapping("/updateById")
|
@PostMapping("/updateById")
|
||||||
@Operation(summary = "更新角色信息")
|
@Operation(summary = "更新角色信息")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public ResponseResult updateById(@RequestBody SysRole sysRole,
|
public ResponseResult updateById(@RequestBody SysRole sysRole) {
|
||||||
@RequestHeader(value = "Tenant_id", required = false) String tenantId) {
|
|
||||||
LambdaQueryWrapper<SysRole> queryWrapper = new LambdaQueryWrapper<>();
|
|
||||||
queryWrapper.eq(SysRole::getId, sysRole.getId())
|
|
||||||
.eq(StrUtil.isNotBlank(tenantId), SysRole::getTenantId, StrUtil.trim(tenantId));
|
|
||||||
if (roleService.getOne(queryWrapper) == null) {
|
|
||||||
return ResponseResult.error("未找到对应租户的角色");
|
|
||||||
}
|
|
||||||
sysRole.setTenantId(StrUtil.trimToNull(tenantId));
|
|
||||||
//更新最近修改人
|
//更新最近修改人
|
||||||
sysRole.setLastmodifier(userService.getUsername());
|
sysRole.setLastmodifier(userService.getUsername());
|
||||||
//更新最近修改时间
|
//更新最近修改时间
|
||||||
@ -349,17 +287,7 @@ public class SysRoleController {
|
|||||||
@PostMapping("/deleteById")
|
@PostMapping("/deleteById")
|
||||||
@Operation(summary = "根据id删除角色")
|
@Operation(summary = "根据id删除角色")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public ResponseResult deleteById(@RequestParam String id,
|
public ResponseResult deleteById(@RequestParam String id) {
|
||||||
@RequestHeader(value = "Tenant_id", required = false) String tenantId) {
|
|
||||||
String[] roleIds = id.split(",");
|
|
||||||
for (String roleId : roleIds) {
|
|
||||||
LambdaQueryWrapper<SysRole> queryWrapper = new LambdaQueryWrapper<>();
|
|
||||||
queryWrapper.eq(SysRole::getId, roleId)
|
|
||||||
.eq(StrUtil.isNotBlank(tenantId), SysRole::getTenantId, StrUtil.trim(tenantId));
|
|
||||||
if (roleService.getOne(queryWrapper) == null) {
|
|
||||||
return ResponseResult.error("存在不属于当前租户的角色");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
roleService.deleteById(id);
|
roleService.deleteById(id);
|
||||||
return ResponseResult.success();
|
return ResponseResult.success();
|
||||||
}
|
}
|
||||||
@ -380,10 +308,9 @@ public class SysRoleController {
|
|||||||
@ResponseBody
|
@ResponseBody
|
||||||
public List<Map> listRoleUsers(String orgid, String username,
|
public List<Map> listRoleUsers(String orgid, String username,
|
||||||
String status, String level,
|
String status, String level,
|
||||||
String rolename, String isvaild,
|
String rolename, String isvaild) {
|
||||||
@RequestHeader(value = "Tenant_id", required = false) String tenantId) {
|
|
||||||
return roleService.listRoleUsers(orgid, username, status, level,
|
return roleService.listRoleUsers(orgid, username, status, level,
|
||||||
rolename, isvaild, StrUtil.trimToNull(tenantId));
|
rolename, isvaild);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1,14 +1,11 @@
|
|||||||
package com.yfd.platform.system.controller;
|
package com.yfd.platform.system.controller;
|
||||||
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.yfd.platform.annotation.Log;
|
import com.yfd.platform.annotation.Log;
|
||||||
import com.yfd.platform.config.ResponseResult;
|
import com.yfd.platform.common.response.ResponseResult;
|
||||||
import com.yfd.platform.datasource.DataSource;
|
import com.yfd.platform.datasource.DataSource;
|
||||||
import com.yfd.platform.system.domain.SysUser;
|
import com.yfd.platform.system.domain.SysUser;
|
||||||
import com.yfd.platform.system.domain.SysUserRequest;
|
|
||||||
import com.yfd.platform.system.service.ISmsVerifyCodeService;
|
|
||||||
import com.yfd.platform.system.service.IUserService;
|
import com.yfd.platform.system.service.IUserService;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
@ -35,17 +32,11 @@ public class UserController {
|
|||||||
@Resource
|
@Resource
|
||||||
private IUserService userService;
|
private IUserService userService;
|
||||||
|
|
||||||
@Resource
|
|
||||||
private ISmsVerifyCodeService smsVerifyCodeService;
|
|
||||||
|
|
||||||
@Log(module = "系统用户", value = "新增系统用户")
|
@Log(module = "系统用户", value = "新增系统用户")
|
||||||
@PostMapping("/addUser")
|
@PostMapping("/addUser")
|
||||||
@Operation(summary = "新增系统用户")
|
@Operation(summary = "新增系统用户")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public ResponseResult addUser(@RequestBody SysUser user,
|
public ResponseResult addUser(@RequestBody SysUser user, String roleids) {
|
||||||
String roleids,
|
|
||||||
@RequestHeader(value = "Tenant_id", required = false) String tenantId) {
|
|
||||||
user.setTenantId(StrUtil.trimToNull(tenantId));
|
|
||||||
Map reslut = userService.addUser(user, roleids);
|
Map reslut = userService.addUser(user, roleids);
|
||||||
return ResponseResult.successData(reslut);
|
return ResponseResult.successData(reslut);
|
||||||
}
|
}
|
||||||
@ -55,12 +46,10 @@ public class UserController {
|
|||||||
@Operation(summary = "修改用户信息")
|
@Operation(summary = "修改用户信息")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public ResponseResult updateUser(@RequestBody SysUser user,
|
public ResponseResult updateUser(@RequestBody SysUser user,
|
||||||
String roleids,
|
String roleids) {
|
||||||
@RequestHeader(value = "Tenant_id", required = false) String tenantId) {
|
|
||||||
if (StrUtil.isEmpty(user.getId())) {
|
if (StrUtil.isEmpty(user.getId())) {
|
||||||
return ResponseResult.error("没有用户ID");
|
return ResponseResult.error("没有用户ID");
|
||||||
}
|
}
|
||||||
user.setTenantId(StrUtil.trimToNull(tenantId));
|
|
||||||
//填写 当前用户名称
|
//填写 当前用户名称
|
||||||
user.setLastmodifier(userService.getUsername());
|
user.setLastmodifier(userService.getUsername());
|
||||||
//填写 当前日期
|
//填写 当前日期
|
||||||
@ -69,17 +58,14 @@ public class UserController {
|
|||||||
return ResponseResult.successData(reslut);
|
return ResponseResult.successData(reslut);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@GetMapping("/queryUsers")
|
@GetMapping("/queryUsers")
|
||||||
@Operation(summary = "查询用户信息")
|
@Operation(summary = "查询用户信息")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public ResponseResult queryUsers(String orgid,
|
public ResponseResult queryUsers(String orgid,
|
||||||
String username,
|
String username, Page<SysUser> page) {
|
||||||
Page<SysUser> page,
|
|
||||||
@RequestHeader(value = "Tenant_id", required = false) String tenantId) {
|
|
||||||
|
|
||||||
Page<SysUser> mapPage = userService.queryUsers(orgid,
|
Page<SysUser> mapPage = userService.queryUsers(orgid,
|
||||||
username, StrUtil.trimToNull(tenantId), page);
|
username, page);
|
||||||
return ResponseResult.successData(mapPage);
|
return ResponseResult.successData(mapPage);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,25 +88,6 @@ public class UserController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********************************
|
|
||||||
* 用途说明:根据id查询用户信息
|
|
||||||
* 参数说明
|
|
||||||
*id 用户id
|
|
||||||
* 返回值说明: 用户信息
|
|
||||||
************************************/
|
|
||||||
@GetMapping("/queryUserById")
|
|
||||||
@Operation(summary = "根据id查询用户信息")
|
|
||||||
@ResponseBody
|
|
||||||
public ResponseResult queryUserById(String id,
|
|
||||||
@RequestHeader(value = "Tenant_id", required = false) String tenantId) {
|
|
||||||
LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
|
|
||||||
queryWrapper.eq(SysUser::getId, id)
|
|
||||||
.eq(StrUtil.isNotBlank(tenantId), SysUser::getTenantId, StrUtil.trim(tenantId));
|
|
||||||
SysUser user = userService.getOne(queryWrapper);
|
|
||||||
return ResponseResult.successData(user);
|
|
||||||
}
|
|
||||||
|
|
||||||
/***********************************
|
/***********************************
|
||||||
* 用途说明:根据id删除用户
|
* 用途说明:根据id删除用户
|
||||||
* 参数说明
|
* 参数说明
|
||||||
@ -173,7 +140,12 @@ public class UserController {
|
|||||||
if (StrUtil.isBlank(id)) {
|
if (StrUtil.isBlank(id)) {
|
||||||
ResponseResult.error("参数为空");
|
ResponseResult.error("参数为空");
|
||||||
}
|
}
|
||||||
return userService.resetPassword(id);
|
boolean ok = userService.resetPassword(id);
|
||||||
|
if (ok) {
|
||||||
|
return ResponseResult.success();
|
||||||
|
} else {
|
||||||
|
return ResponseResult.error();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************
|
/***********************************
|
||||||
@ -213,42 +185,4 @@ public class UserController {
|
|||||||
boolean ok = userService.uploadAvatar(id, multipartFile);
|
boolean ok = userService.uploadAvatar(id, multipartFile);
|
||||||
return ResponseResult.success();
|
return ResponseResult.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Log(module = "系统用户", value = "审核用户注册")
|
|
||||||
@PostMapping("/auditUser")
|
|
||||||
@Operation(summary = "审核用户注册")
|
|
||||||
@ResponseBody
|
|
||||||
public ResponseResult auditUser(@RequestBody SysUserRequest sysUserRequest) {
|
|
||||||
String userId = sysUserRequest.getUserId();
|
|
||||||
String auditStatus = sysUserRequest.getRegStatus();
|
|
||||||
if (userId == null || userId.isEmpty()) {
|
|
||||||
return ResponseResult.error("用户ID不能为空");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (StrUtil.isBlank(auditStatus) || ( !"APPROVED".equals(auditStatus)&&!"REJECTED".equals(auditStatus))) {
|
|
||||||
return ResponseResult.error("审核状态错误");
|
|
||||||
}
|
|
||||||
SysUser user = userService.getById(userId);
|
|
||||||
if (user == null) {
|
|
||||||
return ResponseResult.error("用户不存在");
|
|
||||||
}
|
|
||||||
boolean ok = userService.auditUser(userId, auditStatus);
|
|
||||||
if (ok) {
|
|
||||||
smsVerifyCodeService.sendAuditNotify(user.getPhone(), auditStatus, sysUserRequest.getCommentInfo());
|
|
||||||
return ResponseResult.success();
|
|
||||||
} else {
|
|
||||||
return ResponseResult.error("审核失败");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/queryPendingAuditUsers")
|
|
||||||
@Operation(summary = "查询待审核用户列表")
|
|
||||||
@ResponseBody
|
|
||||||
public ResponseResult queryPendingAuditUsers(Page<SysUser> page,
|
|
||||||
String name,
|
|
||||||
String regStatus,
|
|
||||||
@RequestHeader(value = "Tenant_id", required = false) String tenantId) {
|
|
||||||
Page<SysUser> result = userService.queryPendingAuditUsers(page, name, regStatus, StrUtil.trimToNull(tenantId));
|
|
||||||
return ResponseResult.successData(result);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@ -1,6 +1,6 @@
|
|||||||
package com.yfd.platform.system.domain;
|
package com.yfd.platform.system.domain;
|
||||||
|
|
||||||
import com.alibaba.fastjson.annotation.JSONField;
|
import com.alibaba.fastjson2.annotation.JSONField;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
@ -8,7 +8,6 @@ import org.springframework.security.core.GrantedAuthority;
|
|||||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||||
import org.springframework.security.core.userdetails.UserDetails;
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
@ -20,19 +19,11 @@ public class LoginUser implements UserDetails {
|
|||||||
|
|
||||||
private SysUser user;
|
private SysUser user;
|
||||||
|
|
||||||
private String username;
|
private List<String> permissions;
|
||||||
|
|
||||||
private List<String> permissions=new ArrayList<>();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 自定义构造函数(如果需要特殊逻辑)
|
|
||||||
*/
|
|
||||||
public LoginUser(SysUser user, List<String> permissions) {
|
public LoginUser(SysUser user, List<String> permissions) {
|
||||||
this.user = user;
|
this.user = user;
|
||||||
// 4. 增加非空判断,确保 permissions 永远不为 null
|
this.permissions = permissions;
|
||||||
if (permissions != null) {
|
|
||||||
this.permissions = permissions;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@JSONField(serialize = false)
|
@JSONField(serialize = false)
|
||||||
@ -41,6 +32,10 @@ public class LoginUser implements UserDetails {
|
|||||||
@Override
|
@Override
|
||||||
public Collection<? extends GrantedAuthority> getAuthorities() {
|
public Collection<? extends GrantedAuthority> getAuthorities() {
|
||||||
// 将权限信息放入集合
|
// 将权限信息放入集合
|
||||||
|
if (permissions == null || permissions.isEmpty()) {
|
||||||
|
authorities = new java.util.ArrayList<>();
|
||||||
|
return authorities;
|
||||||
|
}
|
||||||
authorities = permissions.stream()
|
authorities = permissions.stream()
|
||||||
.map(SimpleGrantedAuthority::new)
|
.map(SimpleGrantedAuthority::new)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
@ -1,7 +1,6 @@
|
|||||||
package com.yfd.platform.system.domain;
|
package com.yfd.platform.system.domain;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.annotation.IdType;
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
import com.baomidou.mybatisplus.annotation.TableField;
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
|
||||||
@ -116,18 +115,4 @@ public class QuartzJob implements Serializable {
|
|||||||
@Schema(description = "备用3")
|
@Schema(description = "备用3")
|
||||||
private String custom3;
|
private String custom3;
|
||||||
|
|
||||||
/**
|
|
||||||
* 业务模块编码(如:PUSH-推送配置,SYNC-数据同步,REPORT-报表生成)
|
|
||||||
*/
|
|
||||||
@Schema(description = "业务模块编码")
|
|
||||||
@TableField("BIZ_MODULE")
|
|
||||||
private String bizModule;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 关联业务表的主键ID(如 PUSH_CONFIG.ID)
|
|
||||||
*/
|
|
||||||
@Schema(description = "关联业务主键ID")
|
|
||||||
@TableField("BIZ_ID")
|
|
||||||
private String bizId;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -48,12 +48,6 @@ public class SysConfig implements Serializable {
|
|||||||
*/
|
*/
|
||||||
private String remark;
|
private String remark;
|
||||||
|
|
||||||
/**
|
|
||||||
* 租户ID
|
|
||||||
*/
|
|
||||||
@TableField("TENANT_ID")
|
|
||||||
private String tenantId;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 最近修改者
|
* 最近修改者
|
||||||
*/
|
*/
|
||||||
@ -83,12 +83,6 @@ public class SysLog implements Serializable {
|
|||||||
@TableField("REQUESTIP")
|
@TableField("REQUESTIP")
|
||||||
private String requestip;
|
private String requestip;
|
||||||
|
|
||||||
/**
|
|
||||||
* 租户ID
|
|
||||||
*/
|
|
||||||
@TableField("TENANT_ID")
|
|
||||||
private String tenantId;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 浏览器类型
|
* 浏览器类型
|
||||||
*/
|
*/
|
||||||
@ -85,12 +85,6 @@ public class SysMenu implements Serializable {
|
|||||||
*/
|
*/
|
||||||
private String isdisplay;
|
private String isdisplay;
|
||||||
|
|
||||||
/**
|
|
||||||
* 租户ID
|
|
||||||
*/
|
|
||||||
@TableField("TENANT_ID")
|
|
||||||
private String tenantId;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 最近修改者
|
* 最近修改者
|
||||||
*/
|
*/
|
||||||
@ -63,12 +63,6 @@ public class SysOrganization implements Serializable {
|
|||||||
*/
|
*/
|
||||||
private String description;
|
private String description;
|
||||||
|
|
||||||
/**
|
|
||||||
* 租户ID
|
|
||||||
*/
|
|
||||||
@TableField("TENANT_ID")
|
|
||||||
private String tenantId;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 最近修改者
|
* 最近修改者
|
||||||
*/
|
*/
|
||||||
@ -69,12 +69,6 @@ public class SysRole implements Serializable {
|
|||||||
*/
|
*/
|
||||||
private String isvaild;
|
private String isvaild;
|
||||||
|
|
||||||
/**
|
|
||||||
* 租户ID
|
|
||||||
*/
|
|
||||||
@TableField("TENANT_ID")
|
|
||||||
private String tenantId;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 最近修改者
|
* 最近修改者
|
||||||
*/
|
*/
|
||||||
@ -6,7 +6,6 @@ import lombok.EqualsAndHashCode;
|
|||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.sql.Timestamp;
|
import java.sql.Timestamp;
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -79,12 +78,6 @@ public class SysUser implements Serializable {
|
|||||||
*/
|
*/
|
||||||
private String orgid;
|
private String orgid;
|
||||||
|
|
||||||
/**
|
|
||||||
* 租户ID
|
|
||||||
*/
|
|
||||||
@TableField("TENANT_ID")
|
|
||||||
private String tenantId;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 密码重置时间
|
* 密码重置时间
|
||||||
*/
|
*/
|
||||||
@ -122,57 +115,6 @@ public class SysUser implements Serializable {
|
|||||||
*/
|
*/
|
||||||
private String custom3;
|
private String custom3;
|
||||||
|
|
||||||
/**
|
|
||||||
* 真实姓名(注册必填)
|
|
||||||
*/
|
|
||||||
private String realName;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 审批状态(PENDING待审批 / APPROVED已通过 / REJECTED已驳回)
|
|
||||||
*/
|
|
||||||
private String regStatus;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 审核人ID
|
|
||||||
*/
|
|
||||||
private String auditUser;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 所属单位
|
|
||||||
*/
|
|
||||||
private String belongingUnit;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 审核时间
|
|
||||||
*/
|
|
||||||
private Date auditTime;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 注册申请时间
|
|
||||||
*/
|
|
||||||
private Date regTime;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 集团编号
|
|
||||||
*/
|
|
||||||
private String groupCode;
|
|
||||||
/**
|
|
||||||
* 公司编号
|
|
||||||
*/
|
|
||||||
private String companyCode;
|
|
||||||
|
|
||||||
@TableField(exist = false)
|
|
||||||
/**
|
|
||||||
* 登录密码(加密存储)
|
|
||||||
*/
|
|
||||||
private String oldPassword;
|
|
||||||
|
|
||||||
@TableField(exist = false)
|
@TableField(exist = false)
|
||||||
List<SysRole> roles;
|
List<SysRole> roles;
|
||||||
|
|
||||||
@TableField(exist = false)
|
|
||||||
private String basinNames;
|
|
||||||
|
|
||||||
@TableField(exist = false)
|
|
||||||
private String stationNames;
|
|
||||||
}
|
}
|
||||||
@ -25,10 +25,7 @@ public interface SysMenuMapper extends BaseMapper<SysMenu> {
|
|||||||
*upOrderno 大于等于序号(更改的序号加一)
|
*upOrderno 大于等于序号(更改的序号加一)
|
||||||
* 返回值说明: 是否更新成功
|
* 返回值说明: 是否更新成功
|
||||||
***********************************/
|
***********************************/
|
||||||
boolean upMoveOrderno(@Param("parentid") String parentid,
|
boolean upMoveOrderno(@Param("parentid") String parentid, @Param("Orderno") int Orderno, @Param("upOrderno") int upOrderno);
|
||||||
@Param("Orderno") int Orderno,
|
|
||||||
@Param("upOrderno") int upOrderno,
|
|
||||||
@Param("tenantId") String tenantId);
|
|
||||||
|
|
||||||
/***********************************
|
/***********************************
|
||||||
* 用途说明:菜单及按钮序号向下移动
|
* 用途说明:菜单及按钮序号向下移动
|
||||||
@ -38,16 +35,13 @@ public interface SysMenuMapper extends BaseMapper<SysMenu> {
|
|||||||
*downOrderno 小于等于序号(更改的序号减一)
|
*downOrderno 小于等于序号(更改的序号减一)
|
||||||
* 返回值说明: 是否更新成功
|
* 返回值说明: 是否更新成功
|
||||||
***********************************/
|
***********************************/
|
||||||
boolean downMoveOrderno(@Param("parentid") String parentid,
|
boolean downMoveOrderno(@Param("parentid") String parentid, @Param("Orderno") int Orderno, @Param("downOrderno") int downOrderno);
|
||||||
@Param("Orderno") int Orderno,
|
|
||||||
@Param("downOrderno") int downOrderno,
|
|
||||||
@Param("tenantId") String tenantId);
|
|
||||||
|
|
||||||
|
|
||||||
List<String> selectPermsByUserId(String userId);
|
List<String> selectPermsByUserId(String userId);
|
||||||
|
|
||||||
//List<SysMenu> selectMenuByUserId(String userId);
|
//List<SysMenu> selectMenuByUserId(String userId);
|
||||||
List<SysMenu> selectMenuByUserId(@Param("userId") String userId, @Param("tenantId") String tenantId);
|
List<SysMenu> selectMenuByUserId(String userId);
|
||||||
|
|
||||||
/***********************************
|
/***********************************
|
||||||
* 用途说明:根据权限id查找系统类型
|
* 用途说明:根据权限id查找系统类型
|
||||||
@ -61,5 +55,5 @@ public interface SysMenuMapper extends BaseMapper<SysMenu> {
|
|||||||
* 参数说明 id 权限id
|
* 参数说明 id 权限id
|
||||||
* 返回值说明: 返回权限集合
|
* 返回值说明: 返回权限集合
|
||||||
***********************************/
|
***********************************/
|
||||||
List<String> selectMenuByRoleId(@Param("id") String id, @Param("tenantId") String tenantId);
|
List<String> selectMenuByRoleId(String id);
|
||||||
}
|
}
|
||||||
@ -44,13 +44,8 @@ public interface SysRoleMapper extends BaseMapper<SysRole> {
|
|||||||
* isvaild 角色是否有效
|
* isvaild 角色是否有效
|
||||||
* 返回值说明: 系统用户角色数据集合
|
* 返回值说明: 系统用户角色数据集合
|
||||||
***********************************/
|
***********************************/
|
||||||
List<Map> listRoleUsers(@Param("orgid") String orgid,
|
List<Map> listRoleUsers(String orgid, String username, String status,
|
||||||
@Param("username") String username,
|
String level, String rolename, String isvaild);
|
||||||
@Param("status") String status,
|
|
||||||
@Param("level") String level,
|
|
||||||
@Param("rolename") String rolename,
|
|
||||||
@Param("isvaild") String isvaild,
|
|
||||||
@Param("tenantId") String tenantId);
|
|
||||||
|
|
||||||
/***********************************
|
/***********************************
|
||||||
* 用途说明:根据 角色id和用户id 删除 (admin除外)
|
* 用途说明:根据 角色id和用户id 删除 (admin除外)
|
||||||
@ -68,12 +63,6 @@ public interface SysRoleMapper extends BaseMapper<SysRole> {
|
|||||||
***********************************/
|
***********************************/
|
||||||
List<SysRole> getRoleByUserId(String id);
|
List<SysRole> getRoleByUserId(String id);
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 批量获取用户角色(含userId映射)
|
|
||||||
*/
|
|
||||||
List<Map<String, Object>> getUserRolesByUserIds(@Param("userIds") List<String> userIds);
|
|
||||||
|
|
||||||
/**********************************
|
/**********************************
|
||||||
* 用途说明: 根据角色ID删除菜单与角色关联信息
|
* 用途说明: 根据角色ID删除菜单与角色关联信息
|
||||||
* 参数说明 id 角色id
|
* 参数说明 id 角色id
|
||||||
@ -118,6 +107,6 @@ public interface SysRoleMapper extends BaseMapper<SysRole> {
|
|||||||
* 参数说明:rolename - 角色名称
|
* 参数说明:rolename - 角色名称
|
||||||
* 返回值说明:角色列表
|
* 返回值说明:角色列表
|
||||||
***********************************/
|
***********************************/
|
||||||
List<SysRole> selectRoleList(@Param("rolename") String rolename, @Param("tenantId") String tenantId);
|
List<SysRole> selectRoleList(@Param("rolename") String rolename);
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1,7 +1,6 @@
|
|||||||
package com.yfd.platform.system.mapper;
|
package com.yfd.platform.system.mapper;
|
||||||
|
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
||||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.yfd.platform.system.domain.SysUser;
|
import com.yfd.platform.system.domain.SysUser;
|
||||||
@ -62,7 +61,7 @@ public interface SysUserMapper extends BaseMapper<SysUser> {
|
|||||||
* userid 用户id
|
* userid 用户id
|
||||||
* 返回值说明:
|
* 返回值说明:
|
||||||
************************************/
|
************************************/
|
||||||
String getMaxLevel(@Param("userId") String userId);
|
String getMaxLevel(@Param("userid") String userid);
|
||||||
|
|
||||||
/***********************************
|
/***********************************
|
||||||
* 用途说明:根据用户id删除所分配的角色
|
* 用途说明:根据用户id删除所分配的角色
|
||||||
@ -81,10 +80,9 @@ public interface SysUserMapper extends BaseMapper<SysUser> {
|
|||||||
************************************/
|
************************************/
|
||||||
boolean delInRoleUsersByUserid(@Param("userid") String userid,@Param("roleids")String[] roleids);
|
boolean delInRoleUsersByUserid(@Param("userid") String userid,@Param("roleids")String[] roleids);
|
||||||
|
|
||||||
Page<SysUser> queryUsers(@Param("orgid") String orgid,
|
Page<SysUser> queryUsers(String orgid,
|
||||||
@Param("username") String username,
|
String username,
|
||||||
@Param("tenantId") String tenantId,
|
Page<SysUser> page);
|
||||||
Page<SysUser> page);
|
|
||||||
|
|
||||||
Map<String, String> getOrganizationByid(String id);
|
Map<String, String> getOrganizationByid(String id);
|
||||||
|
|
||||||
@ -3,10 +3,6 @@ package com.yfd.platform.system.service;
|
|||||||
import com.baomidou.mybatisplus.extension.service.IService;
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
import com.yfd.platform.system.domain.SysConfig;
|
import com.yfd.platform.system.domain.SysConfig;
|
||||||
|
|
||||||
import javax.sound.sampled.UnsupportedAudioFileException;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* 系统全局配置 服务类
|
* 系统全局配置 服务类
|
||||||
@ -44,11 +44,4 @@ public interface ISysDictionaryItemsService extends IService<SysDictionaryItems>
|
|||||||
* 返回值说明: com.yfd.platform.config.ResponseResult 返回导出成功或失败
|
* 返回值说明: com.yfd.platform.config.ResponseResult 返回导出成功或失败
|
||||||
***********************************/
|
***********************************/
|
||||||
void exportExcel(List<SysDictionaryItems> records, HttpServletResponse response);
|
void exportExcel(List<SysDictionaryItems> records, HttpServletResponse response);
|
||||||
|
|
||||||
/**********************************
|
|
||||||
* 用途说明: 根据字典ID查询字典项列表
|
|
||||||
* 参数说明 dictId 字典ID
|
|
||||||
* 返回值说明: List<SysDictionaryItems> 字典项列表
|
|
||||||
***********************************/
|
|
||||||
List<SysDictionaryItems> listByDictId(String dictId);
|
|
||||||
}
|
}
|
||||||
@ -42,11 +42,4 @@ public interface ISysDictionaryService extends IService<SysDictionary> {
|
|||||||
* 返回值说明: com.yfd.platform.config.ResponseResult 返回拖动成功或者失败
|
* 返回值说明: com.yfd.platform.config.ResponseResult 返回拖动成功或者失败
|
||||||
***********************************/
|
***********************************/
|
||||||
boolean changeDictOrder(String fromID, String toID);
|
boolean changeDictOrder(String fromID, String toID);
|
||||||
|
|
||||||
/**********************************
|
|
||||||
* 用途说明: 根据字典编号查询字典
|
|
||||||
* 参数说明 dictCode 字典编号
|
|
||||||
* 返回值说明: SysDictionary 字典对象
|
|
||||||
***********************************/
|
|
||||||
SysDictionary getByDictCode(String dictCode);
|
|
||||||
}
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user