init
This commit is contained in:
24
.gitignore
vendored
Normal file
24
.gitignore
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
# 默认忽略的文件
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# 基于编辑器的 HTTP 客户端请求
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
||||
|
||||
.idea
|
||||
.vscode
|
||||
.trae
|
||||
|
||||
target
|
||||
logs
|
||||
|
||||
deployment.log.jsonl
|
||||
/src/main/resources/prompts.txt
|
||||
|
||||
prompts.txt
|
||||
/src/main/resources/test.json
|
||||
|
||||
*.pyc
|
||||
pycache/
|
||||
29
Dockerfile
Normal file
29
Dockerfile
Normal file
@@ -0,0 +1,29 @@
|
||||
# 贝尔实验室 Spring 官方推荐镜像 JDK下载地址 https://bell-sw.com/pages/downloads/
|
||||
FROM bellsoft/liberica-openjdk-rocky:17.0.16-cds
|
||||
#FROM bellsoft/liberica-openjdk-rocky:21.0.8-cds
|
||||
#FROM findepi/graalvm:java17-native
|
||||
|
||||
LABEL maintainer="shihongwei"
|
||||
|
||||
RUN mkdir -p /hot-platform/server/logs \
|
||||
/hot-platform/server/temp \
|
||||
/hot-platform/skywalking/agent
|
||||
|
||||
WORKDIR /hot-platform/server
|
||||
|
||||
ENV SERVER_PORT=19090 SNAIL_PORT=28080 LANG=C.UTF-8 LC_ALL=C.UTF-8 JAVA_OPTS="" TZ=Asia/Shanghai
|
||||
|
||||
EXPOSE ${SERVER_PORT}
|
||||
# 暴露 snail job 客户端端口 用于定时任务调度中心通信
|
||||
EXPOSE ${SNAIL_PORT}
|
||||
|
||||
ADD ./target/hot-platform.jar ./app.jar
|
||||
|
||||
SHELL ["/bin/bash", "-c"]
|
||||
|
||||
ENTRYPOINT java -Djava.security.egd=file:/dev/./urandom -Dserver.port=${SERVER_PORT} \
|
||||
-Dsnail-job.port=${SNAIL_PORT} \
|
||||
-Duser.timezone=Asia/Shanghai \
|
||||
-XX:+HeapDumpOnOutOfMemoryError -XX:+UseZGC ${JAVA_OPTS} \
|
||||
-jar app.jar
|
||||
|
||||
63
README.md
Normal file
63
README.md
Normal file
@@ -0,0 +1,63 @@
|
||||
# HOT交通安全管理清单平台 后端服务
|
||||
|
||||
**项目概览**
|
||||
- 基于 `Spring Boot 3.5.7`、`Java 17` 的后端服务,提供系统管理、代码生成、工作流等能力。
|
||||
- 项目坐标:`com.hotwj:hot-platform:1.0.0`(pom.xml:15-17),构件名:`hot-backend`(pom.xml:18)。
|
||||
- 默认打包为可执行 `jar`(build.finalName 为 `hot-platform`,pom.xml:409-411)。
|
||||
|
||||
**技术栈**
|
||||
- Web与容器:`spring-boot-starter-web`(Undertow 容器,pom.xml:336-351),`spring-webmvc`(pom.xml:157-160)。
|
||||
- ORM与数据源:`mybatis-plus`(pom.xml:162-175)、`dynamic-datasource`(pom.xml:232-237)。
|
||||
- 安全与认证:`Sa-Token`(pom.xml:303-322),JWT 集成。
|
||||
- 缓存与并发:`redisson`(pom.xml:284-289)、`lock4j`(pom.xml:291-295)、`caffeine`(pom.xml:297-301)。
|
||||
- 文档与OpenAPI:`springdoc-openapi`(pom.xml:134-138、400-405)。
|
||||
- 任务与调度:`snail-job` 客户端(pom.xml:192-203)。
|
||||
- 工作流:`warm-flow`(pom.xml:377-386)。
|
||||
- 存储与工具:`AWS S3 SDK`(pom.xml:246-282)、`hutool`(pom.xml:115-119)、`mapstruct-plus`(pom.xml:121-125)。
|
||||
- 其他:`velocity` 模板引擎(pom.xml:358-363)、`ip2region`(pom.xml:127-132)、`JustAuth` 社交登录(pom.xml:330-334)、`jakarta.mail`(pom.xml:223-230)。
|
||||
|
||||
**环境要求**
|
||||
- `JDK 17+`(pom.xml:26)。
|
||||
- `Maven 3.9+`。
|
||||
- 数据库:`MySQL 8.0.x`(pom.xml:58、72-77)。
|
||||
|
||||
**快速开始**
|
||||
- 配置环境:`application.yml` 默认激活 `dev`(src/main/resources/application.yml:73)。
|
||||
- 开发运行:
|
||||
- 使用 Maven 插件直接运行:`mvn spring-boot:run -Dspring-boot.run.profiles=dev`
|
||||
- 或打包运行:
|
||||
- `mvn clean package -DskipTests=true`
|
||||
- `java -jar target/hot-platform.jar --spring.profiles.active=dev`
|
||||
- 生产运行:`java -jar target/hot-platform.jar --spring.profiles.active=prod`
|
||||
|
||||
**构建说明**
|
||||
- 默认打包跳过测试(pom.xml:65-67),如需执行测试:`mvn clean package -DskipTests=false`。
|
||||
- 生成的可执行包名为 `hot-platform.jar`(由 `finalName` 决定,pom.xml:409-411)。
|
||||
- 支持 `spring-boot-maven-plugin` 重打包(pom.xml:412-422),可用 `spring-boot:run` 快速启动。
|
||||
|
||||
**配置要点**
|
||||
- 端口与上下文:`server.port=8080`、`context-path=/`(src/main/resources/application.yml:3-7)。
|
||||
- Undertow 线程与缓冲配置(src/main/resources/application.yml:8-21)。
|
||||
- 日志:`logback-plus.xml`(src/main/resources/application.yml:43)。
|
||||
- 国际化:`spring.messages.basename=i18n/messages`(src/main/resources/application.yml:69-71)。
|
||||
- 模块扫描分组(系统/代码生成/工作流 等,src/main/resources/application.yml:211-216)。
|
||||
- 安全与令牌:`sa-token`(src/main/resources/application.yml:98-108)。
|
||||
- WebSocket/SSE:`sse.enabled`、`websocket.enabled`(src/main/resources/application.yml:239-259)。
|
||||
- 工作流:`warm-flow.*`(src/main/resources/application.yml:260-275)。
|
||||
|
||||
**常用端点**
|
||||
- Actuator 健康检查:`/actuator/health`(src/main/resources/application.yml:268-279)。
|
||||
- OpenAPI 文档:`/v3/api-docs`,Swagger UI:`/swagger-ui/index.html`(由 springdoc 依赖启用,pom.xml:400-405)。
|
||||
|
||||
**Docker 运行**
|
||||
- 项目提供 `Dockerfile`(Dockerfile:1-31),基础镜像为 `JDK 17`(Dockerfile:1)。
|
||||
- 镜像构建前需确保 `target` 下存在打包产物。
|
||||
- 当前 `Dockerfile` 的 `ADD` 指向 `ruoyi-admin.jar`(Dockerfile:17),如使用本项目构件,请将其改为 `hot-platform.jar` 或生成同名文件。
|
||||
|
||||
**常用命令**
|
||||
- 清理并打包:`mvn clean package -DskipTests=true`
|
||||
- 执行测试:`mvn test`
|
||||
- 启动(开发):`mvn spring-boot:run -Dspring-boot.run.profiles=dev`
|
||||
- 启动(Jar):`java -jar target/hot-platform.jar --spring.profiles.active=dev`
|
||||
|
||||
|
||||
139
REPORT_SYSTEM_GUIDE.md
Normal file
139
REPORT_SYSTEM_GUIDE.md
Normal file
@@ -0,0 +1,139 @@
|
||||
# 报表打印系统架构与使用说明
|
||||
|
||||
本文档详细介绍了当前报表打印系统的架构设计、核心组件及其使用方法。
|
||||
|
||||
## 1. 架构设计概览
|
||||
|
||||
本系统采用 **Provider 模式** 与 **流式任务构建 (Builder Pattern)** 相结合的设计,旨在实现报表生成的解耦、灵活配置与高扩展性。
|
||||
|
||||
### 核心组件
|
||||
|
||||
1. **IReportDataProvider (报表数据提供者)**
|
||||
* **职责**:定义单一报表的元数据(模版、标题、类型)和数据准备逻辑。
|
||||
* **优势**:将业务逻辑从 Service 层剥离,每个报表对应一个 Provider,互不干扰,易于维护。
|
||||
* **关键方法**:
|
||||
* `getReportType()`: 唯一标识(如 `APPLICATION_FORM`)。
|
||||
* `prepareData(params)`: 准备模版所需的数据。
|
||||
* `getCoverProviderType()`: 定义关联的封面类型(支持自动封面)。
|
||||
|
||||
2. **ReportPrintJob (打印任务构建器)**
|
||||
* **职责**:负责组装打印任务。它像一条流水线,可以按需添加封面、报表片段、设置公章/水印等。
|
||||
* **特性**:
|
||||
* **链式调用**:`createJob().addCover().addBatch().render()`。
|
||||
* **混合布局**:自动处理横向 (Landscape) 与纵向 (Portrait) 页面的合并。
|
||||
* **上下文注入**:支持注入 CompanyId 用于公章/水印生成。
|
||||
|
||||
3. **ReportRenderService (渲染服务)**
|
||||
* **职责**:底层的渲染引擎。
|
||||
* **功能**:
|
||||
* 解析 Velocity 模版。
|
||||
* 调用 Gotenberg 进行 HTML 转 PDF。
|
||||
* 处理水印 (Watermark) 和电子公章 (Seal)。
|
||||
* 合并多个 PDF 片段。
|
||||
|
||||
## 2. 现有报表类型
|
||||
|
||||
目前系统已实现的 Provider 如下:
|
||||
|
||||
| 报表类型 (Type) | Provider 类 | 描述 |
|
||||
| :--- | :--- | :--- |
|
||||
| `APPLICATION_FORM` | `DriverApplicationFormProvider` | 驾驶员应聘申请表 |
|
||||
| `ID_CARD_SCAN` | `IdCardScanProvider` | 身份证扫描件 |
|
||||
| `DRIVER_LICENSE_COPY` | `DriverLicenseCopyProvider` | 驾驶证复印件 |
|
||||
| `QUALIFICATION_CERTIFICATE_COPY` | `QualificationCertificateCopyProvider` | 从业资格证复印件 |
|
||||
| `QUALIFICATION_REVIEW` | `QualificationReviewProvider` | 资格审查及技能考核登记表 |
|
||||
| `ACCIDENT_RECORD` | `AccidentRecordProvider` | 安全行车事故记录 (横向) |
|
||||
| `VIOLATION_RECORD` | `ViolationRecordProvider` | 违章记录 (横向) |
|
||||
| `ANNUAL_ASSESSMENT_RECORD` | `AnnualAssessmentRecordProvider` | 年度考核记录 |
|
||||
| `MEDICAL_EXAMINATION_REPORT` | `MedicalExaminationReportProvider` | 体检报告 |
|
||||
| `REWARD_PUNISHMENT_RECORD` | `RewardPunishmentRecordProvider` | 奖惩记录表 |
|
||||
|
||||
## 3. 使用方法 (开发指南)
|
||||
|
||||
### 3.1 创建新报表
|
||||
|
||||
1. **定义 Provider**:
|
||||
新建一个类实现 `IReportDataProvider`,并注册为 Spring Bean (`@Component`)。
|
||||
```java
|
||||
@Component
|
||||
public class MyReportProvider implements IReportDataProvider {
|
||||
@Override
|
||||
public String getReportType() { return "MY_REPORT"; }
|
||||
|
||||
@Override
|
||||
public String getTemplateCode() { return "templates/my/report.html.vm"; }
|
||||
|
||||
@Override
|
||||
public Map<String, Object> prepareData(Map<String, Object> params) {
|
||||
// 准备数据...
|
||||
return Map.of("data", "value");
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
2. **创建 Velocity 模版**:
|
||||
在 `src/main/resources/templates/my/report.html.vm` 中编写 HTML。
|
||||
|
||||
### 3.2 调用打印服务
|
||||
|
||||
在业务 Service 中注入 `ReportRenderService` 和 `providerMap`,然后使用链式调用:
|
||||
|
||||
#### 场景 A:单个报表打印 (带自动封面)
|
||||
|
||||
```java
|
||||
public byte[] printMyReport(List<String> ids) {
|
||||
// 1. 获取 Provider
|
||||
IReportDataProvider provider = providerMap.get("MY_REPORT");
|
||||
|
||||
// 2. 构建任务
|
||||
return reportRenderService.createJob(providerMap::get) // 传入查找器以支持自动封面
|
||||
.withCompanyId(companyId) // 设置公司ID(用于公章)
|
||||
.addCover(provider) // 自动添加关联封面
|
||||
.addBatch(provider, ids, "id") // 批量添加报表内容
|
||||
.useSeal(true) // 启用公章
|
||||
.render(); // 渲染并返回 PDF
|
||||
}
|
||||
```
|
||||
|
||||
#### 场景 B:一键打印 (多报表合并)
|
||||
|
||||
```java
|
||||
public byte[] printAll(List<String> driverIds, List<String> types) {
|
||||
var job = reportRenderService.createJob(providerMap::get)
|
||||
.withCompanyId(companyId)
|
||||
.useSeal(false); // 全局公章开关
|
||||
|
||||
for (String id : driverIds) {
|
||||
// 1. 为每个驾驶员添加一个独立封面
|
||||
job.addCover("COMMON_COVER", Map.of(
|
||||
"title", "驾驶员档案",
|
||||
"subtitle", "张三"
|
||||
));
|
||||
|
||||
// 2. 依次添加选中的报表
|
||||
for (String type : types) {
|
||||
job.add(providerMap.get(type), Map.of("driverId", id));
|
||||
}
|
||||
}
|
||||
return job.render();
|
||||
}
|
||||
```
|
||||
|
||||
### 3.3 进阶配置
|
||||
|
||||
* **横向布局**:在 Provider 中重写 `isLandscape()` 返回 `true`,或者在 Job 中调用 `.isLandscape(true)` (通常由 Provider
|
||||
决定)。
|
||||
* **自定义封面**:Provider 可重写 `getCoverProviderType()` 指定特定封面,或重写 `getCoverData()` 自定义封面参数。
|
||||
* **水印控制**:`job.useWatermark(true).watermarkText("自定义水印")`。
|
||||
|
||||
## 4. 模版工具支持
|
||||
|
||||
模版中内置了 `$tool` 工具类 (`ReportVelocityTool`),提供常用功能:
|
||||
|
||||
* `$tool.getDictLabel('type', value)`: 字典翻译
|
||||
* `$tool.formatDate(date, 'yyyy-MM-dd')`: 日期格式化
|
||||
* `$tool.getOssUrls(urlStr)`: 解析 OSS 图片链接
|
||||
* `$tool.numberToChinese(num)`: 数字转中文大写
|
||||
|
||||
---
|
||||
*文档生成日期:2026-03-01*
|
||||
43
deploy.sh
Normal file
43
deploy.sh
Normal file
@@ -0,0 +1,43 @@
|
||||
ls#!/bin/bash
|
||||
|
||||
# 定义变量
|
||||
APP_NAME="hot-platform"
|
||||
IMAGE_NAME="hot-platform"
|
||||
PORT_HOST=50004
|
||||
PORT_CONTAINER=19090
|
||||
LOG_DIR="/opt/hot-platform/logs"
|
||||
|
||||
# 停止并删除旧容器
|
||||
if [ "$(docker ps -q -f name=$APP_NAME)" ]; then
|
||||
echo "Stopping existing container..."
|
||||
docker stop $APP_NAME
|
||||
fi
|
||||
|
||||
if [ "$(docker ps -aq -f name=$APP_NAME)" ]; then
|
||||
echo "Removing existing container..."
|
||||
docker rm $APP_NAME
|
||||
fi
|
||||
|
||||
# 删除旧镜像(可选,如果每次都构建新镜像的话建议开启)
|
||||
# if [ "$(docker images -q $IMAGE_NAME)" ]; then
|
||||
# echo "Removing old image..."
|
||||
# docker rmi $IMAGE_NAME
|
||||
# fi
|
||||
|
||||
# 构建新镜像
|
||||
echo "Building new image..."
|
||||
docker build -t $IMAGE_NAME .
|
||||
|
||||
# 启动新容器
|
||||
echo "Starting new container..."
|
||||
docker run -d \
|
||||
--name $APP_NAME \
|
||||
--restart always \
|
||||
--add-host=host.docker.internal:host-gateway \
|
||||
-p $PORT_HOST:$PORT_CONTAINER \
|
||||
-v $LOG_DIR:/hot-platform/server/logs \
|
||||
-e JAVA_OPTS="-Dspring.profiles.active=test" \
|
||||
$IMAGE_NAME
|
||||
|
||||
echo "Container started successfully!"
|
||||
docker logs -f --tail 100 $APP_NAME
|
||||
119
docs/TrainingProgressLogic.md
Normal file
119
docs/TrainingProgressLogic.md
Normal file
@@ -0,0 +1,119 @@
|
||||
# 培训计划学员进度计算逻辑说明
|
||||
|
||||
本文档说明了在生成“在线教育培训月度统计表”时,学员完成培训进度的计算逻辑及相关数据库表关联关系。
|
||||
|
||||
## 1. 总体进度计算逻辑
|
||||
|
||||
学员的培训进度取决于 `hot_training_participant` 表中的状态。
|
||||
|
||||
### 1.1 已完成学员
|
||||
如果学员在 `hot_training_participant` 表中的 `is_completed` 字段为 `1`(或 `complete_time` 不为空),则该学员的进度直接记为 **100%**。
|
||||
这意味着学员已经完成了所有的课程学习以及综合检测(如果有)。
|
||||
|
||||
### 1.2 未完成学员
|
||||
如果学员尚未完成(`is_completed = 0`),则进度计算公式如下:
|
||||
|
||||
$$
|
||||
\text{总进度} = \frac{\sum \text{各课程进度} + \text{综合检测进度}}{\text{课程数量} + 1}
|
||||
$$
|
||||
|
||||
* **课程数量**:当前培训计划包含的课程总数(来自 `hot_training_course_config`)。
|
||||
* **综合检测进度**:对于未完成学员,综合检测部分默认记为 **0%**。
|
||||
* **各课程进度**:见下文详细计算。
|
||||
|
||||
---
|
||||
|
||||
## 2. 单门课程进度计算逻辑
|
||||
|
||||
对于培训计划中的每一门课程,其进度计算取决于该课程是否包含**随堂练习**(题目)。
|
||||
|
||||
### 2.1 判断课程是否有随堂练习
|
||||
1. 通过 `hot_training_course_config` 表找到对应的 `course_id`。
|
||||
2. 查询 `hot_course_resource` 表,条件为 `course_id` 且 `resource_type = 3`(题目)。
|
||||
3. 如果存在记录,则认为该课程包含随堂练习;否则认为不包含。
|
||||
|
||||
### 2.2 课程进度计算公式
|
||||
|
||||
#### 情况 A:无随堂练习
|
||||
$$
|
||||
\text{课程进度} = \text{视频播放进度}
|
||||
$$
|
||||
* **视频播放进度**:取 `hot_training_course_record` 表中该用户该课程的 `progress_rate`(百分比值,最大100)。
|
||||
|
||||
#### 情况 B:有随堂练习
|
||||
$$
|
||||
\text{课程进度} = (\text{视频播放进度} \times 90\%) + (\text{随堂练习得分} \times 10\%)
|
||||
$$
|
||||
* **视频播放进度**:同上。
|
||||
* **随堂练习得分**:
|
||||
* 检查 `hot_training_course_record` 表中的 `check_status` 字段。
|
||||
* 如果 `check_status = 1`(已完成),则得分为 **100**。
|
||||
* 否则,得分为 **0**。
|
||||
|
||||
---
|
||||
|
||||
## 3. 课程时长计算逻辑(分钟)
|
||||
|
||||
“教育培训内容”区域除展示课程名称外,同时展示每门课程的视频总时长(分钟)。
|
||||
|
||||
### 3.1 计算步骤
|
||||
|
||||
1. 通过 `hot_training_course_config` 获取当前培训计划的课程列表(按 `sort_no` 排序),得到每门课的 `course_id`。
|
||||
2. 查询 `hot_course_resource` 表中该 `course_id` 下的视频资源:
|
||||
- 条件:`course_id = ? AND resource_type = 1`(视频)
|
||||
- 得到视频资源 ID 列表:`resource_id`(对应 `hot_media_resource.id`)
|
||||
3. 查询 `hot_media_resource` 表,按资源 ID 集合汇总视频时长:
|
||||
- 汇总字段:`SUM(duration_seconds)`
|
||||
4. 将秒数转换为分钟并向上取整:
|
||||
- `duration_min = ceil(duration_seconds / 60)`
|
||||
|
||||
### 3.2 展示规则
|
||||
|
||||
- 若课程无视频资源或汇总时长为空,则时长列显示空白。
|
||||
- 否则显示 `X分钟`。
|
||||
|
||||
---
|
||||
|
||||
## 4. 学习记录表 - 学习时长计算逻辑
|
||||
|
||||
在“学习记录表”中,会显示“学习分钟数/计划分钟数”。
|
||||
|
||||
### 4.1 计划分钟数
|
||||
逻辑同第3节“课程时长计算逻辑”,为该培训计划下所有课程视频时长的总和(分钟,向上取整)。
|
||||
|
||||
### 4.2 学习分钟数
|
||||
取 `hot_training_course_record` 表中的 `learn_duration_min` 字段。
|
||||
**注意**:尽管字段名为 `min`,但在实际业务中存储的是**秒**。
|
||||
因此计算逻辑为:
|
||||
1. 获取该用户在该培训计划下所有课程的学习记录。
|
||||
2. 若同一课程有多条记录,取 `learn_duration_min` 最大值。
|
||||
3. **对于每一门课程,将其学习时长与该课程的计划视频时长进行比较,取较小值(即学习时长不大于课程时长)。**
|
||||
4. 累加所有课程的**处理后时长**(秒)。
|
||||
5. 将总秒数除以 60 并向上取整,得到最终的学习分钟数。
|
||||
|
||||
---
|
||||
|
||||
## 5. 数据库表关联关系
|
||||
|
||||
以下是涉及的关键数据库表及其关联方式:
|
||||
|
||||
1. **hot_training (培训计划主表)**
|
||||
* `id`: 培训计划ID
|
||||
|
||||
2. **hot_training_participant (培训参与人员表)**
|
||||
* `training_id`: 关联 `hot_training.id`
|
||||
* `user_id`: 学员ID
|
||||
* `is_completed`: 是否完成培训 (1=是, 0=否)
|
||||
* `complete_time`: 完成时间
|
||||
|
||||
3. **hot_training_course_config (培训课程配置表)**
|
||||
* `training_id`: 关联 `hot_training.id`
|
||||
* `course_id`: 关联 `hot_course.id` (实际课程ID)
|
||||
* `id`: 培训课程配置ID (用于关联学习记录)
|
||||
|
||||
4. **hot_course_resource (课程资源关联表)**
|
||||
* `course_id`: 关联 `hot_course.id`
|
||||
* `resource_type`: 资源类型 (1=视频 2=音频 3=题目)
|
||||
* 用于判断课程是否有随堂练习。
|
||||
|
||||
5. **hot_training_course_record (培训课程学习记录表)**
|
||||
99
docs/dev_specs.md
Normal file
99
docs/dev_specs.md
Normal file
@@ -0,0 +1,99 @@
|
||||
# 车辆档案打印功能开发规范
|
||||
|
||||
## 1. 核心技术栈
|
||||
* **模板引擎**: Velocity (`.html.vm`)
|
||||
* **PDF生成**: Gotenberg (HTML转PDF)
|
||||
* **水印处理**: PDFBox (`PdfWatermarkUtil`)
|
||||
* **存储**: OSS (图片URL处理)
|
||||
|
||||
## 2. 通用样式与布局规范 (Template)
|
||||
所有打印模板位于 `src/main/resources/templates/vehicle/` 目录下。
|
||||
|
||||
### 2.1 页面布局
|
||||
* **纸张设置**: A4 纵向 (Vertical)。
|
||||
* **容器宽度**: `.page-content` 宽度建议设置为 **99%** 或留出微小边距,防止浏览器预览或打印时**右侧边框**被截断。
|
||||
* **表格样式**:
|
||||
* 必须使用标准 HTML `<table>`。
|
||||
* 边框合并: `border-collapse: collapse;`。
|
||||
* 边框线条: 统一使用细线 (`1px solid #000` 或 `#333`),避免出现粗细不一的视觉效果。
|
||||
* **禁止**使用 `<div>` 模拟表格边框,防止分页截断错位。
|
||||
|
||||
### 2.2 图片展示 (核心优化)
|
||||
* **容器**: 图片必须放置在表格单元格 (`<td>`) 内部。
|
||||
* **布局方式**: 使用 Flex 布局 (`display: flex; flex-wrap: wrap;`)。
|
||||
* **动态宽度逻辑** (Velocity):
|
||||
* **单张图片**: 宽度设为 **98%** (占满整行),居中显示。
|
||||
* **多张图片**: 宽度设为 **48%** (一行两张),保留 1% 间距。
|
||||
* **样式代码参考**:
|
||||
```html
|
||||
<div style="display: flex; flex-wrap: wrap; justify-content: flex-start;">
|
||||
#if($images.size() == 1)
|
||||
#set($widthStyle = "width: 98%;")
|
||||
#else
|
||||
#set($widthStyle = "width: 48%;")
|
||||
#end
|
||||
#foreach($img in $images)
|
||||
<div style="$!widthStyle height: 350px; margin: 1%; display: flex; align-items: center; justify-content: center; border: 1px solid #eee;">
|
||||
<img src="$!img" style="max-width: 100%; max-height: 100%; object-fit: contain;" />
|
||||
</div>
|
||||
#end
|
||||
</div>
|
||||
```
|
||||
|
||||
### 2.3 水印设置
|
||||
* **位置调整**: 为防止 A4 纵向打印时最后一行水印被截断,Y 轴偏移量需增加。
|
||||
* **代码位置**: `PdfWatermarkUtil.java`
|
||||
* **参数**: `y + 100` (原为 `y + 50`)。
|
||||
|
||||
---
|
||||
|
||||
## 3. 后端接口开发规范 (Java)
|
||||
|
||||
### 3.1 接口定义
|
||||
* **Controller**: `VehicleFileController`
|
||||
* **Service**: `IVehicleFilePrintService`
|
||||
* **请求方式**: `POST` (支持批量打印)
|
||||
* **参数**: `List<Long> vehicleIds`
|
||||
* **响应**: `void` (写入 `HttpServletResponse` 流,Content-Type: `application/pdf`)
|
||||
|
||||
### 3.2 数据查询逻辑
|
||||
所有打印业务需遵循“**取最新一条记录**”的原则:
|
||||
1. **查询条件**: `vehicle_id`
|
||||
2. **排序**: 按业务时间或完成时间 **倒序** (`orderByDesc`)
|
||||
3. **限制**: 取第一条 (`LIMIT 1`)
|
||||
4. **容错**:
|
||||
* 如果记录不存在 (`null`),跳过该车辆 (`continue`)。
|
||||
* **数据补全**: 如果业务表中缺失关键信息(如 `plateNumber`),**必须**回查 `hot_vehicle` 基础表进行补全。
|
||||
|
||||
### 3.3 图片URL处理
|
||||
* 数据库中图片通常以逗号分隔字符串存储 (`img1.jpg,img2.jpg`)。
|
||||
* **必须**使用 `splitUrls` 方法分割为 `List<String>`。
|
||||
* **必须**通过 `ossService.selectUrlByIds` 处理(如需签名或转换)。
|
||||
|
||||
---
|
||||
|
||||
## 4. 具体业务模块规范
|
||||
|
||||
### 4.1 车辆年审报告 (Inspection Report)
|
||||
* **接口地址**: `/vehicle/file/inspectionReport`
|
||||
* **数据源表**: `hot_vehicle_annual_review`
|
||||
* **关键字段**: `review_date` (年审日期), `image_urls` (附件)
|
||||
* **模板文件**: `inspectionReport.html.vm`
|
||||
* **特殊要求**:
|
||||
* 评定等级需转义 (1=一级, 2=二级)。
|
||||
* 所有附件图片需放入表格行中。
|
||||
|
||||
### 4.2 车辆二级维护记录 (Maintenance Record)
|
||||
* **接口地址**: `/vehicle/file/maintenanceRecord`
|
||||
* **数据源表**: `hot_vehicle_maintenance`
|
||||
* **关键字段**:
|
||||
* `finish_time` (完成时间 - 排序依据)
|
||||
* `entry_inspect_image_urls` (进厂检验单)
|
||||
* `process_inspect_image_urls` (过程检验单)
|
||||
* `final_inspect_image_urls` (竣工检验单)
|
||||
* `factory_cert_image_urls` (出厂合格证)
|
||||
* **模板文件**: `maintenanceRecord.html.vm`
|
||||
* **特殊要求**:
|
||||
* **纯表格布局**: 整个页面(包括标题、信息、四类图片)全部在 `<table>` 内部。
|
||||
* **标题样式**: 表格内的分类标题(如“竣工检验单”)**不需要**背景色,字体加粗居中。
|
||||
* **图片布局**: 严格执行“单张全宽、多张半宽”的动态布局规则。
|
||||
542
pom.xml
Normal file
542
pom.xml
Normal file
@@ -0,0 +1,542 @@
|
||||
<?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>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>3.5.7</version>
|
||||
<relativePath/>
|
||||
</parent>
|
||||
|
||||
<groupId>com.hotwj</groupId>
|
||||
<artifactId>hot-platform</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<name>hot-backend</name>
|
||||
<description>hot平台后端</description>
|
||||
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
|
||||
<java.version>17</java.version>
|
||||
<maven.build.timestamp.format>yyyy-MM-dd'T'HH:mm:ssXXX</maven.build.timestamp.format>
|
||||
|
||||
<springdoc.version>2.8.13</springdoc.version>
|
||||
<therapi-javadoc.version>0.15.0</therapi-javadoc.version>
|
||||
<fastexcel.version>1.3.0</fastexcel.version>
|
||||
<velocity.version>2.3</velocity.version>
|
||||
<satoken.version>1.44.0</satoken.version>
|
||||
<mybatis-plus.version>3.5.14</mybatis-plus.version>
|
||||
<p6spy.version>3.9.1</p6spy.version>
|
||||
<hutool.version>5.8.40</hutool.version>
|
||||
<spring-boot-admin.version>3.5.5</spring-boot-admin.version>
|
||||
<redisson.version>3.51.0</redisson.version>
|
||||
<lock4j.version>2.2.7</lock4j.version>
|
||||
<dynamic-ds.version>4.3.1</dynamic-ds.version>
|
||||
<snailjob.version>1.8.0</snailjob.version>
|
||||
<mapstruct-plus.version>1.5.0</mapstruct-plus.version>
|
||||
<mapstruct-plus.lombok.version>0.2.0</mapstruct-plus.lombok.version>
|
||||
<lombok.version>1.18.40</lombok.version>
|
||||
<bouncycastle.version>1.80</bouncycastle.version>
|
||||
<justauth.version>1.16.7</justauth.version>
|
||||
<!-- 离线IP地址定位库 -->
|
||||
<ip2region.version>2.7.0</ip2region.version>
|
||||
<!-- OSS 配置 -->
|
||||
<aws.sdk.version>2.28.22</aws.sdk.version>
|
||||
<!-- SMS 配置 -->
|
||||
<sms4j.version>3.3.5</sms4j.version>
|
||||
<!-- 限制框架中的fastjson版本 -->
|
||||
<fastjson.version>2.0.60</fastjson.version>
|
||||
<!-- 面向运行时的D-ORM依赖 -->
|
||||
<anyline.version>8.7.2-20250603</anyline.version>
|
||||
<!-- 工作流配置 -->
|
||||
<warm-flow.version>1.8.2</warm-flow.version>
|
||||
<mysql.version>9.5.0</mysql.version>
|
||||
|
||||
<!-- 工具 -->
|
||||
<commons-text.version>1.15.0</commons-text.version>
|
||||
|
||||
<!-- 插件版本 -->
|
||||
<maven-jar-plugin.version>3.4.2</maven-jar-plugin.version>
|
||||
<maven-war-plugin.version>3.4.0</maven-war-plugin.version>
|
||||
<maven-compiler-plugin.version>3.14.0</maven-compiler-plugin.version>
|
||||
<maven-surefire-plugin.version>3.5.3</maven-surefire-plugin.version>
|
||||
<flatten-maven-plugin.version>1.3.0</flatten-maven-plugin.version>
|
||||
<!-- 打包默认跳过测试 -->
|
||||
<skipTests>true</skipTests>
|
||||
</properties>
|
||||
|
||||
|
||||
<dependencies>
|
||||
|
||||
<!-- MySQL Driver -->
|
||||
<dependency>
|
||||
<groupId>com.mysql</groupId>
|
||||
<artifactId>mysql-connector-j</artifactId>
|
||||
<version>${mysql.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!--常用工具类 -->
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>3.18.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- ImageIO 扩展:支持CMYK JPG等更多格式 -->
|
||||
<dependency>
|
||||
<groupId>com.twelvemonkeys.imageio</groupId>
|
||||
<artifactId>imageio-jpeg</artifactId>
|
||||
<version>3.12.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.twelvemonkeys.imageio</groupId>
|
||||
<artifactId>imageio-tiff</artifactId>
|
||||
<version>3.12.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.twelvemonkeys.imageio</groupId>
|
||||
<artifactId>imageio-webp</artifactId>
|
||||
<version>3.12.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Hutool工具类 -->
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-all</artifactId>
|
||||
<version>${hutool.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- MapStruct 工具类 -->
|
||||
<dependency>
|
||||
<groupId>io.github.linpeilie</groupId>
|
||||
<artifactId>mapstruct-plus-spring-boot-starter</artifactId>
|
||||
<version>${mapstruct-plus.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 离线IP地址定位库 -->
|
||||
<dependency>
|
||||
<groupId>org.lionsoul</groupId>
|
||||
<artifactId>ip2region</artifactId>
|
||||
<version>${ip2region.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 加密工具类 -->
|
||||
<dependency>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<artifactId>bcprov-jdk15to18</artifactId>
|
||||
<version>${bouncycastle.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- MyBatis-Plus 依赖 -->
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
|
||||
<version>${mybatis-plus.version}</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<!-- jdk 11+ 引入可选模块 -->
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-jsqlparser</artifactId>
|
||||
<version>${mybatis-plus.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 快速导出Excel工具类 -->
|
||||
<dependency>
|
||||
<groupId>cn.idev.excel</groupId>
|
||||
<artifactId>fastexcel</artifactId>
|
||||
<version>${fastexcel.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- WebSocket 支持 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-websocket</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- SnailJob client -->
|
||||
<dependency>
|
||||
<groupId>com.aizuda</groupId>
|
||||
<artifactId>snail-job-client-starter</artifactId>
|
||||
<version>${snailjob.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- SnailJob 核心作业组件 -->
|
||||
<dependency>
|
||||
<groupId>com.aizuda</groupId>
|
||||
<artifactId>snail-job-client-job-core</artifactId>
|
||||
<version>${snailjob.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Lombok 注解库(编译期) -->
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>${lombok.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 邮件发送:Jakarta Mail API + 实现(Angus Mail) -->
|
||||
<dependency>
|
||||
<groupId>jakarta.mail</groupId>
|
||||
<artifactId>jakarta.mail-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.angus</groupId>
|
||||
<artifactId>jakarta.mail</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- dynamic-datasource 多数据源-->
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>dynamic-datasource-spring-boot3-starter</artifactId>
|
||||
<version>${dynamic-ds.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- sql性能分析插件 -->
|
||||
<dependency>
|
||||
<groupId>p6spy</groupId>
|
||||
<artifactId>p6spy</artifactId>
|
||||
<version>${p6spy.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- AWS SDK for Java 2.x -->
|
||||
<dependency>
|
||||
<groupId>software.amazon.awssdk</groupId>
|
||||
<artifactId>s3</artifactId>
|
||||
<version>${aws.sdk.version}</version>
|
||||
<exclusions>
|
||||
<!-- 将基于 CRT 的 HTTP 客户端从类路径中移除 -->
|
||||
<exclusion>
|
||||
<groupId>software.amazon.awssdk</groupId>
|
||||
<artifactId>aws-crt-client</artifactId>
|
||||
</exclusion>
|
||||
<!-- 将基于 Apache 的 HTTP 客户端从类路径中移除 -->
|
||||
<exclusion>
|
||||
<groupId>software.amazon.awssdk</groupId>
|
||||
<artifactId>apache-client</artifactId>
|
||||
</exclusion>
|
||||
<!-- 将配置基于 URL 连接的 HTTP 客户端从类路径中移除 -->
|
||||
<exclusion>
|
||||
<groupId>software.amazon.awssdk</groupId>
|
||||
<artifactId>url-connection-client</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<!-- 引入基于 Netty 的 HTTP 客户端 -->
|
||||
<dependency>
|
||||
<groupId>software.amazon.awssdk</groupId>
|
||||
<artifactId>netty-nio-client</artifactId>
|
||||
<version>${aws.sdk.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 基于 AWS CRT 的 S3 客户端的性能增强的 S3 传输管理器 -->
|
||||
<dependency>
|
||||
<groupId>software.amazon.awssdk</groupId>
|
||||
<artifactId>s3-transfer-manager</artifactId>
|
||||
<version>${aws.sdk.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!--redisson-->
|
||||
<dependency>
|
||||
<groupId>org.redisson</groupId>
|
||||
<artifactId>redisson-spring-boot-starter</artifactId>
|
||||
<version>${redisson.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 分布式锁:Lock4j 与 Redisson 集成 -->
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>lock4j-redisson-spring-boot-starter</artifactId>
|
||||
<version>${lock4j.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 本地缓存:Caffeine -->
|
||||
<dependency>
|
||||
<groupId>com.github.ben-manes.caffeine</groupId>
|
||||
<artifactId>caffeine</artifactId>
|
||||
|
||||
</dependency>
|
||||
|
||||
<!-- Sa-Token 权限认证, 在线文档:http://sa-token.dev33.cn/ -->
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-spring-boot3-starter</artifactId>
|
||||
<version>${satoken.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Sa-Token 整合 jwt -->
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-jwt</artifactId>
|
||||
<version>${satoken.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 短信发送框架:SMS4J -->
|
||||
<dependency>
|
||||
<groupId>org.dromara.sms4j</groupId>
|
||||
<artifactId>sms4j-spring-boot-starter</artifactId>
|
||||
<version>${sms4j.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 第三方登录:JustAuth -->
|
||||
<dependency>
|
||||
<groupId>me.zhyd.oauth</groupId>
|
||||
<artifactId>JustAuth</artifactId>
|
||||
<version>${justauth.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- SpringBoot Web容器 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>spring-boot-starter-tomcat</artifactId>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<!-- web 容器使用 undertow 性能更强 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-undertow</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Spring Boot 监控端点:Actuator -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 测试依赖 -->
|
||||
<dependency>
|
||||
<groupId>net.jthink</groupId>
|
||||
<artifactId>jaudiotagger</artifactId>
|
||||
<version>3.0.1</version>
|
||||
</dependency>
|
||||
|
||||
<!-- mp4parser -->
|
||||
<dependency>
|
||||
<groupId>org.mp4parser</groupId>
|
||||
<artifactId>isoparser</artifactId>
|
||||
<version>1.9.41</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-inline</artifactId>
|
||||
<version>5.2.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<!--velocity代码生成使用模板 -->
|
||||
<dependency>
|
||||
<groupId>org.apache.velocity</groupId>
|
||||
<artifactId>velocity-engine-core</artifactId>
|
||||
<version>${velocity.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- AnyLine 与 Spring Data JDBC 适配 -->
|
||||
<dependency>
|
||||
<groupId>org.anyline</groupId>
|
||||
<artifactId>anyline-environment-spring-data-jdbc</artifactId>
|
||||
<version>${anyline.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- AnyLine MySQL JDBC 适配器 -->
|
||||
<dependency>
|
||||
<groupId>org.anyline</groupId>
|
||||
<artifactId>anyline-data-jdbc-mysql</artifactId>
|
||||
<version>${anyline.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 工作流:Warm Flow 与 MyBatis-Plus 集成 -->
|
||||
<dependency>
|
||||
<groupId>org.dromara.warm</groupId>
|
||||
<artifactId>warm-flow-mybatis-plus-sb3-starter</artifactId>
|
||||
<version>${warm-flow.version}</version>
|
||||
</dependency>
|
||||
<!-- 工作流:Warm Flow Web 插件 UI -->
|
||||
<dependency>
|
||||
<groupId>org.dromara.warm</groupId>
|
||||
<artifactId>warm-flow-plugin-ui-sb-web</artifactId>
|
||||
<version>${warm-flow.version}</version>
|
||||
</dependency>
|
||||
<!-- JetBrains 注解(@NotNull 等) -->
|
||||
<dependency>
|
||||
<groupId>org.jetbrains</groupId>
|
||||
<artifactId>annotations</artifactId>
|
||||
<version>24.1.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Json解析 -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.fastjson2</groupId>
|
||||
<artifactId>fastjson2</artifactId>
|
||||
<version>2.0.60</version>
|
||||
</dependency>
|
||||
|
||||
<!-- SpringDoc OpenAPI 3 (Swagger) for Spring Boot 3.x -->
|
||||
<dependency>
|
||||
<groupId>org.springdoc</groupId>
|
||||
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
|
||||
<version>${springdoc.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 拼音转换工具:pinyin4j -->
|
||||
<dependency>
|
||||
<groupId>com.belerweb</groupId>
|
||||
<artifactId>pinyin4j</artifactId>
|
||||
<version>2.5.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 二维码生成工具 -->
|
||||
<dependency>
|
||||
<groupId>com.google.zxing</groupId>
|
||||
<artifactId>core</artifactId>
|
||||
<version>3.5.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.zxing</groupId>
|
||||
<artifactId>javase</artifactId>
|
||||
<version>3.5.2</version>
|
||||
</dependency>
|
||||
|
||||
<!-- PDFBox for PDF manipulation -->
|
||||
<dependency>
|
||||
<groupId>org.apache.pdfbox</groupId>
|
||||
<artifactId>pdfbox</artifactId>
|
||||
<version>2.0.31</version>
|
||||
</dependency>
|
||||
|
||||
<!-- POI for Office documents -->
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>poi</artifactId>
|
||||
<version>5.2.3</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>poi-ooxml</artifactId>
|
||||
<version>5.2.3</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>poi-scratchpad</artifactId>
|
||||
<version>5.2.3</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-text</artifactId>
|
||||
<version>${commons-text.version}</version> <!-- 请使用最新版本 -->
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>${project.artifactId}</finalName>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>build-helper-maven-plugin</artifactId>
|
||||
<version>3.6.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>timestamp-property</id>
|
||||
<goals>
|
||||
<goal>timestamp-property</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<name>local.build.time</name>
|
||||
<pattern>yyyy-MM-dd HH:mm:ss</pattern>
|
||||
<timeZone>Asia/Shanghai</timeZone>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<manifestEntries>
|
||||
<Implementation-Version>${project.version}</Implementation-Version>
|
||||
<Build-Time>${local.build.time}</Build-Time>
|
||||
</manifestEntries>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>repackage</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>${maven-compiler-plugin.version}</version>
|
||||
<configuration>
|
||||
<source>${java.version}</source>
|
||||
<target>${java.version}</target>
|
||||
<annotationProcessorPaths>
|
||||
<path>
|
||||
<groupId>io.github.linpeilie</groupId>
|
||||
<artifactId>mapstruct-plus-processor</artifactId>
|
||||
<version>${mapstruct-plus.version}</version>
|
||||
</path>
|
||||
<path>
|
||||
<groupId>org.mapstruct</groupId>
|
||||
<artifactId>mapstruct-processor</artifactId>
|
||||
<version>1.5.5.Final</version>
|
||||
</path>
|
||||
<path>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>${lombok.version}</version>
|
||||
</path>
|
||||
</annotationProcessorPaths>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>${maven-jar-plugin.version}</version>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifest>
|
||||
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
|
||||
</manifest>
|
||||
<manifestEntries>
|
||||
<Implementation-Version>${project.version}</Implementation-Version>
|
||||
<Build-Time>${local.build.time}</Build-Time>
|
||||
</manifestEntries>
|
||||
</archive>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-war-plugin</artifactId>
|
||||
<version>${maven-war-plugin.version}</version>
|
||||
<configuration>
|
||||
<failOnMissingWebXml>false</failOnMissingWebXml>
|
||||
<warName>${project.artifactId}</warName>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
827
sql/1289/1.sql
Normal file
827
sql/1289/1.sql
Normal file
@@ -0,0 +1,827 @@
|
||||
-- 1) 资金账户表(对应“账户余额:0元”)
|
||||
CREATE TABLE `hot_fund_account`
|
||||
(
|
||||
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`company_id` BIGINT UNSIGNED NULL COMMENT '公司ID(应用层保证必填)',
|
||||
|
||||
`user_id` BIGINT UNSIGNED NULL COMMENT '用户ID',
|
||||
`account_no` VARCHAR(32) NULL COMMENT '账户编号',
|
||||
`account_type` TINYINT NULL DEFAULT 1 COMMENT '账户类型:1=个人 2=企业',
|
||||
`balance_amount` DECIMAL(18, 2) NULL DEFAULT 0.00 COMMENT '可用余额',
|
||||
`status` TINYINT NULL DEFAULT 1 COMMENT '状态:1=正常 0=禁用',
|
||||
`version` INT NULL DEFAULT 0 COMMENT '乐观锁版本号',
|
||||
|
||||
`create_dept` BIGINT NULL COMMENT '创建部门',
|
||||
`create_by` BIGINT NULL COMMENT '创建者',
|
||||
`create_by_name` VARCHAR(64) NULL COMMENT '创建者姓名',
|
||||
`create_time` DATETIME NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_by` BIGINT NULL COMMENT '更新者',
|
||||
`update_by_name` VARCHAR(64) NULL COMMENT '更新者姓名',
|
||||
`update_time` DATETIME NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`is_deleted` TINYINT NULL DEFAULT 0 COMMENT '0=正常, 1=已删除',
|
||||
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_account_no` (`account_no`),
|
||||
KEY `idx_company_id` (`company_id`),
|
||||
KEY `idx_user_id` (`user_id`),
|
||||
KEY `idx_company_user_del_status` (`company_id`, `user_id`, `is_deleted`, `status`)
|
||||
) ENGINE = InnoDB
|
||||
DEFAULT CHARSET = utf8mb4
|
||||
COLLATE = utf8mb4_general_ci COMMENT ='资金账户表';
|
||||
|
||||
|
||||
-- 2) 充值订单表(对应:指定充值金额 + 支付方式)
|
||||
CREATE TABLE `hot_fund_recharge_order`
|
||||
(
|
||||
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`company_id` BIGINT UNSIGNED NULL COMMENT '公司ID(应用层保证必填)',
|
||||
|
||||
`account_id` BIGINT UNSIGNED NULL COMMENT '账户ID(逻辑外键)',
|
||||
`user_id` BIGINT UNSIGNED NULL COMMENT '用户ID',
|
||||
`recharge_order_no` VARCHAR(32) NULL COMMENT '充值订单号',
|
||||
`recharge_amount` DECIMAL(18, 2) NULL COMMENT '充值金额(如5.00)',
|
||||
`pay_method` TINYINT NULL COMMENT '支付方式:1=微信 2=支付宝 3=银行卡',
|
||||
`pay_scene` TINYINT NULL DEFAULT 1 COMMENT '支付场景:1=H5 2=小程序 3=APP 4=PC',
|
||||
`pay_status` TINYINT NULL DEFAULT 1 COMMENT '支付状态:1=待支付 2=支付中 3=支付成功 4=支付失败 5=已关闭 6=已退款',
|
||||
`third_trade_no` VARCHAR(64) NULL COMMENT '三方支付流水号',
|
||||
`paid_time` DATETIME NULL COMMENT '支付成功时间',
|
||||
`fail_reason` VARCHAR(255) NULL COMMENT '失败原因',
|
||||
`remark` VARCHAR(255) NULL COMMENT '备注',
|
||||
|
||||
`create_dept` BIGINT NULL COMMENT '创建部门',
|
||||
`create_by` BIGINT NULL COMMENT '创建者',
|
||||
`create_by_name` VARCHAR(64) NULL COMMENT '创建者姓名',
|
||||
`create_time` DATETIME NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_by` BIGINT NULL COMMENT '更新者',
|
||||
`update_by_name` VARCHAR(64) NULL COMMENT '更新者姓名',
|
||||
`update_time` DATETIME NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`is_deleted` TINYINT NULL DEFAULT 0 COMMENT '0=正常, 1=已删除',
|
||||
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_recharge_order_no` (`recharge_order_no`),
|
||||
KEY `idx_company_id` (`company_id`),
|
||||
KEY `idx_account_id` (`account_id`),
|
||||
KEY `idx_user_id` (`user_id`),
|
||||
KEY `idx_pay_status` (`pay_status`),
|
||||
KEY `idx_paid_time` (`paid_time`)
|
||||
) ENGINE = InnoDB
|
||||
DEFAULT CHARSET = utf8mb4
|
||||
COLLATE = utf8mb4_general_ci COMMENT ='充值订单表';
|
||||
|
||||
|
||||
-- 3) 订单管理表(对应列表:订单号/用户名/消费型企业/订单类型/产品名称/应付金额/退款金额/实付金额/支付方式/下单时间/支付时间/支付状态)
|
||||
CREATE TABLE `hot_fund_trade_order`
|
||||
(
|
||||
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`company_id` BIGINT UNSIGNED NULL COMMENT '公司ID(应用层保证必填)',
|
||||
|
||||
`account_id` BIGINT UNSIGNED NULL COMMENT '账户ID(逻辑外键)',
|
||||
`user_id` BIGINT UNSIGNED NULL COMMENT '用户ID',
|
||||
`user_name` VARCHAR(64) NULL COMMENT '用户名',
|
||||
`consumer_company_id` BIGINT UNSIGNED NULL COMMENT '消费型企业ID',
|
||||
`consumer_company_name` VARCHAR(128) NULL COMMENT '消费型企业名称',
|
||||
`order_no` VARCHAR(32) NULL COMMENT '订单号',
|
||||
`order_type` TINYINT NULL COMMENT '订单类型:1=拓客订单 2=学习订单 3=短信订单 4=岗前培训订单 5=其他',
|
||||
`biz_scene` TINYINT NULL COMMENT '业务场景:1=学时套餐 2=短信套餐 3=岗前培训套餐 4=岗前活动套餐 5=充值 6=其他',
|
||||
`product_name` VARCHAR(100) NULL COMMENT '产品名称',
|
||||
`package_id` BIGINT UNSIGNED NULL COMMENT '学时套餐ID',
|
||||
`package_name` VARCHAR(100) NULL COMMENT '学时套餐名称(快照)',
|
||||
`hour_type` TINYINT NULL COMMENT '学时类型:1=通用学时 2=其他',
|
||||
`hour_count` INT NULL COMMENT '学时数量(如1/50/100)',
|
||||
`sms_package_id` BIGINT UNSIGNED NULL COMMENT '短信套餐ID',
|
||||
`sms_package_name` VARCHAR(100) NULL COMMENT '短信套餐名称(快照)',
|
||||
`sms_count` INT NULL COMMENT '短信条数(如1000/3000/5000)',
|
||||
`pre_job_package_id` BIGINT UNSIGNED NULL COMMENT '岗前培训套餐ID',
|
||||
`pre_job_package_name` VARCHAR(100) NULL COMMENT '岗前培训套餐名称(快照)',
|
||||
`pre_job_activity_id` BIGINT UNSIGNED NULL COMMENT '岗前活动ID',
|
||||
`pre_job_activity_name` VARCHAR(100) NULL COMMENT '岗前活动名称(快照)',
|
||||
`unit_price` DECIMAL(18, 2) NULL COMMENT '单价(元)',
|
||||
`quantity` INT NULL DEFAULT 1 COMMENT '购买数量',
|
||||
`payable_amount` DECIMAL(18, 2) NULL COMMENT '应付金额(元)',
|
||||
`discount_amount` DECIMAL(18, 2) NULL DEFAULT 0.00 COMMENT '优惠金额(元)',
|
||||
`refund_amount` DECIMAL(18, 2) NULL DEFAULT 0.00 COMMENT '退款金额(元)',
|
||||
`paid_amount` DECIMAL(18, 2) NULL COMMENT '实付金额(元)',
|
||||
`pay_method` TINYINT NULL COMMENT '支付方式:1=微信 2=支付宝 3=银行卡 4=余额',
|
||||
`third_trade_no` VARCHAR(64) NULL COMMENT '三方支付流水号',
|
||||
`order_create_time` DATETIME NULL COMMENT '下单时间',
|
||||
`pay_time` DATETIME NULL COMMENT '支付时间',
|
||||
`pay_status` TINYINT NULL DEFAULT 1 COMMENT '支付状态:1=待支付 2=已支付 3=已退款 4=已取消 5=已关闭',
|
||||
`refund_status` TINYINT NULL DEFAULT 0 COMMENT '退款状态:0=无退款 1=退款中 2=部分退款 3=全额退款 4=退款失败',
|
||||
`refund_time` DATETIME NULL COMMENT '退款完成时间',
|
||||
`cancel_time` DATETIME NULL COMMENT '取消时间',
|
||||
`close_time` DATETIME NULL COMMENT '关闭时间',
|
||||
`contract_id` BIGINT UNSIGNED NULL COMMENT '合同ID',
|
||||
`contract_no` VARCHAR(64) NULL COMMENT '合同编号',
|
||||
`contract_status` TINYINT NULL COMMENT '合同状态:1=草稿 2=已签订 3=已生效 4=已终止 5=已作废',
|
||||
`contract_sign_time` DATETIME NULL COMMENT '合同签订时间',
|
||||
`order_source` VARCHAR(64) NULL COMMENT '订单来源(如渠道/来源ID)',
|
||||
`product_snapshot` TEXT NULL COMMENT '产品快照(JSON)',
|
||||
`remark` VARCHAR(255) NULL COMMENT '备注',
|
||||
|
||||
`create_dept` BIGINT NULL COMMENT '创建部门',
|
||||
`create_by` BIGINT NULL COMMENT '创建者',
|
||||
`create_by_name` VARCHAR(64) NULL COMMENT '创建者姓名',
|
||||
`create_time` DATETIME NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_by` BIGINT NULL COMMENT '更新者',
|
||||
`update_by_name` VARCHAR(64) NULL COMMENT '更新者姓名',
|
||||
`update_time` DATETIME NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`is_deleted` TINYINT NULL DEFAULT 0 COMMENT '0=正常, 1=已删除',
|
||||
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_order_no` (`order_no`),
|
||||
KEY `idx_account_id` (`account_id`),
|
||||
KEY `idx_user_id` (`user_id`),
|
||||
KEY `idx_third_trade_no` (`third_trade_no`),
|
||||
KEY `idx_contract_no` (`contract_no`),
|
||||
KEY `idx_company_time_status` (`company_id`, `order_create_time`, `pay_status`)
|
||||
) ENGINE = InnoDB
|
||||
DEFAULT CHARSET = utf8mb4
|
||||
COLLATE = utf8mb4_general_ci COMMENT ='订单管理表';
|
||||
|
||||
|
||||
-- 4) 学时套餐表(对应页面:培训学时套餐配置)
|
||||
CREATE TABLE `hot_hour_package`
|
||||
(
|
||||
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`company_id` BIGINT UNSIGNED NULL COMMENT '公司ID(应用层保证必填)',
|
||||
|
||||
`package_code` VARCHAR(32) NULL COMMENT '套餐编码',
|
||||
`package_name` VARCHAR(100) NULL COMMENT '套餐名称',
|
||||
`hour_type` TINYINT NULL DEFAULT 1 COMMENT '学时类型:1=通用学时 2=其他',
|
||||
`hour_count` INT NULL COMMENT '学时数(如1/50/100)',
|
||||
`origin_price` DECIMAL(18, 2) NULL COMMENT '原价格(元)',
|
||||
`package_price` DECIMAL(18, 2) NULL COMMENT '套餐价格(元)',
|
||||
`unit_price` DECIMAL(18, 2) NULL COMMENT '单价(元)',
|
||||
`valid_start_time` DATETIME NULL COMMENT '活动有效开始时间',
|
||||
`valid_end_time` DATETIME NULL COMMENT '活动有效结束时间',
|
||||
`applicable_types` VARCHAR(255) NULL COMMENT '适用类型(多选),逗号拼接',
|
||||
`package_desc` VARCHAR(500) NULL COMMENT '套餐说明',
|
||||
`status` TINYINT NULL DEFAULT 1 COMMENT '状态:1=启用 0=停用',
|
||||
`sort_no` INT NULL DEFAULT 0 COMMENT '排序号',
|
||||
`remark` VARCHAR(255) NULL COMMENT '备注',
|
||||
|
||||
`create_dept` BIGINT NULL COMMENT '创建部门',
|
||||
`create_by` BIGINT NULL COMMENT '创建者',
|
||||
`create_by_name` VARCHAR(64) NULL COMMENT '创建者姓名',
|
||||
`create_time` DATETIME NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_by` BIGINT NULL COMMENT '更新者',
|
||||
`update_by_name` VARCHAR(64) NULL COMMENT '更新者姓名',
|
||||
`update_time` DATETIME NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`is_deleted` TINYINT NULL DEFAULT 0 COMMENT '0=正常, 1=已删除',
|
||||
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_package_code` (`package_code`),
|
||||
KEY `idx_company_id` (`company_id`),
|
||||
KEY `idx_hour_type` (`hour_type`),
|
||||
KEY `idx_status` (`status`)
|
||||
) ENGINE = InnoDB
|
||||
DEFAULT CHARSET = utf8mb4
|
||||
COLLATE = utf8mb4_general_ci COMMENT ='学时套餐表';
|
||||
|
||||
|
||||
-- 5) 学时套餐购买记录表(对应页面下单动作)
|
||||
CREATE TABLE `hot_hour_package_purchase`
|
||||
(
|
||||
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`company_id` BIGINT UNSIGNED NULL COMMENT '公司ID(应用层保证必填)',
|
||||
|
||||
`account_id` BIGINT UNSIGNED NULL COMMENT '账户ID(逻辑外键)',
|
||||
`user_id` BIGINT UNSIGNED NULL COMMENT '用户ID',
|
||||
`order_id` BIGINT UNSIGNED NULL COMMENT '订单管理表ID(逻辑外键)',
|
||||
`order_no` VARCHAR(32) NULL COMMENT '订单号',
|
||||
`package_id` BIGINT UNSIGNED NULL COMMENT '学时套餐ID',
|
||||
`package_name` VARCHAR(100) NULL COMMENT '学时套餐名称(快照)',
|
||||
`hour_type` TINYINT NULL COMMENT '学时类型:1=通用学时 2=其他',
|
||||
`hour_count` INT NULL COMMENT '学时数',
|
||||
`origin_price` DECIMAL(18, 2) NULL COMMENT '原价格(元)',
|
||||
`package_price` DECIMAL(18, 2) NULL COMMENT '套餐价格(元)',
|
||||
`unit_price` DECIMAL(18, 2) NULL COMMENT '单价(元)',
|
||||
`quantity` INT NULL DEFAULT 1 COMMENT '购买数量',
|
||||
`total_hours` INT NULL COMMENT '总课时数',
|
||||
`total_amount` DECIMAL(18, 2) NULL COMMENT '总金额(元)',
|
||||
`pay_method` TINYINT NULL COMMENT '支付方式:1=微信 2=支付宝 3=银行卡 4=余额',
|
||||
`wallet_type` TINYINT NULL COMMENT '钱包类型:1=个人钱包 2=企业钱包',
|
||||
`wallet_id` BIGINT UNSIGNED NULL COMMENT '钱包ID',
|
||||
`wallet_transaction_id` BIGINT UNSIGNED NULL COMMENT '钱包流水ID',
|
||||
`wallet_transaction_no` VARCHAR(64) NULL COMMENT '钱包流水号',
|
||||
`pay_status` TINYINT NULL DEFAULT 1 COMMENT '支付状态:1=待支付 2=已支付 3=已退款 4=已取消 5=已关闭',
|
||||
`order_create_time` DATETIME NULL COMMENT '下单时间',
|
||||
`pay_time` DATETIME NULL COMMENT '支付时间',
|
||||
`package_snapshot` TEXT NULL COMMENT '套餐快照(JSON)',
|
||||
`remark` VARCHAR(255) NULL COMMENT '备注',
|
||||
|
||||
`create_dept` BIGINT NULL COMMENT '创建部门',
|
||||
`create_by` BIGINT NULL COMMENT '创建者',
|
||||
`create_by_name` VARCHAR(64) NULL COMMENT '创建者姓名',
|
||||
`create_time` DATETIME NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_by` BIGINT NULL COMMENT '更新者',
|
||||
`update_by_name` VARCHAR(64) NULL COMMENT '更新者姓名',
|
||||
`update_time` DATETIME NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`is_deleted` TINYINT NULL DEFAULT 0 COMMENT '0=正常, 1=已删除',
|
||||
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_company_id` (`company_id`),
|
||||
KEY `idx_account_id` (`account_id`),
|
||||
KEY `idx_user_id` (`user_id`),
|
||||
KEY `idx_order_id` (`order_id`),
|
||||
KEY `idx_order_no` (`order_no`),
|
||||
KEY `idx_package_id` (`package_id`),
|
||||
KEY `idx_wallet_id` (`wallet_id`),
|
||||
KEY `idx_wallet_transaction_id` (`wallet_transaction_id`),
|
||||
KEY `idx_pay_status` (`pay_status`),
|
||||
KEY `idx_order_create_time` (`order_create_time`)
|
||||
) ENGINE = InnoDB
|
||||
DEFAULT CHARSET = utf8mb4
|
||||
COLLATE = utf8mb4_general_ci COMMENT ='学时套餐购买记录表';
|
||||
|
||||
|
||||
-- 6) 短信套餐表(对应页面:短信套餐配置)
|
||||
CREATE TABLE `hot_sms_package`
|
||||
(
|
||||
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`company_id` BIGINT UNSIGNED NULL COMMENT '公司ID(应用层保证必填)',
|
||||
|
||||
`package_code` VARCHAR(32) NULL COMMENT '套餐编码',
|
||||
`package_name` VARCHAR(100) NULL COMMENT '套餐名称',
|
||||
`sms_count` INT NULL COMMENT '短信条数(如1000/3000/5000)',
|
||||
`package_price` DECIMAL(18, 2) NULL COMMENT '套餐价(元)',
|
||||
`unit_price` DECIMAL(18, 4) NULL COMMENT '单条单价(元)',
|
||||
`status` TINYINT NULL DEFAULT 1 COMMENT '状态:1=启用 0=停用',
|
||||
`sort_no` INT NULL DEFAULT 0 COMMENT '排序号',
|
||||
`remark` VARCHAR(255) NULL COMMENT '备注',
|
||||
|
||||
`create_dept` BIGINT NULL COMMENT '创建部门',
|
||||
`create_by` BIGINT NULL COMMENT '创建者',
|
||||
`create_by_name` VARCHAR(64) NULL COMMENT '创建者姓名',
|
||||
`create_time` DATETIME NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_by` BIGINT NULL COMMENT '更新者',
|
||||
`update_by_name` VARCHAR(64) NULL COMMENT '更新者姓名',
|
||||
`update_time` DATETIME NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`is_deleted` TINYINT NULL DEFAULT 0 COMMENT '0=正常, 1=已删除',
|
||||
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_package_code` (`package_code`),
|
||||
KEY `idx_company_id` (`company_id`),
|
||||
KEY `idx_status` (`status`)
|
||||
) ENGINE = InnoDB
|
||||
DEFAULT CHARSET = utf8mb4
|
||||
COLLATE = utf8mb4_general_ci COMMENT ='短信套餐表';
|
||||
|
||||
|
||||
-- 7) 短信套餐购买记录表(对应页面下单动作)
|
||||
CREATE TABLE `hot_sms_package_purchase`
|
||||
(
|
||||
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`company_id` BIGINT UNSIGNED NULL COMMENT '公司ID(应用层保证必填)',
|
||||
|
||||
`account_id` BIGINT UNSIGNED NULL COMMENT '账户ID(逻辑外键)',
|
||||
`user_id` BIGINT UNSIGNED NULL COMMENT '用户ID',
|
||||
`consumer_company_id` BIGINT UNSIGNED NULL COMMENT '充值企业ID',
|
||||
`consumer_company_name` VARCHAR(128) NULL COMMENT '充值企业名称',
|
||||
`order_id` BIGINT UNSIGNED NULL COMMENT '订单管理表ID(逻辑外键)',
|
||||
`order_no` VARCHAR(32) NULL COMMENT '订单号',
|
||||
`package_id` BIGINT UNSIGNED NULL COMMENT '短信套餐ID',
|
||||
`package_name` VARCHAR(100) NULL COMMENT '短信套餐名称(快照)',
|
||||
`sms_count` INT NULL COMMENT '短信条数',
|
||||
`unit_price` DECIMAL(18, 4) NULL COMMENT '单条单价(元)',
|
||||
`quantity` INT NULL DEFAULT 1 COMMENT '购买数量',
|
||||
`total_amount` DECIMAL(18, 2) NULL COMMENT '总金额(元)',
|
||||
`pay_method` TINYINT NULL COMMENT '支付方式:1=微信 2=支付宝 3=银行卡 4=余额',
|
||||
`pay_status` TINYINT NULL DEFAULT 1 COMMENT '支付状态:1=待支付 2=已支付 3=已退款 4=已取消 5=已关闭',
|
||||
`order_create_time` DATETIME NULL COMMENT '下单时间',
|
||||
`pay_time` DATETIME NULL COMMENT '支付时间',
|
||||
`remark` VARCHAR(255) NULL COMMENT '备注',
|
||||
|
||||
`create_dept` BIGINT NULL COMMENT '创建部门',
|
||||
`create_by` BIGINT NULL COMMENT '创建者',
|
||||
`create_by_name` VARCHAR(64) NULL COMMENT '创建者姓名',
|
||||
`create_time` DATETIME NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_by` BIGINT NULL COMMENT '更新者',
|
||||
`update_by_name` VARCHAR(64) NULL COMMENT '更新者姓名',
|
||||
`update_time` DATETIME NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`is_deleted` TINYINT NULL DEFAULT 0 COMMENT '0=正常, 1=已删除',
|
||||
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_company_id` (`company_id`),
|
||||
KEY `idx_account_id` (`account_id`),
|
||||
KEY `idx_user_id` (`user_id`),
|
||||
KEY `idx_consumer_company_id` (`consumer_company_id`),
|
||||
KEY `idx_order_id` (`order_id`),
|
||||
KEY `idx_order_no` (`order_no`),
|
||||
KEY `idx_package_id` (`package_id`),
|
||||
KEY `idx_pay_status` (`pay_status`),
|
||||
KEY `idx_order_create_time` (`order_create_time`)
|
||||
) ENGINE = InnoDB
|
||||
DEFAULT CHARSET = utf8mb4
|
||||
COLLATE = utf8mb4_general_ci COMMENT ='短信套餐购买记录表';
|
||||
|
||||
|
||||
-- 8) 岗前培训套餐表(对应页面:岗前培训套餐配置)
|
||||
CREATE TABLE `hot_pre_job_package`
|
||||
(
|
||||
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`company_id` BIGINT UNSIGNED NULL COMMENT '公司ID(应用层保证必填)',
|
||||
|
||||
`package_code` VARCHAR(32) NULL COMMENT '套餐编码',
|
||||
`package_name` VARCHAR(100) NULL COMMENT '套餐名称',
|
||||
`package_content` VARCHAR(255) NULL COMMENT '套餐内容',
|
||||
`package_type` TINYINT NULL DEFAULT 1 COMMENT '套餐类型:1=常规套餐 2=活动套餐',
|
||||
`activity_id` BIGINT UNSIGNED NULL COMMENT '活动ID',
|
||||
`activity_name` VARCHAR(100) NULL COMMENT '活动名称',
|
||||
`origin_price` DECIMAL(18, 2) NULL COMMENT '原价(元)',
|
||||
`activity_price` DECIMAL(18, 2) NULL COMMENT '活动价(元)',
|
||||
`unit_price` DECIMAL(18, 2) NULL COMMENT '生效单价(元)',
|
||||
`valid_start_time` DATETIME NULL COMMENT '活动有效开始时间',
|
||||
`valid_end_time` DATETIME NULL COMMENT '活动有效结束时间',
|
||||
`status` TINYINT NULL DEFAULT 1 COMMENT '状态:1=启用 0=停用',
|
||||
`sort_no` INT NULL DEFAULT 0 COMMENT '排序号',
|
||||
`remark` VARCHAR(255) NULL COMMENT '备注',
|
||||
|
||||
`create_dept` BIGINT NULL COMMENT '创建部门',
|
||||
`create_by` BIGINT NULL COMMENT '创建者',
|
||||
`create_by_name` VARCHAR(64) NULL COMMENT '创建者姓名',
|
||||
`create_time` DATETIME NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_by` BIGINT NULL COMMENT '更新者',
|
||||
`update_by_name` VARCHAR(64) NULL COMMENT '更新者姓名',
|
||||
`update_time` DATETIME NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`is_deleted` TINYINT NULL DEFAULT 0 COMMENT '0=正常, 1=已删除',
|
||||
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_package_code` (`package_code`),
|
||||
KEY `idx_company_id` (`company_id`),
|
||||
KEY `idx_package_type` (`package_type`),
|
||||
KEY `idx_activity_id` (`activity_id`),
|
||||
KEY `idx_status` (`status`)
|
||||
) ENGINE = InnoDB
|
||||
DEFAULT CHARSET = utf8mb4
|
||||
COLLATE = utf8mb4_general_ci COMMENT ='岗前培训套餐表';
|
||||
|
||||
|
||||
-- 9) 岗前培训套餐购买记录表(对应页面下单动作)
|
||||
CREATE TABLE `hot_pre_job_package_purchase`
|
||||
(
|
||||
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`company_id` BIGINT UNSIGNED NULL COMMENT '公司ID(应用层保证必填)',
|
||||
|
||||
`account_id` BIGINT UNSIGNED NULL COMMENT '账户ID(逻辑外键)',
|
||||
`user_id` BIGINT UNSIGNED NULL COMMENT '用户ID',
|
||||
`consumer_company_id` BIGINT UNSIGNED NULL COMMENT '消费型企业ID',
|
||||
`consumer_company_name` VARCHAR(128) NULL COMMENT '消费型企业名称',
|
||||
`order_id` BIGINT UNSIGNED NULL COMMENT '订单管理表ID(逻辑外键)',
|
||||
`order_no` VARCHAR(32) NULL COMMENT '订单号',
|
||||
`package_id` BIGINT UNSIGNED NULL COMMENT '岗前培训套餐ID',
|
||||
`package_name` VARCHAR(100) NULL COMMENT '岗前培训套餐名称(快照)',
|
||||
`package_content` VARCHAR(255) NULL COMMENT '套餐内容(快照)',
|
||||
`package_type` TINYINT NULL COMMENT '套餐类型:1=常规套餐 2=活动套餐',
|
||||
`activity_id` BIGINT UNSIGNED NULL COMMENT '活动ID',
|
||||
`activity_name` VARCHAR(100) NULL COMMENT '活动名称(快照)',
|
||||
`origin_price` DECIMAL(18, 2) NULL COMMENT '原价(元)',
|
||||
`activity_price` DECIMAL(18, 2) NULL COMMENT '活动价(元)',
|
||||
`unit_price` DECIMAL(18, 2) NULL COMMENT '成交单价(元)',
|
||||
`quantity` INT NULL DEFAULT 1 COMMENT '购买数量',
|
||||
`total_amount` DECIMAL(18, 2) NULL COMMENT '总金额(元)',
|
||||
`pay_method` TINYINT NULL COMMENT '支付方式:1=微信 2=支付宝 3=银行卡 4=余额',
|
||||
`pay_status` TINYINT NULL DEFAULT 1 COMMENT '支付状态:1=待支付 2=已支付 3=已退款 4=已取消 5=已关闭',
|
||||
`order_create_time` DATETIME NULL COMMENT '下单时间',
|
||||
`pay_time` DATETIME NULL COMMENT '支付时间',
|
||||
`remark` VARCHAR(255) NULL COMMENT '备注',
|
||||
|
||||
`create_dept` BIGINT NULL COMMENT '创建部门',
|
||||
`create_by` BIGINT NULL COMMENT '创建者',
|
||||
`create_by_name` VARCHAR(64) NULL COMMENT '创建者姓名',
|
||||
`create_time` DATETIME NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_by` BIGINT NULL COMMENT '更新者',
|
||||
`update_by_name` VARCHAR(64) NULL COMMENT '更新者姓名',
|
||||
`update_time` DATETIME NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`is_deleted` TINYINT NULL DEFAULT 0 COMMENT '0=正常, 1=已删除',
|
||||
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_company_id` (`company_id`),
|
||||
KEY `idx_account_id` (`account_id`),
|
||||
KEY `idx_user_id` (`user_id`),
|
||||
KEY `idx_consumer_company_id` (`consumer_company_id`),
|
||||
KEY `idx_order_id` (`order_id`),
|
||||
KEY `idx_order_no` (`order_no`),
|
||||
KEY `idx_package_id` (`package_id`),
|
||||
KEY `idx_activity_id` (`activity_id`),
|
||||
KEY `idx_pay_status` (`pay_status`),
|
||||
KEY `idx_order_create_time` (`order_create_time`)
|
||||
) ENGINE = InnoDB
|
||||
DEFAULT CHARSET = utf8mb4
|
||||
COLLATE = utf8mb4_general_ci COMMENT ='岗前培训套餐购买记录表';
|
||||
|
||||
|
||||
-- 10) 合同管理表(数据来源:支付时签订的协议)
|
||||
CREATE TABLE `hot_contract_manage`
|
||||
(
|
||||
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`company_id` BIGINT UNSIGNED NULL COMMENT '公司ID(应用层保证必填)',
|
||||
|
||||
`contract_no` VARCHAR(64) NULL COMMENT '合同编号',
|
||||
`contract_name` VARCHAR(128) NULL COMMENT '合同名称',
|
||||
`contract_amount` DECIMAL(18, 2) NULL COMMENT '合同金额(元)',
|
||||
`party_a_name` VARCHAR(128) NULL COMMENT '甲方名称',
|
||||
`party_b_name` VARCHAR(128) NULL COMMENT '乙方名称',
|
||||
`party_b_owner` VARCHAR(64) NULL COMMENT '乙方责任人',
|
||||
`contact_phone` VARCHAR(32) NULL COMMENT '联系电话',
|
||||
`contract_sign_time` DATETIME NULL COMMENT '合同签订时间',
|
||||
`contract_effective_time` DATETIME NULL COMMENT '合同生效时间',
|
||||
`contract_expire_time` DATETIME NULL COMMENT '合同到期时间',
|
||||
`contract_status` TINYINT NULL DEFAULT 2 COMMENT '合同状态:1=草稿 2=已签订 3=已生效 4=已终止 5=已作废',
|
||||
`sign_channel` TINYINT NULL COMMENT '签约渠道:1=微信 2=支付宝 3=银行卡 4=余额 5=线下',
|
||||
`agreement_url` VARCHAR(1024) NULL COMMENT '协议文件URL',
|
||||
`source_order_id` BIGINT UNSIGNED NULL COMMENT '来源订单ID(支付订单)',
|
||||
`source_order_no` VARCHAR(32) NULL COMMENT '来源订单号(支付订单)',
|
||||
`remark` VARCHAR(255) NULL COMMENT '备注',
|
||||
|
||||
`create_dept` BIGINT NULL COMMENT '创建部门',
|
||||
`create_by` BIGINT NULL COMMENT '创建者',
|
||||
`create_by_name` VARCHAR(64) NULL COMMENT '创建者姓名',
|
||||
`create_time` DATETIME NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_by` BIGINT NULL COMMENT '更新者',
|
||||
`update_by_name` VARCHAR(64) NULL COMMENT '更新者姓名',
|
||||
`update_time` DATETIME NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`is_deleted` TINYINT NULL DEFAULT 0 COMMENT '0=正常, 1=已删除',
|
||||
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_contract_no` (`contract_no`),
|
||||
KEY `idx_company_id` (`company_id`),
|
||||
KEY `idx_party_b_name` (`party_b_name`),
|
||||
KEY `idx_contract_status` (`contract_status`),
|
||||
KEY `idx_contract_expire_time` (`contract_expire_time`),
|
||||
KEY `idx_source_order_id` (`source_order_id`),
|
||||
KEY `idx_source_order_no` (`source_order_no`)
|
||||
) ENGINE = InnoDB
|
||||
DEFAULT CHARSET = utf8mb4
|
||||
COLLATE = utf8mb4_general_ci COMMENT ='合同管理表';
|
||||
|
||||
|
||||
-- 11) 培训学时购买明细表(对应页面:套餐名称/适用类型/购买人/购买数量/已使用/剩余)
|
||||
CREATE TABLE `hot_hour_purchase_detail`
|
||||
(
|
||||
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`company_id` BIGINT UNSIGNED NULL COMMENT '公司ID(应用层保证必填)',
|
||||
|
||||
`account_id` BIGINT UNSIGNED NULL COMMENT '账户ID(逻辑外键)',
|
||||
`user_id` BIGINT UNSIGNED NULL COMMENT '用户ID',
|
||||
`buyer_name` VARCHAR(64) NULL COMMENT '购买人',
|
||||
`buyer_company_id` BIGINT UNSIGNED NULL COMMENT '购买企业ID',
|
||||
`buyer_company_name` VARCHAR(128) NULL COMMENT '购买企业名称',
|
||||
`purchase_id` BIGINT UNSIGNED NULL COMMENT '学时套餐购买记录ID',
|
||||
`order_id` BIGINT UNSIGNED NULL COMMENT '订单管理表ID(逻辑外键)',
|
||||
`order_no` VARCHAR(32) NULL COMMENT '订单号',
|
||||
`package_id` BIGINT UNSIGNED NULL COMMENT '学时套餐ID',
|
||||
`package_name` VARCHAR(100) NULL COMMENT '套餐名称(快照)',
|
||||
`applicable_types` VARCHAR(255) NULL COMMENT '适用类型(如日常培训、事故培训等)',
|
||||
`purchase_count` INT NULL DEFAULT 1 COMMENT '购买数量',
|
||||
`total_hours` INT NULL COMMENT '总课时数',
|
||||
`used_hours` INT NULL DEFAULT 0 COMMENT '已使用学时数',
|
||||
`remaining_hours` INT NULL COMMENT '剩余学时数',
|
||||
`wallet_type` TINYINT NULL COMMENT '钱包类型:1=个人钱包 2=企业钱包',
|
||||
`wallet_id` BIGINT UNSIGNED NULL COMMENT '钱包ID',
|
||||
`version` INT NULL DEFAULT 0 COMMENT '乐观锁版本号',
|
||||
`status` TINYINT NULL DEFAULT 1 COMMENT '状态:1=生效 2=已用完 3=已过期 4=已作废',
|
||||
`last_use_time` DATETIME NULL COMMENT '最近使用时间',
|
||||
`expire_time` DATETIME NULL COMMENT '到期时间',
|
||||
`remark` VARCHAR(255) NULL COMMENT '备注',
|
||||
|
||||
`create_dept` BIGINT NULL COMMENT '创建部门',
|
||||
`create_by` BIGINT NULL COMMENT '创建者',
|
||||
`create_by_name` VARCHAR(64) NULL COMMENT '创建者姓名',
|
||||
`create_time` DATETIME NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_by` BIGINT NULL COMMENT '更新者',
|
||||
`update_by_name` VARCHAR(64) NULL COMMENT '更新者姓名',
|
||||
`update_time` DATETIME NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`is_deleted` TINYINT NULL DEFAULT 0 COMMENT '0=正常, 1=已删除',
|
||||
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_company_id` (`company_id`),
|
||||
KEY `idx_account_id` (`account_id`),
|
||||
KEY `idx_user_id` (`user_id`),
|
||||
KEY `idx_order_id` (`order_id`),
|
||||
KEY `idx_order_no` (`order_no`),
|
||||
KEY `idx_purchase_id` (`purchase_id`),
|
||||
KEY `idx_package_id` (`package_id`),
|
||||
KEY `idx_wallet_id` (`wallet_id`),
|
||||
KEY `idx_status` (`status`),
|
||||
KEY `idx_expire_time` (`expire_time`),
|
||||
KEY `idx_remaining_hours` (`remaining_hours`)
|
||||
) ENGINE = InnoDB
|
||||
DEFAULT CHARSET = utf8mb4
|
||||
COLLATE = utf8mb4_general_ci COMMENT ='培训学时购买明细表';
|
||||
|
||||
|
||||
-- 12) 培训学时使用明细表(对应页面:使用人员/使用类型/套餐名称/使用学时数量/使用日期)
|
||||
CREATE TABLE `hot_hour_usage_detail`
|
||||
(
|
||||
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`company_id` BIGINT UNSIGNED NULL COMMENT '公司ID(应用层保证必填)',
|
||||
|
||||
`purchase_detail_id` BIGINT UNSIGNED NULL COMMENT '购买明细ID(逻辑外键)',
|
||||
`account_id` BIGINT UNSIGNED NULL COMMENT '账户ID(逻辑外键)',
|
||||
`user_id` BIGINT UNSIGNED NULL COMMENT '使用人员ID',
|
||||
`user_name` VARCHAR(64) NULL COMMENT '使用人员',
|
||||
`operator_id` BIGINT UNSIGNED NULL COMMENT '操作人ID',
|
||||
`operator_name` VARCHAR(64) NULL COMMENT '操作人',
|
||||
`use_type` VARCHAR(64) NULL COMMENT '使用类型(如日常培训/违章培训)',
|
||||
`package_id` BIGINT UNSIGNED NULL COMMENT '套餐ID',
|
||||
`package_name` VARCHAR(100) NULL COMMENT '套餐名称(快照)',
|
||||
`used_hours` INT NULL COMMENT '使用学时数量(正数存储,展示可加负号)',
|
||||
`before_remaining_hours` INT NULL COMMENT '扣减前剩余学时',
|
||||
`after_remaining_hours` INT NULL COMMENT '扣减后剩余学时',
|
||||
`remaining_hours` INT NULL COMMENT '使用后剩余学时',
|
||||
`use_date` DATE NULL COMMENT '使用日期',
|
||||
`biz_order_id` BIGINT UNSIGNED NULL COMMENT '业务单据ID',
|
||||
`biz_order_no` VARCHAR(32) NULL COMMENT '业务单号',
|
||||
`remark` VARCHAR(255) NULL COMMENT '备注',
|
||||
|
||||
`create_dept` BIGINT NULL COMMENT '创建部门',
|
||||
`create_by` BIGINT NULL COMMENT '创建者',
|
||||
`create_by_name` VARCHAR(64) NULL COMMENT '创建者姓名',
|
||||
`create_time` DATETIME NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_by` BIGINT NULL COMMENT '更新者',
|
||||
`update_by_name` VARCHAR(64) NULL COMMENT '更新者姓名',
|
||||
`update_time` DATETIME NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`is_deleted` TINYINT NULL DEFAULT 0 COMMENT '0=正常, 1=已删除',
|
||||
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_company_id` (`company_id`),
|
||||
KEY `idx_purchase_detail_id` (`purchase_detail_id`),
|
||||
KEY `idx_account_id` (`account_id`),
|
||||
KEY `idx_user_id` (`user_id`),
|
||||
KEY `idx_operator_id` (`operator_id`),
|
||||
KEY `idx_package_id` (`package_id`),
|
||||
KEY `idx_use_type` (`use_type`),
|
||||
KEY `idx_use_date` (`use_date`),
|
||||
KEY `idx_biz_order_no` (`biz_order_no`)
|
||||
) ENGINE = InnoDB
|
||||
DEFAULT CHARSET = utf8mb4
|
||||
COLLATE = utf8mb4_general_ci COMMENT ='培训学时使用明细表';
|
||||
|
||||
|
||||
-- 13) 短信企业统计表(对应页面:企业名称/总充值条数/总发送条数/总成功到达量/总计费量/总充值金额/剩余短信)
|
||||
CREATE TABLE `hot_sms_company_stat`
|
||||
(
|
||||
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`company_id` BIGINT UNSIGNED NULL COMMENT '公司ID(应用层保证必填)',
|
||||
|
||||
`enterprise_id` BIGINT UNSIGNED NULL COMMENT '企业ID',
|
||||
`enterprise_name` VARCHAR(128) NULL COMMENT '企业名称',
|
||||
`total_recharge_count` INT NULL DEFAULT 0 COMMENT '总充值条数',
|
||||
`total_send_count` INT NULL DEFAULT 0 COMMENT '总发送条数',
|
||||
`total_success_count` INT NULL DEFAULT 0 COMMENT '总成功到达量',
|
||||
`total_billable_count` INT NULL DEFAULT 0 COMMENT '总计费量',
|
||||
`total_recharge_amount` DECIMAL(18, 2) NULL DEFAULT 0.00 COMMENT '总充值金额(元)',
|
||||
`remaining_sms_count` INT NULL DEFAULT 0 COMMENT '剩余短信',
|
||||
`last_stat_time` DATETIME NULL COMMENT '最近统计时间',
|
||||
`remark` VARCHAR(255) NULL COMMENT '备注',
|
||||
|
||||
`create_dept` BIGINT NULL COMMENT '创建部门',
|
||||
`create_by` BIGINT NULL COMMENT '创建者',
|
||||
`create_by_name` VARCHAR(64) NULL COMMENT '创建者姓名',
|
||||
`create_time` DATETIME NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_by` BIGINT NULL COMMENT '更新者',
|
||||
`update_by_name` VARCHAR(64) NULL COMMENT '更新者姓名',
|
||||
`update_time` DATETIME NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`is_deleted` TINYINT NULL DEFAULT 0 COMMENT '0=正常, 1=已删除',
|
||||
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_enterprise_id` (`enterprise_id`),
|
||||
KEY `idx_company_id` (`company_id`),
|
||||
KEY `idx_enterprise_name` (`enterprise_name`)
|
||||
) ENGINE = InnoDB
|
||||
DEFAULT CHARSET = utf8mb4
|
||||
COLLATE = utf8mb4_general_ci COMMENT ='短信企业统计表';
|
||||
|
||||
|
||||
-- 14) 短信按日统计表(对应页面:日期/总发送量/成功到达量/计费量)
|
||||
CREATE TABLE `hot_sms_daily_stat`
|
||||
(
|
||||
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`company_id` BIGINT UNSIGNED NULL COMMENT '公司ID(应用层保证必填)',
|
||||
|
||||
`enterprise_id` BIGINT UNSIGNED NULL COMMENT '企业ID',
|
||||
`enterprise_name` VARCHAR(128) NULL COMMENT '企业名称',
|
||||
`stat_date` DATE NULL COMMENT '统计日期',
|
||||
`total_send_count` INT NULL DEFAULT 0 COMMENT '总发送量',
|
||||
`success_count` INT NULL DEFAULT 0 COMMENT '成功到达量',
|
||||
`billable_count` INT NULL DEFAULT 0 COMMENT '计费量',
|
||||
`fail_count` INT NULL DEFAULT 0 COMMENT '失败量',
|
||||
`remark` VARCHAR(255) NULL COMMENT '备注',
|
||||
|
||||
`create_dept` BIGINT NULL COMMENT '创建部门',
|
||||
`create_by` BIGINT NULL COMMENT '创建者',
|
||||
`create_by_name` VARCHAR(64) NULL COMMENT '创建者姓名',
|
||||
`create_time` DATETIME NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_by` BIGINT NULL COMMENT '更新者',
|
||||
`update_by_name` VARCHAR(64) NULL COMMENT '更新者姓名',
|
||||
`update_time` DATETIME NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`is_deleted` TINYINT NULL DEFAULT 0 COMMENT '0=正常, 1=已删除',
|
||||
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_enterprise_stat_date` (`enterprise_id`, `stat_date`),
|
||||
KEY `idx_company_id` (`company_id`),
|
||||
KEY `idx_stat_date` (`stat_date`)
|
||||
) ENGINE = InnoDB
|
||||
DEFAULT CHARSET = utf8mb4
|
||||
COLLATE = utf8mb4_general_ci COMMENT ='短信按日统计表';
|
||||
|
||||
|
||||
-- 15) 短信充值记录表(对应页面:充值时间/充值企业/充值金额/充值条数/过期时间/操作人)
|
||||
CREATE TABLE `hot_sms_recharge_record`
|
||||
(
|
||||
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`company_id` BIGINT UNSIGNED NULL COMMENT '公司ID(应用层保证必填)',
|
||||
|
||||
`enterprise_id` BIGINT UNSIGNED NULL COMMENT '充值企业ID',
|
||||
`enterprise_name` VARCHAR(128) NULL COMMENT '充值企业',
|
||||
`recharge_order_id` BIGINT UNSIGNED NULL COMMENT '短信购买记录ID(逻辑外键)',
|
||||
`recharge_order_no` VARCHAR(32) NULL COMMENT '充值订单号',
|
||||
`recharge_time` DATETIME NULL COMMENT '充值时间',
|
||||
`recharge_amount` DECIMAL(18, 2) NULL COMMENT '充值金额(元)',
|
||||
`recharge_sms_count` INT NULL COMMENT '充值条数',
|
||||
`expire_time` DATETIME NULL COMMENT '过期时间',
|
||||
`operator_id` BIGINT UNSIGNED NULL COMMENT '操作人ID',
|
||||
`operator_name` VARCHAR(64) NULL COMMENT '操作人',
|
||||
`status` TINYINT NULL DEFAULT 1 COMMENT '状态:1=生效 2=已过期 3=已作废',
|
||||
`remark` VARCHAR(255) NULL COMMENT '备注',
|
||||
|
||||
`create_dept` BIGINT NULL COMMENT '创建部门',
|
||||
`create_by` BIGINT NULL COMMENT '创建者',
|
||||
`create_by_name` VARCHAR(64) NULL COMMENT '创建者姓名',
|
||||
`create_time` DATETIME NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_by` BIGINT NULL COMMENT '更新者',
|
||||
`update_by_name` VARCHAR(64) NULL COMMENT '更新者姓名',
|
||||
`update_time` DATETIME NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`is_deleted` TINYINT NULL DEFAULT 0 COMMENT '0=正常, 1=已删除',
|
||||
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_recharge_order_no` (`recharge_order_no`),
|
||||
KEY `idx_company_id` (`company_id`),
|
||||
KEY `idx_enterprise_id` (`enterprise_id`),
|
||||
KEY `idx_recharge_time` (`recharge_time`),
|
||||
KEY `idx_expire_time` (`expire_time`)
|
||||
) ENGINE = InnoDB
|
||||
DEFAULT CHARSET = utf8mb4
|
||||
COLLATE = utf8mb4_general_ci COMMENT ='短信充值记录表';
|
||||
|
||||
|
||||
-- 16) 短信发送明细表(对应页面:短信类型/姓名/手机号/岗位/是否收到/详情)
|
||||
CREATE TABLE `hot_sms_send_detail`
|
||||
(
|
||||
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`company_id` BIGINT UNSIGNED NULL COMMENT '公司ID(应用层保证必填)',
|
||||
|
||||
`enterprise_id` BIGINT UNSIGNED NULL COMMENT '企业ID',
|
||||
`enterprise_name` VARCHAR(128) NULL COMMENT '企业名称',
|
||||
`biz_type` VARCHAR(64) NULL COMMENT '所属类型(如驾驶员管理)',
|
||||
`sms_type` VARCHAR(64) NULL COMMENT '短信类型',
|
||||
`receiver_id` BIGINT UNSIGNED NULL COMMENT '接收人ID',
|
||||
`receiver_name` VARCHAR(64) NULL COMMENT '姓名',
|
||||
`mobile` VARCHAR(32) NULL COMMENT '手机号',
|
||||
`receiver_role` VARCHAR(64) NULL COMMENT '岗位/接收人类型',
|
||||
`notice_content` TEXT NULL COMMENT '通知内容',
|
||||
`notify_time` DATETIME NULL COMMENT '通知时间',
|
||||
`notify_status` TINYINT NULL DEFAULT 1 COMMENT '通知状态:1=待发送 2=已发送 3=发送失败',
|
||||
`is_received` TINYINT NULL DEFAULT 0 COMMENT '是否收到:0=否 1=是',
|
||||
`receive_time` DATETIME NULL COMMENT '收到时间',
|
||||
`send_channel` TINYINT NULL DEFAULT 1 COMMENT '发送渠道:1=短信 2=站内信',
|
||||
`sms_count` INT NULL DEFAULT 1 COMMENT '消耗短信条数',
|
||||
`billable_count` INT NULL DEFAULT 1 COMMENT '计费条数',
|
||||
`provider_msg_id` VARCHAR(64) NULL COMMENT '供应商消息ID',
|
||||
`remark` VARCHAR(255) NULL COMMENT '备注',
|
||||
|
||||
`create_dept` BIGINT NULL COMMENT '创建部门',
|
||||
`create_by` BIGINT NULL COMMENT '创建者',
|
||||
`create_by_name` VARCHAR(64) NULL COMMENT '创建者姓名',
|
||||
`create_time` DATETIME NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_by` BIGINT NULL COMMENT '更新者',
|
||||
`update_by_name` VARCHAR(64) NULL COMMENT '更新者姓名',
|
||||
`update_time` DATETIME NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`is_deleted` TINYINT NULL DEFAULT 0 COMMENT '0=正常, 1=已删除',
|
||||
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_company_id` (`company_id`),
|
||||
KEY `idx_enterprise_id` (`enterprise_id`),
|
||||
KEY `idx_receiver_id` (`receiver_id`),
|
||||
KEY `idx_mobile` (`mobile`),
|
||||
KEY `idx_sms_type` (`sms_type`),
|
||||
KEY `idx_notify_time` (`notify_time`),
|
||||
KEY `idx_is_received` (`is_received`),
|
||||
KEY `idx_notify_status` (`notify_status`)
|
||||
) ENGINE = InnoDB
|
||||
DEFAULT CHARSET = utf8mb4
|
||||
COLLATE = utf8mb4_general_ci COMMENT ='短信发送明细表';
|
||||
|
||||
|
||||
-- 17) 发票管理表(对应页面:订单号/购买者/订单类型/订单金额/支付方式/开票状态/开票时间)
|
||||
CREATE TABLE `hot_invoice_manage`
|
||||
(
|
||||
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`company_id` BIGINT UNSIGNED NULL COMMENT '公司ID(应用层保证必填)',
|
||||
|
||||
`order_id` BIGINT UNSIGNED NULL COMMENT '订单ID(逻辑外键)',
|
||||
`order_no` VARCHAR(32) NULL COMMENT '订单号',
|
||||
`buyer_company_id` BIGINT UNSIGNED NULL COMMENT '购买者企业ID',
|
||||
`buyer_company_name` VARCHAR(128) NULL COMMENT '购买者(企业名称)',
|
||||
`order_type` TINYINT NULL COMMENT '订单类型:1=拓客订单 2=学习订单 3=短信订单 4=岗前培训订单 5=其他',
|
||||
`order_amount` DECIMAL(18, 2) NULL COMMENT '订单金额(元)',
|
||||
`pay_method` TINYINT NULL COMMENT '支付方式:1=微信 2=支付宝 3=银行卡 4=余额',
|
||||
`pay_time` DATETIME NULL COMMENT '支付时间',
|
||||
|
||||
`invoice_amount` DECIMAL(18, 2) NULL COMMENT '开票金额(元)',
|
||||
`invoice_type` TINYINT NULL COMMENT '发票类型:1=增值税电子普通发票 2=增值税电子专用发票',
|
||||
`invoice_title` VARCHAR(200) NULL COMMENT '发票抬头',
|
||||
`tax_no` VARCHAR(64) NULL COMMENT '税号',
|
||||
`bank_name` VARCHAR(100) NULL COMMENT '开户银行',
|
||||
`bank_account` VARCHAR(64) NULL COMMENT '银行账号',
|
||||
`company_address` VARCHAR(255) NULL COMMENT '企业地址',
|
||||
`company_phone` VARCHAR(32) NULL COMMENT '企业电话',
|
||||
|
||||
`invoice_status` TINYINT NULL DEFAULT 1 COMMENT '开票状态:1=未开票 2=申请开票 3=已开票 4=驳回 5=已作废',
|
||||
`apply_time` DATETIME NULL COMMENT '申请时间',
|
||||
`invoice_time` DATETIME NULL COMMENT '开票时间',
|
||||
`invoice_code` VARCHAR(32) NULL COMMENT '发票代码',
|
||||
`invoice_no` VARCHAR(64) NULL COMMENT '发票号码(可按年月+随机号)',
|
||||
`invoice_url` VARCHAR(1024) NULL COMMENT '电子发票文件URL',
|
||||
`reject_reason` VARCHAR(255) NULL COMMENT '驳回原因',
|
||||
`remark` VARCHAR(255) NULL COMMENT '备注',
|
||||
|
||||
`create_dept` BIGINT NULL COMMENT '创建部门',
|
||||
`create_by` BIGINT NULL COMMENT '创建者',
|
||||
`create_by_name` VARCHAR(64) NULL COMMENT '创建者姓名',
|
||||
`create_time` DATETIME NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_by` BIGINT NULL COMMENT '更新者',
|
||||
`update_by_name` VARCHAR(64) NULL COMMENT '更新者姓名',
|
||||
`update_time` DATETIME NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`is_deleted` TINYINT NULL DEFAULT 0 COMMENT '0=正常, 1=已删除',
|
||||
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE = InnoDB
|
||||
DEFAULT CHARSET = utf8mb4
|
||||
COLLATE = utf8mb4_general_ci COMMENT ='发票管理表';
|
||||
|
||||
|
||||
-- 18) 培训反馈主表(对应页面:反馈列表/我要反馈)
|
||||
CREATE TABLE `hot_training_feedback`
|
||||
(
|
||||
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`company_id` BIGINT UNSIGNED NULL COMMENT '公司ID(应用层保证必填)',
|
||||
|
||||
`feedback_no` VARCHAR(32) NULL COMMENT '反馈单号',
|
||||
`feedback_user_id` BIGINT UNSIGNED NULL COMMENT '反馈人ID',
|
||||
`feedback_user_name` VARCHAR(64) NULL COMMENT '反馈人姓名',
|
||||
`feedback_keyword` VARCHAR(100) NULL COMMENT '反馈关键词',
|
||||
`feedback_content` TEXT NULL COMMENT '反馈内容',
|
||||
`attachment_urls` TEXT NULL COMMENT '附件URL列表(逗号分隔,对应sys_oss)',
|
||||
`feedback_time` DATETIME NULL COMMENT '反馈时间',
|
||||
`status` TINYINT NULL DEFAULT 1 COMMENT '处理状态:1=待处理 2=处理中 3=已回复 4=已关闭',
|
||||
`reply_time` DATETIME NULL COMMENT '最新回复时间',
|
||||
`reply_count` INT NULL DEFAULT 0 COMMENT '回复条数',
|
||||
`last_reply_content` VARCHAR(255) NULL COMMENT '最新回复内容摘要',
|
||||
`remark` VARCHAR(255) NULL COMMENT '备注',
|
||||
|
||||
`create_dept` BIGINT NULL COMMENT '创建部门',
|
||||
`create_by` BIGINT NULL COMMENT '创建者',
|
||||
`create_by_name` VARCHAR(64) NULL COMMENT '创建者姓名',
|
||||
`create_time` DATETIME NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_by` BIGINT NULL COMMENT '更新者',
|
||||
`update_by_name` VARCHAR(64) NULL COMMENT '更新者姓名',
|
||||
`update_time` DATETIME NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`is_deleted` TINYINT NULL DEFAULT 0 COMMENT '0=正常, 1=已删除',
|
||||
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE = InnoDB
|
||||
DEFAULT CHARSET = utf8mb4
|
||||
COLLATE = utf8mb4_general_ci COMMENT ='培训反馈主表';
|
||||
|
||||
|
||||
-- 19) 培训反馈回复表(对应页面:反馈详情时间线“我的反馈/回复”)
|
||||
CREATE TABLE `hot_training_feedback_reply`
|
||||
(
|
||||
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`company_id` BIGINT UNSIGNED NULL COMMENT '公司ID(应用层保证必填)',
|
||||
|
||||
`feedback_id` BIGINT UNSIGNED NULL COMMENT '反馈主表ID(逻辑外键)',
|
||||
`feedback_no` VARCHAR(32) NULL COMMENT '反馈单号',
|
||||
`reply_role` TINYINT NULL COMMENT '回复角色:1=反馈人 2=处理人',
|
||||
`reply_user_id` BIGINT UNSIGNED NULL COMMENT '回复人ID',
|
||||
`reply_user_name` VARCHAR(64) NULL COMMENT '回复人姓名',
|
||||
`reply_content` TEXT NULL COMMENT '回复内容',
|
||||
`reply_time` DATETIME NULL COMMENT '回复时间',
|
||||
`status` TINYINT NULL DEFAULT 1 COMMENT '状态:1=有效 0=无效',
|
||||
`remark` VARCHAR(255) NULL COMMENT '备注',
|
||||
|
||||
`create_dept` BIGINT NULL COMMENT '创建部门',
|
||||
`create_by` BIGINT NULL COMMENT '创建者',
|
||||
`create_by_name` VARCHAR(64) NULL COMMENT '创建者姓名',
|
||||
`create_time` DATETIME NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_by` BIGINT NULL COMMENT '更新者',
|
||||
`update_by_name` VARCHAR(64) NULL COMMENT '更新者姓名',
|
||||
`update_time` DATETIME NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`is_deleted` TINYINT NULL DEFAULT 0 COMMENT '0=正常, 1=已删除',
|
||||
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE = InnoDB
|
||||
DEFAULT CHARSET = utf8mb4
|
||||
COLLATE = utf8mb4_general_ci COMMENT ='培训反馈回复表';
|
||||
241
sql/1289/2_pay_module.sql
Normal file
241
sql/1289/2_pay_module.sql
Normal file
@@ -0,0 +1,241 @@
|
||||
-- 支付模块基础表
|
||||
CREATE TABLE IF NOT EXISTS `pay_app`
|
||||
(
|
||||
`id`
|
||||
BIGINT
|
||||
UNSIGNED
|
||||
NOT
|
||||
NULL
|
||||
AUTO_INCREMENT
|
||||
COMMENT
|
||||
'应用编号',
|
||||
`app_key`
|
||||
VARCHAR
|
||||
(
|
||||
64
|
||||
) NOT NULL COMMENT '应用标识',
|
||||
`name` VARCHAR
|
||||
(
|
||||
100
|
||||
) NOT NULL COMMENT '应用名称',
|
||||
`status` TINYINT NOT NULL DEFAULT 1 COMMENT '状态:1启用 0停用',
|
||||
`remark` VARCHAR
|
||||
(
|
||||
255
|
||||
) DEFAULT NULL COMMENT '备注',
|
||||
`order_notify_url` VARCHAR
|
||||
(
|
||||
255
|
||||
) DEFAULT NULL COMMENT '业务回调地址',
|
||||
`create_by` BIGINT DEFAULT NULL,
|
||||
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
`update_by` BIGINT DEFAULT NULL,
|
||||
`update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
`is_deleted` TINYINT NOT NULL DEFAULT 0 COMMENT '0正常 1删除',
|
||||
PRIMARY KEY
|
||||
(
|
||||
`id`
|
||||
),
|
||||
UNIQUE KEY `uk_pay_app_key`
|
||||
(
|
||||
`app_key`
|
||||
)
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COMMENT ='支付应用';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `pay_channel`
|
||||
(
|
||||
`id`
|
||||
BIGINT
|
||||
UNSIGNED
|
||||
NOT
|
||||
NULL
|
||||
AUTO_INCREMENT
|
||||
COMMENT
|
||||
'渠道编号',
|
||||
`code`
|
||||
VARCHAR
|
||||
(
|
||||
64
|
||||
) NOT NULL COMMENT '渠道编码',
|
||||
`status` TINYINT NOT NULL DEFAULT 1 COMMENT '状态:1启用 0停用',
|
||||
`remark` VARCHAR
|
||||
(
|
||||
255
|
||||
) DEFAULT NULL COMMENT '备注',
|
||||
`app_id` BIGINT UNSIGNED NOT NULL COMMENT '应用编号',
|
||||
`config` LONGTEXT NOT NULL COMMENT '渠道配置(JSON)',
|
||||
`create_by` BIGINT DEFAULT NULL,
|
||||
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
`update_by` BIGINT DEFAULT NULL,
|
||||
`update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
`is_deleted` TINYINT NOT NULL DEFAULT 0 COMMENT '0正常 1删除',
|
||||
PRIMARY KEY
|
||||
(
|
||||
`id`
|
||||
),
|
||||
UNIQUE KEY `uk_pay_channel_app_code`
|
||||
(
|
||||
`app_id`,
|
||||
`code`
|
||||
)
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COMMENT ='支付渠道';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `pay_order`
|
||||
(
|
||||
`id`
|
||||
BIGINT
|
||||
UNSIGNED
|
||||
NOT
|
||||
NULL
|
||||
AUTO_INCREMENT
|
||||
COMMENT
|
||||
'支付订单编号',
|
||||
`app_id`
|
||||
BIGINT
|
||||
UNSIGNED
|
||||
NOT
|
||||
NULL
|
||||
COMMENT
|
||||
'应用编号',
|
||||
`merchant_order_no`
|
||||
VARCHAR
|
||||
(
|
||||
64
|
||||
) DEFAULT NULL COMMENT '业务订单号',
|
||||
`biz_order_type` VARCHAR
|
||||
(
|
||||
64
|
||||
) DEFAULT NULL COMMENT '业务类型',
|
||||
`biz_order_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '业务主键',
|
||||
`subject` VARCHAR
|
||||
(
|
||||
128
|
||||
) DEFAULT NULL COMMENT '订单标题',
|
||||
`body` VARCHAR
|
||||
(
|
||||
255
|
||||
) DEFAULT NULL COMMENT '订单描述',
|
||||
`channel_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '渠道编号',
|
||||
`channel_code` VARCHAR
|
||||
(
|
||||
64
|
||||
) DEFAULT NULL COMMENT '渠道编码',
|
||||
`notify_url` VARCHAR
|
||||
(
|
||||
255
|
||||
) DEFAULT NULL COMMENT '异步回调地址',
|
||||
`return_url` VARCHAR
|
||||
(
|
||||
255
|
||||
) DEFAULT NULL COMMENT '同步跳转地址',
|
||||
`price` DECIMAL
|
||||
(
|
||||
18,
|
||||
2
|
||||
) NOT NULL COMMENT '支付金额(元)',
|
||||
`status` TINYINT NOT NULL DEFAULT 1 COMMENT '状态:1待支付 2支付中 3成功 4失败 5关闭',
|
||||
`user_ip` VARCHAR
|
||||
(
|
||||
64
|
||||
) DEFAULT NULL COMMENT '用户IP',
|
||||
`expire_time` DATETIME DEFAULT NULL COMMENT '失效时间',
|
||||
`success_time` DATETIME DEFAULT NULL COMMENT '支付成功时间',
|
||||
`extension_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '支付成功拓展单编号',
|
||||
`no` VARCHAR
|
||||
(
|
||||
64
|
||||
) DEFAULT NULL COMMENT '平台支付订单号',
|
||||
`channel_user_id` VARCHAR
|
||||
(
|
||||
64
|
||||
) DEFAULT NULL COMMENT '渠道用户编号',
|
||||
`channel_order_no` VARCHAR
|
||||
(
|
||||
64
|
||||
) DEFAULT NULL COMMENT '渠道订单号',
|
||||
`create_by` BIGINT DEFAULT NULL,
|
||||
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
`update_by` BIGINT DEFAULT NULL,
|
||||
`update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
`is_deleted` TINYINT NOT NULL DEFAULT 0 COMMENT '0正常 1删除',
|
||||
PRIMARY KEY
|
||||
(
|
||||
`id`
|
||||
),
|
||||
UNIQUE KEY `uk_pay_order_no`
|
||||
(
|
||||
`no`
|
||||
),
|
||||
KEY `idx_pay_order_biz`
|
||||
(
|
||||
`biz_order_type`,
|
||||
`biz_order_id`
|
||||
)
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COMMENT ='支付订单';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `pay_order_extension`
|
||||
(
|
||||
`id`
|
||||
BIGINT
|
||||
UNSIGNED
|
||||
NOT
|
||||
NULL
|
||||
AUTO_INCREMENT
|
||||
COMMENT
|
||||
'拓展单编号',
|
||||
`no`
|
||||
VARCHAR
|
||||
(
|
||||
64
|
||||
) NOT NULL COMMENT '三方侧商户单号',
|
||||
`order_id` BIGINT UNSIGNED NOT NULL COMMENT '支付订单编号',
|
||||
`channel_id` BIGINT UNSIGNED NOT NULL COMMENT '渠道编号',
|
||||
`channel_code` VARCHAR
|
||||
(
|
||||
64
|
||||
) NOT NULL COMMENT '渠道编码',
|
||||
`user_ip` VARCHAR
|
||||
(
|
||||
64
|
||||
) DEFAULT NULL COMMENT '用户IP',
|
||||
`status` TINYINT NOT NULL DEFAULT 1 COMMENT '状态:1待支付 2支付中 3成功 4失败 5关闭',
|
||||
`channel_extras` LONGTEXT DEFAULT NULL COMMENT '渠道扩展信息',
|
||||
`channel_error_code` VARCHAR
|
||||
(
|
||||
64
|
||||
) DEFAULT NULL COMMENT '渠道错误码',
|
||||
`channel_error_msg` VARCHAR
|
||||
(
|
||||
255
|
||||
) DEFAULT NULL COMMENT '渠道错误信息',
|
||||
`channel_notify_data` LONGTEXT DEFAULT NULL COMMENT '渠道回调原文',
|
||||
`create_by` BIGINT DEFAULT NULL,
|
||||
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
`update_by` BIGINT DEFAULT NULL,
|
||||
`update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
`is_deleted` TINYINT NOT NULL DEFAULT 0 COMMENT '0正常 1删除',
|
||||
PRIMARY KEY
|
||||
(
|
||||
`id`
|
||||
),
|
||||
UNIQUE KEY `uk_pay_order_extension_no`
|
||||
(
|
||||
`no`
|
||||
),
|
||||
KEY `idx_pay_order_extension_order`
|
||||
(
|
||||
`order_id`
|
||||
)
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COMMENT ='支付订单拓展单';
|
||||
|
||||
ALTER TABLE `hot_fund_recharge_order`
|
||||
MODIFY COLUMN `recharge_amount` DECIMAL (18, 2) NULL COMMENT '充值金额(元)',
|
||||
MODIFY COLUMN `pay_status` TINYINT NULL DEFAULT 1 COMMENT '支付状态:1待支付 2支付中 3支付成功 4支付失败 5已关闭 6已退款';
|
||||
|
||||
-- 初始化建议
|
||||
-- INSERT INTO pay_app(app_key, name, status, remark) VALUES ('wallet-recharge', '钱包充值', 1, '钱包充值支付应用');
|
||||
-- 渠道编码建议:
|
||||
-- WECHAT_QR / WECHAT_H5 / WECHAT_APP / ALIPAY_QR / ALIPAY_H5 / ALIPAY_APP
|
||||
-- 支付渠道 config 示例:
|
||||
-- 支付宝:{"appId":"xxx","privateKey":"-----BEGIN PRIVATE KEY-----...","alipayPublicKey":"-----BEGIN PUBLIC KEY-----...","gateway":"https://openapi.alipay.com/gateway.do"}
|
||||
-- 微信:{"appId":"wxxxx","merchantId":"1xxxx","merchantSerialNo":"xxxx","privateKey":"-----BEGIN PRIVATE KEY-----...","apiV3Key":"32位密钥","platformPublicKey":"-----BEGIN PUBLIC KEY-----...","gateway":"https://api.mch.weixin.qq.com"}
|
||||
2
sql/add_avatar_to_sys_user_login_port.sql
Normal file
2
sql/add_avatar_to_sys_user_login_port.sql
Normal file
@@ -0,0 +1,2 @@
|
||||
ALTER TABLE sys_user_login_port
|
||||
ADD COLUMN avatar VARCHAR(500) COMMENT '头像';
|
||||
20
sql/add_hot_company_notice_read.sql
Normal file
20
sql/add_hot_company_notice_read.sql
Normal file
@@ -0,0 +1,20 @@
|
||||
CREATE TABLE `hot_company_notice_read`
|
||||
(
|
||||
`id` bigint NOT NULL COMMENT '主键',
|
||||
`notice_id` bigint DEFAULT NULL COMMENT '公告ID',
|
||||
`company_id` bigint DEFAULT NULL COMMENT '公司ID',
|
||||
`reader_id` varchar(64) DEFAULT NULL COMMENT '阅读人ID',
|
||||
`read_time` datetime DEFAULT NULL COMMENT '阅读时间',
|
||||
`is_deleted` bigint DEFAULT 0 COMMENT '0=正常, 1=已删除',
|
||||
`create_dept` bigint DEFAULT NULL COMMENT '创建部门',
|
||||
`create_by` bigint DEFAULT NULL COMMENT '创建者',
|
||||
`create_by_name` varchar(255) DEFAULT NULL COMMENT '创建者姓名',
|
||||
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
|
||||
`update_by` bigint DEFAULT NULL COMMENT '更新者',
|
||||
`update_by_name` varchar(255) DEFAULT NULL COMMENT '更新者姓名',
|
||||
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_notice_reader` (`notice_id`, `reader_id`),
|
||||
KEY `idx_company_reader` (`company_id`, `reader_id`)
|
||||
) ENGINE = InnoDB
|
||||
DEFAULT CHARSET = utf8mb4 COMMENT ='公司公告阅读记录';
|
||||
41
sql/alter_hot_hour_tables_20260511.sql
Normal file
41
sql/alter_hot_hour_tables_20260511.sql
Normal file
@@ -0,0 +1,41 @@
|
||||
-- hot_hour 相关表结构升级(2026-05-11)
|
||||
-- 目的:
|
||||
-- 1) 支持总部配置学时套餐(原价、活动价、套餐说明、课时时长、适用类型)
|
||||
-- 2) 支持企业端/移动端通过企业钱包或个人钱包购买并记录钱包流水关联
|
||||
-- 3) 支持课时扣减链路(总/已用/剩余、使用时间、扣减前后值、并发控制)
|
||||
|
||||
ALTER TABLE `hot_hour_package`
|
||||
ADD COLUMN `origin_price` DECIMAL(18, 2) NULL COMMENT '原价格(元)' AFTER `hour_count`,
|
||||
ADD COLUMN `package_price` DECIMAL(18, 2) NULL COMMENT '套餐价格(元)' AFTER `origin_price`,
|
||||
ADD COLUMN `valid_start_time` DATETIME NULL COMMENT '活动有效开始时间' AFTER `unit_price`,
|
||||
ADD COLUMN `valid_end_time` DATETIME NULL COMMENT '活动有效结束时间' AFTER `valid_start_time`,
|
||||
ADD COLUMN `applicable_types` VARCHAR(255) NULL COMMENT '适用类型(多选),逗号拼接' AFTER `valid_end_time`,
|
||||
ADD COLUMN `package_desc` VARCHAR(500) NULL COMMENT '套餐说明' AFTER `applicable_types`;
|
||||
|
||||
ALTER TABLE `hot_hour_package_purchase`
|
||||
ADD COLUMN `origin_price` DECIMAL(18, 2) NULL COMMENT '原价格(元)' AFTER `hour_count`,
|
||||
ADD COLUMN `package_price` DECIMAL(18, 2) NULL COMMENT '套餐价格(元)' AFTER `origin_price`,
|
||||
ADD COLUMN `total_hours` INT NULL COMMENT '总课时数' AFTER `quantity`,
|
||||
ADD COLUMN `wallet_type` TINYINT NULL COMMENT '钱包类型:1=个人钱包 2=企业钱包' AFTER `pay_method`,
|
||||
ADD COLUMN `wallet_id` BIGINT UNSIGNED NULL COMMENT '钱包ID' AFTER `wallet_type`,
|
||||
ADD COLUMN `wallet_transaction_id` BIGINT UNSIGNED NULL COMMENT '钱包流水ID' AFTER `wallet_id`,
|
||||
ADD COLUMN `wallet_transaction_no` VARCHAR(64) NULL COMMENT '钱包流水号' AFTER `wallet_transaction_id`,
|
||||
ADD COLUMN `package_snapshot` TEXT NULL COMMENT '套餐快照(JSON)' AFTER `pay_time`,
|
||||
ADD KEY `idx_wallet_id` (`wallet_id`),
|
||||
ADD KEY `idx_wallet_transaction_id` (`wallet_transaction_id`);
|
||||
|
||||
ALTER TABLE `hot_hour_purchase_detail`
|
||||
ADD COLUMN `purchase_id` BIGINT UNSIGNED NULL COMMENT '学时套餐购买记录ID' AFTER `buyer_company_name`,
|
||||
ADD COLUMN `total_hours` INT NULL COMMENT '总课时数' AFTER `purchase_count`,
|
||||
ADD COLUMN `wallet_type` TINYINT NULL COMMENT '钱包类型:1=个人钱包 2=企业钱包' AFTER `remaining_hours`,
|
||||
ADD COLUMN `wallet_id` BIGINT UNSIGNED NULL COMMENT '钱包ID' AFTER `wallet_type`,
|
||||
ADD COLUMN `version` INT NULL DEFAULT 0 COMMENT '乐观锁版本号' AFTER `wallet_id`,
|
||||
ADD KEY `idx_purchase_id` (`purchase_id`),
|
||||
ADD KEY `idx_wallet_id` (`wallet_id`);
|
||||
|
||||
ALTER TABLE `hot_hour_usage_detail`
|
||||
ADD COLUMN `operator_id` BIGINT UNSIGNED NULL COMMENT '操作人ID' AFTER `user_name`,
|
||||
ADD COLUMN `operator_name` VARCHAR(64) NULL COMMENT '操作人' AFTER `operator_id`,
|
||||
ADD COLUMN `before_remaining_hours` INT NULL COMMENT '扣减前剩余学时' AFTER `used_hours`,
|
||||
ADD COLUMN `after_remaining_hours` INT NULL COMMENT '扣减后剩余学时' AFTER `before_remaining_hours`,
|
||||
ADD KEY `idx_operator_id` (`operator_id`);
|
||||
@@ -0,0 +1,4 @@
|
||||
-- 安全学习使用学时套餐字段(2026-05-12)
|
||||
ALTER TABLE `hot_training_course_record`
|
||||
ADD COLUMN `is_use_hour_package` TINYINT NULL DEFAULT 0 COMMENT '是否已使用购买课时套餐:0=否 1=是' AFTER `signature_oss_id`,
|
||||
ADD COLUMN `hour_package_used_hours` BIGINT NULL DEFAULT 0 COMMENT '已扣减课时数' AFTER `is_use_hour_package`;
|
||||
5
sql/alter_pay_wallet_freeze_status_20260509.sql
Normal file
5
sql/alter_pay_wallet_freeze_status_20260509.sql
Normal file
@@ -0,0 +1,5 @@
|
||||
-- pay_wallet 新增冻结状态字段
|
||||
-- 0=正常 1=冻结
|
||||
|
||||
ALTER TABLE `pay_wallet`
|
||||
ADD COLUMN `freeze_status` TINYINT NULL DEFAULT 0 COMMENT '冻结状态:0=正常 1=冻结' AFTER `wallet_type`;
|
||||
57
sql/flow_init.sql
Normal file
57
sql/flow_init.sql
Normal file
@@ -0,0 +1,57 @@
|
||||
-- 流程实例表
|
||||
DROP TABLE IF EXISTS `sys_flow_instance`;
|
||||
CREATE TABLE `sys_flow_instance`
|
||||
(
|
||||
`instance_id` varchar(32) NOT NULL COMMENT '主键ID (UUID)',
|
||||
`flow_code` varchar(64) DEFAULT NULL COMMENT '流程编码',
|
||||
`business_id` varchar(64) DEFAULT NULL COMMENT '业务单据ID',
|
||||
`status` int DEFAULT NULL COMMENT '状态: 0-进行中, 1-已完成, 2-已撤销, 9-已终止',
|
||||
`company_id` bigint DEFAULT NULL COMMENT '租户/公司ID',
|
||||
`initiator_id` varchar(64) DEFAULT NULL COMMENT '发起人ID',
|
||||
`finish_time` datetime DEFAULT NULL COMMENT '结束时间',
|
||||
`create_by` varchar(64) DEFAULT NULL COMMENT '创建者',
|
||||
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
|
||||
`update_by` varchar(64) DEFAULT NULL COMMENT '更新者',
|
||||
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
|
||||
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
|
||||
PRIMARY KEY (`instance_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='流程实例表';
|
||||
|
||||
-- 流程待办任务表
|
||||
DROP TABLE IF EXISTS `sys_flow_task`;
|
||||
CREATE TABLE `sys_flow_task`
|
||||
(
|
||||
`task_id` varchar(32) NOT NULL COMMENT '任务ID (UUID)',
|
||||
`instance_id` varchar(32) DEFAULT NULL COMMENT '关联流程实例ID',
|
||||
`node_code` varchar(64) DEFAULT NULL COMMENT '节点编码',
|
||||
`node_name` varchar(64) DEFAULT NULL COMMENT '节点名称',
|
||||
`approver_id` varchar(64) DEFAULT NULL COMMENT '待审批人ID',
|
||||
`company_id` bigint DEFAULT NULL COMMENT '租户/公司ID',
|
||||
`create_by` varchar(64) DEFAULT NULL COMMENT '创建者',
|
||||
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
|
||||
`update_by` varchar(64) DEFAULT NULL COMMENT '更新者',
|
||||
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
|
||||
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
|
||||
PRIMARY KEY (`task_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='流程待办任务表';
|
||||
|
||||
-- 流程处理历史表
|
||||
DROP TABLE IF EXISTS `sys_flow_task_his`;
|
||||
CREATE TABLE `sys_flow_task_his`
|
||||
(
|
||||
`his_id` varchar(32) NOT NULL COMMENT '历史记录ID (UUID)',
|
||||
`instance_id` varchar(32) DEFAULT NULL COMMENT '关联流程实例ID',
|
||||
`task_id` varchar(32) DEFAULT NULL COMMENT '关联原待办任务ID',
|
||||
`node_code` varchar(64) DEFAULT NULL COMMENT '节点编码',
|
||||
`node_name` varchar(64) DEFAULT NULL COMMENT '节点名称',
|
||||
`approver_id` varchar(64) DEFAULT NULL COMMENT '实际处理人ID',
|
||||
`status` int DEFAULT NULL COMMENT '审批结果: 1-通过, 2-驳回, 3-转办, 9-终止',
|
||||
`comment` varchar(500) DEFAULT NULL COMMENT '审批意见',
|
||||
`audit_time` datetime DEFAULT NULL COMMENT '审批时间',
|
||||
`company_id` bigint DEFAULT NULL COMMENT '租户/公司ID',
|
||||
`create_by` varchar(64) DEFAULT NULL COMMENT '创建者',
|
||||
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
|
||||
`update_by` varchar(64) DEFAULT NULL COMMENT '更新者',
|
||||
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
|
||||
PRIMARY KEY (`his_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='流程处理历史表';
|
||||
4
sql/flow_update_read.sql
Normal file
4
sql/flow_update_read.sql
Normal file
@@ -0,0 +1,4 @@
|
||||
ALTER TABLE sys_flow_task
|
||||
ADD COLUMN is_read TINYINT(1) DEFAULT 0 COMMENT '是否已读';
|
||||
ALTER TABLE sys_flow_task_his
|
||||
ADD COLUMN is_read TINYINT(1) DEFAULT 0 COMMENT '是否已读';
|
||||
1
sql/modify_avatar_type_in_sys_user_login_port.sql
Normal file
1
sql/modify_avatar_type_in_sys_user_login_port.sql
Normal file
@@ -0,0 +1 @@
|
||||
ALTER TABLE sys_user_login_port MODIFY COLUMN avatar BIGINT COMMENT '头像(OSS ID)';
|
||||
3
sql/update_hidden_danger_inspection_flow.sql
Normal file
3
sql/update_hidden_danger_inspection_flow.sql
Normal file
@@ -0,0 +1,3 @@
|
||||
ALTER TABLE `hot_hidden_danger_inspection`
|
||||
ADD COLUMN `instance_id` varchar(64) NULL COMMENT '流程实例ID' AFTER `project_type`,
|
||||
ADD COLUMN `flow_status` varchar(32) NULL COMMENT '流程状态' AFTER `instance_id`;
|
||||
3
sql/update_hot_hidden_danger_flow.sql
Normal file
3
sql/update_hot_hidden_danger_flow.sql
Normal file
@@ -0,0 +1,3 @@
|
||||
ALTER TABLE `hot_hidden_danger`
|
||||
ADD COLUMN `instance_id` varchar(64) NULL COMMENT '流程实例ID' AFTER `is_deleted`,
|
||||
ADD COLUMN `flow_status` varchar(32) NULL COMMENT '流程状态' AFTER `instance_id`;
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.hotwj.platform.common.controller;
|
||||
|
||||
import com.hotwj.platform.common.mapper.PublicMapper;
|
||||
import com.hotwj.platform.common.vo.AddressVo;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.dromara.common.core.domain.R;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/common/region")
|
||||
@Tag(name = "区域管理", description = "区域树查询接口")
|
||||
public class RegionController {
|
||||
|
||||
private final PublicMapper publicMapper;
|
||||
|
||||
/**
|
||||
* 查询区域树列表
|
||||
*/
|
||||
@GetMapping("/tree")
|
||||
@Operation(summary = "查询区域树列表")
|
||||
public R<List<AddressVo>> tree() {
|
||||
// 查询数据库,查询所有区域树
|
||||
List<AddressVo> addressVoList = publicMapper.selectList();
|
||||
// 组装成树
|
||||
List<AddressVo> tree = AddressVo.buildTree(addressVoList);
|
||||
|
||||
return R.ok(tree);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
package com.hotwj.platform.common.helper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.hotwj.platform.driverManagement.driver.domain.HotDriver;
|
||||
import com.hotwj.platform.driverManagement.driver.mapper.HotDriverMapper;
|
||||
import com.hotwj.platform.resourceManagement.company.domain.vo.SysUserLoginPortVo;
|
||||
import com.hotwj.platform.resourceManagement.company.service.ISysUserLoginPortService;
|
||||
import org.dromara.common.core.domain.model.LoginUser;
|
||||
import org.dromara.common.core.exception.ServiceException;
|
||||
import org.dromara.common.core.utils.SpringUtils;
|
||||
import org.dromara.common.core.utils.StringUtils;
|
||||
import org.dromara.common.satoken.utils.LoginHelper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 驾驶员登录上下文帮助类
|
||||
*
|
||||
* @author shihongwei
|
||||
* @date 2026/02/22
|
||||
*/
|
||||
public final class DriverLoginContextHelper {
|
||||
|
||||
private DriverLoginContextHelper() {
|
||||
}
|
||||
|
||||
public static boolean isDriverPort() {
|
||||
LoginUser loginUser = LoginHelper.getLoginUser();
|
||||
if (loginUser == null) {
|
||||
return false;
|
||||
}
|
||||
return StringUtils.equals(loginUser.getLoginPort(), ISysUserLoginPortService.DRIVER_PORT);
|
||||
}
|
||||
|
||||
public static HotDriver getCurrentDriver() {
|
||||
if (!isDriverPort()) {
|
||||
throw new ServiceException("当前登录端口不是驾驶员端");
|
||||
}
|
||||
LoginUser loginUser = LoginHelper.getLoginUser();
|
||||
if (loginUser == null) {
|
||||
throw new ServiceException("登录信息不存在");
|
||||
}
|
||||
String businessUserId = loginUser.getBusinessUserId();
|
||||
if (StringUtils.isBlank(businessUserId)) {
|
||||
Long userId = loginUser.getUserId();
|
||||
if (userId == null) {
|
||||
throw new ServiceException("用户ID不存在");
|
||||
}
|
||||
ISysUserLoginPortService userLoginPortService = SpringUtils.getBean(ISysUserLoginPortService.class);
|
||||
List<SysUserLoginPortVo> ports = userLoginPortService.selectLoginPortListByPort(userId, ISysUserLoginPortService.DRIVER_PORT);
|
||||
Long companyId = ports.stream()
|
||||
.map(SysUserLoginPortVo::getCompanyId)
|
||||
.filter(id -> id != null)
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
if (companyId == null) {
|
||||
throw new ServiceException("未找到驾驶员所属企业信息");
|
||||
}
|
||||
LambdaQueryWrapper<HotDriver> lqw = new LambdaQueryWrapper<>();
|
||||
lqw.eq(HotDriver::getCompanyId, companyId);
|
||||
lqw.eq(HotDriver::getId, userId);
|
||||
lqw.eq(HotDriver::getStatus, 1L);
|
||||
lqw.eq(HotDriver::getAuditStatus, 1);
|
||||
lqw.orderByDesc(HotDriver::getCreateTime);
|
||||
lqw.last("limit 1");
|
||||
HotDriverMapper hotDriverMapper = SpringUtils.getBean(HotDriverMapper.class);
|
||||
HotDriver driver = hotDriverMapper.selectOne(lqw);
|
||||
if (driver == null) {
|
||||
throw new ServiceException("未找到当前登录用户对应的驾驶员信息");
|
||||
}
|
||||
return driver;
|
||||
}
|
||||
HotDriverMapper hotDriverMapper = SpringUtils.getBean(HotDriverMapper.class);
|
||||
HotDriver driver = hotDriverMapper.selectById(businessUserId);
|
||||
if (driver == null) {
|
||||
throw new ServiceException("驾驶员信息不存在");
|
||||
}
|
||||
return driver;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.hotwj.platform.common.mapper;
|
||||
|
||||
import com.hotwj.platform.common.vo.AddressVo;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface PublicMapper {
|
||||
|
||||
/**
|
||||
* 查询所有区域树,目前只查四川省的
|
||||
*/
|
||||
List<AddressVo> selectList();
|
||||
|
||||
/**
|
||||
* 单SQL透视:根据6位区划代码返回“省 市 区”全名
|
||||
*/
|
||||
String selectRegionFullNameByCode(String code);
|
||||
|
||||
/**
|
||||
* 根据code查询
|
||||
*/
|
||||
AddressVo selectAddressByCode(String code);
|
||||
|
||||
/**
|
||||
* 根据用户ID列表查询用户名称 (逗号分隔)
|
||||
*/
|
||||
String selectUserNamesByIds(@org.apache.ibatis.annotations.Param("userIds") List<Long> userIds);
|
||||
|
||||
/**
|
||||
* 根据课程ID列表查询课程名称 (逗号分隔)
|
||||
*/
|
||||
String selectCourseNamesByIds(@org.apache.ibatis.annotations.Param("courseIds") List<Long> courseIds);
|
||||
|
||||
/**
|
||||
* 根据ID列表查询参会人员姓名(驾驶员 + 安全管理员),按中文顿号拼接
|
||||
*/
|
||||
String selectAttendeeNamesByIds(@org.apache.ibatis.annotations.Param("ids") List<String> ids);
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.hotwj.platform.common.photoEvidence.controller;
|
||||
|
||||
import com.hotwj.platform.common.photoEvidence.domain.bo.PhotoEvidenceCreateBo;
|
||||
import com.hotwj.platform.common.photoEvidence.domain.vo.PhotoEvidenceVo;
|
||||
import com.hotwj.platform.common.photoEvidence.service.IPhotoEvidenceService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import org.dromara.common.core.domain.R;
|
||||
import org.dromara.common.core.domain.model.LoginUser;
|
||||
import org.dromara.common.idempotent.annotation.RepeatSubmit;
|
||||
import org.dromara.common.log.annotation.Log;
|
||||
import org.dromara.common.log.enums.BusinessType;
|
||||
import org.dromara.common.satoken.utils.LoginHelper;
|
||||
import org.dromara.common.web.core.BaseController;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@Validated
|
||||
@RestController
|
||||
@RequestMapping("/common/photoEvidence")
|
||||
public class PhotoEvidenceController extends BaseController {
|
||||
|
||||
@Resource
|
||||
private IPhotoEvidenceService photoEvidenceService;
|
||||
|
||||
@RepeatSubmit
|
||||
@Log(title = "照片取证水印生成", businessType = BusinessType.INSERT)
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "生成带时间地点水印的照片取证记录")
|
||||
public R<PhotoEvidenceVo> create(@Valid @RequestBody PhotoEvidenceCreateBo bo) {
|
||||
LoginUser loginUser = LoginHelper.getLoginUser();
|
||||
Long companyId = loginUser.getCompanyId();
|
||||
bo.setCompanyId(companyId);
|
||||
bo.setOperatorId(loginUser.getBusinessUserId());
|
||||
bo.setOperatorName(loginUser.getUsername());
|
||||
|
||||
PhotoEvidenceVo vo = photoEvidenceService.create(bo);
|
||||
return R.ok(vo);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package com.hotwj.platform.common.photoEvidence.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.util.Date;
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("hot_photo_evidence")
|
||||
public class HotPhotoEvidence extends BaseEntity {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@TableId(value = "id")
|
||||
private Long id;
|
||||
|
||||
private Long originalOssId;
|
||||
|
||||
private Long watermarkedOssId;
|
||||
|
||||
private Date captureTimeClient;
|
||||
|
||||
private Date captureTimeServer;
|
||||
|
||||
private Double latitude;
|
||||
|
||||
private Double longitude;
|
||||
|
||||
private String addressTextServer;
|
||||
|
||||
private String addressTextClient;
|
||||
|
||||
private String addressSource;
|
||||
|
||||
private String bizType;
|
||||
|
||||
private String bizId;
|
||||
|
||||
private Long companyId;
|
||||
|
||||
private String operatorId;
|
||||
|
||||
private String operatorName;
|
||||
|
||||
/**
|
||||
* 0=正常, 1=已删除
|
||||
*/
|
||||
@TableLogic
|
||||
private Long isDeleted;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.hotwj.platform.common.photoEvidence.domain.bo;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class PhotoEvidenceCreateBo {
|
||||
|
||||
@NotBlank(message = "originalOssId不能为空")
|
||||
private String originalOssId;
|
||||
|
||||
@NotNull(message = "latitude不能为空")
|
||||
private Double latitude;
|
||||
|
||||
@NotNull(message = "longitude不能为空")
|
||||
private Double longitude;
|
||||
|
||||
private String addressTextClient;
|
||||
|
||||
@NotBlank(message = "bizType不能为空")
|
||||
private String bizType;
|
||||
|
||||
private String bizId;
|
||||
|
||||
private Long companyId;
|
||||
|
||||
private String operatorId;
|
||||
|
||||
private String operatorName;
|
||||
|
||||
/**
|
||||
* 0=正常, 1=已删除
|
||||
*/
|
||||
private Long isDeleted;
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
package com.hotwj.platform.common.photoEvidence.domain.vo;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 照片取证水印生成的返回视图对象
|
||||
* 对应 hot_photo_evidence 表记录返回给前端的字段
|
||||
*/
|
||||
@Data
|
||||
public class PhotoEvidenceVo {
|
||||
|
||||
/**
|
||||
* 取证记录主键ID
|
||||
*/
|
||||
private String evidenceId;
|
||||
|
||||
/**
|
||||
* 原始图片 OSS 记录主键(ossId)
|
||||
*/
|
||||
private String originalOssId;
|
||||
|
||||
/**
|
||||
* 生成的水印图片 OSS 记录主键(ossId)
|
||||
*/
|
||||
private String watermarkedOssId;
|
||||
|
||||
/**
|
||||
* 客户端拍摄时间字符串(yyyy-MM-dd HH:mm:ss)
|
||||
*/
|
||||
private String captureTimeClient;
|
||||
|
||||
/**
|
||||
* 服务端生成取证记录时间字符串
|
||||
*/
|
||||
private String captureTimeServer;
|
||||
|
||||
/**
|
||||
* 拍摄位置纬度
|
||||
*/
|
||||
private Double latitude;
|
||||
|
||||
/**
|
||||
* 拍摄位置经度
|
||||
*/
|
||||
private Double longitude;
|
||||
|
||||
/**
|
||||
* 服务端(高德逆地理)解析到的地址
|
||||
*/
|
||||
private String addressTextServer;
|
||||
|
||||
/**
|
||||
* 客户端上传的地址文本
|
||||
*/
|
||||
private String addressTextClient;
|
||||
|
||||
/**
|
||||
* 地址来源:SERVER(服务端解析)/ CLIENT(客户端上传)
|
||||
*/
|
||||
private String addressSource;
|
||||
|
||||
/**
|
||||
* 业务类型标识
|
||||
*/
|
||||
private String bizType;
|
||||
|
||||
/**
|
||||
* 业务主键或业务单号
|
||||
*/
|
||||
private String bizId;
|
||||
|
||||
/**
|
||||
* 公司ID
|
||||
*/
|
||||
private Long companyId;
|
||||
|
||||
/**
|
||||
* 操作人ID
|
||||
*/
|
||||
private String operatorId;
|
||||
|
||||
/**
|
||||
* 操作人姓名
|
||||
*/
|
||||
private String operatorName;
|
||||
|
||||
/**
|
||||
* 0=正常, 1=已删除
|
||||
*/
|
||||
private Long isDeleted;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.hotwj.platform.common.photoEvidence.mapper;
|
||||
|
||||
import com.hotwj.platform.common.photoEvidence.domain.HotPhotoEvidence;
|
||||
import com.hotwj.platform.common.photoEvidence.domain.vo.PhotoEvidenceVo;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
|
||||
|
||||
@Mapper
|
||||
public interface HotPhotoEvidenceMapper extends BaseMapperPlus<HotPhotoEvidence, PhotoEvidenceVo> {
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.hotwj.platform.common.photoEvidence.service;
|
||||
|
||||
import com.hotwj.platform.common.photoEvidence.domain.bo.PhotoEvidenceCreateBo;
|
||||
import com.hotwj.platform.common.photoEvidence.domain.vo.PhotoEvidenceVo;
|
||||
|
||||
public interface IPhotoEvidenceService {
|
||||
|
||||
PhotoEvidenceVo create(PhotoEvidenceCreateBo bo);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,335 @@
|
||||
package com.hotwj.platform.common.photoEvidence.service.impl;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.hotwj.platform.common.photoEvidence.domain.HotPhotoEvidence;
|
||||
import com.hotwj.platform.common.photoEvidence.domain.bo.PhotoEvidenceCreateBo;
|
||||
import com.hotwj.platform.common.photoEvidence.domain.vo.PhotoEvidenceVo;
|
||||
import com.hotwj.platform.common.photoEvidence.mapper.HotPhotoEvidenceMapper;
|
||||
import com.hotwj.platform.common.photoEvidence.service.IPhotoEvidenceService;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.common.core.enums.FormatsType;
|
||||
import org.dromara.common.core.exception.ServiceException;
|
||||
import org.dromara.common.core.utils.DateUtils;
|
||||
import org.dromara.common.core.utils.StringUtils;
|
||||
import org.dromara.common.json.utils.JsonUtils;
|
||||
import org.dromara.common.oss.core.OssClient;
|
||||
import org.dromara.common.oss.factory.OssFactory;
|
||||
import org.dromara.common.satoken.utils.LoginHelper;
|
||||
import org.dromara.system.domain.vo.SysOssVo;
|
||||
import org.dromara.system.service.ISysOssService;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.*;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
public class PhotoEvidenceServiceImpl implements IPhotoEvidenceService {
|
||||
|
||||
@Resource
|
||||
private HotPhotoEvidenceMapper hotPhotoEvidenceMapper;
|
||||
|
||||
@Resource
|
||||
private ISysOssService ossService;
|
||||
|
||||
@Value("${map.gd.key:}")
|
||||
private String gdKey;
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public PhotoEvidenceVo create(PhotoEvidenceCreateBo bo) {
|
||||
Long originalOssId = parseOssId(bo.getOriginalOssId());
|
||||
SysOssVo originalOss = ossService.getById(originalOssId);
|
||||
if (originalOss == null) {
|
||||
throw new ServiceException("原始图片不存在");
|
||||
}
|
||||
|
||||
Date captureTimeClient = new Date();
|
||||
Date captureTimeServer = captureTimeClient;
|
||||
|
||||
String addressServer = reverseGeocode(bo.getLatitude(), bo.getLongitude());
|
||||
String addressSource;
|
||||
String addressForWatermark;
|
||||
if (StringUtils.isNotBlank(addressServer)) {
|
||||
addressSource = "SERVER";
|
||||
addressForWatermark = addressServer;
|
||||
} else {
|
||||
addressSource = "CLIENT";
|
||||
addressForWatermark = bo.getAddressTextClient();
|
||||
}
|
||||
|
||||
Long watermarkedOssId = generateAndUploadWatermarkedImage(
|
||||
originalOss,
|
||||
captureTimeClient,
|
||||
addressForWatermark
|
||||
);
|
||||
String operatorName = bo.getOperatorName();
|
||||
if (StringUtils.isBlank(operatorName)) {
|
||||
operatorName = LoginHelper.getUsername();
|
||||
}
|
||||
|
||||
HotPhotoEvidence entity = new HotPhotoEvidence();
|
||||
entity.setOriginalOssId(originalOssId);
|
||||
entity.setWatermarkedOssId(watermarkedOssId);
|
||||
entity.setCaptureTimeClient(captureTimeClient);
|
||||
entity.setCaptureTimeServer(captureTimeServer);
|
||||
entity.setLatitude(bo.getLatitude());
|
||||
entity.setLongitude(bo.getLongitude());
|
||||
entity.setAddressTextServer(addressServer);
|
||||
entity.setAddressTextClient(bo.getAddressTextClient());
|
||||
entity.setAddressSource(addressSource);
|
||||
entity.setBizType(bo.getBizType());
|
||||
entity.setBizId(bo.getBizId());
|
||||
entity.setCompanyId(bo.getCompanyId());
|
||||
entity.setOperatorId(bo.getOperatorId());
|
||||
entity.setOperatorName(operatorName);
|
||||
|
||||
hotPhotoEvidenceMapper.insert(entity);
|
||||
|
||||
PhotoEvidenceVo vo = new PhotoEvidenceVo();
|
||||
vo.setEvidenceId(entity.getId() != null ? String.valueOf(entity.getId()) : null);
|
||||
vo.setOriginalOssId(String.valueOf(originalOssId));
|
||||
vo.setWatermarkedOssId(watermarkedOssId != null ? String.valueOf(watermarkedOssId) : null);
|
||||
vo.setCaptureTimeClient(DateUtils.parseDateToStr(FormatsType.YYYY_MM_DD_HH_MM_SS, captureTimeClient));
|
||||
vo.setCaptureTimeServer(DateUtils.parseDateToStr(FormatsType.YYYY_MM_DD_HH_MM_SS, captureTimeServer));
|
||||
vo.setLatitude(bo.getLatitude());
|
||||
vo.setLongitude(bo.getLongitude());
|
||||
vo.setAddressTextServer(addressServer);
|
||||
vo.setAddressTextClient(bo.getAddressTextClient());
|
||||
vo.setAddressSource(addressSource);
|
||||
vo.setBizType(bo.getBizType());
|
||||
vo.setBizId(bo.getBizId());
|
||||
vo.setCompanyId(bo.getCompanyId());
|
||||
vo.setOperatorId(bo.getOperatorId());
|
||||
vo.setOperatorName(operatorName);
|
||||
|
||||
return vo;
|
||||
}
|
||||
|
||||
private Long parseOssId(String ossIdStr) {
|
||||
try {
|
||||
return Long.valueOf(ossIdStr);
|
||||
} catch (NumberFormatException e) {
|
||||
throw new ServiceException("originalOssId格式不正确");
|
||||
}
|
||||
}
|
||||
|
||||
private Long generateAndUploadWatermarkedImage(SysOssVo originalOss,
|
||||
Date captureTimeClient,
|
||||
String address) {
|
||||
byte[] originalBytes = downloadOssFile(originalOss);
|
||||
BufferedImage originalImage = readImage(originalBytes);
|
||||
BufferedImage watermarked = addWatermark(originalImage, captureTimeClient, address);
|
||||
|
||||
File tempFile = null;
|
||||
try {
|
||||
String suffix = originalOss.getFileSuffix();
|
||||
if (StringUtils.isBlank(suffix)) {
|
||||
suffix = "jpg";
|
||||
}
|
||||
if (suffix.startsWith(".")) {
|
||||
suffix = suffix.substring(1);
|
||||
}
|
||||
tempFile = File.createTempFile("photo_evidence_", "." + suffix);
|
||||
try (OutputStream os = new FileOutputStream(tempFile)) {
|
||||
ImageIO.write(watermarked, suffix, os);
|
||||
}
|
||||
return ossService.upload(tempFile).getOssId();
|
||||
} catch (IOException e) {
|
||||
throw new ServiceException("水印图片生成失败");
|
||||
} finally {
|
||||
if (tempFile != null && tempFile.exists()) {
|
||||
if (!tempFile.delete()) {
|
||||
log.warn("临时文件删除失败: {}", tempFile.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] downloadOssFile(SysOssVo oss) {
|
||||
OssClient storage = OssFactory.instance(oss.getService());
|
||||
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
|
||||
storage.download(oss.getFileName(), baos, null);
|
||||
return baos.toByteArray();
|
||||
} catch (Exception e) {
|
||||
throw new ServiceException("原始图片下载失败");
|
||||
}
|
||||
}
|
||||
|
||||
private BufferedImage readImage(byte[] bytes) {
|
||||
try (InputStream is = new ByteArrayInputStream(bytes)) {
|
||||
BufferedImage image = ImageIO.read(is);
|
||||
if (image == null) {
|
||||
String hex = "";
|
||||
if (bytes.length >= 4) {
|
||||
hex = String.format("%02X%02X%02X%02X", bytes[0], bytes[1], bytes[2], bytes[3]);
|
||||
}
|
||||
log.error("ImageIO.read returned null. Header: {}", hex);
|
||||
throw new ServiceException("原始图片格式不支持 (Header: " + hex + ")");
|
||||
}
|
||||
return image;
|
||||
} catch (IOException e) {
|
||||
log.error("图片解析失败", e);
|
||||
throw new ServiceException("原始图片解析失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private BufferedImage addWatermark(BufferedImage original,
|
||||
Date captureTimeClient,
|
||||
String address) {
|
||||
int width = original.getWidth();
|
||||
int height = original.getHeight();
|
||||
|
||||
// 强制最小画布宽度,防止文字区域过窄
|
||||
int minWidth = 600;
|
||||
if (width < minWidth) {
|
||||
int newWidth = minWidth;
|
||||
int newHeight = (int) Math.round((double) height * newWidth / width);
|
||||
BufferedImage resized = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_RGB);
|
||||
Graphics2D gResize = resized.createGraphics();
|
||||
gResize.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
|
||||
gResize.drawImage(original, 0, 0, newWidth, newHeight, null);
|
||||
gResize.dispose();
|
||||
original = resized;
|
||||
width = newWidth;
|
||||
height = newHeight;
|
||||
}
|
||||
|
||||
// 字体大小随宽度自适应(设置最小值)
|
||||
int fontSize = Math.max(20, width / 30);
|
||||
int padding = Math.max(fontSize, 16);
|
||||
|
||||
String timeText = DateUtils.parseDateToStr(FormatsType.YYYY_MM_DD_HH_MM_SS, captureTimeClient);
|
||||
String addressText = "地址:" + (address != null ? address : "");
|
||||
|
||||
// 构建字体并测量
|
||||
Font font;
|
||||
try (InputStream is = getClass().getResourceAsStream("/fonts/simsun.ttc")) {
|
||||
if (is == null) {
|
||||
font = new Font("SansSerif", Font.PLAIN, fontSize);
|
||||
} else {
|
||||
font = Font.createFont(Font.TRUETYPE_FONT, is).deriveFont(Font.PLAIN, fontSize);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("Failed to load simsun font, fallback to SansSerif", e);
|
||||
font = new Font("SansSerif", Font.PLAIN, fontSize);
|
||||
}
|
||||
|
||||
// 使用临时图形上下文计算文字宽度与行高
|
||||
BufferedImage tmp = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);
|
||||
Graphics2D gMeasure = tmp.createGraphics();
|
||||
gMeasure.setFont(font);
|
||||
FontMetrics fm = gMeasure.getFontMetrics();
|
||||
int contentWidth = Math.max(1, width - padding * 2);
|
||||
|
||||
// 构造文本行:第一行时间,后续为地址按宽度换行
|
||||
List<String> lines = new ArrayList<>();
|
||||
lines.add(timeText);
|
||||
if (fm.stringWidth(addressText) <= contentWidth) {
|
||||
lines.add(addressText);
|
||||
} else {
|
||||
StringBuilder current = new StringBuilder();
|
||||
for (char c : addressText.toCharArray()) {
|
||||
if (fm.stringWidth(current.toString() + c) > contentWidth) {
|
||||
lines.add(current.toString());
|
||||
current = new StringBuilder();
|
||||
}
|
||||
current.append(c);
|
||||
}
|
||||
if (current.length() > 0) {
|
||||
lines.add(current.toString());
|
||||
}
|
||||
}
|
||||
int lineHeight = fm.getHeight() + fontSize / 4;
|
||||
gMeasure.dispose();
|
||||
|
||||
// 计算白条高度,确保所有行完整显示
|
||||
int barHeight = Math.max(lineHeight + padding * 2, lines.size() * lineHeight + padding * 2);
|
||||
|
||||
// 输出结果图
|
||||
BufferedImage result = new BufferedImage(width, height + barHeight, BufferedImage.TYPE_INT_RGB);
|
||||
Graphics2D g = result.createGraphics();
|
||||
try {
|
||||
// 绘制原图
|
||||
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
|
||||
g.drawImage(original, 0, 0, null);
|
||||
|
||||
// 绘制底部白条
|
||||
g.setColor(Color.WHITE);
|
||||
g.fillRect(0, height, width, barHeight);
|
||||
|
||||
// 绘制文本
|
||||
g.setFont(font);
|
||||
g.setColor(new Color(51, 51, 51));
|
||||
g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
|
||||
|
||||
int y = height + padding + fm.getAscent();
|
||||
for (String line : lines) {
|
||||
g.drawString(line, padding, y);
|
||||
y += lineHeight;
|
||||
}
|
||||
return result;
|
||||
} finally {
|
||||
g.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private String reverseGeocode(Double latitude, Double longitude) {
|
||||
if (latitude == null || longitude == null) {
|
||||
return null;
|
||||
}
|
||||
if (StringUtils.isBlank(gdKey)) {
|
||||
return null;
|
||||
}
|
||||
String location = longitude + "," + latitude;
|
||||
String url = "https://restapi.amap.com/v3/geocode/regeo?output=JSON&location="
|
||||
+ location + "&key=" + gdKey + "&radius=1000&extensions=base";
|
||||
HttpURLConnection connection = null;
|
||||
try {
|
||||
URL u = new URL(url);
|
||||
connection = (HttpURLConnection) u.openConnection();
|
||||
connection.setConnectTimeout(3000);
|
||||
connection.setReadTimeout(3000);
|
||||
connection.setRequestMethod("GET");
|
||||
int code = connection.getResponseCode();
|
||||
if (code != HttpURLConnection.HTTP_OK) {
|
||||
return null;
|
||||
}
|
||||
try (InputStream is = connection.getInputStream()) {
|
||||
String body = new String(is.readAllBytes(), StandardCharsets.UTF_8);
|
||||
JsonNode root = JsonUtils.getObjectMapper().readTree(body);
|
||||
if (root == null) {
|
||||
return null;
|
||||
}
|
||||
if (!"1".equals(root.path("status").asText())) {
|
||||
return null;
|
||||
}
|
||||
JsonNode regeocode = root.path("regeocode");
|
||||
String formatted = regeocode.path("formatted_address").asText();
|
||||
if (StringUtils.isNotBlank(formatted)) {
|
||||
return formatted;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("高德逆地理解析失败: {},{}", latitude, longitude);
|
||||
return null;
|
||||
} finally {
|
||||
if (connection != null) {
|
||||
connection.disconnect();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.hotwj.platform.common.service;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 通用模板填充服务
|
||||
*
|
||||
* @author shihongwei
|
||||
*/
|
||||
public interface ITemplateService {
|
||||
|
||||
/**
|
||||
* 根据模板内容和数据映射,填充模板变量
|
||||
*
|
||||
* @param templateContent 包含 {变量名} 的模板字符串
|
||||
* @param dataMap 变量名到实际数据的映射
|
||||
* @return 填充后的字符串
|
||||
*/
|
||||
String fillTemplate(String templateContent, Map<String, Object> dataMap);
|
||||
|
||||
/**
|
||||
* 为指定的签订文件明细记录准备模板所需的数据映射
|
||||
*
|
||||
* @param detailId 签订文件明细ID (hot_sign_file_detail.id)
|
||||
* @return 包含所有可替换变量的Map
|
||||
*/
|
||||
Map<String, Object> prepareDataMapForSignDetail(Long detailId);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
package com.hotwj.platform.common.service.impl;
|
||||
|
||||
import cn.hutool.core.util.NumberUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.hotwj.platform.common.service.ITemplateService;
|
||||
import com.hotwj.platform.driverManagement.driver.domain.HotDriver;
|
||||
import com.hotwj.platform.driverManagement.driver.mapper.HotDriverMapper;
|
||||
import com.hotwj.platform.noticeManagerment.signFileDetail.domain.vo.HotSignFileDetailVo;
|
||||
import com.hotwj.platform.noticeManagerment.signFileDetail.mapper.HotSignFileDetailMapper;
|
||||
import com.hotwj.platform.resourceManagement.company.domain.vo.SysCompanyVo;
|
||||
import com.hotwj.platform.resourceManagement.company.service.ISysCompanyService;
|
||||
import com.hotwj.platform.resourceManagement.companySafetyManager.domain.HotCompanySafetyManager;
|
||||
import com.hotwj.platform.resourceManagement.companySafetyManager.mapper.HotCompanySafetyManagerMapper;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.commons.text.StringSubstitutor;
|
||||
import org.dromara.common.core.service.OssService;
|
||||
import org.dromara.common.core.utils.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.time.ZoneId;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class TemplateServiceImpl implements ITemplateService {
|
||||
|
||||
private static final DateTimeFormatter SIGN_DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy年MM月dd日");
|
||||
|
||||
private final HotSignFileDetailMapper signFileDetailMapper;
|
||||
private final ISysCompanyService companyService;
|
||||
private final HotCompanySafetyManagerMapper safetyManagerMapper;
|
||||
private final HotDriverMapper driverMapper;
|
||||
private final OssService ossService;
|
||||
|
||||
@Override
|
||||
public String fillTemplate(String templateContent, Map<String, Object> dataMap) {
|
||||
if (StrUtil.isBlank(templateContent)) {
|
||||
return "";
|
||||
}
|
||||
Map<String, Object> renderMap = dataMap == null ? new HashMap<>() : dataMap;
|
||||
StringSubstitutor substitutor = new StringSubstitutor(renderMap, "{", "}");
|
||||
substitutor.setEnableUndefinedVariableException(false);
|
||||
String rendered = substitutor.replace(templateContent);
|
||||
return rendered.replaceAll("\\{[^{}]+\\}", "");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> prepareDataMapForSignDetail(Long detailId) {
|
||||
Map<String, Object> dataMap = new HashMap<>();
|
||||
HotSignFileDetailVo detail = signFileDetailMapper.selectVoById(detailId);
|
||||
if (detail == null) {
|
||||
return dataMap;
|
||||
}
|
||||
String signOssId = detail.getSignOssId();
|
||||
|
||||
if (detail.getCompanyId() != null) {
|
||||
SysCompanyVo company = companyService.queryById(detail.getCompanyId());
|
||||
if (company != null) {
|
||||
dataMap.put("企业名字", StringUtils.defaultString(company.getCompanyName()));
|
||||
dataMap.put("信用代码", StringUtils.defaultString(company.getCreditCode()));
|
||||
String sealUrl = resolveOssUrl(company.getSealUrl());
|
||||
if (StrUtil.isNotBlank(sealUrl)) {
|
||||
dataMap.put("电子公章", buildSealImgTag(sealUrl));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (StrUtil.isNotBlank(detail.getStaffId()) && NumberUtil.isLong(detail.getStaffId())) {
|
||||
HotCompanySafetyManager manager;
|
||||
try {
|
||||
manager = safetyManagerMapper.selectById(Long.valueOf(detail.getStaffId()));
|
||||
} catch (Exception e) {
|
||||
manager = null;
|
||||
}
|
||||
if (manager != null && manager.getId() != null) {
|
||||
dataMap.put("管理员姓名", StringUtils.defaultString(manager.getName()));
|
||||
dataMap.put("管理员身份证号码", StringUtils.defaultString(manager.getIdCardNo()));
|
||||
dataMap.put("管理员手机号码", StringUtils.defaultString(manager.getPhone()));
|
||||
dataMap.put("管理员岗位", StringUtils.defaultString(manager.getJobName()));
|
||||
if (StrUtil.isNotBlank(signOssId)) {
|
||||
String signImg = resolveOssUrl(signOssId);
|
||||
dataMap.put("管理员签名", buildSignImgTag(signImg));
|
||||
if (detail.getSignTime() != null) {
|
||||
String signDate = detail.getSignTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate().format(SIGN_DATE_FORMATTER);
|
||||
dataMap.put("管理员签字日期", signDate);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (StrUtil.isNotBlank(detail.getStaffId()) && !NumberUtil.isLong(detail.getStaffId())) {
|
||||
HotDriver driver = driverMapper.selectById(detail.getStaffId());
|
||||
if (driver != null && driver.getId() != null) {
|
||||
dataMap.put("驾驶员姓名", StringUtils.defaultString(driver.getName()));
|
||||
dataMap.put("驾驶员身份证号码", StringUtils.defaultString(driver.getIdCardNo()));
|
||||
dataMap.put("驾驶员手机号码", StringUtils.defaultString(driver.getPhone()));
|
||||
dataMap.put("驾驶员从业资格证号码", StringUtils.defaultString(driver.getQualificationNo()));
|
||||
dataMap.put("驾驶员驾驶车牌号", StringUtils.defaultString(driver.getPlateNumber()));
|
||||
if (StrUtil.isNotBlank(signOssId)) {
|
||||
String signImg = resolveOssUrl(signOssId);
|
||||
dataMap.put("驾驶员签名", buildSignImgTag(signImg));
|
||||
if (detail.getSignTime() != null) {
|
||||
String signDate = detail.getSignTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate().format(SIGN_DATE_FORMATTER);
|
||||
dataMap.put("驾驶员签字日期", signDate);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return dataMap;
|
||||
}
|
||||
|
||||
private String resolveOssUrl(String source) {
|
||||
if (StrUtil.isBlank(source)) {
|
||||
return null;
|
||||
}
|
||||
if (source.startsWith("http://") || source.startsWith("https://")) {
|
||||
return source;
|
||||
}
|
||||
String urls = ossService.selectUrlByIds(source);
|
||||
if (StrUtil.isBlank(urls)) {
|
||||
return source;
|
||||
}
|
||||
if (urls.contains(",")) {
|
||||
for (String part : urls.split(",")) {
|
||||
if (StrUtil.isNotBlank(part)) {
|
||||
return part.trim();
|
||||
}
|
||||
}
|
||||
}
|
||||
return urls;
|
||||
}
|
||||
|
||||
private String buildSignImgTag(String url) {
|
||||
return "<img src=\"" + url + "\" style=\"display:inline-block !important; max-height: 66px; max-width: 160px; vertical-align: middle; margin: 0 2px;\" />";
|
||||
}
|
||||
|
||||
private String buildSealImgTag(String url) {
|
||||
return "<span style=\"display:inline-block; position:relative; width:0; height:0; line-height:0; vertical-align:middle; overflow:visible;\"><img src=\"" + url + "\" style=\"position:absolute; left:-35px; top:-60px; max-height:120px; max-width:220px; z-index:9; pointer-events:none;\" /></span>";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
package com.hotwj.platform.common.utils;
|
||||
|
||||
import cn.hutool.core.io.IoUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||
import org.apache.pdfbox.text.PDFTextStripper;
|
||||
import org.apache.poi.hslf.usermodel.HSLFSlideShow;
|
||||
import org.apache.poi.hssf.extractor.ExcelExtractor;
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
import org.apache.poi.hwpf.HWPFDocument;
|
||||
import org.apache.poi.hwpf.extractor.WordExtractor;
|
||||
import org.apache.poi.sl.extractor.SlideShowExtractor;
|
||||
import org.apache.poi.xslf.usermodel.XMLSlideShow;
|
||||
import org.apache.poi.xssf.extractor.XSSFExcelExtractor;
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||
import org.apache.poi.xwpf.extractor.XWPFWordExtractor;
|
||||
import org.apache.poi.xwpf.usermodel.XWPFDocument;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
@Slf4j
|
||||
public class FileTextExtractor {
|
||||
|
||||
public static String extractText(InputStream is, String fileExtension) {
|
||||
if (is == null || StrUtil.isBlank(fileExtension)) {
|
||||
return "";
|
||||
}
|
||||
|
||||
String ext = fileExtension.toLowerCase();
|
||||
// Remove dot if present
|
||||
if (ext.startsWith(".")) {
|
||||
ext = ext.substring(1);
|
||||
}
|
||||
|
||||
try {
|
||||
switch (ext) {
|
||||
case "txt":
|
||||
return IoUtil.read(is, StandardCharsets.UTF_8);
|
||||
case "pdf":
|
||||
try (PDDocument document = PDDocument.load(is)) {
|
||||
PDFTextStripper stripper = new PDFTextStripper();
|
||||
return stripper.getText(document);
|
||||
}
|
||||
case "doc":
|
||||
try (HWPFDocument doc = new HWPFDocument(is);
|
||||
WordExtractor extractor = new WordExtractor(doc)) {
|
||||
return extractor.getText();
|
||||
}
|
||||
case "docx":
|
||||
try (XWPFDocument doc = new XWPFDocument(is);
|
||||
XWPFWordExtractor extractor = new XWPFWordExtractor(doc)) {
|
||||
return extractor.getText();
|
||||
}
|
||||
case "xls":
|
||||
try (HSSFWorkbook wb = new HSSFWorkbook(is);
|
||||
ExcelExtractor extractor = new ExcelExtractor(wb)) {
|
||||
extractor.setFormulasNotResults(false);
|
||||
extractor.setIncludeSheetNames(false);
|
||||
return extractor.getText();
|
||||
}
|
||||
case "xlsx":
|
||||
try (XSSFWorkbook wb = new XSSFWorkbook(is);
|
||||
XSSFExcelExtractor extractor = new XSSFExcelExtractor(wb)) {
|
||||
extractor.setFormulasNotResults(false);
|
||||
extractor.setIncludeSheetNames(false);
|
||||
return extractor.getText();
|
||||
}
|
||||
case "ppt":
|
||||
try (HSLFSlideShow ppt = new HSLFSlideShow(is);
|
||||
SlideShowExtractor extractor = new SlideShowExtractor(ppt)) {
|
||||
return extractor.getText();
|
||||
}
|
||||
case "pptx":
|
||||
try (XMLSlideShow ppt = new XMLSlideShow(is);
|
||||
SlideShowExtractor extractor = new SlideShowExtractor(ppt)) {
|
||||
return extractor.getText();
|
||||
}
|
||||
default:
|
||||
log.warn("Unsupported file extension for text extraction: {}", ext);
|
||||
return "";
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("Failed to extract text from file type: " + ext, e);
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.hotwj.platform.common.utils;
|
||||
|
||||
import cn.hutool.crypto.digest.BCrypt;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* 密码工具类
|
||||
*
|
||||
* @author shihongwei
|
||||
* @date 2025-12-10
|
||||
*/
|
||||
@Slf4j
|
||||
public class PasswordUtils {
|
||||
|
||||
/**
|
||||
* 默认密码规则:手机号+hot
|
||||
*
|
||||
* @param phone
|
||||
* @return
|
||||
*/
|
||||
public static String createDefaultPassword(String phone) {
|
||||
return BCrypt.hashpw(phone + "hot");
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过明文创建密文
|
||||
*
|
||||
* @param password
|
||||
* @return
|
||||
*/
|
||||
public static String createPassword(String password) {
|
||||
return BCrypt.hashpw(password);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,381 @@
|
||||
package com.hotwj.platform.common.utils;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.fontbox.ttf.TrueTypeCollection;
|
||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||
import org.apache.pdfbox.pdmodel.PDPage;
|
||||
import org.apache.pdfbox.pdmodel.PDPageContentStream;
|
||||
import org.apache.pdfbox.pdmodel.font.PDFont;
|
||||
import org.apache.pdfbox.pdmodel.font.PDType0Font;
|
||||
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
|
||||
import org.apache.pdfbox.pdmodel.graphics.state.PDExtendedGraphicsState;
|
||||
import org.apache.pdfbox.rendering.PDFRenderer;
|
||||
import org.apache.pdfbox.util.Matrix;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* PDF Watermark Utility
|
||||
* Adds text watermarks to PDF files using PDFBox.
|
||||
*
|
||||
* @author shihongwei
|
||||
* @date 2026-01-02
|
||||
*/
|
||||
@Slf4j
|
||||
public class PdfWatermarkUtil {
|
||||
|
||||
private static final String DEFAULT_APP_NAME = "HOT交通安全管理清单平台";
|
||||
private static final String DEFAULT_WATERMARK_TEXT = "HOT交通安全\n管理清单平台";
|
||||
private static final float WATERMARK_ALPHA = 0.15f;
|
||||
private static final float PAGE_NUMBER_ALPHA = 1.0f;
|
||||
private static final int WATERMARK_FONT_SIZE = 18;
|
||||
private static final float PAGE_NUMBER_FONT_SIZE = 7.5f;
|
||||
private static final int WATERMARK_ANGLE = -30;
|
||||
private static final int WATERMARK_GAP = 200;
|
||||
|
||||
private static volatile byte[] cachedFontBytes;
|
||||
|
||||
/**
|
||||
* Lazy loads the font bytes from classpath
|
||||
*/
|
||||
private static byte[] getFontBytes() {
|
||||
if (cachedFontBytes != null) {
|
||||
return cachedFontBytes;
|
||||
}
|
||||
synchronized (PdfWatermarkUtil.class) {
|
||||
if (cachedFontBytes == null) {
|
||||
try {
|
||||
ClassPathResource fontResource = new ClassPathResource("fonts/simsun.ttc");
|
||||
if (fontResource.exists()) {
|
||||
try (InputStream is = fontResource.getInputStream()) {
|
||||
cachedFontBytes = is.readAllBytes();
|
||||
}
|
||||
} else {
|
||||
log.warn("Watermark font file not found at fonts/simsun.ttc");
|
||||
}
|
||||
} catch (IOException e) {
|
||||
log.error("Failed to load watermark font", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
return cachedFontBytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a text watermark to the provided PDF bytes (optimized for Landscape A4).
|
||||
*
|
||||
* @param pdfBytes The original PDF bytes
|
||||
* @param appName The text to use as watermark
|
||||
* @return The PDF bytes with watermark added
|
||||
*/
|
||||
public static byte[] addWatermarkLandscape(byte[] pdfBytes, String appName) {
|
||||
return addWatermark(pdfBytes, appName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a text watermark to the provided PDF bytes.
|
||||
*
|
||||
* @param pdfBytes The original PDF bytes
|
||||
* @param appName The text to use as watermark (usually application name)
|
||||
* @return The PDF bytes with watermark added
|
||||
*/
|
||||
public static byte[] addWatermark(byte[] pdfBytes, String appName) {
|
||||
byte[] fontBytes = getFontBytes();
|
||||
if (fontBytes == null) {
|
||||
log.warn("Watermark font not loaded, skipping watermark.");
|
||||
return pdfBytes;
|
||||
}
|
||||
|
||||
String wmText = formatWatermarkText(appName);
|
||||
|
||||
try (PDDocument doc = PDDocument.load(pdfBytes)) {
|
||||
PDFont font = loadFont(doc, fontBytes);
|
||||
if (font == null) {
|
||||
return pdfBytes;
|
||||
}
|
||||
|
||||
PDExtendedGraphicsState r0 = new PDExtendedGraphicsState();
|
||||
r0.setNonStrokingAlphaConstant(WATERMARK_ALPHA);
|
||||
|
||||
String[] lines = wmText.split("\n|\\\\n");
|
||||
|
||||
for (PDPage page : doc.getPages()) {
|
||||
try (PDPageContentStream cs = new PDPageContentStream(doc, page, PDPageContentStream.AppendMode.APPEND, true, true)) {
|
||||
cs.setGraphicsStateParameters(r0);
|
||||
cs.setFont(font, WATERMARK_FONT_SIZE);
|
||||
cs.setNonStrokingColor(Color.BLACK);
|
||||
|
||||
float pageWidth = page.getMediaBox().getWidth();
|
||||
float pageHeight = page.getMediaBox().getHeight();
|
||||
|
||||
for (int x = 0; x < pageWidth; x += WATERMARK_GAP) {
|
||||
for (int y = 0; y < pageHeight; y += WATERMARK_GAP) {
|
||||
drawWatermarkText(cs, lines, x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
doc.save(baos);
|
||||
return baos.toByteArray();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Failed to add watermark to PDF", e);
|
||||
}
|
||||
}
|
||||
|
||||
private static PDFont loadFont(PDDocument doc, byte[] fontBytes) {
|
||||
try (InputStream is = new ByteArrayInputStream(fontBytes)) {
|
||||
TrueTypeCollection ttc = new TrueTypeCollection(is);
|
||||
return PDType0Font.load(doc, ttc.getFontByName("SimSun"), true);
|
||||
} catch (Exception e) {
|
||||
log.error("Error loading font from cached bytes", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static void drawWatermarkText(PDPageContentStream cs, String[] lines, float x, float y) throws IOException {
|
||||
cs.beginText();
|
||||
// Add offset to center within the grid cell roughly
|
||||
// Shift y up by 100 (instead of 50) to prevent bottom row cutoff
|
||||
Matrix matrix = Matrix.getRotateInstance(Math.toRadians(WATERMARK_ANGLE), x + 50, y + 100);
|
||||
cs.setTextMatrix(matrix);
|
||||
|
||||
float leading = 20f;
|
||||
for (String line : lines) {
|
||||
cs.showText(line);
|
||||
cs.newLineAtOffset(0, -leading);
|
||||
}
|
||||
cs.endText();
|
||||
}
|
||||
|
||||
private static String formatWatermarkText(String appName) {
|
||||
String wmText = appName;
|
||||
if (wmText == null || wmText.isEmpty() || DEFAULT_APP_NAME.equals(wmText)) {
|
||||
return DEFAULT_WATERMARK_TEXT;
|
||||
}
|
||||
if (wmText.length() > 10 && !wmText.contains("<br>") && !wmText.contains("\n")) {
|
||||
int mid = wmText.length() / 2;
|
||||
return wmText.substring(0, mid) + "\n" + wmText.substring(mid);
|
||||
}
|
||||
return wmText;
|
||||
}
|
||||
|
||||
public static byte[] addSealBottomRight(byte[] pdfBytes, byte[] sealImageBytes) {
|
||||
if (pdfBytes == null || sealImageBytes == null || sealImageBytes.length == 0) {
|
||||
return pdfBytes;
|
||||
}
|
||||
try (PDDocument doc = PDDocument.load(pdfBytes)) {
|
||||
PDImageXObject image = PDImageXObject.createFromByteArray(doc, sealImageBytes, "seal");
|
||||
PDFRenderer renderer = new PDFRenderer(doc);
|
||||
float imageWidth = image.getWidth();
|
||||
float imageHeight = image.getHeight();
|
||||
int pageIndex = 0;
|
||||
for (PDPage page : doc.getPages()) {
|
||||
float pageWidth = page.getMediaBox().getWidth();
|
||||
float pageHeight = page.getMediaBox().getHeight();
|
||||
float targetWidth = pageWidth * 0.18f;
|
||||
float scale = targetWidth / imageWidth;
|
||||
float targetHeight = imageHeight * scale;
|
||||
float marginX = pageWidth * 0.04f;
|
||||
float marginY = pageHeight * 0.04f;
|
||||
float x = pageWidth - targetWidth - marginX;
|
||||
float y = marginY;
|
||||
|
||||
try {
|
||||
BufferedImage pageImage = renderer.renderImageWithDPI(pageIndex, 110);
|
||||
int width = pageImage.getWidth();
|
||||
int height = pageImage.getHeight();
|
||||
int denseRowThreshold = Math.max(20, (int) (width * 0.30f));
|
||||
int denseColThreshold = Math.max(12, (int) (height * 0.06f));
|
||||
int lastDenseRow = -1;
|
||||
int rightDenseCol = -1;
|
||||
|
||||
for (int iy = 0; iy < height; iy++) {
|
||||
int darkCount = 0;
|
||||
for (int ix = 0; ix < width; ix++) {
|
||||
int rgb = pageImage.getRGB(ix, iy);
|
||||
int r = (rgb >> 16) & 0xff;
|
||||
int g = (rgb >> 8) & 0xff;
|
||||
int b = rgb & 0xff;
|
||||
if (r < 120 || g < 120 || b < 120) {
|
||||
darkCount++;
|
||||
}
|
||||
}
|
||||
if (darkCount >= denseRowThreshold) {
|
||||
lastDenseRow = iy;
|
||||
}
|
||||
}
|
||||
|
||||
for (int ix = 0; ix < width; ix++) {
|
||||
int darkCount = 0;
|
||||
for (int iy = 0; iy < height; iy++) {
|
||||
int rgb = pageImage.getRGB(ix, iy);
|
||||
int r = (rgb >> 16) & 0xff;
|
||||
int g = (rgb >> 8) & 0xff;
|
||||
int b = rgb & 0xff;
|
||||
if (r < 120 || g < 120 || b < 120) {
|
||||
darkCount++;
|
||||
}
|
||||
}
|
||||
if (darkCount >= denseColThreshold) {
|
||||
rightDenseCol = ix;
|
||||
}
|
||||
}
|
||||
|
||||
if (lastDenseRow >= 0 && rightDenseCol >= 0) {
|
||||
float contentRight = (rightDenseCol + 1f) * pageWidth / width;
|
||||
float contentBottom = pageHeight - ((lastDenseRow + 1f) * pageHeight / height);
|
||||
float insetX = targetWidth * 0.06f;
|
||||
float insetY = targetHeight * 0.06f;
|
||||
float sealX = contentRight - targetWidth - insetX;
|
||||
float sealY = contentBottom + insetY;
|
||||
float maxX = pageWidth - targetWidth - marginX;
|
||||
float maxY = pageHeight - targetHeight - marginY;
|
||||
float minX = marginX;
|
||||
float minY = marginY;
|
||||
x = Math.max(minX, Math.min(sealX, maxX));
|
||||
y = Math.max(minY, Math.min(sealY, maxY));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("Failed to detect table edge for seal placement on page {}", pageIndex + 1, e);
|
||||
}
|
||||
try (PDPageContentStream cs = new PDPageContentStream(doc, page, PDPageContentStream.AppendMode.APPEND, true, true)) {
|
||||
cs.drawImage(image, x, y, targetWidth, targetHeight);
|
||||
}
|
||||
pageIndex++;
|
||||
}
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
doc.save(baos);
|
||||
return baos.toByteArray();
|
||||
} catch (Exception e) {
|
||||
log.error("Failed to add seal to PDF", e);
|
||||
return pdfBytes;
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] addPageNumbers(byte[] pdfBytes) {
|
||||
byte[] fontBytes = getFontBytes();
|
||||
if (fontBytes == null) {
|
||||
return pdfBytes;
|
||||
}
|
||||
try (PDDocument doc = PDDocument.load(pdfBytes)) {
|
||||
PDFont font = loadFont(doc, fontBytes);
|
||||
if (font == null) {
|
||||
return pdfBytes;
|
||||
}
|
||||
int total = doc.getNumberOfPages();
|
||||
PDExtendedGraphicsState r0 = new PDExtendedGraphicsState();
|
||||
r0.setNonStrokingAlphaConstant(PAGE_NUMBER_ALPHA);
|
||||
int index = 1;
|
||||
for (PDPage page : doc.getPages()) {
|
||||
try (PDPageContentStream cs = new PDPageContentStream(doc, page, PDPageContentStream.AppendMode.APPEND, true, true)) {
|
||||
cs.setGraphicsStateParameters(r0);
|
||||
cs.setFont(font, PAGE_NUMBER_FONT_SIZE);
|
||||
float pageWidth = page.getMediaBox().getWidth();
|
||||
|
||||
float leftPaddingX = 28.35f;
|
||||
float rightPaddingX = 18.0f;
|
||||
float y = 24f;
|
||||
|
||||
cs.setNonStrokingColor(new Color(0x88, 0x88, 0x88));
|
||||
cs.beginText();
|
||||
cs.newLineAtOffset(leftPaddingX, y);
|
||||
cs.showText("平台信息依实为准,信息使用自判");
|
||||
cs.endText();
|
||||
|
||||
String pageLabel = "第 " + index + "/" + total + " 页";
|
||||
float pageLabelWidth = font.getStringWidth(pageLabel) / 1000f * PAGE_NUMBER_FONT_SIZE;
|
||||
float x = pageWidth - rightPaddingX - pageLabelWidth;
|
||||
cs.setNonStrokingColor(Color.BLACK);
|
||||
cs.beginText();
|
||||
cs.newLineAtOffset(x, y);
|
||||
cs.showText(pageLabel);
|
||||
cs.endText();
|
||||
}
|
||||
index++;
|
||||
}
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
doc.save(baos);
|
||||
return baos.toByteArray();
|
||||
} catch (Exception e) {
|
||||
return pdfBytes;
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] addImageTopLeft(byte[] pdfBytes, byte[] imageBytes) {
|
||||
return addImageTopLeft(pdfBytes, imageBytes, 0.18f, 0.04f);
|
||||
}
|
||||
|
||||
public static byte[] addImageTopLeft(byte[] pdfBytes, byte[] imageBytes, float widthRatio, float marginRatio) {
|
||||
if (pdfBytes == null || imageBytes == null || imageBytes.length == 0) {
|
||||
return pdfBytes;
|
||||
}
|
||||
try (PDDocument doc = PDDocument.load(pdfBytes)) {
|
||||
PDImageXObject image = PDImageXObject.createFromByteArray(doc, imageBytes, "wm_top_left");
|
||||
float imageWidth = image.getWidth();
|
||||
float imageHeight = image.getHeight();
|
||||
for (PDPage page : doc.getPages()) {
|
||||
float pageWidth = page.getMediaBox().getWidth();
|
||||
float pageHeight = page.getMediaBox().getHeight();
|
||||
float targetWidth = pageWidth * widthRatio;
|
||||
float scale = targetWidth / imageWidth;
|
||||
float targetHeight = imageHeight * scale;
|
||||
float marginX = pageWidth * marginRatio;
|
||||
float marginY = pageHeight * marginRatio;
|
||||
float x = marginX;
|
||||
float y = pageHeight - targetHeight - marginY;
|
||||
try (PDPageContentStream cs = new PDPageContentStream(doc, page, PDPageContentStream.AppendMode.APPEND, true, true)) {
|
||||
cs.drawImage(image, x, y, targetWidth, targetHeight);
|
||||
}
|
||||
}
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
doc.save(baos);
|
||||
return baos.toByteArray();
|
||||
} catch (Exception e) {
|
||||
log.error("Failed to add top-left image to PDF", e);
|
||||
return pdfBytes;
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] addImageTopRight(byte[] pdfBytes, byte[] imageBytes) {
|
||||
return addImageTopRight(pdfBytes, imageBytes, 0.18f, 0.04f);
|
||||
}
|
||||
|
||||
public static byte[] addImageTopRight(byte[] pdfBytes, byte[] imageBytes, float widthRatio, float marginRatio) {
|
||||
if (pdfBytes == null || imageBytes == null || imageBytes.length == 0) {
|
||||
return pdfBytes;
|
||||
}
|
||||
try (PDDocument doc = PDDocument.load(pdfBytes)) {
|
||||
PDImageXObject image = PDImageXObject.createFromByteArray(doc, imageBytes, "wm_top_right");
|
||||
float imageWidth = image.getWidth();
|
||||
float imageHeight = image.getHeight();
|
||||
for (PDPage page : doc.getPages()) {
|
||||
float pageWidth = page.getMediaBox().getWidth();
|
||||
float pageHeight = page.getMediaBox().getHeight();
|
||||
float targetWidth = pageWidth * widthRatio;
|
||||
float scale = targetWidth / imageWidth;
|
||||
float targetHeight = imageHeight * scale;
|
||||
float marginX = pageWidth * marginRatio;
|
||||
float marginY = pageHeight * marginRatio;
|
||||
float x = pageWidth - targetWidth - marginX;
|
||||
float y = pageHeight - targetHeight - marginY;
|
||||
try (PDPageContentStream cs = new PDPageContentStream(doc, page, PDPageContentStream.AppendMode.APPEND, true, true)) {
|
||||
cs.drawImage(image, x, y, targetWidth, targetHeight);
|
||||
}
|
||||
}
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
doc.save(baos);
|
||||
return baos.toByteArray();
|
||||
} catch (Exception e) {
|
||||
log.error("Failed to add top-right image to PDF", e);
|
||||
return pdfBytes;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
package com.hotwj.platform.common.utils;
|
||||
|
||||
import java.time.DayOfWeek;
|
||||
import java.time.LocalDate;
|
||||
import java.time.ZoneId;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.temporal.TemporalAdjusters;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 时间范围工具类
|
||||
*/
|
||||
public class TimeRangeUtil {
|
||||
|
||||
public static class TimeRange {
|
||||
private final Date startTime;
|
||||
private final Date endTime;
|
||||
|
||||
public TimeRange(Date startTime, Date endTime) {
|
||||
this.startTime = startTime;
|
||||
this.endTime = endTime;
|
||||
}
|
||||
|
||||
public Date getStartTime() {
|
||||
return startTime;
|
||||
}
|
||||
|
||||
public Date getEndTime() {
|
||||
return endTime;
|
||||
}
|
||||
}
|
||||
|
||||
public static TimeRange getCurrentWeek() {
|
||||
LocalDate today = LocalDate.now();
|
||||
LocalDate startOfWeek = today.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
|
||||
LocalDate endOfWeek = today.with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY));
|
||||
return new TimeRange(toDate(startOfWeek), toDate(endOfWeek));
|
||||
}
|
||||
|
||||
public static TimeRange getCurrentMonth() {
|
||||
LocalDate today = LocalDate.now();
|
||||
LocalDate startOfMonth = today.with(TemporalAdjusters.firstDayOfMonth());
|
||||
LocalDate endOfMonth = today.with(TemporalAdjusters.lastDayOfMonth());
|
||||
return new TimeRange(toDate(startOfMonth), toDate(endOfMonth));
|
||||
}
|
||||
|
||||
public static TimeRange getCurrentQuarter() {
|
||||
LocalDate today = LocalDate.now();
|
||||
int month = today.getMonthValue();
|
||||
int quarterStartMonth = month - (month - 1) % 3;
|
||||
LocalDate startOfQuarter = today.withMonth(quarterStartMonth).with(TemporalAdjusters.firstDayOfMonth());
|
||||
LocalDate endOfQuarter = startOfQuarter.plusMonths(2).with(TemporalAdjusters.lastDayOfMonth());
|
||||
return new TimeRange(toDate(startOfQuarter), toDate(endOfQuarter));
|
||||
}
|
||||
|
||||
public static TimeRange getCurrentHalfYear() {
|
||||
LocalDate today = LocalDate.now();
|
||||
int month = today.getMonthValue();
|
||||
LocalDate startOfHalfYear;
|
||||
LocalDate endOfHalfYear;
|
||||
if (month <= 6) {
|
||||
startOfHalfYear = LocalDate.of(today.getYear(), 1, 1);
|
||||
endOfHalfYear = LocalDate.of(today.getYear(), 6, 30);
|
||||
} else {
|
||||
startOfHalfYear = LocalDate.of(today.getYear(), 7, 1);
|
||||
endOfHalfYear = LocalDate.of(today.getYear(), 12, 31);
|
||||
}
|
||||
return new TimeRange(toDate(startOfHalfYear), toDate(endOfHalfYear));
|
||||
}
|
||||
|
||||
public static TimeRange getCurrentYear() {
|
||||
LocalDate today = LocalDate.now();
|
||||
LocalDate startOfYear = today.with(TemporalAdjusters.firstDayOfYear());
|
||||
LocalDate endOfYear = today.with(TemporalAdjusters.lastDayOfYear());
|
||||
return new TimeRange(toDate(startOfYear), toDate(endOfYear));
|
||||
}
|
||||
|
||||
public static int getCurrentQuarterNumber() {
|
||||
return (LocalDate.now().getMonthValue() - 1) / 3 + 1;
|
||||
}
|
||||
|
||||
public static String getCurrentHalfYearDescription() {
|
||||
return LocalDate.now().getMonthValue() <= 6 ? "上半年" : "下半年";
|
||||
}
|
||||
|
||||
public static String formatDate(Date date, String pattern) {
|
||||
if (date == null) return "";
|
||||
return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate().format(DateTimeFormatter.ofPattern(pattern));
|
||||
}
|
||||
|
||||
private static Date toDate(LocalDate localDate) {
|
||||
return Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
|
||||
}
|
||||
}
|
||||
62
src/main/java/com/hotwj/platform/common/vo/AddressVo.java
Normal file
62
src/main/java/com/hotwj/platform/common/vo/AddressVo.java
Normal file
@@ -0,0 +1,62 @@
|
||||
package com.hotwj.platform.common.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Data
|
||||
public class AddressVo {
|
||||
private Long id;
|
||||
private String label;
|
||||
private String value;
|
||||
private List<AddressVo> children;
|
||||
|
||||
public static List<AddressVo> buildTree(List<AddressVo> list) {
|
||||
Map<String, AddressVo> map = new HashMap<>();
|
||||
List<AddressVo> roots = new ArrayList<>();
|
||||
for (AddressVo vo : list) {
|
||||
if (vo != null && vo.getValue() != null) {
|
||||
map.put(vo.getValue(), vo);
|
||||
}
|
||||
}
|
||||
for (AddressVo vo : list) {
|
||||
if (vo == null) {
|
||||
continue;
|
||||
}
|
||||
String code = vo.getValue();
|
||||
String parent = parentCode(code);
|
||||
AddressVo p = parent == null ? null : map.get(parent);
|
||||
if (p == null) {
|
||||
roots.add(vo);
|
||||
} else {
|
||||
List<AddressVo> c = p.getChildren();
|
||||
if (c == null) {
|
||||
c = new ArrayList<>();
|
||||
p.setChildren(c);
|
||||
}
|
||||
c.add(vo);
|
||||
}
|
||||
}
|
||||
return roots;
|
||||
}
|
||||
|
||||
private static String parentCode(String code) {
|
||||
if (code == null) {
|
||||
return null;
|
||||
}
|
||||
String c = code.trim();
|
||||
if (c.length() == 6) {
|
||||
if (c.endsWith("0000")) {
|
||||
return null;
|
||||
}
|
||||
if (c.endsWith("00")) {
|
||||
return c.substring(0, 2) + "0000";
|
||||
}
|
||||
return c.substring(0, 4) + "00";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
package com.hotwj.platform.config.accidentLevelConfig.controller;
|
||||
|
||||
import com.hotwj.platform.config.accidentLevelConfig.domain.bo.HotAccidentLevelConfigBo;
|
||||
import com.hotwj.platform.config.accidentLevelConfig.domain.vo.HotAccidentLevelConfigVo;
|
||||
import com.hotwj.platform.config.accidentLevelConfig.service.IHotAccidentLevelConfigService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.dromara.common.core.domain.R;
|
||||
import org.dromara.common.core.validate.AddGroup;
|
||||
import org.dromara.common.core.validate.EditGroup;
|
||||
import org.dromara.common.excel.utils.ExcelUtil;
|
||||
import org.dromara.common.idempotent.annotation.RepeatSubmit;
|
||||
import org.dromara.common.log.annotation.Log;
|
||||
import org.dromara.common.log.enums.BusinessType;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.dromara.common.web.core.BaseController;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 事故等级划分
|
||||
*
|
||||
* @author shihongwei
|
||||
* @date 2026-01-06
|
||||
*/
|
||||
@Validated
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/config/accidentLevelConfig")
|
||||
@Tag(name = "事故等级划分", description = "事故等级划分管理")
|
||||
public class HotAccidentLevelConfigController extends BaseController {
|
||||
|
||||
private final IHotAccidentLevelConfigService hotAccidentLevelConfigService;
|
||||
|
||||
/**
|
||||
* 查询事故等级划分列表
|
||||
*/
|
||||
//@SaCheckPermission("config:accidentLevelConfig:list")
|
||||
@GetMapping("/list")
|
||||
@Operation(summary = "分页查询事故等级划分列表")
|
||||
public TableDataInfo<HotAccidentLevelConfigVo> list(HotAccidentLevelConfigBo bo, PageQuery pageQuery) {
|
||||
return hotAccidentLevelConfigService.queryPageList(bo, pageQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出事故等级划分列表
|
||||
*/
|
||||
//@SaCheckPermission("config:accidentLevelConfig:export")
|
||||
@Log(title = "事故等级划分", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/export")
|
||||
@Operation(summary = "导出事故等级划分列表")
|
||||
public void export(HotAccidentLevelConfigBo bo, HttpServletResponse response) {
|
||||
List<HotAccidentLevelConfigVo> list = hotAccidentLevelConfigService.queryList(bo);
|
||||
ExcelUtil.exportExcel(list, "事故等级划分", HotAccidentLevelConfigVo.class, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取事故等级划分详细信息
|
||||
*
|
||||
* @param id 主键
|
||||
*/
|
||||
//@SaCheckPermission("config:accidentLevelConfig:query")
|
||||
@GetMapping("/{id}")
|
||||
@Operation(summary = "获取事故等级划分详细信息")
|
||||
public R<HotAccidentLevelConfigVo> getInfo(@NotNull(message = "主键不能为空")
|
||||
@Parameter(name = "id", description = "主键", required = true, example = "1")
|
||||
@PathVariable Long id) {
|
||||
return R.ok(hotAccidentLevelConfigService.queryById(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增事故等级划分
|
||||
*/
|
||||
//@SaCheckPermission("config:accidentLevelConfig:add")
|
||||
@Log(title = "事故等级划分", businessType = BusinessType.INSERT)
|
||||
@RepeatSubmit()
|
||||
@PostMapping()
|
||||
@Operation(summary = "新增事故等级划分")
|
||||
public R<Void> add(@Validated(AddGroup.class) @RequestBody HotAccidentLevelConfigBo bo) {
|
||||
return toAjax(hotAccidentLevelConfigService.insertByBo(bo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改事故等级划分
|
||||
*/
|
||||
//@SaCheckPermission("config:accidentLevelConfig:edit")
|
||||
@Log(title = "事故等级划分", businessType = BusinessType.UPDATE)
|
||||
@RepeatSubmit()
|
||||
@PutMapping()
|
||||
@Operation(summary = "修改事故等级划分")
|
||||
public R<Void> edit(@Validated(EditGroup.class) @RequestBody HotAccidentLevelConfigBo bo) {
|
||||
return toAjax(hotAccidentLevelConfigService.updateByBo(bo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除事故等级划分
|
||||
*
|
||||
* @param ids 主键串
|
||||
*/
|
||||
//@SaCheckPermission("config:accidentLevelConfig:remove")
|
||||
@Log(title = "事故等级划分", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{ids}")
|
||||
@Operation(summary = "删除事故等级划分")
|
||||
public R<Void> remove(@NotEmpty(message = "主键不能为空")
|
||||
@Parameter(name = "ids", description = "主键串", required = true, example = "1,2,3")
|
||||
@PathVariable Long[] ids) {
|
||||
return toAjax(hotAccidentLevelConfigService.deleteWithValidByIds(List.of(ids), true));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
package com.hotwj.platform.config.accidentLevelConfig.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
||||
|
||||
import java.io.Serial;
|
||||
|
||||
/**
|
||||
* 事故等级划分对象 hot_accident_level_config
|
||||
*
|
||||
* @author shihongwei
|
||||
* @date 2026-01-06
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("hot_accident_level_config")
|
||||
public class HotAccidentLevelConfig extends BaseEntity {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@TableId(value = "id")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 风险值小值
|
||||
*/
|
||||
private Long minRiskValue;
|
||||
|
||||
/**
|
||||
* 风险值大值
|
||||
*/
|
||||
private Long maxRiskValue;
|
||||
|
||||
/**
|
||||
* 评价分级
|
||||
*/
|
||||
private String levelName;
|
||||
|
||||
/**
|
||||
* 管控级别
|
||||
*/
|
||||
private String controlLevel;
|
||||
|
||||
/**
|
||||
* 管控措施级别
|
||||
*/
|
||||
private String controlMeasureLevel;
|
||||
|
||||
/**
|
||||
* 完成期限
|
||||
*/
|
||||
private String deadlineDesc;
|
||||
|
||||
/**
|
||||
* 0=正常, 1=已删除
|
||||
*/
|
||||
@TableLogic
|
||||
private Long isDeleted;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
package com.hotwj.platform.config.accidentLevelConfig.domain.bo;
|
||||
|
||||
import com.hotwj.platform.config.accidentLevelConfig.domain.HotAccidentLevelConfig;
|
||||
import io.github.linpeilie.annotations.AutoMapper;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.dromara.common.core.validate.AddGroup;
|
||||
import org.dromara.common.core.validate.EditGroup;
|
||||
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
||||
|
||||
/**
|
||||
* 事故等级划分业务对象 hot_accident_level_config
|
||||
*
|
||||
* @author shihongwei
|
||||
* @date 2026-01-06
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@AutoMapper(target = HotAccidentLevelConfig.class, reverseConvertGenerate = false)
|
||||
public class HotAccidentLevelConfigBo extends BaseEntity {
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@NotNull(message = "主键不能为空", groups = {EditGroup.class})
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 风险值小值
|
||||
*/
|
||||
@NotNull(message = "风险值小值不能为空", groups = {AddGroup.class, EditGroup.class})
|
||||
private Long minRiskValue;
|
||||
|
||||
/**
|
||||
* 风险值大值
|
||||
*/
|
||||
@NotNull(message = "风险值大值不能为空", groups = {AddGroup.class, EditGroup.class})
|
||||
private Long maxRiskValue;
|
||||
|
||||
/**
|
||||
* 评价分级
|
||||
*/
|
||||
@NotBlank(message = "评价分级不能为空", groups = {AddGroup.class, EditGroup.class})
|
||||
private String levelName;
|
||||
|
||||
/**
|
||||
* 管控级别
|
||||
*/
|
||||
@NotBlank(message = "管控级别不能为空", groups = {AddGroup.class, EditGroup.class})
|
||||
private String controlLevel;
|
||||
|
||||
/**
|
||||
* 管控措施级别
|
||||
*/
|
||||
@NotBlank(message = "管控措施级别不能为空", groups = {AddGroup.class, EditGroup.class})
|
||||
private String controlMeasureLevel;
|
||||
|
||||
/**
|
||||
* 完成期限
|
||||
*/
|
||||
@NotBlank(message = "完成期限不能为空", groups = {AddGroup.class, EditGroup.class})
|
||||
private String deadlineDesc;
|
||||
|
||||
/**
|
||||
* 0=正常, 1=已删除
|
||||
*/
|
||||
private Long isDeleted;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package com.hotwj.platform.config.accidentLevelConfig.domain.vo;
|
||||
|
||||
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import cn.idev.excel.annotation.ExcelProperty;
|
||||
import com.hotwj.platform.config.accidentLevelConfig.domain.HotAccidentLevelConfig;
|
||||
import io.github.linpeilie.annotations.AutoMapper;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
|
||||
/**
|
||||
* 事故等级划分视图对象 hot_accident_level_config
|
||||
*
|
||||
* @author shihongwei
|
||||
* @date 2026-01-06
|
||||
*/
|
||||
@Data
|
||||
@ExcelIgnoreUnannotated
|
||||
@AutoMapper(target = HotAccidentLevelConfig.class)
|
||||
public class HotAccidentLevelConfigVo implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@ExcelProperty(value = "主键")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 风险值小值
|
||||
*/
|
||||
@ExcelProperty(value = "风险值小值")
|
||||
private Long minRiskValue;
|
||||
|
||||
/**
|
||||
* 风险值大值
|
||||
*/
|
||||
@ExcelProperty(value = "风险值大值")
|
||||
private Long maxRiskValue;
|
||||
|
||||
/**
|
||||
* 评价分级
|
||||
*/
|
||||
@ExcelProperty(value = "评价分级")
|
||||
private String levelName;
|
||||
|
||||
/**
|
||||
* 管控级别
|
||||
*/
|
||||
@ExcelProperty(value = "管控级别")
|
||||
private String controlLevel;
|
||||
|
||||
/**
|
||||
* 管控措施级别
|
||||
*/
|
||||
@ExcelProperty(value = "管控措施级别")
|
||||
private String controlMeasureLevel;
|
||||
|
||||
/**
|
||||
* 完成期限
|
||||
*/
|
||||
@ExcelProperty(value = "完成期限")
|
||||
private String deadlineDesc;
|
||||
|
||||
/**
|
||||
* 0=正常, 1=已删除
|
||||
*/
|
||||
@ExcelProperty(value = "0=正常, 1=已删除")
|
||||
private Long isDeleted;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.hotwj.platform.config.accidentLevelConfig.mapper;
|
||||
|
||||
import com.hotwj.platform.config.accidentLevelConfig.domain.HotAccidentLevelConfig;
|
||||
import com.hotwj.platform.config.accidentLevelConfig.domain.vo.HotAccidentLevelConfigVo;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
|
||||
|
||||
/**
|
||||
* 事故等级划分Mapper接口
|
||||
*
|
||||
* @author shihongwei
|
||||
* @date 2026-01-06
|
||||
*/
|
||||
@Mapper
|
||||
public interface HotAccidentLevelConfigMapper extends BaseMapperPlus<HotAccidentLevelConfig, HotAccidentLevelConfigVo> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package com.hotwj.platform.config.accidentLevelConfig.service;
|
||||
|
||||
import com.hotwj.platform.config.accidentLevelConfig.domain.bo.HotAccidentLevelConfigBo;
|
||||
import com.hotwj.platform.config.accidentLevelConfig.domain.vo.HotAccidentLevelConfigVo;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 事故等级划分Service接口
|
||||
*
|
||||
* @author shihongwei
|
||||
* @date 2026-01-06
|
||||
*/
|
||||
public interface IHotAccidentLevelConfigService {
|
||||
|
||||
/**
|
||||
* 查询事故等级划分
|
||||
*
|
||||
* @param id 主键
|
||||
* @return 事故等级划分
|
||||
*/
|
||||
HotAccidentLevelConfigVo queryById(Long id);
|
||||
|
||||
/**
|
||||
* 分页查询事故等级划分列表
|
||||
*
|
||||
* @param bo 查询条件
|
||||
* @param pageQuery 分页参数
|
||||
* @return 事故等级划分分页列表
|
||||
*/
|
||||
TableDataInfo<HotAccidentLevelConfigVo> queryPageList(HotAccidentLevelConfigBo bo, PageQuery pageQuery);
|
||||
|
||||
/**
|
||||
* 查询符合条件的事故等级划分列表
|
||||
*
|
||||
* @param bo 查询条件
|
||||
* @return 事故等级划分列表
|
||||
*/
|
||||
List<HotAccidentLevelConfigVo> queryList(HotAccidentLevelConfigBo bo);
|
||||
|
||||
/**
|
||||
* 新增事故等级划分
|
||||
*
|
||||
* @param bo 事故等级划分
|
||||
* @return 是否新增成功
|
||||
*/
|
||||
Boolean insertByBo(HotAccidentLevelConfigBo bo);
|
||||
|
||||
/**
|
||||
* 修改事故等级划分
|
||||
*
|
||||
* @param bo 事故等级划分
|
||||
* @return 是否修改成功
|
||||
*/
|
||||
Boolean updateByBo(HotAccidentLevelConfigBo bo);
|
||||
|
||||
/**
|
||||
* 校验并批量删除事故等级划分信息
|
||||
*
|
||||
* @param ids 待删除的主键集合
|
||||
* @param isValid 是否进行有效性校验
|
||||
* @return 是否删除成功
|
||||
*/
|
||||
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
package com.hotwj.platform.config.accidentLevelConfig.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.hotwj.platform.config.accidentLevelConfig.domain.HotAccidentLevelConfig;
|
||||
import com.hotwj.platform.config.accidentLevelConfig.domain.bo.HotAccidentLevelConfigBo;
|
||||
import com.hotwj.platform.config.accidentLevelConfig.domain.vo.HotAccidentLevelConfigVo;
|
||||
import com.hotwj.platform.config.accidentLevelConfig.mapper.HotAccidentLevelConfigMapper;
|
||||
import com.hotwj.platform.config.accidentLevelConfig.service.IHotAccidentLevelConfigService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.common.core.utils.MapstructUtils;
|
||||
import org.dromara.common.core.utils.StringUtils;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 事故等级划分Service业务层处理
|
||||
*
|
||||
* @author shihongwei
|
||||
* @date 2026-01-06
|
||||
*/
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
@Service
|
||||
public class HotAccidentLevelConfigServiceImpl implements IHotAccidentLevelConfigService {
|
||||
|
||||
private final HotAccidentLevelConfigMapper baseMapper;
|
||||
|
||||
/**
|
||||
* 查询事故等级划分
|
||||
*
|
||||
* @param id 主键
|
||||
* @return 事故等级划分
|
||||
*/
|
||||
@Override
|
||||
public HotAccidentLevelConfigVo queryById(Long id) {
|
||||
return baseMapper.selectVoById(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询事故等级划分列表
|
||||
*
|
||||
* @param bo 查询条件
|
||||
* @param pageQuery 分页参数
|
||||
* @return 事故等级划分分页列表
|
||||
*/
|
||||
@Override
|
||||
public TableDataInfo<HotAccidentLevelConfigVo> queryPageList(HotAccidentLevelConfigBo bo, PageQuery pageQuery) {
|
||||
LambdaQueryWrapper<HotAccidentLevelConfig> lqw = buildQueryWrapper(bo);
|
||||
Page<HotAccidentLevelConfigVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
|
||||
return TableDataInfo.build(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询符合条件的事故等级划分列表
|
||||
*
|
||||
* @param bo 查询条件
|
||||
* @return 事故等级划分列表
|
||||
*/
|
||||
@Override
|
||||
public List<HotAccidentLevelConfigVo> queryList(HotAccidentLevelConfigBo bo) {
|
||||
LambdaQueryWrapper<HotAccidentLevelConfig> lqw = buildQueryWrapper(bo);
|
||||
return baseMapper.selectVoList(lqw);
|
||||
}
|
||||
|
||||
private LambdaQueryWrapper<HotAccidentLevelConfig> buildQueryWrapper(HotAccidentLevelConfigBo bo) {
|
||||
Map<String, Object> params = bo.getParams();
|
||||
LambdaQueryWrapper<HotAccidentLevelConfig> lqw = Wrappers.lambdaQuery();
|
||||
lqw.orderByAsc(HotAccidentLevelConfig::getId);
|
||||
lqw.eq(bo.getMinRiskValue() != null, HotAccidentLevelConfig::getMinRiskValue, bo.getMinRiskValue());
|
||||
lqw.eq(bo.getMaxRiskValue() != null, HotAccidentLevelConfig::getMaxRiskValue, bo.getMaxRiskValue());
|
||||
lqw.like(StringUtils.isNotBlank(bo.getLevelName()), HotAccidentLevelConfig::getLevelName, bo.getLevelName());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getControlLevel()), HotAccidentLevelConfig::getControlLevel, bo.getControlLevel());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getControlMeasureLevel()), HotAccidentLevelConfig::getControlMeasureLevel, bo.getControlMeasureLevel());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getDeadlineDesc()), HotAccidentLevelConfig::getDeadlineDesc, bo.getDeadlineDesc());
|
||||
lqw.eq(bo.getIsDeleted() != null, HotAccidentLevelConfig::getIsDeleted, bo.getIsDeleted());
|
||||
return lqw;
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增事故等级划分
|
||||
*
|
||||
* @param bo 事故等级划分
|
||||
* @return 是否新增成功
|
||||
*/
|
||||
@Override
|
||||
public Boolean insertByBo(HotAccidentLevelConfigBo bo) {
|
||||
HotAccidentLevelConfig add = MapstructUtils.convert(bo, HotAccidentLevelConfig.class);
|
||||
validEntityBeforeSave(add);
|
||||
boolean flag = baseMapper.insert(add) > 0;
|
||||
if (flag) {
|
||||
bo.setId(add.getId());
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改事故等级划分
|
||||
*
|
||||
* @param bo 事故等级划分
|
||||
* @return 是否修改成功
|
||||
*/
|
||||
@Override
|
||||
public Boolean updateByBo(HotAccidentLevelConfigBo bo) {
|
||||
HotAccidentLevelConfig update = MapstructUtils.convert(bo, HotAccidentLevelConfig.class);
|
||||
validEntityBeforeSave(update);
|
||||
return baseMapper.updateById(update) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存前的数据校验
|
||||
*/
|
||||
private void validEntityBeforeSave(HotAccidentLevelConfig entity) {
|
||||
//TODO 做一些数据校验,如唯一约束
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验并批量删除事故等级划分信息
|
||||
*
|
||||
* @param ids 待删除的主键集合
|
||||
* @param isValid 是否进行有效性校验
|
||||
* @return 是否删除成功
|
||||
*/
|
||||
@Override
|
||||
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
|
||||
if (isValid) {
|
||||
//TODO 做一些业务上的校验,判断是否需要校验
|
||||
}
|
||||
return baseMapper.deleteByIds(ids) > 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
package com.hotwj.platform.config.accidentLikelihoodLevelConfig.controller;
|
||||
|
||||
import com.hotwj.platform.config.accidentLikelihoodLevelConfig.domain.bo.HotAccidentLikelihoodLevelConfigBo;
|
||||
import com.hotwj.platform.config.accidentLikelihoodLevelConfig.domain.vo.HotAccidentLikelihoodLevelConfigVo;
|
||||
import com.hotwj.platform.config.accidentLikelihoodLevelConfig.service.IHotAccidentLikelihoodLevelConfigService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.dromara.common.core.domain.R;
|
||||
import org.dromara.common.core.validate.AddGroup;
|
||||
import org.dromara.common.core.validate.EditGroup;
|
||||
import org.dromara.common.excel.utils.ExcelUtil;
|
||||
import org.dromara.common.idempotent.annotation.RepeatSubmit;
|
||||
import org.dromara.common.log.annotation.Log;
|
||||
import org.dromara.common.log.enums.BusinessType;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.dromara.common.web.core.BaseController;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 事故等级划分(可能性)
|
||||
*
|
||||
* @author shihongwei
|
||||
* @date 2026-01-05
|
||||
*/
|
||||
@Validated
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/config/accidentLikelihoodLevelConfig")
|
||||
@Tag(name = "事故等级划分(可能性)", description = "事故等级划分(可能性)管理")
|
||||
public class HotAccidentLikelihoodLevelConfigController extends BaseController {
|
||||
|
||||
private final IHotAccidentLikelihoodLevelConfigService hotAccidentLikelihoodLevelConfigService;
|
||||
|
||||
/**
|
||||
* 查询事故等级划分(可能性)列表
|
||||
*/
|
||||
//@SaCheckPermission("config:accidentLikelihoodLevelConfig:list")
|
||||
@GetMapping("/list")
|
||||
@Operation(summary = "分页查询事故等级划分(可能性)列表")
|
||||
public TableDataInfo<HotAccidentLikelihoodLevelConfigVo> list(HotAccidentLikelihoodLevelConfigBo bo, PageQuery pageQuery) {
|
||||
return hotAccidentLikelihoodLevelConfigService.queryPageList(bo, pageQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出事故等级划分(可能性)列表
|
||||
*/
|
||||
//@SaCheckPermission("config:accidentLikelihoodLevelConfig:export")
|
||||
@Log(title = "事故等级划分(可能性)", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/export")
|
||||
@Operation(summary = "导出事故等级划分(可能性)列表")
|
||||
public void export(HotAccidentLikelihoodLevelConfigBo bo, HttpServletResponse response) {
|
||||
List<HotAccidentLikelihoodLevelConfigVo> list = hotAccidentLikelihoodLevelConfigService.queryList(bo);
|
||||
ExcelUtil.exportExcel(list, "事故等级划分(可能性)", HotAccidentLikelihoodLevelConfigVo.class, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取事故等级划分(可能性)详细信息
|
||||
*
|
||||
* @param id 主键
|
||||
*/
|
||||
//@SaCheckPermission("config:accidentLikelihoodLevelConfig:query")
|
||||
@GetMapping("/{id}")
|
||||
@Operation(summary = "获取事故等级划分(可能性)详细信息")
|
||||
public R<HotAccidentLikelihoodLevelConfigVo> getInfo(@NotNull(message = "主键不能为空")
|
||||
@Parameter(name = "id", description = "主键", required = true, example = "1")
|
||||
@PathVariable Long id) {
|
||||
return R.ok(hotAccidentLikelihoodLevelConfigService.queryById(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增事故等级划分(可能性)
|
||||
*/
|
||||
//@SaCheckPermission("config:accidentLikelihoodLevelConfig:add")
|
||||
@Log(title = "事故等级划分(可能性)", businessType = BusinessType.INSERT)
|
||||
@RepeatSubmit()
|
||||
@PostMapping()
|
||||
@Operation(summary = "新增事故等级划分(可能性)")
|
||||
public R<Void> add(@Validated(AddGroup.class) @RequestBody HotAccidentLikelihoodLevelConfigBo bo) {
|
||||
return toAjax(hotAccidentLikelihoodLevelConfigService.insertByBo(bo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改事故等级划分(可能性)
|
||||
*/
|
||||
//@SaCheckPermission("config:accidentLikelihoodLevelConfig:edit")
|
||||
@Log(title = "事故等级划分(可能性)", businessType = BusinessType.UPDATE)
|
||||
@RepeatSubmit()
|
||||
@PutMapping()
|
||||
@Operation(summary = "修改事故等级划分(可能性)")
|
||||
public R<Void> edit(@Validated(EditGroup.class) @RequestBody HotAccidentLikelihoodLevelConfigBo bo) {
|
||||
return toAjax(hotAccidentLikelihoodLevelConfigService.updateByBo(bo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除事故等级划分(可能性)
|
||||
*
|
||||
* @param ids 主键串
|
||||
*/
|
||||
//@SaCheckPermission("config:accidentLikelihoodLevelConfig:remove")
|
||||
@Log(title = "事故等级划分(可能性)", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{ids}")
|
||||
@Operation(summary = "删除事故等级划分(可能性)")
|
||||
public R<Void> remove(@NotEmpty(message = "主键不能为空")
|
||||
@Parameter(name = "ids", description = "主键串", required = true, example = "1,2,3")
|
||||
@PathVariable Long[] ids) {
|
||||
return toAjax(hotAccidentLikelihoodLevelConfigService.deleteWithValidByIds(List.of(ids), true));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.hotwj.platform.config.accidentLikelihoodLevelConfig.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
||||
|
||||
import java.io.Serial;
|
||||
|
||||
/**
|
||||
* 事故等级划分(可能性)对象 hot_accident_likelihood_level_config
|
||||
*
|
||||
* @author shihongwei
|
||||
* @date 2026-01-05
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("hot_accident_likelihood_level_config")
|
||||
public class HotAccidentLikelihoodLevelConfig extends BaseEntity {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@TableId(value = "id")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 取值(级别)
|
||||
*/
|
||||
private Long levelValue;
|
||||
|
||||
/**
|
||||
* 判定标准
|
||||
*/
|
||||
private String criterion;
|
||||
|
||||
/**
|
||||
* 0=正常, 1=已删除
|
||||
*/
|
||||
@TableLogic
|
||||
private Long isDeleted;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package com.hotwj.platform.config.accidentLikelihoodLevelConfig.domain.bo;
|
||||
|
||||
import com.hotwj.platform.config.accidentLikelihoodLevelConfig.domain.HotAccidentLikelihoodLevelConfig;
|
||||
import io.github.linpeilie.annotations.AutoMapper;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.dromara.common.core.validate.AddGroup;
|
||||
import org.dromara.common.core.validate.EditGroup;
|
||||
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
||||
|
||||
/**
|
||||
* 事故等级划分(可能性)业务对象 hot_accident_likelihood_level_config
|
||||
*
|
||||
* @author shihongwei
|
||||
* @date 2026-01-05
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@AutoMapper(target = HotAccidentLikelihoodLevelConfig.class, reverseConvertGenerate = false)
|
||||
public class HotAccidentLikelihoodLevelConfigBo extends BaseEntity {
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@NotNull(message = "主键不能为空", groups = {EditGroup.class})
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 取值(级别)
|
||||
*/
|
||||
@NotNull(message = "取值(级别)不能为空", groups = {AddGroup.class, EditGroup.class})
|
||||
private Long levelValue;
|
||||
|
||||
/**
|
||||
* 判定标准
|
||||
*/
|
||||
@NotBlank(message = "判定标准不能为空", groups = {AddGroup.class, EditGroup.class})
|
||||
private String criterion;
|
||||
|
||||
/**
|
||||
* 0=正常, 1=已删除
|
||||
*/
|
||||
private Long isDeleted;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package com.hotwj.platform.config.accidentLikelihoodLevelConfig.domain.vo;
|
||||
|
||||
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import cn.idev.excel.annotation.ExcelProperty;
|
||||
import com.hotwj.platform.config.accidentLikelihoodLevelConfig.domain.HotAccidentLikelihoodLevelConfig;
|
||||
import io.github.linpeilie.annotations.AutoMapper;
|
||||
import lombok.Data;
|
||||
import org.dromara.common.excel.annotation.ExcelDictFormat;
|
||||
import org.dromara.common.excel.convert.ExcelDictConvert;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
|
||||
/**
|
||||
* 事故等级划分(可能性)视图对象 hot_accident_likelihood_level_config
|
||||
*
|
||||
* @author shihongwei
|
||||
* @date 2026-01-05
|
||||
*/
|
||||
@Data
|
||||
@ExcelIgnoreUnannotated
|
||||
@AutoMapper(target = HotAccidentLikelihoodLevelConfig.class)
|
||||
public class HotAccidentLikelihoodLevelConfigVo implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@ExcelProperty(value = "主键")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 取值(级别)
|
||||
*/
|
||||
@ExcelProperty(value = "取值", converter = ExcelDictConvert.class)
|
||||
@ExcelDictFormat(readConverterExp = "级=别")
|
||||
private Long levelValue;
|
||||
|
||||
/**
|
||||
* 判定标准
|
||||
*/
|
||||
@ExcelProperty(value = "判定标准")
|
||||
private String criterion;
|
||||
|
||||
/**
|
||||
* 0=正常, 1=已删除
|
||||
*/
|
||||
@ExcelProperty(value = "0=正常, 1=已删除")
|
||||
private Long isDeleted;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.hotwj.platform.config.accidentLikelihoodLevelConfig.mapper;
|
||||
|
||||
import com.hotwj.platform.config.accidentLikelihoodLevelConfig.domain.HotAccidentLikelihoodLevelConfig;
|
||||
import com.hotwj.platform.config.accidentLikelihoodLevelConfig.domain.vo.HotAccidentLikelihoodLevelConfigVo;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
|
||||
|
||||
/**
|
||||
* 事故等级划分(可能性)Mapper接口
|
||||
*
|
||||
* @author shihongwei
|
||||
* @date 2026-01-05
|
||||
*/
|
||||
@Mapper
|
||||
public interface HotAccidentLikelihoodLevelConfigMapper extends BaseMapperPlus<HotAccidentLikelihoodLevelConfig, HotAccidentLikelihoodLevelConfigVo> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package com.hotwj.platform.config.accidentLikelihoodLevelConfig.service;
|
||||
|
||||
import com.hotwj.platform.config.accidentLikelihoodLevelConfig.domain.bo.HotAccidentLikelihoodLevelConfigBo;
|
||||
import com.hotwj.platform.config.accidentLikelihoodLevelConfig.domain.vo.HotAccidentLikelihoodLevelConfigVo;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 事故等级划分(可能性)Service接口
|
||||
*
|
||||
* @author shihongwei
|
||||
* @date 2026-01-05
|
||||
*/
|
||||
public interface IHotAccidentLikelihoodLevelConfigService {
|
||||
|
||||
/**
|
||||
* 查询事故等级划分(可能性)
|
||||
*
|
||||
* @param id 主键
|
||||
* @return 事故等级划分(可能性)
|
||||
*/
|
||||
HotAccidentLikelihoodLevelConfigVo queryById(Long id);
|
||||
|
||||
/**
|
||||
* 分页查询事故等级划分(可能性)列表
|
||||
*
|
||||
* @param bo 查询条件
|
||||
* @param pageQuery 分页参数
|
||||
* @return 事故等级划分(可能性)分页列表
|
||||
*/
|
||||
TableDataInfo<HotAccidentLikelihoodLevelConfigVo> queryPageList(HotAccidentLikelihoodLevelConfigBo bo, PageQuery pageQuery);
|
||||
|
||||
/**
|
||||
* 查询符合条件的事故等级划分(可能性)列表
|
||||
*
|
||||
* @param bo 查询条件
|
||||
* @return 事故等级划分(可能性)列表
|
||||
*/
|
||||
List<HotAccidentLikelihoodLevelConfigVo> queryList(HotAccidentLikelihoodLevelConfigBo bo);
|
||||
|
||||
/**
|
||||
* 新增事故等级划分(可能性)
|
||||
*
|
||||
* @param bo 事故等级划分(可能性)
|
||||
* @return 是否新增成功
|
||||
*/
|
||||
Boolean insertByBo(HotAccidentLikelihoodLevelConfigBo bo);
|
||||
|
||||
/**
|
||||
* 修改事故等级划分(可能性)
|
||||
*
|
||||
* @param bo 事故等级划分(可能性)
|
||||
* @return 是否修改成功
|
||||
*/
|
||||
Boolean updateByBo(HotAccidentLikelihoodLevelConfigBo bo);
|
||||
|
||||
/**
|
||||
* 校验并批量删除事故等级划分(可能性)信息
|
||||
*
|
||||
* @param ids 待删除的主键集合
|
||||
* @param isValid 是否进行有效性校验
|
||||
* @return 是否删除成功
|
||||
*/
|
||||
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
package com.hotwj.platform.config.accidentLikelihoodLevelConfig.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.hotwj.platform.config.accidentLikelihoodLevelConfig.domain.HotAccidentLikelihoodLevelConfig;
|
||||
import com.hotwj.platform.config.accidentLikelihoodLevelConfig.domain.bo.HotAccidentLikelihoodLevelConfigBo;
|
||||
import com.hotwj.platform.config.accidentLikelihoodLevelConfig.domain.vo.HotAccidentLikelihoodLevelConfigVo;
|
||||
import com.hotwj.platform.config.accidentLikelihoodLevelConfig.mapper.HotAccidentLikelihoodLevelConfigMapper;
|
||||
import com.hotwj.platform.config.accidentLikelihoodLevelConfig.service.IHotAccidentLikelihoodLevelConfigService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.common.core.utils.MapstructUtils;
|
||||
import org.dromara.common.core.utils.StringUtils;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 事故等级划分(可能性)Service业务层处理
|
||||
*
|
||||
* @author shihongwei
|
||||
* @date 2026-01-05
|
||||
*/
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
@Service
|
||||
public class HotAccidentLikelihoodLevelConfigServiceImpl implements IHotAccidentLikelihoodLevelConfigService {
|
||||
|
||||
private final HotAccidentLikelihoodLevelConfigMapper baseMapper;
|
||||
|
||||
/**
|
||||
* 查询事故等级划分(可能性)
|
||||
*
|
||||
* @param id 主键
|
||||
* @return 事故等级划分(可能性)
|
||||
*/
|
||||
@Override
|
||||
public HotAccidentLikelihoodLevelConfigVo queryById(Long id) {
|
||||
return baseMapper.selectVoById(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询事故等级划分(可能性)列表
|
||||
*
|
||||
* @param bo 查询条件
|
||||
* @param pageQuery 分页参数
|
||||
* @return 事故等级划分(可能性)分页列表
|
||||
*/
|
||||
@Override
|
||||
public TableDataInfo<HotAccidentLikelihoodLevelConfigVo> queryPageList(HotAccidentLikelihoodLevelConfigBo bo, PageQuery pageQuery) {
|
||||
LambdaQueryWrapper<HotAccidentLikelihoodLevelConfig> lqw = buildQueryWrapper(bo);
|
||||
Page<HotAccidentLikelihoodLevelConfigVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
|
||||
return TableDataInfo.build(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询符合条件的事故等级划分(可能性)列表
|
||||
*
|
||||
* @param bo 查询条件
|
||||
* @return 事故等级划分(可能性)列表
|
||||
*/
|
||||
@Override
|
||||
public List<HotAccidentLikelihoodLevelConfigVo> queryList(HotAccidentLikelihoodLevelConfigBo bo) {
|
||||
LambdaQueryWrapper<HotAccidentLikelihoodLevelConfig> lqw = buildQueryWrapper(bo);
|
||||
return baseMapper.selectVoList(lqw);
|
||||
}
|
||||
|
||||
private LambdaQueryWrapper<HotAccidentLikelihoodLevelConfig> buildQueryWrapper(HotAccidentLikelihoodLevelConfigBo bo) {
|
||||
Map<String, Object> params = bo.getParams();
|
||||
LambdaQueryWrapper<HotAccidentLikelihoodLevelConfig> lqw = Wrappers.lambdaQuery();
|
||||
lqw.orderByAsc(HotAccidentLikelihoodLevelConfig::getId);
|
||||
lqw.eq(bo.getLevelValue() != null, HotAccidentLikelihoodLevelConfig::getLevelValue, bo.getLevelValue());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getCriterion()), HotAccidentLikelihoodLevelConfig::getCriterion, bo.getCriterion());
|
||||
lqw.eq(bo.getIsDeleted() != null, HotAccidentLikelihoodLevelConfig::getIsDeleted, bo.getIsDeleted());
|
||||
return lqw;
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增事故等级划分(可能性)
|
||||
*
|
||||
* @param bo 事故等级划分(可能性)
|
||||
* @return 是否新增成功
|
||||
*/
|
||||
@Override
|
||||
public Boolean insertByBo(HotAccidentLikelihoodLevelConfigBo bo) {
|
||||
HotAccidentLikelihoodLevelConfig add = MapstructUtils.convert(bo, HotAccidentLikelihoodLevelConfig.class);
|
||||
validEntityBeforeSave(add);
|
||||
boolean flag = baseMapper.insert(add) > 0;
|
||||
if (flag) {
|
||||
bo.setId(add.getId());
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改事故等级划分(可能性)
|
||||
*
|
||||
* @param bo 事故等级划分(可能性)
|
||||
* @return 是否修改成功
|
||||
*/
|
||||
@Override
|
||||
public Boolean updateByBo(HotAccidentLikelihoodLevelConfigBo bo) {
|
||||
HotAccidentLikelihoodLevelConfig update = MapstructUtils.convert(bo, HotAccidentLikelihoodLevelConfig.class);
|
||||
validEntityBeforeSave(update);
|
||||
return baseMapper.updateById(update) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存前的数据校验
|
||||
*/
|
||||
private void validEntityBeforeSave(HotAccidentLikelihoodLevelConfig entity) {
|
||||
//TODO 做一些数据校验,如唯一约束
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验并批量删除事故等级划分(可能性)信息
|
||||
*
|
||||
* @param ids 待删除的主键集合
|
||||
* @param isValid 是否进行有效性校验
|
||||
* @return 是否删除成功
|
||||
*/
|
||||
@Override
|
||||
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
|
||||
if (isValid) {
|
||||
//TODO 做一些业务上的校验,判断是否需要校验
|
||||
}
|
||||
return baseMapper.deleteByIds(ids) > 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
package com.hotwj.platform.config.accidentSeverityLevelConfig.controller;
|
||||
|
||||
import com.hotwj.platform.config.accidentSeverityLevelConfig.domain.bo.HotAccidentSeverityLevelConfigBo;
|
||||
import com.hotwj.platform.config.accidentSeverityLevelConfig.domain.vo.HotAccidentSeverityLevelConfigVo;
|
||||
import com.hotwj.platform.config.accidentSeverityLevelConfig.service.IHotAccidentSeverityLevelConfigService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.dromara.common.core.domain.R;
|
||||
import org.dromara.common.core.validate.AddGroup;
|
||||
import org.dromara.common.core.validate.EditGroup;
|
||||
import org.dromara.common.excel.utils.ExcelUtil;
|
||||
import org.dromara.common.idempotent.annotation.RepeatSubmit;
|
||||
import org.dromara.common.log.annotation.Log;
|
||||
import org.dromara.common.log.enums.BusinessType;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.dromara.common.web.core.BaseController;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 事故等级划分(严重程度)
|
||||
*
|
||||
* @author shihongwei
|
||||
* @date 2026-01-05
|
||||
*/
|
||||
@Validated
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/config/accidentSeverityLevelConfig")
|
||||
@Tag(name = "事故等级划分(严重程度)", description = "事故等级划分(严重程度)管理")
|
||||
public class HotAccidentSeverityLevelConfigController extends BaseController {
|
||||
|
||||
private final IHotAccidentSeverityLevelConfigService hotAccidentSeverityLevelConfigService;
|
||||
|
||||
/**
|
||||
* 查询事故等级划分(严重程度)列表
|
||||
*/
|
||||
//@SaCheckPermission("config:accidentSeverityLevelConfig:list")
|
||||
@GetMapping("/list")
|
||||
@Operation(summary = "分页查询事故等级划分(严重程度)列表")
|
||||
public TableDataInfo<HotAccidentSeverityLevelConfigVo> list(HotAccidentSeverityLevelConfigBo bo, PageQuery pageQuery) {
|
||||
return hotAccidentSeverityLevelConfigService.queryPageList(bo, pageQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出事故等级划分(严重程度)列表
|
||||
*/
|
||||
//@SaCheckPermission("config:accidentSeverityLevelConfig:export")
|
||||
@Log(title = "事故等级划分(严重程度)", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/export")
|
||||
@Operation(summary = "导出事故等级划分(严重程度)列表")
|
||||
public void export(HotAccidentSeverityLevelConfigBo bo, HttpServletResponse response) {
|
||||
List<HotAccidentSeverityLevelConfigVo> list = hotAccidentSeverityLevelConfigService.queryList(bo);
|
||||
ExcelUtil.exportExcel(list, "事故等级划分(严重程度)", HotAccidentSeverityLevelConfigVo.class, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取事故等级划分(严重程度)详细信息
|
||||
*
|
||||
* @param id 主键
|
||||
*/
|
||||
//@SaCheckPermission("config:accidentSeverityLevelConfig:query")
|
||||
@GetMapping("/{id}")
|
||||
@Operation(summary = "获取事故等级划分(严重程度)详细信息")
|
||||
public R<HotAccidentSeverityLevelConfigVo> getInfo(@NotNull(message = "主键不能为空")
|
||||
@Parameter(name = "id", description = "主键", required = true, example = "1")
|
||||
@PathVariable Long id) {
|
||||
return R.ok(hotAccidentSeverityLevelConfigService.queryById(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增事故等级划分(严重程度)
|
||||
*/
|
||||
//@SaCheckPermission("config:accidentSeverityLevelConfig:add")
|
||||
@Log(title = "事故等级划分(严重程度)", businessType = BusinessType.INSERT)
|
||||
@RepeatSubmit()
|
||||
@PostMapping()
|
||||
@Operation(summary = "新增事故等级划分(严重程度)")
|
||||
public R<Void> add(@Validated(AddGroup.class) @RequestBody HotAccidentSeverityLevelConfigBo bo) {
|
||||
return toAjax(hotAccidentSeverityLevelConfigService.insertByBo(bo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改事故等级划分(严重程度)
|
||||
*/
|
||||
//@SaCheckPermission("config:accidentSeverityLevelConfig:edit")
|
||||
@Log(title = "事故等级划分(严重程度)", businessType = BusinessType.UPDATE)
|
||||
@RepeatSubmit()
|
||||
@PutMapping()
|
||||
@Operation(summary = "修改事故等级划分(严重程度)")
|
||||
public R<Void> edit(@Validated(EditGroup.class) @RequestBody HotAccidentSeverityLevelConfigBo bo) {
|
||||
return toAjax(hotAccidentSeverityLevelConfigService.updateByBo(bo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除事故等级划分(严重程度)
|
||||
*
|
||||
* @param ids 主键串
|
||||
*/
|
||||
//@SaCheckPermission("config:accidentSeverityLevelConfig:remove")
|
||||
@Log(title = "事故等级划分(严重程度)", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{ids}")
|
||||
@Operation(summary = "删除事故等级划分(严重程度)")
|
||||
public R<Void> remove(@NotEmpty(message = "主键不能为空")
|
||||
@Parameter(name = "ids", description = "主键串", required = true, example = "1,2,3")
|
||||
@PathVariable Long[] ids) {
|
||||
return toAjax(hotAccidentSeverityLevelConfigService.deleteWithValidByIds(List.of(ids), true));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package com.hotwj.platform.config.accidentSeverityLevelConfig.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
||||
|
||||
import java.io.Serial;
|
||||
|
||||
/**
|
||||
* 事故等级划分(严重程度)对象 hot_accident_severity_level_config
|
||||
*
|
||||
* @author shihongwei
|
||||
* @date 2026-01-05
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("hot_accident_severity_level_config")
|
||||
public class HotAccidentSeverityLevelConfig extends BaseEntity {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@TableId(value = "id")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 取值(级别)
|
||||
*/
|
||||
private Long levelValue;
|
||||
|
||||
/**
|
||||
* 法律法规及其他要求
|
||||
*/
|
||||
private String lawRequirement;
|
||||
|
||||
/**
|
||||
* 人员
|
||||
*/
|
||||
private String personnelDescription;
|
||||
|
||||
/**
|
||||
* 直接经济损失
|
||||
*/
|
||||
private String directEconomicLoss;
|
||||
|
||||
/**
|
||||
* 企业形象(社会影响)
|
||||
*/
|
||||
private String enterpriseReputation;
|
||||
|
||||
/**
|
||||
* 0=正常, 1=已删除
|
||||
*/
|
||||
@TableLogic
|
||||
private Long isDeleted;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
package com.hotwj.platform.config.accidentSeverityLevelConfig.domain.bo;
|
||||
|
||||
import com.hotwj.platform.config.accidentSeverityLevelConfig.domain.HotAccidentSeverityLevelConfig;
|
||||
import io.github.linpeilie.annotations.AutoMapper;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.dromara.common.core.validate.AddGroup;
|
||||
import org.dromara.common.core.validate.EditGroup;
|
||||
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
||||
|
||||
/**
|
||||
* 事故等级划分(严重程度)业务对象 hot_accident_severity_level_config
|
||||
*
|
||||
* @author shihongwei
|
||||
* @date 2026-01-05
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@AutoMapper(target = HotAccidentSeverityLevelConfig.class, reverseConvertGenerate = false)
|
||||
public class HotAccidentSeverityLevelConfigBo extends BaseEntity {
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@NotNull(message = "主键不能为空", groups = {EditGroup.class})
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 取值(级别)
|
||||
*/
|
||||
@NotNull(message = "取值(级别)不能为空", groups = {AddGroup.class, EditGroup.class})
|
||||
private Long levelValue;
|
||||
|
||||
/**
|
||||
* 法律法规及其他要求
|
||||
*/
|
||||
@NotBlank(message = "法律法规及其他要求不能为空", groups = {AddGroup.class, EditGroup.class})
|
||||
private String lawRequirement;
|
||||
|
||||
/**
|
||||
* 人员
|
||||
*/
|
||||
@NotBlank(message = "人员不能为空", groups = {AddGroup.class, EditGroup.class})
|
||||
private String personnelDescription;
|
||||
|
||||
/**
|
||||
* 直接经济损失
|
||||
*/
|
||||
@NotBlank(message = "直接经济损失不能为空", groups = {AddGroup.class, EditGroup.class})
|
||||
private String directEconomicLoss;
|
||||
|
||||
/**
|
||||
* 企业形象(社会影响)
|
||||
*/
|
||||
@NotBlank(message = "企业形象(社会影响)不能为空", groups = {AddGroup.class, EditGroup.class})
|
||||
private String enterpriseReputation;
|
||||
|
||||
/**
|
||||
* 0=正常, 1=已删除
|
||||
*/
|
||||
private Long isDeleted;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package com.hotwj.platform.config.accidentSeverityLevelConfig.domain.vo;
|
||||
|
||||
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import cn.idev.excel.annotation.ExcelProperty;
|
||||
import com.hotwj.platform.config.accidentSeverityLevelConfig.domain.HotAccidentSeverityLevelConfig;
|
||||
import io.github.linpeilie.annotations.AutoMapper;
|
||||
import lombok.Data;
|
||||
import org.dromara.common.excel.annotation.ExcelDictFormat;
|
||||
import org.dromara.common.excel.convert.ExcelDictConvert;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
|
||||
/**
|
||||
* 事故等级划分(严重程度)视图对象 hot_accident_severity_level_config
|
||||
*
|
||||
* @author shihongwei
|
||||
* @date 2026-01-05
|
||||
*/
|
||||
@Data
|
||||
@ExcelIgnoreUnannotated
|
||||
@AutoMapper(target = HotAccidentSeverityLevelConfig.class)
|
||||
public class HotAccidentSeverityLevelConfigVo implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@ExcelProperty(value = "主键")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 取值(级别)
|
||||
*/
|
||||
@ExcelProperty(value = "取值", converter = ExcelDictConvert.class)
|
||||
@ExcelDictFormat(readConverterExp = "级=别")
|
||||
private Long levelValue;
|
||||
|
||||
/**
|
||||
* 法律法规及其他要求
|
||||
*/
|
||||
@ExcelProperty(value = "法律法规及其他要求")
|
||||
private String lawRequirement;
|
||||
|
||||
/**
|
||||
* 人员
|
||||
*/
|
||||
@ExcelProperty(value = "人员")
|
||||
private String personnelDescription;
|
||||
|
||||
/**
|
||||
* 直接经济损失
|
||||
*/
|
||||
@ExcelProperty(value = "直接经济损失")
|
||||
private String directEconomicLoss;
|
||||
|
||||
/**
|
||||
* 企业形象(社会影响)
|
||||
*/
|
||||
@ExcelProperty(value = "企业形象", converter = ExcelDictConvert.class)
|
||||
@ExcelDictFormat(readConverterExp = "社=会影响")
|
||||
private String enterpriseReputation;
|
||||
|
||||
/**
|
||||
* 0=正常, 1=已删除
|
||||
*/
|
||||
@ExcelProperty(value = "0=正常, 1=已删除")
|
||||
private Long isDeleted;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.hotwj.platform.config.accidentSeverityLevelConfig.mapper;
|
||||
|
||||
import com.hotwj.platform.config.accidentSeverityLevelConfig.domain.HotAccidentSeverityLevelConfig;
|
||||
import com.hotwj.platform.config.accidentSeverityLevelConfig.domain.vo.HotAccidentSeverityLevelConfigVo;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
|
||||
|
||||
/**
|
||||
* 事故等级划分(严重程度)Mapper接口
|
||||
*
|
||||
* @author shihongwei
|
||||
* @date 2026-01-05
|
||||
*/
|
||||
@Mapper
|
||||
public interface HotAccidentSeverityLevelConfigMapper extends BaseMapperPlus<HotAccidentSeverityLevelConfig, HotAccidentSeverityLevelConfigVo> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package com.hotwj.platform.config.accidentSeverityLevelConfig.service;
|
||||
|
||||
import com.hotwj.platform.config.accidentSeverityLevelConfig.domain.bo.HotAccidentSeverityLevelConfigBo;
|
||||
import com.hotwj.platform.config.accidentSeverityLevelConfig.domain.vo.HotAccidentSeverityLevelConfigVo;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 事故等级划分(严重程度)Service接口
|
||||
*
|
||||
* @author shihongwei
|
||||
* @date 2026-01-05
|
||||
*/
|
||||
public interface IHotAccidentSeverityLevelConfigService {
|
||||
|
||||
/**
|
||||
* 查询事故等级划分(严重程度)
|
||||
*
|
||||
* @param id 主键
|
||||
* @return 事故等级划分(严重程度)
|
||||
*/
|
||||
HotAccidentSeverityLevelConfigVo queryById(Long id);
|
||||
|
||||
/**
|
||||
* 分页查询事故等级划分(严重程度)列表
|
||||
*
|
||||
* @param bo 查询条件
|
||||
* @param pageQuery 分页参数
|
||||
* @return 事故等级划分(严重程度)分页列表
|
||||
*/
|
||||
TableDataInfo<HotAccidentSeverityLevelConfigVo> queryPageList(HotAccidentSeverityLevelConfigBo bo, PageQuery pageQuery);
|
||||
|
||||
/**
|
||||
* 查询符合条件的事故等级划分(严重程度)列表
|
||||
*
|
||||
* @param bo 查询条件
|
||||
* @return 事故等级划分(严重程度)列表
|
||||
*/
|
||||
List<HotAccidentSeverityLevelConfigVo> queryList(HotAccidentSeverityLevelConfigBo bo);
|
||||
|
||||
/**
|
||||
* 新增事故等级划分(严重程度)
|
||||
*
|
||||
* @param bo 事故等级划分(严重程度)
|
||||
* @return 是否新增成功
|
||||
*/
|
||||
Boolean insertByBo(HotAccidentSeverityLevelConfigBo bo);
|
||||
|
||||
/**
|
||||
* 修改事故等级划分(严重程度)
|
||||
*
|
||||
* @param bo 事故等级划分(严重程度)
|
||||
* @return 是否修改成功
|
||||
*/
|
||||
Boolean updateByBo(HotAccidentSeverityLevelConfigBo bo);
|
||||
|
||||
/**
|
||||
* 校验并批量删除事故等级划分(严重程度)信息
|
||||
*
|
||||
* @param ids 待删除的主键集合
|
||||
* @param isValid 是否进行有效性校验
|
||||
* @return 是否删除成功
|
||||
*/
|
||||
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
package com.hotwj.platform.config.accidentSeverityLevelConfig.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.hotwj.platform.config.accidentSeverityLevelConfig.domain.HotAccidentSeverityLevelConfig;
|
||||
import com.hotwj.platform.config.accidentSeverityLevelConfig.domain.bo.HotAccidentSeverityLevelConfigBo;
|
||||
import com.hotwj.platform.config.accidentSeverityLevelConfig.domain.vo.HotAccidentSeverityLevelConfigVo;
|
||||
import com.hotwj.platform.config.accidentSeverityLevelConfig.mapper.HotAccidentSeverityLevelConfigMapper;
|
||||
import com.hotwj.platform.config.accidentSeverityLevelConfig.service.IHotAccidentSeverityLevelConfigService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.common.core.utils.MapstructUtils;
|
||||
import org.dromara.common.core.utils.StringUtils;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 事故等级划分(严重程度)Service业务层处理
|
||||
*
|
||||
* @author shihongwei
|
||||
* @date 2026-01-05
|
||||
*/
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
@Service
|
||||
public class HotAccidentSeverityLevelConfigServiceImpl implements IHotAccidentSeverityLevelConfigService {
|
||||
|
||||
private final HotAccidentSeverityLevelConfigMapper baseMapper;
|
||||
|
||||
/**
|
||||
* 查询事故等级划分(严重程度)
|
||||
*
|
||||
* @param id 主键
|
||||
* @return 事故等级划分(严重程度)
|
||||
*/
|
||||
@Override
|
||||
public HotAccidentSeverityLevelConfigVo queryById(Long id) {
|
||||
return baseMapper.selectVoById(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询事故等级划分(严重程度)列表
|
||||
*
|
||||
* @param bo 查询条件
|
||||
* @param pageQuery 分页参数
|
||||
* @return 事故等级划分(严重程度)分页列表
|
||||
*/
|
||||
@Override
|
||||
public TableDataInfo<HotAccidentSeverityLevelConfigVo> queryPageList(HotAccidentSeverityLevelConfigBo bo, PageQuery pageQuery) {
|
||||
LambdaQueryWrapper<HotAccidentSeverityLevelConfig> lqw = buildQueryWrapper(bo);
|
||||
Page<HotAccidentSeverityLevelConfigVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
|
||||
return TableDataInfo.build(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询符合条件的事故等级划分(严重程度)列表
|
||||
*
|
||||
* @param bo 查询条件
|
||||
* @return 事故等级划分(严重程度)列表
|
||||
*/
|
||||
@Override
|
||||
public List<HotAccidentSeverityLevelConfigVo> queryList(HotAccidentSeverityLevelConfigBo bo) {
|
||||
LambdaQueryWrapper<HotAccidentSeverityLevelConfig> lqw = buildQueryWrapper(bo);
|
||||
return baseMapper.selectVoList(lqw);
|
||||
}
|
||||
|
||||
private LambdaQueryWrapper<HotAccidentSeverityLevelConfig> buildQueryWrapper(HotAccidentSeverityLevelConfigBo bo) {
|
||||
Map<String, Object> params = bo.getParams();
|
||||
LambdaQueryWrapper<HotAccidentSeverityLevelConfig> lqw = Wrappers.lambdaQuery();
|
||||
lqw.orderByAsc(HotAccidentSeverityLevelConfig::getId);
|
||||
lqw.eq(bo.getLevelValue() != null, HotAccidentSeverityLevelConfig::getLevelValue, bo.getLevelValue());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getLawRequirement()), HotAccidentSeverityLevelConfig::getLawRequirement, bo.getLawRequirement());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getPersonnelDescription()), HotAccidentSeverityLevelConfig::getPersonnelDescription, bo.getPersonnelDescription());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getDirectEconomicLoss()), HotAccidentSeverityLevelConfig::getDirectEconomicLoss, bo.getDirectEconomicLoss());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getEnterpriseReputation()), HotAccidentSeverityLevelConfig::getEnterpriseReputation, bo.getEnterpriseReputation());
|
||||
lqw.eq(bo.getIsDeleted() != null, HotAccidentSeverityLevelConfig::getIsDeleted, bo.getIsDeleted());
|
||||
return lqw;
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增事故等级划分(严重程度)
|
||||
*
|
||||
* @param bo 事故等级划分(严重程度)
|
||||
* @return 是否新增成功
|
||||
*/
|
||||
@Override
|
||||
public Boolean insertByBo(HotAccidentSeverityLevelConfigBo bo) {
|
||||
HotAccidentSeverityLevelConfig add = MapstructUtils.convert(bo, HotAccidentSeverityLevelConfig.class);
|
||||
validEntityBeforeSave(add);
|
||||
boolean flag = baseMapper.insert(add) > 0;
|
||||
if (flag) {
|
||||
bo.setId(add.getId());
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改事故等级划分(严重程度)
|
||||
*
|
||||
* @param bo 事故等级划分(严重程度)
|
||||
* @return 是否修改成功
|
||||
*/
|
||||
@Override
|
||||
public Boolean updateByBo(HotAccidentSeverityLevelConfigBo bo) {
|
||||
HotAccidentSeverityLevelConfig update = MapstructUtils.convert(bo, HotAccidentSeverityLevelConfig.class);
|
||||
validEntityBeforeSave(update);
|
||||
return baseMapper.updateById(update) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存前的数据校验
|
||||
*/
|
||||
private void validEntityBeforeSave(HotAccidentSeverityLevelConfig entity) {
|
||||
//TODO 做一些数据校验,如唯一约束
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验并批量删除事故等级划分(严重程度)信息
|
||||
*
|
||||
* @param ids 待删除的主键集合
|
||||
* @param isValid 是否进行有效性校验
|
||||
* @return 是否删除成功
|
||||
*/
|
||||
@Override
|
||||
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
|
||||
if (isValid) {
|
||||
//TODO 做一些业务上的校验,判断是否需要校验
|
||||
}
|
||||
return baseMapper.deleteByIds(ids) > 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
package com.hotwj.platform.config.companyBasicConfig.controller;
|
||||
|
||||
import com.hotwj.platform.config.companyBasicConfig.domain.bo.HotCompanyBasicConfigBo;
|
||||
import com.hotwj.platform.config.companyBasicConfig.domain.vo.HotCompanyBasicConfigVo;
|
||||
import com.hotwj.platform.config.companyBasicConfig.service.IHotCompanyBasicConfigService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.dromara.common.core.domain.R;
|
||||
import org.dromara.common.core.validate.AddGroup;
|
||||
import org.dromara.common.core.validate.EditGroup;
|
||||
import org.dromara.common.excel.utils.ExcelUtil;
|
||||
import org.dromara.common.idempotent.annotation.RepeatSubmit;
|
||||
import org.dromara.common.log.annotation.Log;
|
||||
import org.dromara.common.log.enums.BusinessType;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.dromara.common.web.core.BaseController;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 企业基础配置
|
||||
*
|
||||
* @author shihongwei
|
||||
* @date 2025-12-29
|
||||
*/
|
||||
@Validated
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/config/companyBasicConfig")
|
||||
@Tag(name = "企业基础配置", description = "企业基础配置管理")
|
||||
public class HotCompanyBasicConfigController extends BaseController {
|
||||
|
||||
private final IHotCompanyBasicConfigService hotCompanyBasicConfigService;
|
||||
|
||||
/**
|
||||
* 查询企业基础配置列表
|
||||
*/
|
||||
//@SaCheckPermission("config:companyBasicConfig:list")
|
||||
@GetMapping("/list")
|
||||
@Operation(summary = "分页查询企业基础配置列表")
|
||||
public TableDataInfo<HotCompanyBasicConfigVo> list(HotCompanyBasicConfigBo bo, PageQuery pageQuery) {
|
||||
return hotCompanyBasicConfigService.queryPageList(bo, pageQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出企业基础配置列表
|
||||
*/
|
||||
//@SaCheckPermission("config:companyBasicConfig:export")
|
||||
@Log(title = "企业基础配置", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/export")
|
||||
@Operation(summary = "导出企业基础配置列表")
|
||||
public void export(HotCompanyBasicConfigBo bo, HttpServletResponse response) {
|
||||
List<HotCompanyBasicConfigVo> list = hotCompanyBasicConfigService.queryList(bo);
|
||||
ExcelUtil.exportExcel(list, "企业基础配置", HotCompanyBasicConfigVo.class, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取企业基础配置详细信息
|
||||
*
|
||||
* @param id 主键
|
||||
*/
|
||||
//@SaCheckPermission("config:companyBasicConfig:query")
|
||||
@GetMapping("/{id}")
|
||||
@Operation(summary = "获取企业基础配置详细信息")
|
||||
public R<HotCompanyBasicConfigVo> getInfo(@NotNull(message = "主键不能为空")
|
||||
@Parameter(name = "id", description = "主键", required = true, example = "1")
|
||||
@PathVariable Long id) {
|
||||
return R.ok(hotCompanyBasicConfigService.queryById(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增企业基础配置
|
||||
*/
|
||||
//@SaCheckPermission("config:companyBasicConfig:add")
|
||||
@Log(title = "企业基础配置", businessType = BusinessType.INSERT)
|
||||
@RepeatSubmit()
|
||||
@PostMapping()
|
||||
@Operation(summary = "新增企业基础配置")
|
||||
public R<Void> add(@Validated(AddGroup.class) @RequestBody HotCompanyBasicConfigBo bo) {
|
||||
return toAjax(hotCompanyBasicConfigService.insertByBo(bo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改企业基础配置
|
||||
*/
|
||||
//@SaCheckPermission("config:companyBasicConfig:edit")
|
||||
@Log(title = "企业基础配置", businessType = BusinessType.UPDATE)
|
||||
@RepeatSubmit()
|
||||
@PutMapping()
|
||||
@Operation(summary = "修改企业基础配置")
|
||||
public R<Void> edit(@Validated(EditGroup.class) @RequestBody HotCompanyBasicConfigBo bo) {
|
||||
return toAjax(hotCompanyBasicConfigService.updateByBo(bo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除企业基础配置
|
||||
*
|
||||
* @param ids 主键串
|
||||
*/
|
||||
//@SaCheckPermission("config:companyBasicConfig:remove")
|
||||
@Log(title = "企业基础配置", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{ids}")
|
||||
@Operation(summary = "删除企业基础配置")
|
||||
public R<Void> remove(@NotEmpty(message = "主键不能为空")
|
||||
@Parameter(name = "ids", description = "主键串", required = true, example = "1,2,3")
|
||||
@PathVariable Long[] ids) {
|
||||
return toAjax(hotCompanyBasicConfigService.deleteWithValidByIds(List.of(ids), true));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
package com.hotwj.platform.config.companyBasicConfig.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
||||
|
||||
import java.io.Serial;
|
||||
|
||||
/**
|
||||
* 企业基础配置对象 hot_company_basic_config
|
||||
*
|
||||
* @author shihongwei
|
||||
* @date 2025-12-29
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("hot_company_basic_config")
|
||||
public class HotCompanyBasicConfig extends BaseEntity {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@TableId(value = "id")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 公司ID
|
||||
*/
|
||||
private Long companyId;
|
||||
|
||||
/**
|
||||
* 是否补学 0=关闭 1=开启
|
||||
*/
|
||||
private Long makeUpStudyEnabled;
|
||||
|
||||
/**
|
||||
* 禁学区间是否开启 0=关闭 1=开启
|
||||
*/
|
||||
private Long forbidPeriodEnabled;
|
||||
|
||||
/**
|
||||
* 禁学开始时间
|
||||
*/
|
||||
private String forbidStartTime;
|
||||
|
||||
/**
|
||||
* 禁学结束时间
|
||||
*/
|
||||
private String forbidEndTime;
|
||||
|
||||
/**
|
||||
* 学习短信提醒是否开启 0=关闭 1=开启
|
||||
*/
|
||||
private Long studySmsEnabled;
|
||||
|
||||
/**
|
||||
* 剩余短信数量
|
||||
*/
|
||||
private Long remainingSmsCount;
|
||||
|
||||
/**
|
||||
* 0=正常, 1=已删除
|
||||
*/
|
||||
@TableLogic
|
||||
private Long isDeleted;
|
||||
|
||||
/**
|
||||
* 隐患排查规则(1=周 2=月 3=季度 4=半年 5=年)
|
||||
*/
|
||||
private Long hiddenDangerRole;
|
||||
|
||||
/**
|
||||
* 隐患排查规则是否启用(0=否 1=是)
|
||||
*/
|
||||
private Long roleIsEnable;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
package com.hotwj.platform.config.companyBasicConfig.domain.bo;
|
||||
|
||||
import com.hotwj.platform.config.companyBasicConfig.domain.HotCompanyBasicConfig;
|
||||
import io.github.linpeilie.annotations.AutoMapper;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.dromara.common.core.validate.AddGroup;
|
||||
import org.dromara.common.core.validate.EditGroup;
|
||||
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
||||
|
||||
/**
|
||||
* 企业基础配置业务对象 hot_company_basic_config
|
||||
*
|
||||
* @author shihongwei
|
||||
* @date 2025-12-29
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@AutoMapper(target = HotCompanyBasicConfig.class, reverseConvertGenerate = false)
|
||||
public class HotCompanyBasicConfigBo extends BaseEntity {
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@NotNull(message = "主键不能为空", groups = {EditGroup.class})
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 公司ID
|
||||
*/
|
||||
@NotNull(message = "公司ID不能为空", groups = {AddGroup.class, EditGroup.class})
|
||||
private Long companyId;
|
||||
|
||||
/**
|
||||
* 是否补学 0=关闭 1=开启
|
||||
*/
|
||||
@NotNull(message = "是否补学 0=关闭 1=开启不能为空", groups = {AddGroup.class, EditGroup.class})
|
||||
private Long makeUpStudyEnabled;
|
||||
|
||||
/**
|
||||
* 禁学区间是否开启 0=关闭 1=开启
|
||||
*/
|
||||
@NotNull(message = "禁学区间是否开启 0=关闭 1=开启不能为空", groups = {AddGroup.class, EditGroup.class})
|
||||
private Long forbidPeriodEnabled;
|
||||
|
||||
/**
|
||||
* 禁学开始时间
|
||||
*/
|
||||
private String forbidStartTime;
|
||||
|
||||
/**
|
||||
* 禁学结束时间
|
||||
*/
|
||||
private String forbidEndTime;
|
||||
|
||||
/**
|
||||
* 学习短信提醒是否开启 0=关闭 1=开启
|
||||
*/
|
||||
@NotNull(message = "学习短信提醒是否开启 0=关闭 1=开启不能为空", groups = {AddGroup.class, EditGroup.class})
|
||||
private Long studySmsEnabled;
|
||||
|
||||
/**
|
||||
* 剩余短信数量
|
||||
*/
|
||||
@NotNull(message = "剩余短信数量不能为空", groups = {AddGroup.class, EditGroup.class})
|
||||
private Long remainingSmsCount;
|
||||
|
||||
/**
|
||||
* 0=正常, 1=已删除
|
||||
*/
|
||||
// @NotNull(message = "0=正常, 1=已删除不能为空", groups = {AddGroup.class, EditGroup.class})
|
||||
private Long isDeleted;
|
||||
|
||||
/**
|
||||
* 隐患排查规则(1=周 2=月 3=季度 4=半年 5=年)
|
||||
*/
|
||||
private Long hiddenDangerRole;
|
||||
|
||||
/**
|
||||
* 隐患排查规则是否启用(0=否 1=是)
|
||||
*/
|
||||
private Long roleIsEnable;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
package com.hotwj.platform.config.companyBasicConfig.domain.vo;
|
||||
|
||||
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import cn.idev.excel.annotation.ExcelProperty;
|
||||
import com.hotwj.platform.config.companyBasicConfig.domain.HotCompanyBasicConfig;
|
||||
import io.github.linpeilie.annotations.AutoMapper;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
|
||||
/**
|
||||
* 企业基础配置视图对象 hot_company_basic_config
|
||||
*
|
||||
* @author shihongwei
|
||||
* @date 2025-12-29
|
||||
*/
|
||||
@Data
|
||||
@ExcelIgnoreUnannotated
|
||||
@AutoMapper(target = HotCompanyBasicConfig.class)
|
||||
public class HotCompanyBasicConfigVo implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@ExcelProperty(value = "主键")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 公司ID
|
||||
*/
|
||||
@ExcelProperty(value = "公司ID")
|
||||
private Long companyId;
|
||||
|
||||
/**
|
||||
* 是否补学 0=关闭 1=开启
|
||||
*/
|
||||
@ExcelProperty(value = "是否补学 0=关闭 1=开启")
|
||||
private Long makeUpStudyEnabled;
|
||||
|
||||
/**
|
||||
* 禁学区间是否开启 0=关闭 1=开启
|
||||
*/
|
||||
@ExcelProperty(value = "禁学区间是否开启 0=关闭 1=开启")
|
||||
private Long forbidPeriodEnabled;
|
||||
|
||||
/**
|
||||
* 禁学开始时间
|
||||
*/
|
||||
@ExcelProperty(value = "禁学开始时间")
|
||||
private String forbidStartTime;
|
||||
|
||||
/**
|
||||
* 禁学结束时间
|
||||
*/
|
||||
@ExcelProperty(value = "禁学结束时间")
|
||||
private String forbidEndTime;
|
||||
|
||||
/**
|
||||
* 学习短信提醒是否开启 0=关闭 1=开启
|
||||
*/
|
||||
@ExcelProperty(value = "学习短信提醒是否开启 0=关闭 1=开启")
|
||||
private Long studySmsEnabled;
|
||||
|
||||
/**
|
||||
* 剩余短信数量
|
||||
*/
|
||||
@ExcelProperty(value = "剩余短信数量")
|
||||
private Long remainingSmsCount;
|
||||
|
||||
/**
|
||||
* 0=正常, 1=已删除
|
||||
*/
|
||||
@ExcelProperty(value = "0=正常, 1=已删除")
|
||||
private Long isDeleted;
|
||||
|
||||
// private Long isChecked;
|
||||
/**
|
||||
* 隐患排查规则(1=周 2=月 3=季度 4=半年 5=年)
|
||||
*/
|
||||
private Long hiddenDangerRole;
|
||||
|
||||
/**
|
||||
* 隐患排查规则是否启用(0=否 1=是)
|
||||
*/
|
||||
private Long roleIsEnable;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.hotwj.platform.config.companyBasicConfig.mapper;
|
||||
|
||||
import com.hotwj.platform.config.companyBasicConfig.domain.HotCompanyBasicConfig;
|
||||
import com.hotwj.platform.config.companyBasicConfig.domain.vo.HotCompanyBasicConfigVo;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
|
||||
|
||||
/**
|
||||
* 企业基础配置Mapper接口
|
||||
*
|
||||
* @author shihongwei
|
||||
* @date 2025-12-29
|
||||
*/
|
||||
@Mapper
|
||||
public interface HotCompanyBasicConfigMapper extends BaseMapperPlus<HotCompanyBasicConfig, HotCompanyBasicConfigVo> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package com.hotwj.platform.config.companyBasicConfig.service;
|
||||
|
||||
import com.hotwj.platform.config.companyBasicConfig.domain.bo.HotCompanyBasicConfigBo;
|
||||
import com.hotwj.platform.config.companyBasicConfig.domain.vo.HotCompanyBasicConfigVo;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 企业基础配置Service接口
|
||||
*
|
||||
* @author shihongwei
|
||||
* @date 2025-12-29
|
||||
*/
|
||||
public interface IHotCompanyBasicConfigService {
|
||||
|
||||
/**
|
||||
* 查询企业基础配置
|
||||
*
|
||||
* @param id 主键
|
||||
* @return 企业基础配置
|
||||
*/
|
||||
HotCompanyBasicConfigVo queryById(Long id);
|
||||
|
||||
/**
|
||||
* 分页查询企业基础配置列表
|
||||
*
|
||||
* @param bo 查询条件
|
||||
* @param pageQuery 分页参数
|
||||
* @return 企业基础配置分页列表
|
||||
*/
|
||||
TableDataInfo<HotCompanyBasicConfigVo> queryPageList(HotCompanyBasicConfigBo bo, PageQuery pageQuery);
|
||||
|
||||
/**
|
||||
* 查询符合条件的企业基础配置列表
|
||||
*
|
||||
* @param bo 查询条件
|
||||
* @return 企业基础配置列表
|
||||
*/
|
||||
List<HotCompanyBasicConfigVo> queryList(HotCompanyBasicConfigBo bo);
|
||||
|
||||
/**
|
||||
* 新增企业基础配置
|
||||
*
|
||||
* @param bo 企业基础配置
|
||||
* @return 是否新增成功
|
||||
*/
|
||||
Boolean insertByBo(HotCompanyBasicConfigBo bo);
|
||||
|
||||
/**
|
||||
* 修改企业基础配置
|
||||
*
|
||||
* @param bo 企业基础配置
|
||||
* @return 是否修改成功
|
||||
*/
|
||||
Boolean updateByBo(HotCompanyBasicConfigBo bo);
|
||||
|
||||
/**
|
||||
* 校验并批量删除企业基础配置信息
|
||||
*
|
||||
* @param ids 待删除的主键集合
|
||||
* @param isValid 是否进行有效性校验
|
||||
* @return 是否删除成功
|
||||
*/
|
||||
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
|
||||
}
|
||||
@@ -0,0 +1,213 @@
|
||||
package com.hotwj.platform.config.companyBasicConfig.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.hotwj.platform.config.companyBasicConfig.domain.HotCompanyBasicConfig;
|
||||
import com.hotwj.platform.config.companyBasicConfig.domain.bo.HotCompanyBasicConfigBo;
|
||||
import com.hotwj.platform.config.companyBasicConfig.domain.vo.HotCompanyBasicConfigVo;
|
||||
import com.hotwj.platform.config.companyBasicConfig.mapper.HotCompanyBasicConfigMapper;
|
||||
import com.hotwj.platform.config.companyBasicConfig.service.IHotCompanyBasicConfigService;
|
||||
import com.hotwj.platform.driverManagement.driver.domain.HotDriver;
|
||||
import com.hotwj.platform.driverManagement.driver.mapper.HotDriverMapper;
|
||||
import com.hotwj.platform.noticeManagerment.systemNotification.domain.bo.HotSystemNotificationGroupBo;
|
||||
import com.hotwj.platform.noticeManagerment.systemNotification.service.IHotSystemNotificationService;
|
||||
import com.hotwj.platform.resourceManagement.companySafetyManager.domain.HotCompanySafetyManager;
|
||||
import com.hotwj.platform.resourceManagement.companySafetyManager.mapper.HotCompanySafetyManagerMapper;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.common.core.utils.MapstructUtils;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 企业基础配置Service业务层处理
|
||||
*
|
||||
* @author shihongwei
|
||||
* @date 2025-12-29
|
||||
*/
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
@Service
|
||||
public class HotCompanyBasicConfigServiceImpl implements IHotCompanyBasicConfigService {
|
||||
|
||||
private final HotCompanyBasicConfigMapper baseMapper;
|
||||
private final HotCompanySafetyManagerMapper managerMapper;
|
||||
private final HotDriverMapper driverMapper;
|
||||
private final IHotSystemNotificationService notificationService;
|
||||
|
||||
/**
|
||||
* 查询企业基础配置
|
||||
*
|
||||
* @param id 主键
|
||||
* @return 企业基础配置
|
||||
*/
|
||||
@Override
|
||||
public HotCompanyBasicConfigVo queryById(Long id) {
|
||||
return baseMapper.selectVoById(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询企业基础配置列表
|
||||
*
|
||||
* @param bo 查询条件
|
||||
* @param pageQuery 分页参数
|
||||
* @return 企业基础配置分页列表
|
||||
*/
|
||||
@Override
|
||||
public TableDataInfo<HotCompanyBasicConfigVo> queryPageList(HotCompanyBasicConfigBo bo, PageQuery pageQuery) {
|
||||
LambdaQueryWrapper<HotCompanyBasicConfig> lqw = buildQueryWrapper(bo);
|
||||
Page<HotCompanyBasicConfigVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
|
||||
return TableDataInfo.build(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询符合条件的企业基础配置列表
|
||||
*
|
||||
* @param bo 查询条件
|
||||
* @return 企业基础配置列表
|
||||
*/
|
||||
@Override
|
||||
public List<HotCompanyBasicConfigVo> queryList(HotCompanyBasicConfigBo bo) {
|
||||
LambdaQueryWrapper<HotCompanyBasicConfig> lqw = buildQueryWrapper(bo);
|
||||
return baseMapper.selectVoList(lqw);
|
||||
}
|
||||
|
||||
private LambdaQueryWrapper<HotCompanyBasicConfig> buildQueryWrapper(HotCompanyBasicConfigBo bo) {
|
||||
Map<String, Object> params = bo.getParams();
|
||||
LambdaQueryWrapper<HotCompanyBasicConfig> lqw = Wrappers.lambdaQuery();
|
||||
lqw.orderByAsc(HotCompanyBasicConfig::getId);
|
||||
lqw.eq(bo.getCompanyId() != null, HotCompanyBasicConfig::getCompanyId, bo.getCompanyId());
|
||||
lqw.eq(bo.getMakeUpStudyEnabled() != null, HotCompanyBasicConfig::getMakeUpStudyEnabled, bo.getMakeUpStudyEnabled());
|
||||
lqw.eq(bo.getForbidPeriodEnabled() != null, HotCompanyBasicConfig::getForbidPeriodEnabled, bo.getForbidPeriodEnabled());
|
||||
lqw.eq(bo.getForbidStartTime() != null, HotCompanyBasicConfig::getForbidStartTime, bo.getForbidStartTime());
|
||||
lqw.eq(bo.getForbidEndTime() != null, HotCompanyBasicConfig::getForbidEndTime, bo.getForbidEndTime());
|
||||
lqw.eq(bo.getStudySmsEnabled() != null, HotCompanyBasicConfig::getStudySmsEnabled, bo.getStudySmsEnabled());
|
||||
lqw.eq(bo.getRemainingSmsCount() != null, HotCompanyBasicConfig::getRemainingSmsCount, bo.getRemainingSmsCount());
|
||||
lqw.eq(bo.getIsDeleted() != null, HotCompanyBasicConfig::getIsDeleted, bo.getIsDeleted());
|
||||
return lqw;
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增企业基础配置
|
||||
*
|
||||
* @param bo 企业基础配置
|
||||
* @return 是否新增成功
|
||||
*/
|
||||
@Override
|
||||
public Boolean insertByBo(HotCompanyBasicConfigBo bo) {
|
||||
HotCompanyBasicConfig add = MapstructUtils.convert(bo, HotCompanyBasicConfig.class);
|
||||
validEntityBeforeSave(add);
|
||||
boolean flag = baseMapper.insert(add) > 0;
|
||||
if (flag) {
|
||||
bo.setId(add.getId());
|
||||
if (add.getCompanyId() != null
|
||||
&& add.getForbidPeriodEnabled() != null && Long.valueOf(1L).equals(add.getForbidPeriodEnabled())
|
||||
&& add.getForbidStartTime() != null && add.getForbidEndTime() != null) {
|
||||
notifyForbidPeriod(add.getCompanyId(), add.getForbidStartTime(), add.getForbidEndTime());
|
||||
}
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改企业基础配置
|
||||
*
|
||||
* @param bo 企业基础配置
|
||||
* @return 是否修改成功
|
||||
*/
|
||||
@Override
|
||||
public Boolean updateByBo(HotCompanyBasicConfigBo bo) {
|
||||
HotCompanyBasicConfig update = MapstructUtils.convert(bo, HotCompanyBasicConfig.class);
|
||||
validEntityBeforeSave(update);
|
||||
boolean flag = baseMapper.updateById(update) > 0;
|
||||
if (flag) {
|
||||
HotCompanyBasicConfig cfg = baseMapper.selectById(update.getId());
|
||||
if (cfg != null
|
||||
&& cfg.getCompanyId() != null
|
||||
&& cfg.getForbidPeriodEnabled() != null && Long.valueOf(1L).equals(cfg.getForbidPeriodEnabled())
|
||||
&& cfg.getForbidStartTime() != null && cfg.getForbidEndTime() != null) {
|
||||
notifyForbidPeriod(cfg.getCompanyId(), bo.getForbidStartTime(), bo.getForbidEndTime());
|
||||
}
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存前的数据校验
|
||||
*/
|
||||
private void validEntityBeforeSave(HotCompanyBasicConfig entity) {
|
||||
//TODO 做一些数据校验,如唯一约束
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验并批量删除企业基础配置信息
|
||||
*
|
||||
* @param ids 待删除的主键集合
|
||||
* @param isValid 是否进行有效性校验
|
||||
* @return 是否删除成功
|
||||
*/
|
||||
@Override
|
||||
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
|
||||
if (isValid) {
|
||||
//TODO 做一些业务上的校验,判断是否需要校验
|
||||
}
|
||||
return baseMapper.deleteByIds(ids) > 0;
|
||||
}
|
||||
|
||||
//通知
|
||||
private void notifyForbidPeriod(Long companyId, String startTime, String endTime) {
|
||||
List<HotCompanySafetyManager> managers = managerMapper.selectList(
|
||||
Wrappers.<HotCompanySafetyManager>lambdaQuery()
|
||||
.eq(HotCompanySafetyManager::getCompanyId, companyId)
|
||||
.eq(HotCompanySafetyManager::getIsDeleted, 0L)
|
||||
.eq(HotCompanySafetyManager::getIsResigned, 0L)
|
||||
.eq(HotCompanySafetyManager::getStatus, 1L)
|
||||
);
|
||||
List<HotDriver> drivers = driverMapper.selectList(
|
||||
Wrappers.<HotDriver>lambdaQuery()
|
||||
.eq(HotDriver::getCompanyId, companyId)
|
||||
.eq(HotDriver::getIsDeleted, 0L)
|
||||
.eq(HotDriver::getStatus, 1L)
|
||||
);
|
||||
String content = "企业已配置禁学期间:" + startTime + " 至 " + endTime + ",期间禁止学习。";
|
||||
|
||||
if (managers != null && !managers.isEmpty()) {
|
||||
List<String> receiverIds = managers.stream().map(m -> String.valueOf(m.getId())).toList();
|
||||
HotSystemNotificationGroupBo bos = new HotSystemNotificationGroupBo();
|
||||
bos.setLevel("普通");
|
||||
bos.setContent(content);
|
||||
bos.setSourceType("企业管理");
|
||||
bos.setSenderType("SYSTEM");
|
||||
bos.setReceiverType("管理员");
|
||||
bos.setReceiverIds(receiverIds);
|
||||
bos.setIsDeleted(0L);
|
||||
try {
|
||||
notificationService.insertByBo(bos);
|
||||
} catch (Exception e) {
|
||||
log.warn("禁学期间通知发送失败 companyId={} type=manager", companyId, e);
|
||||
}
|
||||
}
|
||||
if (drivers != null && !drivers.isEmpty()) {
|
||||
List<String> receiverIds = drivers.stream().map(HotDriver::getId).toList();
|
||||
HotSystemNotificationGroupBo bos = new HotSystemNotificationGroupBo();
|
||||
bos.setLevel("普通");
|
||||
bos.setContent(content);
|
||||
bos.setSourceType("企业管理");
|
||||
bos.setSenderType("SYSTEM");
|
||||
bos.setReceiverType("驾驶员");
|
||||
bos.setReceiverIds(receiverIds);
|
||||
bos.setIsDeleted(0L);
|
||||
try {
|
||||
notificationService.insertByBo(bos);
|
||||
} catch (Exception e) {
|
||||
log.warn("禁学期间通知发送失败 companyId={} type=driver", companyId, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
package com.hotwj.platform.config.companyDeptConfig.controller;
|
||||
|
||||
import com.hotwj.platform.config.companyDeptConfig.domain.bo.HotCompanyDeptConfigBo;
|
||||
import com.hotwj.platform.config.companyDeptConfig.domain.vo.HotCompanyDeptConfigVo;
|
||||
import com.hotwj.platform.config.companyDeptConfig.service.IHotCompanyDeptConfigService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.dromara.common.core.domain.R;
|
||||
import org.dromara.common.core.validate.AddGroup;
|
||||
import org.dromara.common.core.validate.EditGroup;
|
||||
import org.dromara.common.excel.utils.ExcelUtil;
|
||||
import org.dromara.common.idempotent.annotation.RepeatSubmit;
|
||||
import org.dromara.common.log.annotation.Log;
|
||||
import org.dromara.common.log.enums.BusinessType;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.dromara.common.web.core.BaseController;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 企业部门配置
|
||||
*
|
||||
* @author shihongwei
|
||||
* @date 2025-12-29
|
||||
*/
|
||||
@Validated
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/config/companyDeptConfig")
|
||||
@Tag(name = "企业部门配置", description = "企业部门配置管理")
|
||||
public class HotCompanyDeptConfigController extends BaseController {
|
||||
|
||||
private final IHotCompanyDeptConfigService hotCompanyDeptConfigService;
|
||||
|
||||
/**
|
||||
* 查询企业部门配置列表
|
||||
*/
|
||||
//@SaCheckPermission("config:companyDeptConfig:list")
|
||||
@GetMapping("/list")
|
||||
@Operation(summary = "分页查询企业部门配置列表")
|
||||
public TableDataInfo<HotCompanyDeptConfigVo> list(HotCompanyDeptConfigBo bo, PageQuery pageQuery) {
|
||||
return hotCompanyDeptConfigService.queryPageList(bo, pageQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出企业部门配置列表
|
||||
*/
|
||||
//@SaCheckPermission("config:companyDeptConfig:export")
|
||||
@Log(title = "企业部门配置", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/export")
|
||||
@Operation(summary = "导出企业部门配置列表")
|
||||
public void export(HotCompanyDeptConfigBo bo, HttpServletResponse response) {
|
||||
List<HotCompanyDeptConfigVo> list = hotCompanyDeptConfigService.queryList(bo);
|
||||
ExcelUtil.exportExcel(list, "企业部门配置", HotCompanyDeptConfigVo.class, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取企业部门配置详细信息
|
||||
*
|
||||
* @param id 主键
|
||||
*/
|
||||
//@SaCheckPermission("config:companyDeptConfig:query")
|
||||
@GetMapping("/{id}")
|
||||
@Operation(summary = "获取企业部门配置详细信息")
|
||||
public R<HotCompanyDeptConfigVo> getInfo(@NotNull(message = "主键不能为空")
|
||||
@Parameter(name = "id", description = "主键", required = true, example = "1")
|
||||
@PathVariable Long id) {
|
||||
return R.ok(hotCompanyDeptConfigService.queryById(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增企业部门配置
|
||||
*/
|
||||
//@SaCheckPermission("config:companyDeptConfig:add")
|
||||
@Log(title = "企业部门配置", businessType = BusinessType.INSERT)
|
||||
@RepeatSubmit()
|
||||
@PostMapping()
|
||||
@Operation(summary = "新增企业部门配置")
|
||||
public R<Void> add(@Validated(AddGroup.class) @RequestBody HotCompanyDeptConfigBo bo) {
|
||||
return toAjax(hotCompanyDeptConfigService.insertByBo(bo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改企业部门配置
|
||||
*/
|
||||
//@SaCheckPermission("config:companyDeptConfig:edit")
|
||||
@Log(title = "企业部门配置", businessType = BusinessType.UPDATE)
|
||||
@RepeatSubmit()
|
||||
@PutMapping()
|
||||
@Operation(summary = "修改企业部门配置")
|
||||
public R<Void> edit(@Validated(EditGroup.class) @RequestBody HotCompanyDeptConfigBo bo) {
|
||||
return toAjax(hotCompanyDeptConfigService.updateByBo(bo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除企业部门配置
|
||||
*
|
||||
* @param ids 主键串
|
||||
*/
|
||||
//@SaCheckPermission("config:companyDeptConfig:remove")
|
||||
@Log(title = "企业部门配置", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{ids}")
|
||||
@Operation(summary = "删除企业部门配置")
|
||||
public R<Void> remove(@NotEmpty(message = "主键不能为空")
|
||||
@Parameter(name = "ids", description = "主键串", required = true, example = "1,2,3")
|
||||
@PathVariable Long[] ids) {
|
||||
return toAjax(hotCompanyDeptConfigService.deleteWithValidByIds(List.of(ids), true));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package com.hotwj.platform.config.companyDeptConfig.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
||||
|
||||
import java.io.Serial;
|
||||
|
||||
/**
|
||||
* 企业部门配置对象 hot_company_dept_config
|
||||
*
|
||||
* @author shihongwei
|
||||
* @date 2025-12-29
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("hot_company_dept_config")
|
||||
public class HotCompanyDeptConfig extends BaseEntity {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@TableId(value = "id")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 公司ID
|
||||
*/
|
||||
private Long companyId;
|
||||
|
||||
/**
|
||||
* 部门名称
|
||||
*/
|
||||
private String deptName;
|
||||
|
||||
/**
|
||||
* 部门代码,要求大写字母
|
||||
*/
|
||||
private String deptCode;
|
||||
|
||||
/**
|
||||
* 0=正常, 1=已删除
|
||||
*/
|
||||
@TableLogic
|
||||
private Long isDeleted;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package com.hotwj.platform.config.companyDeptConfig.domain.bo;
|
||||
|
||||
import com.hotwj.platform.config.companyDeptConfig.domain.HotCompanyDeptConfig;
|
||||
import io.github.linpeilie.annotations.AutoMapper;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.dromara.common.core.validate.AddGroup;
|
||||
import org.dromara.common.core.validate.EditGroup;
|
||||
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
||||
|
||||
/**
|
||||
* 企业部门配置业务对象 hot_company_dept_config
|
||||
*
|
||||
* @author shihongwei
|
||||
* @date 2025-12-29
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@AutoMapper(target = HotCompanyDeptConfig.class, reverseConvertGenerate = false)
|
||||
public class HotCompanyDeptConfigBo extends BaseEntity {
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@NotNull(message = "主键不能为空", groups = {EditGroup.class})
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 公司ID
|
||||
*/
|
||||
@NotNull(message = "公司ID不能为空", groups = {AddGroup.class, EditGroup.class})
|
||||
private Long companyId;
|
||||
|
||||
/**
|
||||
* 部门名称
|
||||
*/
|
||||
@NotBlank(message = "部门名称不能为空", groups = {AddGroup.class, EditGroup.class})
|
||||
private String deptName;
|
||||
|
||||
/**
|
||||
* 部门代码,要求大写字母
|
||||
*/
|
||||
@NotBlank(message = "部门代码,要求大写字母不能为空", groups = {AddGroup.class, EditGroup.class})
|
||||
private String deptCode;
|
||||
|
||||
/**
|
||||
* 0=正常, 1=已删除
|
||||
*/
|
||||
// @NotNull(message = "0=正常, 1=已删除不能为空", groups = {AddGroup.class, EditGroup.class})
|
||||
private Long isDeleted;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package com.hotwj.platform.config.companyDeptConfig.domain.vo;
|
||||
|
||||
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import cn.idev.excel.annotation.ExcelProperty;
|
||||
import com.hotwj.platform.config.companyDeptConfig.domain.HotCompanyDeptConfig;
|
||||
import io.github.linpeilie.annotations.AutoMapper;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
|
||||
/**
|
||||
* 企业部门配置视图对象 hot_company_dept_config
|
||||
*
|
||||
* @author shihongwei
|
||||
* @date 2025-12-29
|
||||
*/
|
||||
@Data
|
||||
@ExcelIgnoreUnannotated
|
||||
@AutoMapper(target = HotCompanyDeptConfig.class)
|
||||
public class HotCompanyDeptConfigVo implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@ExcelProperty(value = "主键")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 公司ID
|
||||
*/
|
||||
@ExcelProperty(value = "公司ID")
|
||||
private Long companyId;
|
||||
|
||||
/**
|
||||
* 部门名称
|
||||
*/
|
||||
@ExcelProperty(value = "部门名称")
|
||||
private String deptName;
|
||||
|
||||
/**
|
||||
* 部门代码,要求大写字母
|
||||
*/
|
||||
@ExcelProperty(value = "部门代码,要求大写字母")
|
||||
private String deptCode;
|
||||
|
||||
/**
|
||||
* 0=正常, 1=已删除
|
||||
*/
|
||||
@ExcelProperty(value = "0=正常, 1=已删除")
|
||||
private Long isDeleted;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.hotwj.platform.config.companyDeptConfig.mapper;
|
||||
|
||||
import com.hotwj.platform.config.companyDeptConfig.domain.HotCompanyDeptConfig;
|
||||
import com.hotwj.platform.config.companyDeptConfig.domain.vo.HotCompanyDeptConfigVo;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
|
||||
|
||||
/**
|
||||
* 企业部门配置Mapper接口
|
||||
*
|
||||
* @author shihongwei
|
||||
* @date 2025-12-29
|
||||
*/
|
||||
@Mapper
|
||||
public interface HotCompanyDeptConfigMapper extends BaseMapperPlus<HotCompanyDeptConfig, HotCompanyDeptConfigVo> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package com.hotwj.platform.config.companyDeptConfig.service;
|
||||
|
||||
import com.hotwj.platform.config.companyDeptConfig.domain.bo.HotCompanyDeptConfigBo;
|
||||
import com.hotwj.platform.config.companyDeptConfig.domain.vo.HotCompanyDeptConfigVo;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 企业部门配置Service接口
|
||||
*
|
||||
* @author shihongwei
|
||||
* @date 2025-12-29
|
||||
*/
|
||||
public interface IHotCompanyDeptConfigService {
|
||||
|
||||
/**
|
||||
* 查询企业部门配置
|
||||
*
|
||||
* @param id 主键
|
||||
* @return 企业部门配置
|
||||
*/
|
||||
HotCompanyDeptConfigVo queryById(Long id);
|
||||
|
||||
/**
|
||||
* 分页查询企业部门配置列表
|
||||
*
|
||||
* @param bo 查询条件
|
||||
* @param pageQuery 分页参数
|
||||
* @return 企业部门配置分页列表
|
||||
*/
|
||||
TableDataInfo<HotCompanyDeptConfigVo> queryPageList(HotCompanyDeptConfigBo bo, PageQuery pageQuery);
|
||||
|
||||
/**
|
||||
* 查询符合条件的企业部门配置列表
|
||||
*
|
||||
* @param bo 查询条件
|
||||
* @return 企业部门配置列表
|
||||
*/
|
||||
List<HotCompanyDeptConfigVo> queryList(HotCompanyDeptConfigBo bo);
|
||||
|
||||
/**
|
||||
* 新增企业部门配置
|
||||
*
|
||||
* @param bo 企业部门配置
|
||||
* @return 是否新增成功
|
||||
*/
|
||||
Boolean insertByBo(HotCompanyDeptConfigBo bo);
|
||||
|
||||
/**
|
||||
* 修改企业部门配置
|
||||
*
|
||||
* @param bo 企业部门配置
|
||||
* @return 是否修改成功
|
||||
*/
|
||||
Boolean updateByBo(HotCompanyDeptConfigBo bo);
|
||||
|
||||
/**
|
||||
* 校验并批量删除企业部门配置信息
|
||||
*
|
||||
* @param ids 待删除的主键集合
|
||||
* @param isValid 是否进行有效性校验
|
||||
* @return 是否删除成功
|
||||
*/
|
||||
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
package com.hotwj.platform.config.companyDeptConfig.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.hotwj.platform.config.companyDeptConfig.domain.HotCompanyDeptConfig;
|
||||
import com.hotwj.platform.config.companyDeptConfig.domain.bo.HotCompanyDeptConfigBo;
|
||||
import com.hotwj.platform.config.companyDeptConfig.domain.vo.HotCompanyDeptConfigVo;
|
||||
import com.hotwj.platform.config.companyDeptConfig.mapper.HotCompanyDeptConfigMapper;
|
||||
import com.hotwj.platform.config.companyDeptConfig.service.IHotCompanyDeptConfigService;
|
||||
import com.hotwj.platform.resourceManagement.companySafetyManager.domain.HotCompanySafetyManager;
|
||||
import com.hotwj.platform.resourceManagement.companySafetyManager.mapper.HotCompanySafetyManagerMapper;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.common.core.exception.ServiceException;
|
||||
import org.dromara.common.core.utils.MapstructUtils;
|
||||
import org.dromara.common.core.utils.StringUtils;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 企业部门配置Service业务层处理
|
||||
*
|
||||
* @author shihongwei
|
||||
* @date 2025-12-29
|
||||
*/
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
@Service
|
||||
public class HotCompanyDeptConfigServiceImpl implements IHotCompanyDeptConfigService {
|
||||
|
||||
private final HotCompanyDeptConfigMapper baseMapper;
|
||||
private final HotCompanySafetyManagerMapper safetyManagerMapper;
|
||||
|
||||
/**
|
||||
* 查询企业部门配置
|
||||
*
|
||||
* @param id 主键
|
||||
* @return 企业部门配置
|
||||
*/
|
||||
@Override
|
||||
public HotCompanyDeptConfigVo queryById(Long id) {
|
||||
return baseMapper.selectVoById(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询企业部门配置列表
|
||||
*
|
||||
* @param bo 查询条件
|
||||
* @param pageQuery 分页参数
|
||||
* @return 企业部门配置分页列表
|
||||
*/
|
||||
@Override
|
||||
public TableDataInfo<HotCompanyDeptConfigVo> queryPageList(HotCompanyDeptConfigBo bo, PageQuery pageQuery) {
|
||||
LambdaQueryWrapper<HotCompanyDeptConfig> lqw = buildQueryWrapper(bo);
|
||||
Page<HotCompanyDeptConfigVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
|
||||
return TableDataInfo.build(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询符合条件的企业部门配置列表
|
||||
*
|
||||
* @param bo 查询条件
|
||||
* @return 企业部门配置列表
|
||||
*/
|
||||
@Override
|
||||
public List<HotCompanyDeptConfigVo> queryList(HotCompanyDeptConfigBo bo) {
|
||||
LambdaQueryWrapper<HotCompanyDeptConfig> lqw = buildQueryWrapper(bo);
|
||||
return baseMapper.selectVoList(lqw);
|
||||
}
|
||||
|
||||
private LambdaQueryWrapper<HotCompanyDeptConfig> buildQueryWrapper(HotCompanyDeptConfigBo bo) {
|
||||
Map<String, Object> params = bo.getParams();
|
||||
LambdaQueryWrapper<HotCompanyDeptConfig> lqw = Wrappers.lambdaQuery();
|
||||
lqw.orderByAsc(HotCompanyDeptConfig::getId);
|
||||
lqw.eq(bo.getCompanyId() != null, HotCompanyDeptConfig::getCompanyId, bo.getCompanyId());
|
||||
lqw.like(StringUtils.isNotBlank(bo.getDeptName()), HotCompanyDeptConfig::getDeptName, bo.getDeptName());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getDeptCode()), HotCompanyDeptConfig::getDeptCode, bo.getDeptCode());
|
||||
lqw.eq(bo.getIsDeleted() != null, HotCompanyDeptConfig::getIsDeleted, bo.getIsDeleted());
|
||||
return lqw;
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增企业部门配置
|
||||
*
|
||||
* @param bo 企业部门配置
|
||||
* @return 是否新增成功
|
||||
*/
|
||||
@Override
|
||||
public Boolean insertByBo(HotCompanyDeptConfigBo bo) {
|
||||
HotCompanyDeptConfig add = MapstructUtils.convert(bo, HotCompanyDeptConfig.class);
|
||||
validEntityBeforeSave(add);
|
||||
boolean flag = baseMapper.insert(add) > 0;
|
||||
if (flag) {
|
||||
bo.setId(add.getId());
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改企业部门配置
|
||||
*
|
||||
* @param bo 企业部门配置
|
||||
* @return 是否修改成功
|
||||
*/
|
||||
@Override
|
||||
public Boolean updateByBo(HotCompanyDeptConfigBo bo) {
|
||||
HotCompanyDeptConfig update = MapstructUtils.convert(bo, HotCompanyDeptConfig.class);
|
||||
validEntityBeforeSave(update);
|
||||
return baseMapper.updateById(update) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存前的数据校验
|
||||
*/
|
||||
private void validEntityBeforeSave(HotCompanyDeptConfig entity) {
|
||||
//TODO 做一些数据校验,如唯一约束
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验并批量删除企业部门配置信息
|
||||
*
|
||||
* @param ids 待删除的主键集合
|
||||
* @param isValid 是否进行有效性校验
|
||||
* @return 是否删除成功
|
||||
*/
|
||||
@Override
|
||||
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
|
||||
if (isValid) {
|
||||
Long count = safetyManagerMapper.selectCount(Wrappers.<HotCompanySafetyManager>lambdaQuery()
|
||||
.in(HotCompanySafetyManager::getDeptId, ids)
|
||||
.eq(HotCompanySafetyManager::getIsResigned, 0L));
|
||||
if (count > 0) {
|
||||
throw new ServiceException("该部门有未离职人员不可删除");
|
||||
}
|
||||
}
|
||||
return baseMapper.deleteByIds(ids) > 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
package com.hotwj.platform.config.course.controller;
|
||||
|
||||
import com.hotwj.platform.config.course.domain.bo.HotCourseBo;
|
||||
import com.hotwj.platform.config.course.domain.vo.HotCourseVo;
|
||||
import com.hotwj.platform.config.course.service.IHotCourseService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.dromara.common.core.domain.R;
|
||||
import org.dromara.common.core.validate.AddGroup;
|
||||
import org.dromara.common.core.validate.EditGroup;
|
||||
import org.dromara.common.excel.utils.ExcelUtil;
|
||||
import org.dromara.common.idempotent.annotation.RepeatSubmit;
|
||||
import org.dromara.common.log.annotation.Log;
|
||||
import org.dromara.common.log.enums.BusinessType;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.dromara.common.web.core.BaseController;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 课程库
|
||||
*
|
||||
* @author shihongwei
|
||||
* @date 2025-12-23
|
||||
*/
|
||||
@Validated
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/config/course")
|
||||
@Tag(name = "课程库", description = "课程库管理")
|
||||
public class HotCourseController extends BaseController {
|
||||
|
||||
private final IHotCourseService hotCourseService;
|
||||
|
||||
/**
|
||||
* 查询课程库列表
|
||||
*/
|
||||
//@SaCheckPermission("config:course:list")
|
||||
@GetMapping("/list")
|
||||
@Operation(summary = "分页查询课程库列表")
|
||||
public TableDataInfo<HotCourseVo> list(HotCourseBo bo, PageQuery pageQuery) {
|
||||
return hotCourseService.queryPageList(bo, pageQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出课程库列表
|
||||
*/
|
||||
//@SaCheckPermission("config:course:export")
|
||||
@Log(title = "课程库", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/export")
|
||||
@Operation(summary = "导出课程库列表")
|
||||
public void export(HotCourseBo bo, HttpServletResponse response) {
|
||||
List<HotCourseVo> list = hotCourseService.queryList(bo);
|
||||
ExcelUtil.exportExcel(list, "课程库", HotCourseVo.class, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取课程库详细信息
|
||||
*
|
||||
* @param id 主键
|
||||
*/
|
||||
//@SaCheckPermission("config:course:query")
|
||||
@GetMapping("/{id}")
|
||||
@Operation(summary = "获取课程库详细信息")
|
||||
public R<HotCourseVo> getInfo(@NotNull(message = "主键不能为空")
|
||||
@Parameter(name = "id", description = "主键", required = true, example = "1")
|
||||
@PathVariable Long id) {
|
||||
return R.ok(hotCourseService.queryById(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增课程库
|
||||
*/
|
||||
//@SaCheckPermission("config:course:add")
|
||||
@Log(title = "课程库", businessType = BusinessType.INSERT)
|
||||
@RepeatSubmit()
|
||||
@PostMapping()
|
||||
@Operation(summary = "新增课程库")
|
||||
public R<Void> add(@Validated(AddGroup.class) @RequestBody HotCourseBo bo) {
|
||||
return toAjax(hotCourseService.insertByBo(bo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改课程库
|
||||
*/
|
||||
//@SaCheckPermission("config:course:edit")
|
||||
@Log(title = "课程库", businessType = BusinessType.UPDATE)
|
||||
@RepeatSubmit()
|
||||
@PutMapping()
|
||||
@Operation(summary = "修改课程库")
|
||||
public R<Void> edit(@Validated(EditGroup.class) @RequestBody HotCourseBo bo) {
|
||||
return toAjax(hotCourseService.updateByBo(bo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除课程库
|
||||
*
|
||||
* @param ids 主键串
|
||||
*/
|
||||
//@SaCheckPermission("config:course:remove")
|
||||
@Log(title = "课程库", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{ids}")
|
||||
@Operation(summary = "删除课程库")
|
||||
public R<Void> remove(@NotEmpty(message = "主键不能为空")
|
||||
@Parameter(name = "ids", description = "主键串", required = true, example = "1,2,3")
|
||||
@PathVariable Long[] ids) {
|
||||
return toAjax(hotCourseService.deleteWithValidByIds(List.of(ids), true));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
package com.hotwj.platform.config.course.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 课程库对象 hot_course
|
||||
*
|
||||
* @author shihongwei
|
||||
* @date 2025-12-23
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("hot_course")
|
||||
public class HotCourse extends BaseEntity {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@TableId(value = "id")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 公司ID
|
||||
*/
|
||||
private Long companyId;
|
||||
|
||||
/**
|
||||
* 课程名称
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 教育类型字典编码
|
||||
*/
|
||||
private String trainingTypeCode;
|
||||
|
||||
/**
|
||||
* 教育类型子集编码集(JSON/逗号分隔)
|
||||
*/
|
||||
private String trainingSubtypeCodes;
|
||||
|
||||
/**
|
||||
* 课程描述
|
||||
*/
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 封面/预览图URL
|
||||
*/
|
||||
private String coverUrl;
|
||||
|
||||
/**
|
||||
* 课程文件URL(PDF/图片)
|
||||
*/
|
||||
private String materialUrl;
|
||||
|
||||
/**
|
||||
* 文件学习时长(秒)
|
||||
*/
|
||||
private Long learningDuration;
|
||||
|
||||
/**
|
||||
* 课时
|
||||
*/
|
||||
private BigDecimal classHours;
|
||||
|
||||
/**
|
||||
* 课程内容(富文本)
|
||||
*/
|
||||
private String content;
|
||||
|
||||
/**
|
||||
* 状态:1=启用 0=禁用
|
||||
*/
|
||||
private Long status;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 0=正常, 1=已删除
|
||||
*/
|
||||
@TableLogic
|
||||
private Long isDeleted;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
package com.hotwj.platform.config.course.domain.bo;
|
||||
|
||||
import com.hotwj.platform.config.course.domain.HotCourse;
|
||||
import io.github.linpeilie.annotations.AutoMapper;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.dromara.common.core.validate.EditGroup;
|
||||
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 课程库业务对象 hot_course
|
||||
*
|
||||
* @author shihongwei
|
||||
* @date 2025-12-23
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@AutoMapper(target = HotCourse.class, reverseConvertGenerate = false)
|
||||
public class HotCourseBo extends BaseEntity {
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@NotNull(message = "主键不能为空", groups = {EditGroup.class})
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 公司ID
|
||||
*/
|
||||
private Long companyId;
|
||||
|
||||
/**
|
||||
* 课程名称
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 教育类型字典编码
|
||||
*/
|
||||
private String trainingTypeCode;
|
||||
|
||||
/**
|
||||
* 教育类型子集编码集(JSON/逗号分隔)
|
||||
*/
|
||||
private String trainingSubtypeCodes;
|
||||
|
||||
/**
|
||||
* 课程描述
|
||||
*/
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 封面/预览图URL
|
||||
*/
|
||||
private String coverUrl;
|
||||
|
||||
/**
|
||||
* 课程文件URL(PDF/图片)
|
||||
*/
|
||||
private String materialUrl;
|
||||
|
||||
/**
|
||||
* 文件学习时长(秒)
|
||||
*/
|
||||
private Long learningDuration;
|
||||
|
||||
/**
|
||||
* 课时
|
||||
*/
|
||||
private BigDecimal classHours;
|
||||
|
||||
/**
|
||||
* 课程内容(富文本)
|
||||
*/
|
||||
private String content;
|
||||
|
||||
/**
|
||||
* 状态:1=启用 0=禁用
|
||||
*/
|
||||
private Long status;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 0=正常, 1=已删除
|
||||
*/
|
||||
private Long isDeleted;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
package com.hotwj.platform.config.course.domain.vo;
|
||||
|
||||
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import cn.idev.excel.annotation.ExcelProperty;
|
||||
import com.hotwj.platform.config.course.domain.HotCourse;
|
||||
import io.github.linpeilie.annotations.AutoMapper;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
|
||||
|
||||
/**
|
||||
* 课程库视图对象 hot_course
|
||||
*
|
||||
* @author shihongwei
|
||||
* @date 2025-12-23
|
||||
*/
|
||||
@Data
|
||||
@ExcelIgnoreUnannotated
|
||||
@AutoMapper(target = HotCourse.class)
|
||||
public class HotCourseVo implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@ExcelProperty(value = "主键")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 公司ID
|
||||
*/
|
||||
@ExcelProperty(value = "公司ID")
|
||||
private Long companyId;
|
||||
|
||||
/**
|
||||
* 课程名称
|
||||
*/
|
||||
@ExcelProperty(value = "课程名称")
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 教育类型字典编码
|
||||
*/
|
||||
@ExcelProperty(value = "教育类型字典编码")
|
||||
private String trainingTypeCode;
|
||||
|
||||
/**
|
||||
* 教育类型子集编码集(JSON/逗号分隔)
|
||||
*/
|
||||
@ExcelProperty(value = "教育类型子集编码集(JSON/逗号分隔)")
|
||||
private String trainingSubtypeCodes;
|
||||
|
||||
/**
|
||||
* 课程描述
|
||||
*/
|
||||
@ExcelProperty(value = "课程描述")
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 封面/预览图URL
|
||||
*/
|
||||
@ExcelProperty(value = "封面/预览图URL")
|
||||
private String coverUrl;
|
||||
|
||||
/**
|
||||
* 课程文件URL(PDF/图片)
|
||||
*/
|
||||
@ExcelProperty(value = "课程文件URL(PDF/图片)")
|
||||
private String materialUrl;
|
||||
|
||||
/**
|
||||
* 文件学习时长(秒)
|
||||
*/
|
||||
@ExcelProperty(value = "文件学习时长(秒)")
|
||||
private Long learningDuration;
|
||||
|
||||
/**
|
||||
* 课时
|
||||
*/
|
||||
@ExcelProperty(value = "课时")
|
||||
private BigDecimal classHours;
|
||||
|
||||
/**
|
||||
* 课程内容(富文本)
|
||||
*/
|
||||
@ExcelProperty(value = "课程内容(富文本)")
|
||||
private String content;
|
||||
|
||||
/**
|
||||
* 状态:1=启用 0=禁用
|
||||
*/
|
||||
@ExcelProperty(value = "状态:1=启用 0=禁用")
|
||||
private Long status;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
@ExcelProperty(value = "备注")
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 0=正常, 1=已删除
|
||||
*/
|
||||
@ExcelProperty(value = "0=正常, 1=已删除")
|
||||
private Long isDeleted;
|
||||
|
||||
private Date createTime;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.hotwj.platform.config.course.mapper;
|
||||
|
||||
import com.hotwj.platform.config.course.domain.HotCourse;
|
||||
import com.hotwj.platform.config.course.domain.vo.HotCourseVo;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
|
||||
|
||||
/**
|
||||
* 课程库Mapper接口
|
||||
*
|
||||
* @author shihongwei
|
||||
* @date 2025-12-23
|
||||
*/
|
||||
@Mapper
|
||||
public interface HotCourseMapper extends BaseMapperPlus<HotCourse, HotCourseVo> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package com.hotwj.platform.config.course.service;
|
||||
|
||||
import com.hotwj.platform.config.course.domain.bo.HotCourseBo;
|
||||
import com.hotwj.platform.config.course.domain.vo.HotCourseVo;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 课程库Service接口
|
||||
*
|
||||
* @author shihongwei
|
||||
* @date 2025-12-23
|
||||
*/
|
||||
public interface IHotCourseService {
|
||||
|
||||
/**
|
||||
* 查询课程库
|
||||
*
|
||||
* @param id 主键
|
||||
* @return 课程库
|
||||
*/
|
||||
HotCourseVo queryById(Long id);
|
||||
|
||||
/**
|
||||
* 分页查询课程库列表
|
||||
*
|
||||
* @param bo 查询条件
|
||||
* @param pageQuery 分页参数
|
||||
* @return 课程库分页列表
|
||||
*/
|
||||
TableDataInfo<HotCourseVo> queryPageList(HotCourseBo bo, PageQuery pageQuery);
|
||||
|
||||
/**
|
||||
* 查询符合条件的课程库列表
|
||||
*
|
||||
* @param bo 查询条件
|
||||
* @return 课程库列表
|
||||
*/
|
||||
List<HotCourseVo> queryList(HotCourseBo bo);
|
||||
|
||||
/**
|
||||
* 新增课程库
|
||||
*
|
||||
* @param bo 课程库
|
||||
* @return 是否新增成功
|
||||
*/
|
||||
Boolean insertByBo(HotCourseBo bo);
|
||||
|
||||
/**
|
||||
* 修改课程库
|
||||
*
|
||||
* @param bo 课程库
|
||||
* @return 是否修改成功
|
||||
*/
|
||||
Boolean updateByBo(HotCourseBo bo);
|
||||
|
||||
/**
|
||||
* 校验并批量删除课程库信息
|
||||
*
|
||||
* @param ids 待删除的主键集合
|
||||
* @param isValid 是否进行有效性校验
|
||||
* @return 是否删除成功
|
||||
*/
|
||||
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
package com.hotwj.platform.config.course.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.hotwj.platform.config.course.domain.HotCourse;
|
||||
import com.hotwj.platform.config.course.domain.bo.HotCourseBo;
|
||||
import com.hotwj.platform.config.course.domain.vo.HotCourseVo;
|
||||
import com.hotwj.platform.config.course.mapper.HotCourseMapper;
|
||||
import com.hotwj.platform.config.course.service.IHotCourseService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.common.core.utils.MapstructUtils;
|
||||
import org.dromara.common.core.utils.StringUtils;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 课程库Service业务层处理
|
||||
*
|
||||
* @author shihongwei
|
||||
* @date 2025-12-23
|
||||
*/
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
@Service
|
||||
public class HotCourseServiceImpl implements IHotCourseService {
|
||||
|
||||
private final HotCourseMapper baseMapper;
|
||||
|
||||
/**
|
||||
* 查询课程库
|
||||
*
|
||||
* @param id 主键
|
||||
* @return 课程库
|
||||
*/
|
||||
@Override
|
||||
public HotCourseVo queryById(Long id) {
|
||||
return baseMapper.selectVoById(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询课程库列表
|
||||
*
|
||||
* @param bo 查询条件
|
||||
* @param pageQuery 分页参数
|
||||
* @return 课程库分页列表
|
||||
*/
|
||||
@Override
|
||||
public TableDataInfo<HotCourseVo> queryPageList(HotCourseBo bo, PageQuery pageQuery) {
|
||||
LambdaQueryWrapper<HotCourse> lqw = buildQueryWrapper(bo);
|
||||
Page<HotCourseVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
|
||||
return TableDataInfo.build(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询符合条件的课程库列表
|
||||
*
|
||||
* @param bo 查询条件
|
||||
* @return 课程库列表
|
||||
*/
|
||||
@Override
|
||||
public List<HotCourseVo> queryList(HotCourseBo bo) {
|
||||
LambdaQueryWrapper<HotCourse> lqw = buildQueryWrapper(bo);
|
||||
return baseMapper.selectVoList(lqw);
|
||||
}
|
||||
|
||||
private LambdaQueryWrapper<HotCourse> buildQueryWrapper(HotCourseBo bo) {
|
||||
Map<String, Object> params = bo.getParams();
|
||||
LambdaQueryWrapper<HotCourse> lqw = Wrappers.lambdaQuery();
|
||||
lqw.orderByAsc(HotCourse::getId);
|
||||
lqw.eq(bo.getCompanyId() != null, HotCourse::getCompanyId, bo.getCompanyId());
|
||||
lqw.like(StringUtils.isNotBlank(bo.getName()), HotCourse::getName, bo.getName());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getTrainingTypeCode()), HotCourse::getTrainingTypeCode, bo.getTrainingTypeCode());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getTrainingSubtypeCodes()), HotCourse::getTrainingSubtypeCodes, bo.getTrainingSubtypeCodes());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getDescription()), HotCourse::getDescription, bo.getDescription());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getCoverUrl()), HotCourse::getCoverUrl, bo.getCoverUrl());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getMaterialUrl()), HotCourse::getMaterialUrl, bo.getMaterialUrl());
|
||||
lqw.eq(bo.getLearningDuration() != null, HotCourse::getLearningDuration, bo.getLearningDuration());
|
||||
lqw.eq(bo.getClassHours() != null, HotCourse::getClassHours, bo.getClassHours());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getContent()), HotCourse::getContent, bo.getContent());
|
||||
lqw.eq(bo.getStatus() != null, HotCourse::getStatus, bo.getStatus());
|
||||
lqw.eq(bo.getIsDeleted() != null, HotCourse::getIsDeleted, bo.getIsDeleted());
|
||||
lqw.between(params.get("beginTime") != null && params.get("endTime") != null,
|
||||
HotCourse::getCreateTime, params.get("beginTime"), params.get("endTime"));
|
||||
return lqw;
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增课程库
|
||||
*
|
||||
* @param bo 课程库
|
||||
* @return 是否新增成功
|
||||
*/
|
||||
@Override
|
||||
public Boolean insertByBo(HotCourseBo bo) {
|
||||
HotCourse add = MapstructUtils.convert(bo, HotCourse.class);
|
||||
validEntityBeforeSave(add);
|
||||
boolean flag = baseMapper.insert(add) > 0;
|
||||
if (flag) {
|
||||
bo.setId(add.getId());
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改课程库
|
||||
*
|
||||
* @param bo 课程库
|
||||
* @return 是否修改成功
|
||||
*/
|
||||
@Override
|
||||
public Boolean updateByBo(HotCourseBo bo) {
|
||||
HotCourse update = MapstructUtils.convert(bo, HotCourse.class);
|
||||
validEntityBeforeSave(update);
|
||||
return baseMapper.updateById(update) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存前的数据校验
|
||||
*/
|
||||
private void validEntityBeforeSave(HotCourse entity) {
|
||||
//TODO 做一些数据校验,如唯一约束
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验并批量删除课程库信息
|
||||
*
|
||||
* @param ids 待删除的主键集合
|
||||
* @param isValid 是否进行有效性校验
|
||||
* @return 是否删除成功
|
||||
*/
|
||||
@Override
|
||||
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
|
||||
if (isValid) {
|
||||
//TODO 做一些业务上的校验,判断是否需要校验
|
||||
}
|
||||
return baseMapper.deleteByIds(ids) > 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
package com.hotwj.platform.config.courseResource.controller;
|
||||
|
||||
import com.hotwj.platform.config.courseResource.domain.bo.HotCourseResourceBo;
|
||||
import com.hotwj.platform.config.courseResource.domain.vo.HotCourseResourceVo;
|
||||
import com.hotwj.platform.config.courseResource.service.IHotCourseResourceService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.dromara.common.core.domain.R;
|
||||
import org.dromara.common.core.validate.AddGroup;
|
||||
import org.dromara.common.core.validate.EditGroup;
|
||||
import org.dromara.common.excel.utils.ExcelUtil;
|
||||
import org.dromara.common.idempotent.annotation.RepeatSubmit;
|
||||
import org.dromara.common.log.annotation.Log;
|
||||
import org.dromara.common.log.enums.BusinessType;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.dromara.common.web.core.BaseController;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 课程-资源关联
|
||||
*
|
||||
* @author shihongwei
|
||||
* @date 2025-12-23
|
||||
*/
|
||||
@Validated
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/config/courseResource")
|
||||
@Tag(name = "课程-资源关联", description = "课程-资源关联管理")
|
||||
public class HotCourseResourceController extends BaseController {
|
||||
|
||||
private final IHotCourseResourceService hotCourseResourceService;
|
||||
|
||||
/**
|
||||
* 查询课程-资源关联列表
|
||||
*/
|
||||
//@SaCheckPermission("config:courseResource:list")
|
||||
@GetMapping("/list")
|
||||
@Operation(summary = "分页查询课程-资源关联列表")
|
||||
public TableDataInfo<HotCourseResourceVo> list(HotCourseResourceBo bo, PageQuery pageQuery) {
|
||||
return hotCourseResourceService.queryPageList(bo, pageQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出课程-资源关联列表
|
||||
*/
|
||||
//@SaCheckPermission("config:courseResource:export")
|
||||
@Log(title = "课程-资源关联", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/export")
|
||||
@Operation(summary = "导出课程-资源关联列表")
|
||||
public void export(HotCourseResourceBo bo, HttpServletResponse response) {
|
||||
List<HotCourseResourceVo> list = hotCourseResourceService.queryList(bo);
|
||||
ExcelUtil.exportExcel(list, "课程-资源关联", HotCourseResourceVo.class, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取课程-资源关联详细信息
|
||||
*
|
||||
* @param id 主键
|
||||
*/
|
||||
//@SaCheckPermission("config:courseResource:query")
|
||||
@GetMapping("/{id}")
|
||||
@Operation(summary = "获取课程-资源关联详细信息")
|
||||
public R<HotCourseResourceVo> getInfo(@NotNull(message = "主键不能为空")
|
||||
@Parameter(name = "id", description = "主键", required = true, example = "1")
|
||||
@PathVariable Long id) {
|
||||
return R.ok(hotCourseResourceService.queryById(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增课程-资源关联
|
||||
*/
|
||||
//@SaCheckPermission("config:courseResource:add")
|
||||
@Log(title = "课程-资源关联", businessType = BusinessType.INSERT)
|
||||
@RepeatSubmit()
|
||||
@PostMapping()
|
||||
@Operation(summary = "新增课程-资源关联")
|
||||
public R<Void> add(@Validated(AddGroup.class) @RequestBody HotCourseResourceBo bo) {
|
||||
return toAjax(hotCourseResourceService.insertByBo(bo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改课程-资源关联
|
||||
*/
|
||||
//@SaCheckPermission("config:courseResource:edit")
|
||||
@Log(title = "课程-资源关联", businessType = BusinessType.UPDATE)
|
||||
@RepeatSubmit()
|
||||
@PutMapping()
|
||||
@Operation(summary = "修改课程-资源关联")
|
||||
public R<Void> edit(@Validated(EditGroup.class) @RequestBody HotCourseResourceBo bo) {
|
||||
return toAjax(hotCourseResourceService.updateByBo(bo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除课程-资源关联
|
||||
*
|
||||
* @param ids 主键串
|
||||
*/
|
||||
//@SaCheckPermission("config:courseResource:remove")
|
||||
@Log(title = "课程-资源关联", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{ids}")
|
||||
@Operation(summary = "删除课程-资源关联")
|
||||
public R<Void> remove(@NotEmpty(message = "主键不能为空")
|
||||
@Parameter(name = "ids", description = "主键串", required = true, example = "1,2,3")
|
||||
@PathVariable Long[] ids) {
|
||||
return toAjax(hotCourseResourceService.deleteWithValidByIds(List.of(ids), true));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package com.hotwj.platform.config.courseResource.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
||||
|
||||
import java.io.Serial;
|
||||
|
||||
/**
|
||||
* 课程-资源关联对象 hot_course_resource
|
||||
*
|
||||
* @author shihongwei
|
||||
* @date 2025-12-23
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("hot_course_resource")
|
||||
public class HotCourseResource extends BaseEntity {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@TableId(value = "id")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 公司ID
|
||||
*/
|
||||
private Long companyId;
|
||||
|
||||
/**
|
||||
* 课程ID
|
||||
*/
|
||||
private Long courseId;
|
||||
|
||||
/**
|
||||
* 资源类型:1=视频 2=音频 3=题目
|
||||
*/
|
||||
private Long resourceType;
|
||||
|
||||
/**
|
||||
* 资源ID(根据类型关联不同表)
|
||||
*/
|
||||
private Long resourceId;
|
||||
|
||||
/**
|
||||
* 排序值
|
||||
*/
|
||||
private Long sortOrder;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package com.hotwj.platform.config.courseResource.domain.bo;
|
||||
|
||||
import com.hotwj.platform.config.courseResource.domain.HotCourseResource;
|
||||
import io.github.linpeilie.annotations.AutoMapper;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.dromara.common.core.validate.AddGroup;
|
||||
import org.dromara.common.core.validate.EditGroup;
|
||||
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
||||
|
||||
/**
|
||||
* 课程-资源关联业务对象 hot_course_resource
|
||||
*
|
||||
* @author shihongwei
|
||||
* @date 2025-12-23
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@AutoMapper(target = HotCourseResource.class, reverseConvertGenerate = false)
|
||||
public class HotCourseResourceBo extends BaseEntity {
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@NotNull(message = "主键不能为空", groups = {EditGroup.class})
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 公司ID
|
||||
*/
|
||||
private Long companyId;
|
||||
|
||||
/**
|
||||
* 课程ID
|
||||
*/
|
||||
@NotNull(message = "课程ID不能为空", groups = {AddGroup.class, EditGroup.class})
|
||||
private Long courseId;
|
||||
|
||||
/**
|
||||
* 资源类型:1=视频 2=音频 3=题目
|
||||
*/
|
||||
@NotNull(message = "资源类型:1=视频 2=音频 3=题目不能为空", groups = {AddGroup.class, EditGroup.class})
|
||||
private Long resourceType;
|
||||
|
||||
/**
|
||||
* 资源ID(根据类型关联不同表)
|
||||
*/
|
||||
@NotNull(message = "资源ID(根据类型关联不同表)不能为空", groups = {AddGroup.class, EditGroup.class})
|
||||
private Long resourceId;
|
||||
|
||||
/**
|
||||
* 排序值
|
||||
*/
|
||||
private Long sortOrder;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package com.hotwj.platform.config.courseResource.domain.vo;
|
||||
|
||||
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import cn.idev.excel.annotation.ExcelProperty;
|
||||
import com.hotwj.platform.config.courseResource.domain.HotCourseResource;
|
||||
import io.github.linpeilie.annotations.AutoMapper;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
|
||||
/**
|
||||
* 课程-资源关联视图对象 hot_course_resource
|
||||
*
|
||||
* @author shihongwei
|
||||
* @date 2025-12-23
|
||||
*/
|
||||
@Data
|
||||
@ExcelIgnoreUnannotated
|
||||
@AutoMapper(target = HotCourseResource.class)
|
||||
public class HotCourseResourceVo implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@ExcelProperty(value = "主键")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 公司ID
|
||||
*/
|
||||
@ExcelProperty(value = "公司ID")
|
||||
private Long companyId;
|
||||
|
||||
/**
|
||||
* 课程ID
|
||||
*/
|
||||
@ExcelProperty(value = "课程ID")
|
||||
private Long courseId;
|
||||
|
||||
/**
|
||||
* 资源类型:1=视频 2=音频 3=题目
|
||||
*/
|
||||
@ExcelProperty(value = "资源类型:1=视频 2=音频 3=题目")
|
||||
private Long resourceType;
|
||||
|
||||
/**
|
||||
* 资源ID(根据类型关联不同表)
|
||||
*/
|
||||
@ExcelProperty(value = "资源ID(根据类型关联不同表)")
|
||||
private Long resourceId;
|
||||
|
||||
/**
|
||||
* 排序值
|
||||
*/
|
||||
@ExcelProperty(value = "排序值")
|
||||
private Long sortOrder;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.hotwj.platform.config.courseResource.mapper;
|
||||
|
||||
import com.hotwj.platform.config.courseResource.domain.HotCourseResource;
|
||||
import com.hotwj.platform.config.courseResource.domain.vo.HotCourseResourceVo;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
|
||||
|
||||
/**
|
||||
* 课程-资源关联Mapper接口
|
||||
*
|
||||
* @author shihongwei
|
||||
* @date 2025-12-23
|
||||
*/
|
||||
@Mapper
|
||||
public interface HotCourseResourceMapper extends BaseMapperPlus<HotCourseResource, HotCourseResourceVo> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package com.hotwj.platform.config.courseResource.service;
|
||||
|
||||
import com.hotwj.platform.config.courseResource.domain.bo.HotCourseResourceBo;
|
||||
import com.hotwj.platform.config.courseResource.domain.vo.HotCourseResourceVo;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 课程-资源关联Service接口
|
||||
*
|
||||
* @author shihongwei
|
||||
* @date 2025-12-23
|
||||
*/
|
||||
public interface IHotCourseResourceService {
|
||||
|
||||
/**
|
||||
* 查询课程-资源关联
|
||||
*
|
||||
* @param id 主键
|
||||
* @return 课程-资源关联
|
||||
*/
|
||||
HotCourseResourceVo queryById(Long id);
|
||||
|
||||
/**
|
||||
* 分页查询课程-资源关联列表
|
||||
*
|
||||
* @param bo 查询条件
|
||||
* @param pageQuery 分页参数
|
||||
* @return 课程-资源关联分页列表
|
||||
*/
|
||||
TableDataInfo<HotCourseResourceVo> queryPageList(HotCourseResourceBo bo, PageQuery pageQuery);
|
||||
|
||||
/**
|
||||
* 查询符合条件的课程-资源关联列表
|
||||
*
|
||||
* @param bo 查询条件
|
||||
* @return 课程-资源关联列表
|
||||
*/
|
||||
List<HotCourseResourceVo> queryList(HotCourseResourceBo bo);
|
||||
|
||||
/**
|
||||
* 新增课程-资源关联
|
||||
*
|
||||
* @param bo 课程-资源关联
|
||||
* @return 是否新增成功
|
||||
*/
|
||||
Boolean insertByBo(HotCourseResourceBo bo);
|
||||
|
||||
/**
|
||||
* 修改课程-资源关联
|
||||
*
|
||||
* @param bo 课程-资源关联
|
||||
* @return 是否修改成功
|
||||
*/
|
||||
Boolean updateByBo(HotCourseResourceBo bo);
|
||||
|
||||
/**
|
||||
* 校验并批量删除课程-资源关联信息
|
||||
*
|
||||
* @param ids 待删除的主键集合
|
||||
* @param isValid 是否进行有效性校验
|
||||
* @return 是否删除成功
|
||||
*/
|
||||
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
package com.hotwj.platform.config.courseResource.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.hotwj.platform.config.courseResource.domain.HotCourseResource;
|
||||
import com.hotwj.platform.config.courseResource.domain.bo.HotCourseResourceBo;
|
||||
import com.hotwj.platform.config.courseResource.domain.vo.HotCourseResourceVo;
|
||||
import com.hotwj.platform.config.courseResource.mapper.HotCourseResourceMapper;
|
||||
import com.hotwj.platform.config.courseResource.service.IHotCourseResourceService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.common.core.utils.MapstructUtils;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 课程-资源关联Service业务层处理
|
||||
*
|
||||
* @author shihongwei
|
||||
* @date 2025-12-23
|
||||
*/
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
@Service
|
||||
public class HotCourseResourceServiceImpl implements IHotCourseResourceService {
|
||||
|
||||
private final HotCourseResourceMapper baseMapper;
|
||||
|
||||
/**
|
||||
* 查询课程-资源关联
|
||||
*
|
||||
* @param id 主键
|
||||
* @return 课程-资源关联
|
||||
*/
|
||||
@Override
|
||||
public HotCourseResourceVo queryById(Long id) {
|
||||
return baseMapper.selectVoById(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询课程-资源关联列表
|
||||
*
|
||||
* @param bo 查询条件
|
||||
* @param pageQuery 分页参数
|
||||
* @return 课程-资源关联分页列表
|
||||
*/
|
||||
@Override
|
||||
public TableDataInfo<HotCourseResourceVo> queryPageList(HotCourseResourceBo bo, PageQuery pageQuery) {
|
||||
LambdaQueryWrapper<HotCourseResource> lqw = buildQueryWrapper(bo);
|
||||
Page<HotCourseResourceVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
|
||||
return TableDataInfo.build(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询符合条件的课程-资源关联列表
|
||||
*
|
||||
* @param bo 查询条件
|
||||
* @return 课程-资源关联列表
|
||||
*/
|
||||
@Override
|
||||
public List<HotCourseResourceVo> queryList(HotCourseResourceBo bo) {
|
||||
LambdaQueryWrapper<HotCourseResource> lqw = buildQueryWrapper(bo);
|
||||
return baseMapper.selectVoList(lqw);
|
||||
}
|
||||
|
||||
private LambdaQueryWrapper<HotCourseResource> buildQueryWrapper(HotCourseResourceBo bo) {
|
||||
Map<String, Object> params = bo.getParams();
|
||||
LambdaQueryWrapper<HotCourseResource> lqw = Wrappers.lambdaQuery();
|
||||
lqw.orderByAsc(HotCourseResource::getId);
|
||||
lqw.eq(bo.getCompanyId() != null, HotCourseResource::getCompanyId, bo.getCompanyId());
|
||||
lqw.eq(bo.getCourseId() != null, HotCourseResource::getCourseId, bo.getCourseId());
|
||||
lqw.eq(bo.getResourceType() != null, HotCourseResource::getResourceType, bo.getResourceType());
|
||||
lqw.eq(bo.getResourceId() != null, HotCourseResource::getResourceId, bo.getResourceId());
|
||||
lqw.eq(bo.getSortOrder() != null, HotCourseResource::getSortOrder, bo.getSortOrder());
|
||||
return lqw;
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增课程-资源关联
|
||||
*
|
||||
* @param bo 课程-资源关联
|
||||
* @return 是否新增成功
|
||||
*/
|
||||
@Override
|
||||
public Boolean insertByBo(HotCourseResourceBo bo) {
|
||||
HotCourseResource add = MapstructUtils.convert(bo, HotCourseResource.class);
|
||||
validEntityBeforeSave(add);
|
||||
boolean flag = baseMapper.insert(add) > 0;
|
||||
if (flag) {
|
||||
bo.setId(add.getId());
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改课程-资源关联
|
||||
*
|
||||
* @param bo 课程-资源关联
|
||||
* @return 是否修改成功
|
||||
*/
|
||||
@Override
|
||||
public Boolean updateByBo(HotCourseResourceBo bo) {
|
||||
HotCourseResource update = MapstructUtils.convert(bo, HotCourseResource.class);
|
||||
validEntityBeforeSave(update);
|
||||
return baseMapper.updateById(update) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存前的数据校验
|
||||
*/
|
||||
private void validEntityBeforeSave(HotCourseResource entity) {
|
||||
//TODO 做一些数据校验,如唯一约束
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验并批量删除课程-资源关联信息
|
||||
*
|
||||
* @param ids 待删除的主键集合
|
||||
* @param isValid 是否进行有效性校验
|
||||
* @return 是否删除成功
|
||||
*/
|
||||
@Override
|
||||
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
|
||||
if (isValid) {
|
||||
//TODO 做一些业务上的校验,判断是否需要校验
|
||||
}
|
||||
return baseMapper.deleteByIds(ids) > 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
package com.hotwj.platform.config.dispatchTemplate.controller;
|
||||
|
||||
import com.hotwj.platform.config.dispatchTemplate.domain.bo.HotDispatchTemplateBo;
|
||||
import com.hotwj.platform.config.dispatchTemplate.domain.vo.HotDispatchTemplateVo;
|
||||
import com.hotwj.platform.config.dispatchTemplate.service.IHotDispatchTemplateService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.dromara.common.core.domain.R;
|
||||
import org.dromara.common.core.validate.AddGroup;
|
||||
import org.dromara.common.core.validate.EditGroup;
|
||||
import org.dromara.common.excel.utils.ExcelUtil;
|
||||
import org.dromara.common.idempotent.annotation.RepeatSubmit;
|
||||
import org.dromara.common.log.annotation.Log;
|
||||
import org.dromara.common.log.enums.BusinessType;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.dromara.common.web.core.BaseController;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 下发模板
|
||||
*
|
||||
* @author shihongwei
|
||||
* @date 2026-02-15
|
||||
*/
|
||||
@Validated
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/config/dispatchTemplate")
|
||||
@Tag(name = "下发模板", description = "下发模板管理")
|
||||
public class HotDispatchTemplateController extends BaseController {
|
||||
|
||||
private final IHotDispatchTemplateService hotDispatchTemplateService;
|
||||
|
||||
/**
|
||||
* 查询下发模板列表
|
||||
*/
|
||||
//@SaCheckPermission("config:dispatchTemplate:list")
|
||||
@GetMapping("/list")
|
||||
@Operation(summary = "分页查询下发模板列表")
|
||||
public TableDataInfo<HotDispatchTemplateVo> list(HotDispatchTemplateBo bo, PageQuery pageQuery) {
|
||||
return hotDispatchTemplateService.queryPageList(bo, pageQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出下发模板列表
|
||||
*/
|
||||
//@SaCheckPermission("config:dispatchTemplate:export")
|
||||
@Log(title = "下发模板", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/export")
|
||||
@Operation(summary = "导出下发模板列表")
|
||||
public void export(HotDispatchTemplateBo bo, HttpServletResponse response) {
|
||||
List<HotDispatchTemplateVo> list = hotDispatchTemplateService.queryList(bo);
|
||||
ExcelUtil.exportExcel(list, "下发模板", HotDispatchTemplateVo.class, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取下发模板详细信息
|
||||
*
|
||||
* @param id 主键
|
||||
*/
|
||||
//@SaCheckPermission("config:dispatchTemplate:query")
|
||||
@GetMapping("/{id}")
|
||||
@Operation(summary = "获取下发模板详细信息")
|
||||
public R<HotDispatchTemplateVo> getInfo(@NotNull(message = "主键不能为空")
|
||||
@Parameter(name = "id", description = "主键", required = true, example = "1")
|
||||
@PathVariable Long id) {
|
||||
return R.ok(hotDispatchTemplateService.queryById(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增下发模板
|
||||
*/
|
||||
//@SaCheckPermission("config:dispatchTemplate:add")
|
||||
@Log(title = "下发模板", businessType = BusinessType.INSERT)
|
||||
@RepeatSubmit()
|
||||
@PostMapping()
|
||||
@Operation(summary = "新增下发模板")
|
||||
public R<Void> add(@Validated(AddGroup.class) @RequestBody HotDispatchTemplateBo bo) {
|
||||
return toAjax(hotDispatchTemplateService.insertByBo(bo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改下发模板
|
||||
*/
|
||||
//@SaCheckPermission("config:dispatchTemplate:edit")
|
||||
@Log(title = "下发模板", businessType = BusinessType.UPDATE)
|
||||
@RepeatSubmit()
|
||||
@PutMapping()
|
||||
@Operation(summary = "修改下发模板")
|
||||
public R<Void> edit(@Validated(EditGroup.class) @RequestBody HotDispatchTemplateBo bo) {
|
||||
return toAjax(hotDispatchTemplateService.updateByBo(bo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除下发模板
|
||||
*
|
||||
* @param ids 主键串
|
||||
*/
|
||||
//@SaCheckPermission("config:dispatchTemplate:remove")
|
||||
@Log(title = "下发模板", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{ids}")
|
||||
@Operation(summary = "删除下发模板")
|
||||
public R<Void> remove(@NotEmpty(message = "主键不能为空")
|
||||
@Parameter(name = "ids", description = "主键串", required = true, example = "1,2,3")
|
||||
@PathVariable Long[] ids) {
|
||||
return toAjax(hotDispatchTemplateService.deleteWithValidByIds(List.of(ids), true));
|
||||
}
|
||||
|
||||
@Log(title = "下发模板", businessType = BusinessType.INSERT)
|
||||
@RepeatSubmit()
|
||||
@PostMapping("/useDefault")
|
||||
@Operation(summary = "采用默认配置")
|
||||
public R<Void> useDefault() {
|
||||
return toAjax(hotDispatchTemplateService.useDefault());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package com.hotwj.platform.config.dispatchTemplate.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
||||
|
||||
import java.io.Serial;
|
||||
|
||||
/**
|
||||
* 下发模板对象 hot_dispatch_template
|
||||
*
|
||||
* @author shihongwei
|
||||
* @date 2026-02-15
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("hot_dispatch_template")
|
||||
public class HotDispatchTemplate extends BaseEntity {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@TableId(value = "id")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 公司ID(由应用层保证必填)
|
||||
*/
|
||||
private Long companyId;
|
||||
|
||||
/**
|
||||
* 模板名称
|
||||
*/
|
||||
private String templateName;
|
||||
|
||||
/**
|
||||
* 模板类型(字典)
|
||||
*/
|
||||
private String templateType;
|
||||
|
||||
/**
|
||||
* 样式图OSS附件ID
|
||||
*/
|
||||
private String styleOssId;
|
||||
|
||||
/**
|
||||
* 内容(富文本)
|
||||
*/
|
||||
private String content;
|
||||
|
||||
/**
|
||||
* 0=正常, 1=已删除
|
||||
*/
|
||||
@TableLogic
|
||||
private Long isDeleted;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package com.hotwj.platform.config.dispatchTemplate.domain.bo;
|
||||
|
||||
import com.hotwj.platform.config.dispatchTemplate.domain.HotDispatchTemplate;
|
||||
import io.github.linpeilie.annotations.AutoMapper;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.dromara.common.core.validate.EditGroup;
|
||||
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
||||
|
||||
/**
|
||||
* 下发模板业务对象 hot_dispatch_template
|
||||
*
|
||||
* @author shihongwei
|
||||
* @date 2026-02-15
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@AutoMapper(target = HotDispatchTemplate.class, reverseConvertGenerate = false)
|
||||
public class HotDispatchTemplateBo extends BaseEntity {
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@NotNull(message = "主键不能为空", groups = {EditGroup.class})
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 公司ID(由应用层保证必填)
|
||||
*/
|
||||
private Long companyId;
|
||||
|
||||
/**
|
||||
* 模板名称
|
||||
*/
|
||||
private String templateName;
|
||||
|
||||
/**
|
||||
* 模板类型(字典)
|
||||
*/
|
||||
private String templateType;
|
||||
|
||||
/**
|
||||
* 样式图OSS附件ID
|
||||
*/
|
||||
private String styleOssId;
|
||||
|
||||
/**
|
||||
* 内容(富文本)
|
||||
*/
|
||||
private String content;
|
||||
|
||||
/**
|
||||
* 0=正常, 1=已删除
|
||||
*/
|
||||
private Long isDeleted;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
package com.hotwj.platform.config.dispatchTemplate.domain.vo;
|
||||
|
||||
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import cn.idev.excel.annotation.ExcelProperty;
|
||||
import com.hotwj.platform.config.dispatchTemplate.domain.HotDispatchTemplate;
|
||||
import io.github.linpeilie.annotations.AutoMapper;
|
||||
import lombok.Data;
|
||||
import org.dromara.common.excel.annotation.ExcelDictFormat;
|
||||
import org.dromara.common.excel.convert.ExcelDictConvert;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
|
||||
/**
|
||||
* 下发模板视图对象 hot_dispatch_template
|
||||
*
|
||||
* @author shihongwei
|
||||
* @date 2026-02-15
|
||||
*/
|
||||
@Data
|
||||
@ExcelIgnoreUnannotated
|
||||
@AutoMapper(target = HotDispatchTemplate.class)
|
||||
public class HotDispatchTemplateVo implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@ExcelProperty(value = "主键")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 公司ID(由应用层保证必填)
|
||||
*/
|
||||
@ExcelProperty(value = "公司ID", converter = ExcelDictConvert.class)
|
||||
@ExcelDictFormat(readConverterExp = "由=应用层保证必填")
|
||||
private Long companyId;
|
||||
|
||||
/**
|
||||
* 模板名称
|
||||
*/
|
||||
@ExcelProperty(value = "模板名称")
|
||||
private String templateName;
|
||||
|
||||
/**
|
||||
* 模板类型(字典)
|
||||
*/
|
||||
@ExcelProperty(value = "模板类型", converter = ExcelDictConvert.class)
|
||||
@ExcelDictFormat(readConverterExp = "字=典")
|
||||
private String templateType;
|
||||
|
||||
/**
|
||||
* 样式图OSS附件ID
|
||||
*/
|
||||
@ExcelProperty(value = "样式图OSS附件ID")
|
||||
private String styleOssId;
|
||||
|
||||
/**
|
||||
* 内容(富文本)
|
||||
*/
|
||||
@ExcelProperty(value = "内容", converter = ExcelDictConvert.class)
|
||||
@ExcelDictFormat(readConverterExp = "富=文本")
|
||||
private String content;
|
||||
|
||||
/**
|
||||
* 创建者姓名
|
||||
*/
|
||||
@ExcelProperty(value = "创建者姓名")
|
||||
private String createByName;
|
||||
|
||||
/**
|
||||
* 更新者姓名
|
||||
*/
|
||||
@ExcelProperty(value = "更新者姓名")
|
||||
private String updateByName;
|
||||
|
||||
/**
|
||||
* 0=正常, 1=已删除
|
||||
*/
|
||||
@ExcelProperty(value = "0=正常, 1=已删除")
|
||||
private Long isDeleted;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.hotwj.platform.config.dispatchTemplate.mapper;
|
||||
|
||||
import com.hotwj.platform.config.dispatchTemplate.domain.HotDispatchTemplate;
|
||||
import com.hotwj.platform.config.dispatchTemplate.domain.vo.HotDispatchTemplateVo;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
|
||||
|
||||
/**
|
||||
* 下发模板Mapper接口
|
||||
*
|
||||
* @author shihongwei
|
||||
* @date 2026-02-15
|
||||
*/
|
||||
@Mapper
|
||||
public interface HotDispatchTemplateMapper extends BaseMapperPlus<HotDispatchTemplate, HotDispatchTemplateVo> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
package com.hotwj.platform.config.dispatchTemplate.service;
|
||||
|
||||
import com.hotwj.platform.config.dispatchTemplate.domain.bo.HotDispatchTemplateBo;
|
||||
import com.hotwj.platform.config.dispatchTemplate.domain.vo.HotDispatchTemplateVo;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 下发模板Service接口
|
||||
*
|
||||
* @author shihongwei
|
||||
* @date 2026-02-15
|
||||
*/
|
||||
public interface IHotDispatchTemplateService {
|
||||
|
||||
/**
|
||||
* 查询下发模板
|
||||
*
|
||||
* @param id 主键
|
||||
* @return 下发模板
|
||||
*/
|
||||
HotDispatchTemplateVo queryById(Long id);
|
||||
|
||||
/**
|
||||
* 分页查询下发模板列表
|
||||
*
|
||||
* @param bo 查询条件
|
||||
* @param pageQuery 分页参数
|
||||
* @return 下发模板分页列表
|
||||
*/
|
||||
TableDataInfo<HotDispatchTemplateVo> queryPageList(HotDispatchTemplateBo bo, PageQuery pageQuery);
|
||||
|
||||
/**
|
||||
* 查询符合条件的下发模板列表
|
||||
*
|
||||
* @param bo 查询条件
|
||||
* @return 下发模板列表
|
||||
*/
|
||||
List<HotDispatchTemplateVo> queryList(HotDispatchTemplateBo bo);
|
||||
|
||||
/**
|
||||
* 新增下发模板
|
||||
*
|
||||
* @param bo 下发模板
|
||||
* @return 是否新增成功
|
||||
*/
|
||||
Boolean insertByBo(HotDispatchTemplateBo bo);
|
||||
|
||||
/**
|
||||
* 修改下发模板
|
||||
*
|
||||
* @param bo 下发模板
|
||||
* @return 是否修改成功
|
||||
*/
|
||||
Boolean updateByBo(HotDispatchTemplateBo bo);
|
||||
|
||||
/**
|
||||
* 校验并批量删除下发模板信息
|
||||
*
|
||||
* @param ids 待删除的主键集合
|
||||
* @param isValid 是否进行有效性校验
|
||||
* @return 是否删除成功
|
||||
*/
|
||||
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
|
||||
|
||||
Boolean useDefault();
|
||||
}
|
||||
@@ -0,0 +1,186 @@
|
||||
package com.hotwj.platform.config.dispatchTemplate.service.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.hotwj.platform.config.dispatchTemplate.domain.HotDispatchTemplate;
|
||||
import com.hotwj.platform.config.dispatchTemplate.domain.bo.HotDispatchTemplateBo;
|
||||
import com.hotwj.platform.config.dispatchTemplate.domain.vo.HotDispatchTemplateVo;
|
||||
import com.hotwj.platform.config.dispatchTemplate.mapper.HotDispatchTemplateMapper;
|
||||
import com.hotwj.platform.config.dispatchTemplate.service.IHotDispatchTemplateService;
|
||||
import com.hotwj.platform.resourceManagement.company.domain.vo.SysCompanyVo;
|
||||
import com.hotwj.platform.resourceManagement.company.service.ISysCompanyService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.common.core.exception.ServiceException;
|
||||
import org.dromara.common.core.utils.MapstructUtils;
|
||||
import org.dromara.common.core.utils.StringUtils;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.dromara.common.satoken.utils.LoginHelper;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 下发模板Service业务层处理
|
||||
*
|
||||
* @author shihongwei
|
||||
* @date 2026-02-15
|
||||
*/
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
@Service
|
||||
public class HotDispatchTemplateServiceImpl implements IHotDispatchTemplateService {
|
||||
|
||||
private final HotDispatchTemplateMapper baseMapper;
|
||||
private final ISysCompanyService sysCompanyService;
|
||||
|
||||
/**
|
||||
* 查询下发模板
|
||||
*
|
||||
* @param id 主键
|
||||
* @return 下发模板
|
||||
*/
|
||||
@Override
|
||||
public HotDispatchTemplateVo queryById(Long id) {
|
||||
return baseMapper.selectVoById(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询下发模板列表
|
||||
*
|
||||
* @param bo 查询条件
|
||||
* @param pageQuery 分页参数
|
||||
* @return 下发模板分页列表
|
||||
*/
|
||||
@Override
|
||||
public TableDataInfo<HotDispatchTemplateVo> queryPageList(HotDispatchTemplateBo bo, PageQuery pageQuery) {
|
||||
LambdaQueryWrapper<HotDispatchTemplate> lqw = buildQueryWrapper(bo);
|
||||
Page<HotDispatchTemplateVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
|
||||
return TableDataInfo.build(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询符合条件的下发模板列表
|
||||
*
|
||||
* @param bo 查询条件
|
||||
* @return 下发模板列表
|
||||
*/
|
||||
@Override
|
||||
public List<HotDispatchTemplateVo> queryList(HotDispatchTemplateBo bo) {
|
||||
LambdaQueryWrapper<HotDispatchTemplate> lqw = buildQueryWrapper(bo);
|
||||
return baseMapper.selectVoList(lqw);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean useDefault() {
|
||||
Long companyId = LoginHelper.getCompanyId();
|
||||
if (companyId == null) {
|
||||
throw new ServiceException("当前登录用户无公司信息");
|
||||
}
|
||||
SysCompanyVo company = sysCompanyService.queryById(companyId);
|
||||
if (company == null) {
|
||||
throw new ServiceException("公司不存在");
|
||||
}
|
||||
Long count = baseMapper.selectCount(
|
||||
Wrappers.lambdaQuery(HotDispatchTemplate.class)
|
||||
.eq(HotDispatchTemplate::getCompanyId, companyId)
|
||||
);
|
||||
if (count != null && count > 0) {
|
||||
throw new ServiceException("当前公司已存在下发模板配置,请先清除已存在数据");
|
||||
}
|
||||
List<HotDispatchTemplate> defaultConfigs = baseMapper.selectList(
|
||||
Wrappers.lambdaQuery(HotDispatchTemplate.class)
|
||||
.eq(HotDispatchTemplate::getCompanyId, 1L)
|
||||
);
|
||||
if (CollUtil.isEmpty(defaultConfigs)) {
|
||||
throw new ServiceException("默认配置不存在,请联系管理员");
|
||||
}
|
||||
List<HotDispatchTemplate> newConfigs = new ArrayList<>();
|
||||
for (HotDispatchTemplate cfg : defaultConfigs) {
|
||||
HotDispatchTemplate newCfg = new HotDispatchTemplate();
|
||||
newCfg.setCompanyId(companyId);
|
||||
newCfg.setTemplateName(cfg.getTemplateName());
|
||||
newCfg.setTemplateType(cfg.getTemplateType());
|
||||
newCfg.setStyleOssId(cfg.getStyleOssId());
|
||||
newCfg.setContent(cfg.getContent());
|
||||
newCfg.setIsDeleted(0L);
|
||||
newConfigs.add(newCfg);
|
||||
}
|
||||
return baseMapper.insertBatch(newConfigs);
|
||||
}
|
||||
|
||||
private LambdaQueryWrapper<HotDispatchTemplate> buildQueryWrapper(HotDispatchTemplateBo bo) {
|
||||
Map<String, Object> params = bo.getParams();
|
||||
LambdaQueryWrapper<HotDispatchTemplate> lqw = Wrappers.lambdaQuery();
|
||||
lqw.orderByAsc(HotDispatchTemplate::getId);
|
||||
lqw.eq(bo.getCompanyId() != null, HotDispatchTemplate::getCompanyId, bo.getCompanyId());
|
||||
lqw.like(StringUtils.isNotBlank(bo.getTemplateName()), HotDispatchTemplate::getTemplateName, bo.getTemplateName());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getTemplateType()), HotDispatchTemplate::getTemplateType, bo.getTemplateType());
|
||||
lqw.eq(bo.getStyleOssId() != null, HotDispatchTemplate::getStyleOssId, bo.getStyleOssId());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getContent()), HotDispatchTemplate::getContent, bo.getContent());
|
||||
lqw.like(StringUtils.isNotBlank(bo.getCreateByName()), HotDispatchTemplate::getCreateByName, bo.getCreateByName());
|
||||
lqw.like(StringUtils.isNotBlank(bo.getUpdateByName()), HotDispatchTemplate::getUpdateByName, bo.getUpdateByName());
|
||||
lqw.eq(bo.getIsDeleted() != null, HotDispatchTemplate::getIsDeleted, bo.getIsDeleted());
|
||||
return lqw;
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增下发模板
|
||||
*
|
||||
* @param bo 下发模板
|
||||
* @return 是否新增成功
|
||||
*/
|
||||
@Override
|
||||
public Boolean insertByBo(HotDispatchTemplateBo bo) {
|
||||
HotDispatchTemplate add = MapstructUtils.convert(bo, HotDispatchTemplate.class);
|
||||
validEntityBeforeSave(add);
|
||||
boolean flag = baseMapper.insert(add) > 0;
|
||||
if (flag) {
|
||||
bo.setId(add.getId());
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改下发模板
|
||||
*
|
||||
* @param bo 下发模板
|
||||
* @return 是否修改成功
|
||||
*/
|
||||
@Override
|
||||
public Boolean updateByBo(HotDispatchTemplateBo bo) {
|
||||
HotDispatchTemplate update = MapstructUtils.convert(bo, HotDispatchTemplate.class);
|
||||
validEntityBeforeSave(update);
|
||||
return baseMapper.updateById(update) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存前的数据校验
|
||||
*/
|
||||
private void validEntityBeforeSave(HotDispatchTemplate entity) {
|
||||
//TODO 做一些数据校验,如唯一约束
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验并批量删除下发模板信息
|
||||
*
|
||||
* @param ids 待删除的主键集合
|
||||
* @param isValid 是否进行有效性校验
|
||||
* @return 是否删除成功
|
||||
*/
|
||||
@Override
|
||||
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
|
||||
if (isValid) {
|
||||
//TODO 做一些业务上的校验,判断是否需要校验
|
||||
}
|
||||
return baseMapper.deleteByIds(ids) > 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
package com.hotwj.platform.config.driverAnnualAssessmentConfig.controller;
|
||||
|
||||
import com.hotwj.platform.config.driverAnnualAssessmentConfig.domain.bo.HotDriverAnnualAssessmentConfigBo;
|
||||
import com.hotwj.platform.config.driverAnnualAssessmentConfig.domain.vo.HotDriverAnnualAssessmentConfigVo;
|
||||
import com.hotwj.platform.config.driverAnnualAssessmentConfig.service.IHotDriverAnnualAssessmentConfigService;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.dromara.common.core.domain.R;
|
||||
import org.dromara.common.core.validate.AddGroup;
|
||||
import org.dromara.common.core.validate.EditGroup;
|
||||
import org.dromara.common.excel.utils.ExcelUtil;
|
||||
import org.dromara.common.idempotent.annotation.RepeatSubmit;
|
||||
import org.dromara.common.log.annotation.Log;
|
||||
import org.dromara.common.log.enums.BusinessType;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.dromara.common.web.core.BaseController;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 驾驶员年度考核配置
|
||||
*
|
||||
* @author shihongwei
|
||||
* @date 2025-12-16
|
||||
*/
|
||||
@Validated
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/config/driverAnnualAssessmentConfig")
|
||||
@Tag(name = "驾驶员年度考核配置", description = "年度考核配置管理")
|
||||
public class HotDriverAnnualAssessmentConfigController extends BaseController {
|
||||
|
||||
private final IHotDriverAnnualAssessmentConfigService hotDriverAnnualAssessmentConfigService;
|
||||
|
||||
/**
|
||||
* 查询驾驶员年度考核配置列表
|
||||
*/
|
||||
//@SaCheckPermission("config:driverAnnualAssessmentConfig:list")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo<HotDriverAnnualAssessmentConfigVo> list(HotDriverAnnualAssessmentConfigBo bo, PageQuery pageQuery) {
|
||||
return hotDriverAnnualAssessmentConfigService.queryPageList(bo, pageQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出驾驶员年度考核配置列表
|
||||
*/
|
||||
//@SaCheckPermission("config:driverAnnualAssessmentConfig:export")
|
||||
@Log(title = "驾驶员年度考核配置", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/export")
|
||||
public void export(HotDriverAnnualAssessmentConfigBo bo, HttpServletResponse response) {
|
||||
List<HotDriverAnnualAssessmentConfigVo> list = hotDriverAnnualAssessmentConfigService.queryList(bo);
|
||||
ExcelUtil.exportExcel(list, "驾驶员年度考核配置", HotDriverAnnualAssessmentConfigVo.class, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取驾驶员年度考核配置详细信息
|
||||
*
|
||||
* @param id 主键
|
||||
*/
|
||||
//@SaCheckPermission("config:driverAnnualAssessmentConfig:query")
|
||||
@GetMapping("/{id}")
|
||||
public R<HotDriverAnnualAssessmentConfigVo> getInfo(@NotNull(message = "主键不能为空")
|
||||
@PathVariable Long id) {
|
||||
return R.ok(hotDriverAnnualAssessmentConfigService.queryById(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增驾驶员年度考核配置
|
||||
*/
|
||||
//@SaCheckPermission("config:driverAnnualAssessmentConfig:add")
|
||||
@Log(title = "驾驶员年度考核配置", businessType = BusinessType.INSERT)
|
||||
@RepeatSubmit()
|
||||
@PostMapping()
|
||||
public R<Void> add(@Validated(AddGroup.class) @RequestBody HotDriverAnnualAssessmentConfigBo bo) {
|
||||
return toAjax(hotDriverAnnualAssessmentConfigService.insertByBo(bo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改驾驶员年度考核配置
|
||||
*/
|
||||
//@SaCheckPermission("config:driverAnnualAssessmentConfig:edit")
|
||||
@Log(title = "驾驶员年度考核配置", businessType = BusinessType.UPDATE)
|
||||
@RepeatSubmit()
|
||||
@PutMapping()
|
||||
public R<Void> edit(@Validated(EditGroup.class) @RequestBody HotDriverAnnualAssessmentConfigBo bo) {
|
||||
return toAjax(hotDriverAnnualAssessmentConfigService.updateByBo(bo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除驾驶员年度考核配置
|
||||
*
|
||||
* @param ids 主键串
|
||||
*/
|
||||
//@SaCheckPermission("config:driverAnnualAssessmentConfig:remove")
|
||||
@Log(title = "驾驶员年度考核配置", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{ids}")
|
||||
public R<Void> remove(@NotEmpty(message = "主键不能为空")
|
||||
@PathVariable Long[] ids) {
|
||||
return toAjax(hotDriverAnnualAssessmentConfigService.deleteWithValidByIds(List.of(ids), true));
|
||||
}
|
||||
|
||||
/**
|
||||
* 采用默认配置
|
||||
*/
|
||||
//@SaCheckPermission("config:driverAnnualAssessmentConfig:add")
|
||||
@Log(title = "驾驶员年度考核配置", businessType = BusinessType.INSERT)
|
||||
@RepeatSubmit()
|
||||
@PostMapping("/useDefault")
|
||||
public R<Void> useDefault() {
|
||||
return toAjax(hotDriverAnnualAssessmentConfigService.useDefault());
|
||||
}
|
||||
|
||||
/**
|
||||
* 一键清空
|
||||
*/
|
||||
//@SaCheckPermission("config:driverAnnualAssessmentConfig:remove")
|
||||
@Log(title = "驾驶员年度考核配置", businessType = BusinessType.DELETE)
|
||||
@RepeatSubmit()
|
||||
@PostMapping("/clearAll")
|
||||
public R<Void> clearAll() {
|
||||
return toAjax(hotDriverAnnualAssessmentConfigService.clearAll());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package com.hotwj.platform.config.driverAnnualAssessmentConfig.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
||||
|
||||
import java.io.Serial;
|
||||
|
||||
/**
|
||||
* 驾驶员年度考核配置对象 hot_driver_annual_assessment_config
|
||||
*
|
||||
* @author shihongwei
|
||||
* @date 2025-12-16
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("hot_driver_annual_assessment_config")
|
||||
public class HotDriverAnnualAssessmentConfig extends BaseEntity {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@TableId(value = "id")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 公司ID
|
||||
*/
|
||||
private Long companyId;
|
||||
|
||||
/**
|
||||
* 考核内容
|
||||
*/
|
||||
private String content;
|
||||
|
||||
/**
|
||||
* 分数
|
||||
*/
|
||||
private Long score;
|
||||
|
||||
/**
|
||||
* 类型
|
||||
*/
|
||||
private String category;
|
||||
|
||||
/**
|
||||
* 0=正常, 1=已删除
|
||||
*/
|
||||
@TableLogic
|
||||
private Long isDeleted;
|
||||
|
||||
/**
|
||||
* 是否启用
|
||||
*/
|
||||
private Long isEnabled;
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package com.hotwj.platform.config.driverAnnualAssessmentConfig.domain.bo;
|
||||
|
||||
import com.hotwj.platform.config.driverAnnualAssessmentConfig.domain.HotDriverAnnualAssessmentConfig;
|
||||
import io.github.linpeilie.annotations.AutoMapper;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.dromara.common.core.validate.EditGroup;
|
||||
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
||||
|
||||
/**
|
||||
* 驾驶员年度考核配置业务对象 hot_driver_annual_assessment_config
|
||||
*
|
||||
* @author shihongwei
|
||||
* @date 2025-12-16
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@AutoMapper(target = HotDriverAnnualAssessmentConfig.class, reverseConvertGenerate = false)
|
||||
public class HotDriverAnnualAssessmentConfigBo extends BaseEntity {
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@NotNull(message = "主键不能为空", groups = {EditGroup.class})
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 公司ID
|
||||
*/
|
||||
private Long companyId;
|
||||
|
||||
/**
|
||||
* 考核内容
|
||||
*/
|
||||
private String content;
|
||||
|
||||
/**
|
||||
* 分数
|
||||
*/
|
||||
private Long score;
|
||||
|
||||
/**
|
||||
* 类型
|
||||
*/
|
||||
private String category;
|
||||
|
||||
/**
|
||||
* 0=正常, 1=已删除
|
||||
*/
|
||||
private Long isDeleted;
|
||||
|
||||
|
||||
/**
|
||||
* 是否启用
|
||||
*/
|
||||
private Long isEnabled;
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package com.hotwj.platform.config.driverAnnualAssessmentConfig.domain.vo;
|
||||
|
||||
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import cn.idev.excel.annotation.ExcelProperty;
|
||||
import com.hotwj.platform.config.driverAnnualAssessmentConfig.domain.HotDriverAnnualAssessmentConfig;
|
||||
import io.github.linpeilie.annotations.AutoMapper;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
|
||||
/**
|
||||
* 驾驶员年度考核配置视图对象 hot_driver_annual_assessment_config
|
||||
*
|
||||
* @author shihongwei
|
||||
* @date 2025-12-16
|
||||
*/
|
||||
@Data
|
||||
@ExcelIgnoreUnannotated
|
||||
@AutoMapper(target = HotDriverAnnualAssessmentConfig.class)
|
||||
public class HotDriverAnnualAssessmentConfigVo implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@ExcelProperty(value = "主键")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 公司ID
|
||||
*/
|
||||
@ExcelProperty(value = "公司ID")
|
||||
private Long companyId;
|
||||
|
||||
/**
|
||||
* 考核内容
|
||||
*/
|
||||
@ExcelProperty(value = "考核内容")
|
||||
private String content;
|
||||
|
||||
/**
|
||||
* 分数
|
||||
*/
|
||||
@ExcelProperty(value = "分数")
|
||||
private Long score;
|
||||
|
||||
/**
|
||||
* 类型
|
||||
*/
|
||||
@ExcelProperty(value = "类型")
|
||||
private String category;
|
||||
|
||||
/**
|
||||
* 0=正常, 1=已删除
|
||||
*/
|
||||
@ExcelProperty(value = "0=正常, 1=已删除")
|
||||
private Long isDeleted;
|
||||
|
||||
/**
|
||||
* 是否启用
|
||||
*/
|
||||
private Long isEnabled;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.hotwj.platform.config.driverAnnualAssessmentConfig.mapper;
|
||||
|
||||
import com.hotwj.platform.config.driverAnnualAssessmentConfig.domain.HotDriverAnnualAssessmentConfig;
|
||||
import com.hotwj.platform.config.driverAnnualAssessmentConfig.domain.vo.HotDriverAnnualAssessmentConfigVo;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
|
||||
|
||||
/**
|
||||
* 驾驶员年度考核配置Mapper接口
|
||||
*
|
||||
* @author shihongwei
|
||||
* @date 2025-12-16
|
||||
*/
|
||||
@Mapper
|
||||
public interface HotDriverAnnualAssessmentConfigMapper extends BaseMapperPlus<HotDriverAnnualAssessmentConfig, HotDriverAnnualAssessmentConfigVo> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
package com.hotwj.platform.config.driverAnnualAssessmentConfig.service;
|
||||
|
||||
import com.hotwj.platform.config.driverAnnualAssessmentConfig.domain.bo.HotDriverAnnualAssessmentConfigBo;
|
||||
import com.hotwj.platform.config.driverAnnualAssessmentConfig.domain.vo.HotDriverAnnualAssessmentConfigVo;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 驾驶员年度考核配置Service接口
|
||||
*
|
||||
* @author shihongwei
|
||||
* @date 2025-12-16
|
||||
*/
|
||||
public interface IHotDriverAnnualAssessmentConfigService {
|
||||
|
||||
/**
|
||||
* 查询驾驶员年度考核配置
|
||||
*
|
||||
* @param id 主键
|
||||
* @return 驾驶员年度考核配置
|
||||
*/
|
||||
HotDriverAnnualAssessmentConfigVo queryById(Long id);
|
||||
|
||||
/**
|
||||
* 分页查询驾驶员年度考核配置列表
|
||||
*
|
||||
* @param bo 查询条件
|
||||
* @param pageQuery 分页参数
|
||||
* @return 驾驶员年度考核配置分页列表
|
||||
*/
|
||||
TableDataInfo<HotDriverAnnualAssessmentConfigVo> queryPageList(HotDriverAnnualAssessmentConfigBo bo, PageQuery pageQuery);
|
||||
|
||||
/**
|
||||
* 查询符合条件的驾驶员年度考核配置列表
|
||||
*
|
||||
* @param bo 查询条件
|
||||
* @return 驾驶员年度考核配置列表
|
||||
*/
|
||||
List<HotDriverAnnualAssessmentConfigVo> queryList(HotDriverAnnualAssessmentConfigBo bo);
|
||||
|
||||
/**
|
||||
* 新增驾驶员年度考核配置
|
||||
*
|
||||
* @param bo 驾驶员年度考核配置
|
||||
* @return 是否新增成功
|
||||
*/
|
||||
Boolean insertByBo(HotDriverAnnualAssessmentConfigBo bo);
|
||||
|
||||
/**
|
||||
* 修改驾驶员年度考核配置
|
||||
*
|
||||
* @param bo 驾驶员年度考核配置
|
||||
* @return 是否修改成功
|
||||
*/
|
||||
Boolean updateByBo(HotDriverAnnualAssessmentConfigBo bo);
|
||||
|
||||
/**
|
||||
* 校验并批量删除驾驶员年度考核配置信息
|
||||
*
|
||||
* @param ids 待删除的主键集合
|
||||
* @param isValid 是否进行有效性校验
|
||||
* @return 是否删除成功
|
||||
*/
|
||||
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
|
||||
|
||||
/**
|
||||
* 采用默认配置
|
||||
*
|
||||
* @return 结果
|
||||
*/
|
||||
Boolean useDefault();
|
||||
|
||||
/**
|
||||
* 清空当前公司所有配置
|
||||
*
|
||||
* @return 是否成功
|
||||
*/
|
||||
Boolean clearAll();
|
||||
}
|
||||
@@ -0,0 +1,268 @@
|
||||
package com.hotwj.platform.config.driverAnnualAssessmentConfig.service.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.hotwj.platform.config.driverAnnualAssessmentConfig.domain.HotDriverAnnualAssessmentConfig;
|
||||
import com.hotwj.platform.config.driverAnnualAssessmentConfig.domain.bo.HotDriverAnnualAssessmentConfigBo;
|
||||
import com.hotwj.platform.config.driverAnnualAssessmentConfig.domain.vo.HotDriverAnnualAssessmentConfigVo;
|
||||
import com.hotwj.platform.config.driverAnnualAssessmentConfig.mapper.HotDriverAnnualAssessmentConfigMapper;
|
||||
import com.hotwj.platform.config.driverAnnualAssessmentConfig.service.IHotDriverAnnualAssessmentConfigService;
|
||||
import com.hotwj.platform.resourceManagement.company.domain.vo.SysCompanyVo;
|
||||
import com.hotwj.platform.resourceManagement.company.service.ISysCompanyService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.common.core.exception.ServiceException;
|
||||
import org.dromara.common.core.utils.MapstructUtils;
|
||||
import org.dromara.common.core.utils.StringUtils;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.dromara.common.satoken.utils.LoginHelper;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 驾驶员年度考核配置Service业务层处理
|
||||
*
|
||||
* @author shihongwei
|
||||
* @date 2025-12-16
|
||||
*/
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
@Service
|
||||
public class HotDriverAnnualAssessmentConfigServiceImpl implements IHotDriverAnnualAssessmentConfigService {
|
||||
|
||||
private static final long ENABLED_STATUS = 1L;
|
||||
private static final long DISABLED_STATUS = 0L;
|
||||
private static final long MAX_ENABLED_TOTAL_SCORE = 100L;
|
||||
|
||||
private final HotDriverAnnualAssessmentConfigMapper baseMapper;
|
||||
private final ISysCompanyService sysCompanyService;
|
||||
|
||||
/**
|
||||
* 查询驾驶员年度考核配置
|
||||
*
|
||||
* @param id 主键
|
||||
* @return 驾驶员年度考核配置
|
||||
*/
|
||||
@Override
|
||||
public HotDriverAnnualAssessmentConfigVo queryById(Long id) {
|
||||
return baseMapper.selectVoById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean useDefault() {
|
||||
Long companyId = LoginHelper.getCompanyId();
|
||||
if (companyId == null) {
|
||||
throw new ServiceException("当前登录用户无公司信息");
|
||||
}
|
||||
|
||||
SysCompanyVo company = sysCompanyService.queryById(companyId);
|
||||
if (company == null) {
|
||||
throw new ServiceException("公司不存在");
|
||||
}
|
||||
|
||||
// 校验当前公司是否已有配置
|
||||
Long count = baseMapper.selectCount(
|
||||
Wrappers.lambdaQuery(HotDriverAnnualAssessmentConfig.class)
|
||||
.eq(HotDriverAnnualAssessmentConfig::getCompanyId, companyId)
|
||||
);
|
||||
if (count != null && count > 0) {
|
||||
throw new ServiceException("当前公司已存在考核配置,请先清除已存在数据");
|
||||
}
|
||||
|
||||
// 获取总部配置 (companyId = 1)
|
||||
List<HotDriverAnnualAssessmentConfig> defaultConfigs = baseMapper.selectList(
|
||||
Wrappers.lambdaQuery(HotDriverAnnualAssessmentConfig.class)
|
||||
.eq(HotDriverAnnualAssessmentConfig::getCompanyId, 1L)
|
||||
);
|
||||
|
||||
if (CollUtil.isEmpty(defaultConfigs)) {
|
||||
throw new ServiceException("默认配置不存在,请联系管理员");
|
||||
}
|
||||
|
||||
List<HotDriverAnnualAssessmentConfig> newConfigs = new ArrayList<>();
|
||||
for (HotDriverAnnualAssessmentConfig cfg : defaultConfigs) {
|
||||
HotDriverAnnualAssessmentConfig newCfg = new HotDriverAnnualAssessmentConfig();
|
||||
// 复制属性,排除ID和创建时间等
|
||||
newCfg.setCompanyId(companyId);
|
||||
newCfg.setContent(cfg.getContent());
|
||||
newCfg.setScore(cfg.getScore());
|
||||
newCfg.setCategory(cfg.getCategory());
|
||||
newCfg.setIsDeleted(0L);
|
||||
newConfigs.add(newCfg);
|
||||
}
|
||||
|
||||
return baseMapper.insertBatch(newConfigs);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 分页查询驾驶员年度考核配置列表
|
||||
*
|
||||
* @param bo 查询条件
|
||||
* @param pageQuery 分页参数
|
||||
* @return 驾驶员年度考核配置分页列表
|
||||
*/
|
||||
@Override
|
||||
public TableDataInfo<HotDriverAnnualAssessmentConfigVo> queryPageList(HotDriverAnnualAssessmentConfigBo bo, PageQuery pageQuery) {
|
||||
LambdaQueryWrapper<HotDriverAnnualAssessmentConfig> lqw = buildQueryWrapper(bo);
|
||||
Page<HotDriverAnnualAssessmentConfigVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
|
||||
return TableDataInfo.build(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询符合条件的驾驶员年度考核配置列表
|
||||
*
|
||||
* @param bo 查询条件
|
||||
* @return 驾驶员年度考核配置列表
|
||||
*/
|
||||
@Override
|
||||
public List<HotDriverAnnualAssessmentConfigVo> queryList(HotDriverAnnualAssessmentConfigBo bo) {
|
||||
LambdaQueryWrapper<HotDriverAnnualAssessmentConfig> lqw = buildQueryWrapper(bo);
|
||||
return baseMapper.selectVoList(lqw);
|
||||
}
|
||||
|
||||
private LambdaQueryWrapper<HotDriverAnnualAssessmentConfig> buildQueryWrapper(HotDriverAnnualAssessmentConfigBo bo) {
|
||||
Map<String, Object> params = bo.getParams();
|
||||
LambdaQueryWrapper<HotDriverAnnualAssessmentConfig> lqw = Wrappers.lambdaQuery();
|
||||
lqw.orderByAsc(HotDriverAnnualAssessmentConfig::getId);
|
||||
lqw.eq(bo.getCompanyId() != null, HotDriverAnnualAssessmentConfig::getCompanyId, bo.getCompanyId());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getContent()), HotDriverAnnualAssessmentConfig::getContent, bo.getContent());
|
||||
lqw.eq(bo.getScore() != null, HotDriverAnnualAssessmentConfig::getScore, bo.getScore());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getCategory()), HotDriverAnnualAssessmentConfig::getCategory, bo.getCategory());
|
||||
lqw.eq(bo.getIsDeleted() != null, HotDriverAnnualAssessmentConfig::getIsDeleted, bo.getIsDeleted());
|
||||
return lqw;
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增驾驶员年度考核配置
|
||||
*
|
||||
* @param bo 驾驶员年度考核配置
|
||||
* @return 是否新增成功
|
||||
*/
|
||||
@Override
|
||||
public Boolean insertByBo(HotDriverAnnualAssessmentConfigBo bo) {
|
||||
HotDriverAnnualAssessmentConfig add = MapstructUtils.convert(bo, HotDriverAnnualAssessmentConfig.class);
|
||||
Long companyId = resolveCompanyId(add.getCompanyId());
|
||||
add.setCompanyId(companyId);
|
||||
applyInsertEnabledRule(add, companyId);
|
||||
validEntityBeforeSave(add);
|
||||
boolean flag = baseMapper.insert(add) > 0;
|
||||
if (flag) {
|
||||
bo.setId(add.getId());
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改驾驶员年度考核配置
|
||||
*
|
||||
* @param bo 驾驶员年度考核配置
|
||||
* @return 是否修改成功
|
||||
*/
|
||||
@Override
|
||||
public Boolean updateByBo(HotDriverAnnualAssessmentConfigBo bo) {
|
||||
HotDriverAnnualAssessmentConfig update = MapstructUtils.convert(bo, HotDriverAnnualAssessmentConfig.class);
|
||||
Long companyId = resolveCompanyId(update.getCompanyId());
|
||||
update.setCompanyId(companyId);
|
||||
validateUpdateEnabledRule(update, companyId);
|
||||
validEntityBeforeSave(update);
|
||||
return baseMapper.updateById(update) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存前的数据校验
|
||||
*/
|
||||
private void validEntityBeforeSave(HotDriverAnnualAssessmentConfig entity) {
|
||||
//TODO 做一些数据校验,如唯一约束
|
||||
}
|
||||
|
||||
private Long resolveCompanyId(Long companyId) {
|
||||
if (companyId != null) {
|
||||
return companyId;
|
||||
}
|
||||
Long loginCompanyId = LoginHelper.getCompanyId();
|
||||
if (loginCompanyId == null) {
|
||||
throw new ServiceException("当前登录用户无公司信息");
|
||||
}
|
||||
return loginCompanyId;
|
||||
}
|
||||
|
||||
private void applyInsertEnabledRule(HotDriverAnnualAssessmentConfig entity, Long companyId) {
|
||||
Long isEnabled = entity.getIsEnabled();
|
||||
if (isEnabled == null || isEnabled != ENABLED_STATUS) {
|
||||
if (isEnabled == null) {
|
||||
entity.setIsEnabled(DISABLED_STATUS);
|
||||
}
|
||||
return;
|
||||
}
|
||||
long enabledTotalScore = getEnabledTotalScore(companyId, null) + safeScore(entity.getScore());
|
||||
if (enabledTotalScore > MAX_ENABLED_TOTAL_SCORE) {
|
||||
entity.setIsEnabled(DISABLED_STATUS);
|
||||
}
|
||||
}
|
||||
|
||||
private void validateUpdateEnabledRule(HotDriverAnnualAssessmentConfig entity, Long companyId) {
|
||||
if (entity.getIsEnabled() == null || entity.getIsEnabled() != ENABLED_STATUS) {
|
||||
return;
|
||||
}
|
||||
long enabledTotalScore = getEnabledTotalScore(companyId, entity.getId()) + safeScore(entity.getScore());
|
||||
if (enabledTotalScore > MAX_ENABLED_TOTAL_SCORE) {
|
||||
throw new ServiceException("启用失败:当前启用项总分值不能超过100分");
|
||||
}
|
||||
}
|
||||
|
||||
private long getEnabledTotalScore(Long companyId, Long excludeId) {
|
||||
LambdaQueryWrapper<HotDriverAnnualAssessmentConfig> lqw = Wrappers.lambdaQuery();
|
||||
lqw.eq(HotDriverAnnualAssessmentConfig::getCompanyId, companyId);
|
||||
lqw.eq(HotDriverAnnualAssessmentConfig::getIsEnabled, ENABLED_STATUS);
|
||||
lqw.ne(excludeId != null, HotDriverAnnualAssessmentConfig::getId, excludeId);
|
||||
List<HotDriverAnnualAssessmentConfig> enabledConfigs = baseMapper.selectList(lqw);
|
||||
return enabledConfigs.stream()
|
||||
.map(HotDriverAnnualAssessmentConfig::getScore)
|
||||
.filter(score -> score != null)
|
||||
.mapToLong(Long::longValue)
|
||||
.sum();
|
||||
}
|
||||
|
||||
private long safeScore(Long score) {
|
||||
return score == null ? 0L : score;
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验并批量删除驾驶员年度考核配置信息
|
||||
*
|
||||
* @param ids 待删除的主键集合
|
||||
* @param isValid 是否进行有效性校验
|
||||
* @return 是否删除成功
|
||||
*/
|
||||
@Override
|
||||
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
|
||||
if (isValid) {
|
||||
//TODO 做一些业务上的校验,判断是否需要校验
|
||||
}
|
||||
return baseMapper.deleteByIds(ids) > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean clearAll() {
|
||||
Long companyId = LoginHelper.getCompanyId();
|
||||
if (companyId == null) {
|
||||
throw new ServiceException("当前登录用户无公司信息");
|
||||
}
|
||||
// 逻辑删除当前公司所有配置
|
||||
return baseMapper.delete(
|
||||
Wrappers.lambdaQuery(HotDriverAnnualAssessmentConfig.class)
|
||||
.eq(HotDriverAnnualAssessmentConfig::getCompanyId, companyId)
|
||||
) > 0;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user