修改:对标流程修改

This commit is contained in:
zjh 2025-12-26 09:51:35 +08:00
parent 80325ef2ea
commit 50cc133c17
11 changed files with 421 additions and 125 deletions

250
README.md
View File

@ -1,39 +1,235 @@
# 数据管理平台
# 数据管理平台用户手册
#### 介绍
{**以下是 Gitee 平台说明,您可以替换此简介**
Gitee 是 OSCHINA 推出的基于 Git 的代码托管平台(同时支持 SVN。专为开发者提供稳定、高效、安全的云端软件开发协作平台
无论是个人、团队、或是企业,都能够用 Gitee 实现代码托管、项目管理、协作开发。企业项目请看 [https://gitee.com/enterprises](https://gitee.com/enterprises)}
## 项目概述
#### 软件架构
软件架构说明
数据管理平台是一个综合性的数据管理系统主要用于发动机型号数据录入、参数配置管理、审批流程控制、基准报告生成等功能。该平台基于Spring Boot框架开发集成了Activiti工作流引擎支持数据录入、维护、审批等完整的业务流程。
## 功能架构
#### 安装教程
### 1. 数据录入与引擎模型管理
- **发动机型号管理**:支持发动机型号的录入、编辑、删除等操作
- **Excel导入功能**支持通过Excel批量导入发动机型号数据
- **型号字段管理**:包括产品型号、产品编号、板块、平台、系列、细分市场、项目名称、项目编号、品牌、排放等信息
1. xxxx
2. xxxx
3. xxxx
### 2. 参数与模板配置
- **参数管理**:管理发动机相关的各类参数信息
- **模板配置**:配置数据录入模板,支持参数模板的增删改查
- **参数详情管理**:管理具体参数的详细信息和版本控制
#### 使用说明
### 3. 审批流程控制
- **Activiti工作流**基于Activiti引擎实现的审批流程
- **参数审批**:支持参数修改的审批流程
- **报告审批**:支持基准报告的审批流程
- **审批节点配置**:可配置多级审批节点
- **审批记录**:记录完整的审批过程和结果
1. xxxx
2. xxxx
3. xxxx
### 4. 基准报告生成
- **报告管理**:支持对标报告的创建、编辑、上传
- **报告审批流程**:集成审批流程的报告管理
- **文件上传**:支持报告附件上传功能
#### 参与贡献
### 5. 待办任务处理
- **待办中心**:集中管理用户需要处理的审批任务
- **已办任务**:查看已完成的任务记录
- **发起任务**:查看用户发起的审批流程
1. Fork 本仓库
2. 新建 Feat_xxx 分支
3. 提交代码
4. 新建 Pull Request
### 6. 部门人员管理
- **部门管理**:管理部门信息和层级关系
- **人员管理**:管理各部门人员信息
- **责任人员配置**:配置各部门的责任人
## 主要模块说明
#### 特技
### 1. 数据录入模块
- 路径:`/custom/dataEntry`
- 支持模板筛选、列表显示、添加模板、导入模板、查看、下载、版本管理、修改等功能
1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md
2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com)
3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目
4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目
5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help)
6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)
### 2. 引擎型号管理模块
- 路径:`/custom/dataEntryEngineModel`
- 支持发动机型号的Excel导入功能
- 管理发动机型号的基本信息
### 3. 参数管理模块
- 路径:`/custom/parameter`
- 管理发动机相关的参数配置
### 4. 审批流程模块
- 路径:`/custom/activitiProcess`
- 处理参数和报告的审批流程
### 5. 基准报告模块
- 路径:`/custom/benchmark`
- 管理对标报告的创建、审批、查看等
### 6. 待办任务模块
- 路径:`/custom/todoTask`
- 管理用户的待办、已办、发起任务
## 技术架构
### 后端技术栈
- **Spring Boot 2.2.7.RELEASE**:核心框架
- **Maven**:项目构建工具
- **Java 1.8**:开发语言
- **Lombok**:简化代码
- **Hutool**:工具库
- **MongoDB**:数据查询
- **Activiti**:工作流引擎
- **Groovy**:编译器集成
### 数据库
- 使用MySQL作为主要数据存储
- 支持多数据源配置
- 通过MpaasQuery进行数据访问
### 接口规范
- RESTful API设计
- 统一的响应格式
- 基于Response的返回结果封装
## 安装部署
### 环境要求
- JDK 1.8
- Maven 3.5+
- MySQL 5.7+
- Redis可选
### 部置步骤
1. **克隆项目**
```bash
git clone <项目地址>
```
2. **配置数据库**
- 修改 [application.properties](file:///D:/JavaProjects/data-management-platform/src/main/resources/application.properties) 文件中的数据库连接信息
- 执行 [sql.sql](file:///D:/JavaProjects/data-management-platform/src/main/resources/sql.sql) 初始化数据库表结构
3. **Maven构建**
```bash
# 使用single profile构建可执行jar
mvn clean package -Psingle
# 或使用lib profile构建库模式
mvn clean package -Plib
```
4. **启动项目**
```bash
java -jar target/data-management-platform.jar
```
## 使用指南
### 1. 发动机型号管理
#### 添加发动机型号
1. 访问数据录入模块
2. 可通过Excel导入或手动添加发动机型号
3. 填写型号信息包括:产品型号、产品编号、板块、平台、系列等
4. 提交后系统会自动为该型号绑定所有参数模板
#### Excel导入
- 支持批量导入发动机型号数据
- 需按照指定的Excel模板格式填写数据
- 上传后系统会自动验证数据格式和重复性
### 2. 参数管理
#### 参数维护
1. 选择具体的发动机型号
2. 查看该型号绑定的参数列表
3. 可编辑参数值、版本信息等
4. 修改后需要提交审批
### 3. 审批流程
#### 发起审批
1. 在参数编辑完成后,点击发起审批
2. 系统会生成审批修改说明
3. 选择审批流程和审批人
4. 提交审批请求
#### 处理审批任务
1. 在待办任务中查看需要处理的审批
2. 查看审批详情和修改内容
3. 选择通过、拒绝或转交操作
4. 填写审批意见
### 4. 基准报告管理
#### 创建报告
1. 进入基准报告模块
2. 填写报告基本信息
3. 上传报告文件
4. 保存为草稿或提交审批
#### 报告审批
1. 选择需要审批的报告
2. 按照预设流程进行审批
3. 查看审批进度和历史记录
## API接口
### 数据录入相关
- `GET /custom/dataEntry/getTemplateByCondition` - 模板条件查询
- `GET /custom/dataEntry/getParameterByCondition` - 参数条件查询
- `POST /custom/dataEntryEngineModel/excelImport` - Excel导入发动机型号
### 审批流程相关
- `POST /custom/activitiProcess/initiateApproval` - 发起参数审批
- `POST /custom/activitiProcess/handleApproval` - 处理审批
- `GET /custom/activitiProcess/getApprovalProcess` - 获取审批流程
### 报告管理相关
- `POST /custom/benchmark/uploadFile` - 上传文件
- `POST /custom/benchmark/insertReport` - 创建报告
- `POST /custom/benchmark/updateReport` - 更新报告
- `GET /custom/benchmark/getReportDetail` - 获取报告详情
### 任务管理相关
- `GET /custom/todoTask/getTodoTaskList` - 获取待办任务列表
- `GET /custom/todoTask/getCompletedTaskList` - 获取已办任务列表
- `GET /custom/todoTask/getInitiatedTaskList` - 获取发起任务列表
## 系统配置
### 配置文件
- [application.properties](file:///D:/JavaProjects/data-management-platform/src/main/resources/application.properties) - 主配置文件
- [application-s.properties](file:///D:/JavaProjects/data-management-platform/src/main/resources/application-s.properties) - 服务配置文件
### 多数据源配置
系统支持配置多个数据源,通过 `mpaas.datasource` 配置项进行设置。
## 常见问题
### 1. Excel导入失败
- 检查文件格式是否为.xlsx或.xls
- 确认Excel模板格式是否正确
- 验证数据是否符合字段要求
### 2. 审批流程异常
- 确认审批人配置是否正确
- 检查工作流配置是否完整
- 查看系统日志获取详细错误信息
### 3. 数据库连接问题
- 检查数据库连接参数
- 确认数据库服务是否正常运行
- 验证数据库用户权限
## 维护说明
### 日志管理
- 系统日志文件默认位于 `log/xdap-app.log`
- 支持日志级别配置和日志轮转
### 数据备份
- 定期备份数据库
- 保留重要配置文件的备份
- 建立数据恢复机制
## 版权声明
本项目为数据管理平台系统,所有权利保留。

View File

@ -22,6 +22,9 @@ public class UserPermissionGetter {
@Resource
private RuntimeAppContextService runtimeAppContextService;
public String getUserId() {
return runtimeAppContextService.getCurrentUserId();
}
// 获取子系统下的零部件权限
public List<String> getParamPermissions(String subsystem, String userId) {

View File

@ -13,8 +13,9 @@ import java.sql.Timestamp;
@SQL(view = "getLatestTemplateOrder",
sql = "SELECT ranked.order_num, ranked.id, ranked.template_name, ranked.version, ranked.status , ranked.created_time, ranked.published_time, xu.username AS \"createBy\" FROM ( SELECT t.*, ROW_NUMBER() OVER (PARTITION BY template_name ORDER BY CASE WHEN status = 'COMPLETE' THEN 1 WHEN status = 'APPROVING' THEN 2 ELSE 3 END, version DESC) AS rn FROM ( SELECT DISTINCT id, template_name, version, status, created_time , published_time, order_num, create_by FROM yfsjglpt_model_template WHERE status IN ('COMPLETE', 'DRAFT', 'APPROVING') ) t ) ranked LEFT JOIN xdap_users xu ON xu.id = ranked.create_by WHERE rn = 1 ORDER BY CASE status WHEN 'COMPLETE' THEN 1 WHEN 'APPROVING' THEN 2 WHEN 'DRAFT' THEN 3 WHEN 'RETURNED' THEN 4 WHEN 'REJECTED' THEN 5 ELSE 6 END ASC, ranked.order_num DESC"),
// 查找每个模板的最新版本并且优先级按照已发布审核中草稿状态转变只有这三种状态
// CASE ranked.status WHEN 'COMPLETE' THEN 1 WHEN 'APPROVING' THEN 2 WHEN 'DRAFT' THEN 3 WHEN 'RETURNED' THEN 4 WHEN 'REJECTED' THEN 5 ELSE 6 END ASC,
@SQL(view = "getLatestTemplate",
sql = "SELECT ROW_NUMBER() OVER (ORDER BY CASE ranked.status WHEN 'COMPLETE' THEN 1 WHEN 'APPROVING' THEN 2 WHEN 'DRAFT' THEN 3 WHEN 'RETURNED' THEN 4 WHEN 'REJECTED' THEN 5 ELSE 6 END ASC, ranked.order_num DESC) AS order_num, ranked.id, ranked.template_name, ranked.version , ranked.status, ranked.created_time, ranked.published_time, xu.username AS \"createBy\" FROM ( SELECT t.*, ROW_NUMBER() OVER (PARTITION BY template_name ORDER BY CASE WHEN status = 'COMPLETE' THEN 1 WHEN status = 'APPROVING' THEN 2 ELSE 3 END, version DESC) AS rn FROM yfsjglpt_model_template t WHERE status IN ('COMPLETE', 'DRAFT', 'APPROVING') ) ranked LEFT JOIN xdap_users xu ON xu.id = ranked.create_by WHERE rn = 1 ORDER BY CASE ranked.status WHEN 'COMPLETE' THEN 1 WHEN 'APPROVING' THEN 2 WHEN 'DRAFT' THEN 3 WHEN 'RETURNED' THEN 4 WHEN 'REJECTED' THEN 5 ELSE 6 END ASC, ranked.order_num DESC"
sql = "SELECT ROW_NUMBER() OVER (ORDER BY CASE ranked.status WHEN 'COMPLETE' THEN 1 WHEN 'APPROVING' THEN 2 WHEN 'DRAFT' THEN 3 WHEN 'RETURNED' THEN 4 WHEN 'REJECTED' THEN 5 ELSE 6 END ASC, ranked.order_num DESC) AS order_num, ranked.id, ranked.template_name, ranked.version , ranked.status, ranked.created_time, ranked.published_time, xu.username AS \"createBy\" FROM ( SELECT t.*, ROW_NUMBER() OVER (PARTITION BY template_name ORDER BY CASE WHEN status = 'COMPLETE' THEN 1 WHEN status = 'APPROVING' THEN 2 ELSE 3 END, version DESC) AS rn FROM yfsjglpt_model_template t WHERE status IN ('COMPLETE', 'DRAFT', 'APPROVING') ) ranked LEFT JOIN xdap_users xu ON xu.id = ranked.create_by WHERE rn = 1 ORDER BY ranked.order_num DESC"
),
// 获取所有模板的最新版本号包括所有状态
@SQL(view = "getNewTemplate",

View File

@ -9,9 +9,10 @@ import lombok.Data;
import java.sql.Timestamp;
import java.util.List;
// CASE af.flow_status WHEN 'COMPLETE' THEN 1 WHEN 'APPROVING' THEN 2 WHEN 'DRAFT' THEN 3 WHEN 'REJECTED' THEN 4 ELSE 5 END ASC,
@SQLQuery(value = {
@SQL(view = "getAllReportApprovalList",
sql = "SELECT af.id AS \"flowId\", r.id AS \"reportId\", r.title AS \"title\", af.flow_status AS \"status\", af.create_by AS \"createBy\" , xu.username AS \"username\", af.created_time AS \"createdTime\", ac.assignees AS current_users FROM yfsjglpt_model_approval_flow af JOIN approval_config ac ON af.id = ac.approval_id AND af.current_node = ac.node_order JOIN yfsjglpt_model_benchmarking_report r ON af.template_id = r.id LEFT JOIN xdap_users xu ON xu.id = af.create_by WHERE af.flow_type = 2 AND r.title LIKE CONCAT('%', #title, '%') AND af.flow_status LIKE CONCAT('%', #status, '%') AND af.created_time LIKE CONCAT('%', #createdTime, '%') AND xu.username LIKE CONCAT('%', #username, '%') ORDER BY CASE af.flow_status WHEN 'COMPLETE' THEN 1 WHEN 'APPROVING' THEN 2 WHEN 'DRAFT' THEN 3 WHEN 'REJECTED' THEN 4 ELSE 5 END ASC, af.created_time DESC")
sql = "SELECT af.id AS flowId, r.id AS reportId, r.title AS title, af.flow_status AS status, af.create_by AS createBy , xu.username AS username, af.created_time AS createdTime, ac.assignees AS current_users FROM yfsjglpt_model_approval_flow af LEFT JOIN approval_config ac ON af.id = ac.approval_id AND af.current_node = ac.node_order LEFT JOIN yfsjglpt_model_benchmarking_report r ON af.template_id = r.id LEFT JOIN xdap_users xu ON xu.id = af.create_by WHERE af.flow_type = 2 AND r.title LIKE CONCAT('%', #title, '%') AND af.flow_status LIKE CONCAT('%', #status, '%') AND af.created_time LIKE CONCAT('%', #createdTime, '%') AND xu.username LIKE CONCAT('%', #username, '%') ORDER BY af.created_time DESC")
})
@Data
public class TodoAndReportListView {

View File

@ -8,8 +8,9 @@ import lombok.Data;
import java.sql.Timestamp;
@SQLQuery(value = {
// CASE br.status WHEN 'COMPLETE' THEN 1 WHEN 'APPROVING' THEN 2 WHEN 'REJECTED' THEN 3 ELSE 4 END ASC ,
@SQL(view = "getAllReport",
sql = "SELECT br.id AS \"reportId\", br.* FROM yfsjglpt_model_benchmarking_report br WHERE br.is_delete = 0 and br.title like CONCAT('%', #title, '%') and br.manufacturer_name like CONCAT('%', #manufacturerName, '%') and br.model_name like CONCAT('%', #modelName, '%') and br.product_number like CONCAT('%', #productNumber, '%') and br.module like CONCAT('%', #module, '%') and br.plate like CONCAT('%', #plate, '%') and br.platform like CONCAT('%', #platform, '%') and br.series like CONCAT('%', #series, '%') and br.market_segment like CONCAT('%', #marketSegment, '%') and br.project_name like CONCAT('%', #projectName, '%') and br.project_number like CONCAT('%', #projectNumber, '%') and br.status like CONCAT('%', #status, '%') ORDER BY CASE br.status WHEN 'COMPLETE' THEN 1 WHEN 'APPROVING' THEN 2 WHEN 'REJECTED' THEN 3 ELSE 4 END ASC , af.created_time DESC")
sql = "SELECT br.id AS \"reportId\", br.* FROM yfsjglpt_model_benchmarking_report br WHERE br.is_delete = 0 and br.title like CONCAT('%', #title, '%') and br.manufacturer_name like CONCAT('%', #manufacturerName, '%') and br.model_name like CONCAT('%', #modelName, '%') and br.product_number like CONCAT('%', #productNumber, '%') and br.module like CONCAT('%', #module, '%') and br.plate like CONCAT('%', #plate, '%') and br.platform like CONCAT('%', #platform, '%') and br.series like CONCAT('%', #series, '%') and br.market_segment like CONCAT('%', #marketSegment, '%') and br.project_name like CONCAT('%', #projectName, '%') and br.project_number like CONCAT('%', #projectNumber, '%') and br.status like CONCAT('%', #status, '%') ORDER BY br.upload_time DESC")
})
@Data
public class TodoAndReportView {

View File

@ -10,8 +10,9 @@ import java.sql.Timestamp;
import java.util.List;
@SQLQuery(value = {
// CASE af.flow_status WHEN 'COMPLETE' THEN 1 WHEN 'APPROVING' THEN 2 WHEN 'DRAFT' THEN 3 WHEN 'REJECTED' THEN 4 ELSE 5 END ASC
@SQL(view = "getAllApproval",
sql = "SELECT af.id AS \"flowId\", t.id AS \"templateId\", t.template_name AS \"templateName\", t.version AS \"version\", af.flow_status AS \"status\" , af.create_by AS \"createBy\", xu.username AS \"username\", af.created_time AS \"createdTime\", ac.assignees AS current_users FROM yfsjglpt_model_approval_flow af JOIN approval_config ac ON af.id = ac.approval_id AND af.current_node = ac.node_order JOIN yfsjglpt_model_template t ON af.template_id = t.id LEFT JOIN xdap_users xu ON xu.id = af.create_by WHERE t.template_name LIKE CONCAT('%', #templateName, '%') AND af.flow_status LIKE CONCAT('%', #status, '%') AND af.created_time LIKE CONCAT('%', #createdTime, '%') AND xu.username LIKE CONCAT('%', #username, '%') AND af.flow_type = 1 ORDER BY CASE af.flow_status WHEN 'COMPLETE' THEN 1 WHEN 'APPROVING' THEN 2 WHEN 'DRAFT' THEN 3 WHEN 'REJECTED' THEN 4 ELSE 5 END ASC"),
sql = "SELECT af.id AS flowId, t.id AS templateId, t.template_name AS templateName, t.version AS version, af.flow_status AS status , af.create_by AS createBy, xu.username AS username, af.created_time AS createdTime, ac.assignees AS current_users FROM yfsjglpt_model_approval_flow af LEFT JOIN approval_config ac ON af.id = ac.approval_id AND af.current_node = ac.node_order LEFT JOIN yfsjglpt_model_template t ON af.template_id = t.id LEFT JOIN xdap_users xu ON xu.id = af.create_by WHERE t.template_name LIKE CONCAT('%', #templateName, '%') AND af.flow_status LIKE CONCAT('%', #status, '%') AND af.created_time LIKE CONCAT('%', #createdTime, '%') AND xu.username LIKE CONCAT('%', #username, '%') AND af.flow_type = 1 ORDER BY af.created_time desc"),
@SQL(view = "getApprovalByUserIdAndIds",
sql = "SELECT af.id AS \"flowId\", t.id AS \"templateId\", t.template_name AS \"templateName\", t.version AS \"version\", af.flow_status AS \"status\" , af.create_by AS \"createBy\", af.created_time AS \"createdTime\" , CASE WHEN current_node = 'PROOFREAD' THEN proofread_users WHEN current_node = 'REVIEW' THEN review_users WHEN current_node = 'COUNTERSIGN' THEN countersign_users WHEN current_node = 'APPROVE' THEN approve_users END AS current_users FROM yfsjglpt_model_approval_flow af JOIN yfsjglpt_model_template t ON af.template_id = t.id WHERE t.template_name like CONCAT('%',#templateName, '%') and af.flow_status like CONCAT('%',#status, '%') and af.flow_type = 1 and af.id NOT IN (#ids) AND af.create_by = #createBy"),
@SQL(view = "getTodoAndTemplate",

View File

@ -7,7 +7,6 @@ import com.xdap.self_development.pojo.ClassificationAttribute;
import com.xdap.self_development.pojo.EnginePartsCollection;
import com.xdap.self_development.pojo.view.CalculationParameterView;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@ -45,6 +44,14 @@ public class ParameterValueCalculationTimer {
LocalDate today = LocalDate.now();
log.info("开始执行{}参数计算任务", today);
myResponse.getErrors().add("开始执行"+today+"参数计算任务");
// 统计信息
int totalParameters = 0;
int tcParameters = 0;
int calculatedParameters = 0;
int updatedFromTC = 0;
int failedToUpdateFromTC = 0;
List<CalculationParameterView> toUpdate = new ArrayList<>();
// 1.查询所有参数配置
@ -52,20 +59,31 @@ public class ParameterValueCalculationTimer {
.viewQueryMode(true)
.view("getModelParameterValue")
.doQuery(CalculationParameterView.class);
totalParameters = parameterValues.size();
log.info("共查询到{}个参数配置", totalParameters);
myResponse.getErrors().add("共查询到"+totalParameters+"个参数配置");
if (parameterValues.isEmpty()) {
log.info("无参数配置,跳过计算");
myResponse.getErrors().add("无参数配置,跳过计算");
return myResponse;
}
// 2.从中台更新参数值
for (CalculationParameterView parameter : parameterValues) {
if (Objects.equals(parameter.getParameterSource(), "TC分类表")) {
tcParameters++;
try {
EnginePartsCollection enginePartsCollection = bd.getBusinessDatabase()
.eq("ztj", parameter.getProductNumber())
.eq("lbjmc", parameter.getPartsName())
.doQueryFirst(EnginePartsCollection.class);
if (enginePartsCollection == null || enginePartsCollection.getLbjth() == null) {
log.warn("参数【{}】在TC分类表中未找到对应零部件产品号{},零部件名:{}",
parameter.getParameterName(), parameter.getProductNumber(), parameter.getPartsName());
myResponse.getErrors().add("参数【"+parameter.getParameterName()+"】在TC分类表中未找到对应零部件");
failedToUpdateFromTC++;
continue;
}
ClassificationAttribute classificationAttribute = bd.getBusinessDatabase()
@ -73,14 +91,25 @@ public class ParameterValueCalculationTimer {
.eq("idattrtbutehame", parameter.getParameterName())
.doQueryFirst(ClassificationAttribute.class);
if (classificationAttribute != null && classificationAttribute.getFieldvalue() != null) {
String originalValue = parameter.getParameterValue();
parameter.setParameterValue(classificationAttribute.getFieldvalue());
log.debug("参数【{}】从中台更新值:{} -> {}", parameter.getParameterName(), originalValue, classificationAttribute.getFieldvalue());
updatedFromTC++;
} else {
log.warn("参数【{}】在TC分类表中未找到对应值", parameter.getParameterName());
myResponse.getErrors().add("参数【"+parameter.getParameterName()+"】在TC分类表中未找到对应值");
failedToUpdateFromTC++;
}
} catch (Exception e) {
log.error("参数【{}】从中台更新值失败:{}", parameter.getParameterName(), e.getMessage(), e);
myResponse.getErrors().add("参数【"+parameter.getParameterName()+"】从中台更新值失败:"+e.getMessage());
failedToUpdateFromTC++;
}
}
}
log.info("从中台更新参数完成,共处理{}个TC参数成功{}个,失败{}个", tcParameters, updatedFromTC, failedToUpdateFromTC);
myResponse.getErrors().add("从中台更新参数完成,共处理"+tcParameters+"个TC参数成功"+updatedFromTC+"个,失败"+failedToUpdateFromTC+"");
// 3.维护所有参数的原始值
Map<String, Map<String, String>> originalValueMap = convertMap(parameterValues);
@ -95,10 +124,12 @@ public class ParameterValueCalculationTimer {
int failureCount = 0;
for (CalculationParameterView parameterValue : parameterValues) {
if (Objects.equals(parameterValue.getParameterSource(), "公式计算")) {
calculatedParameters++;
String formula = parameterValue.getNumberOrFormula();
String modelId = parameterValue.getModelId();
try {
String replacedFormula = replaceParametersInFormula(formula, parameterNames, originalValueMap, modelId);
log.debug("参数【{}】替换公式:{} -> {}", parameterValue.getParameterName(), formula, replacedFormula);
Double result = calculateExpression(replacedFormula);
String formattedResult = String.format("%.6f", result);
parameterValue.setParameterValue(formattedResult);
@ -116,10 +147,14 @@ public class ParameterValueCalculationTimer {
}
}
}
log.info("公式计算参数完成,共处理{}个计算参数,成功{}个,失败{}个", calculatedParameters, successCount, failureCount);
myResponse.getErrors().add("公式计算参数完成,共处理"+calculatedParameters+"个计算参数,成功"+successCount+"个,失败"+failureCount+"");
// 批量插入或更新计算结果
int updatedCount = 0;
int dbUpdateFailures = 0;
if (!toUpdate.isEmpty()) {
int updatedCount = 0;
for (CalculationParameterView parameterValue : toUpdate) {
try {
if (parameterValue.getParameterValue() != null) {
@ -141,13 +176,24 @@ public class ParameterValueCalculationTimer {
} catch (Exception e) {
log.error("参数【{}】更新数据库失败:{}", parameterValue.getParameterName(), e.getMessage(), e);
myResponse.getErrors().add("参数【"+parameterValue.getParameterName()+"】更新数据库失败:"+e.getMessage());
dbUpdateFailures++;
}
}
log.info("{}参数计算完成,成功处理{}个参数,失败{}个参数,更新{}个参数", today, successCount, failureCount, updatedCount);
log.info("{}参数计算完成,成功处理{}个参数,失败{}个参数,更新{}个参数,数据库更新失败{}个",
today, successCount, failureCount, updatedCount, dbUpdateFailures);
myResponse.getErrors().add("数据库更新完成,成功更新"+updatedCount+"个参数,更新失败"+dbUpdateFailures+"");
} else {
log.info("{}参数计算完成,无需更新任何参数", today);
myResponse.getErrors().add("无需更新任何参数");
}
myResponse.getErrors().add("参数计算完成,成功处理"+successCount+"个参数,失败"+failureCount+"个参数");
// 添加汇总信息
myResponse.getErrors().add("任务汇总:共处理"+totalParameters+"个参数其中TC参数"+tcParameters+"个(成功"+updatedFromTC+"个,失败"+failedToUpdateFromTC+"个),计算参数"+calculatedParameters+"个(成功"+successCount+"个,失败"+failureCount+"个)");
log.info("{}参数计算任务结束,总参数数{}TC参数{}(成功{},失败{}),计算参数{}(成功{},失败{}),数据库更新{}(失败{})",
today, totalParameters, tcParameters, updatedFromTC, failedToUpdateFromTC,
calculatedParameters, successCount, failureCount, updatedCount, dbUpdateFailures);
return myResponse;
}
@ -220,8 +266,7 @@ public class ParameterValueCalculationTimer {
if (list == null) {
return new HashMap<>();
}
// 参数名在所有子系统都唯一
// 转为以参数名为key机型代号为key参数值为值为值的形式
return list.stream()
.filter(Objects::nonNull)
.filter(item -> item.getParameterName() != null)

View File

@ -2,6 +2,8 @@ package com.xdap.self_development.service;
import com.definesys.mpaas.query.db.PageQueryResult;
import com.xdap.self_development.controller.form.*;
import com.xdap.self_development.pojo.ApprovalConfigPojo;
import com.xdap.self_development.pojo.ApprovalFlow;
import com.xdap.self_development.pojo.BenchmarkingReport;
import com.xdap.self_development.pojo.view.ApprovalFlowNodeView;
import com.xdap.self_development.pojo.view.TodoAndReportListView;
@ -30,4 +32,14 @@ public interface BenchmarkingReportService {
String uploadFile(MultipartFile file, @NotBlank String createBy);
PageQueryResult<TodoAndReportListView> getApprovalList(@Valid ApprovalListForm form);
void processNextNode(ApprovalFlow flow, ApprovalConfigPojo currentNode, String userId);
void processApprovalLogic(ApprovalFlow flow, HandleApprovalRequest request, ApprovalConfigPojo currentNode);
void addNodeTodo(ApprovalFlow flow, ApprovalConfigPojo node, BenchmarkingReport report, String createBy);
void cancelProcess(ApprovalFlow flow, String status);
void updateTasks(ApprovalFlow flow, String status);
}

View File

@ -46,6 +46,8 @@ public class BenchmarkingReportServiceImpl implements BenchmarkingReportService
private RedisLockUtil redisLockUtil;
@Resource
private XdapDeptUsersService xdapDeptUsersService;
@Resource
private BenchmarkingReportService myself;
@Value("${apaas.token.clientId}")
private String clientId;
@ -106,7 +108,7 @@ public class BenchmarkingReportServiceImpl implements BenchmarkingReportService
TodoTaskPojo todoTask = new TodoTaskPojo();
todoTask.setCreatedById(form.getUserId());
todoTask.setCreatedBy(xdapDeptUsersService.selectUserByID(form.getUserId()).getUsername());
todoTask.setCurrentNode("");
todoTask.setCurrentNode(firstNode.getNodeName());
todoTask.setDataType("对标报告审核");
todoTask.setDocumentNo(flow.getId());
todoTask.setCreationDate(Timestamp.valueOf(LocalDateTime.now()));
@ -126,6 +128,7 @@ public class BenchmarkingReportServiceImpl implements BenchmarkingReportService
InitiatedTaskPojo initiatedTask = new InitiatedTaskPojo();
initiatedTask.setDocumentNo(flow.getId());
initiatedTask.setCreatedById(form.getUserId());
initiatedTask.setCreatedBy(xdapDeptUsersService.selectUserByID(form.getUserId()).getUsername());
initiatedTask.setCurrentNode(firstNode.getNodeName());
initiatedTask.setCurrentProcessor(JSON.toJSONString(firstNode.getAssignees()));
initiatedTask.setDataType("对标报告审核");
@ -305,7 +308,7 @@ public class BenchmarkingReportServiceImpl implements BenchmarkingReportService
if (processedCount > 0) {
throw new CommonException("此节点已被他人处理");
}
processApprovalLogic(flow, request, currentNode);
myself.processApprovalLogic(flow, request, currentNode);
} finally {
redisLockUtil.unlock(lockKey, lockValue);
}
@ -339,6 +342,7 @@ public class BenchmarkingReportServiceImpl implements BenchmarkingReportService
CompletedTaskPojo completedTaskPojo = new CompletedTaskPojo();
completedTaskPojo.setDocumentNo(flow.getId());
completedTaskPojo.setCreatedById(request.getUserId());
completedTaskPojo.setCreatedBy(xdapDeptUsersService.selectUserByID(request.getUserId()).getUsername());
completedTaskPojo.setCurrentNode(currentNode.getNodeName());
completedTaskPojo.setCurrentProcessor(JSON.toJSONString(currentNode.getAssignees()));
completedTaskPojo.setDataType("对标报告审核");
@ -351,14 +355,14 @@ public class BenchmarkingReportServiceImpl implements BenchmarkingReportService
// 处理驳回逻辑
if ("REJECT".equals(request.getResult())) {
cancelProcess(flow, "REJECTED");
myself.cancelProcess(flow, "REJECTED");
return;
}
// 处理通过逻辑流转到下一节点
processNextNode(flow, currentNode, request.getUserId());
myself.processNextNode(flow, currentNode, request.getUserId());
}
private void processNextNode(ApprovalFlow flow, ApprovalConfigPojo currentNode, String userId) {
public void processNextNode(ApprovalFlow flow, ApprovalConfigPojo currentNode, String userId) {
// 查询报告状态
BenchmarkingReport report = bd.getBusinessDatabase()
.eq("id", flow.getTemplateId())
@ -378,10 +382,10 @@ public class BenchmarkingReportServiceImpl implements BenchmarkingReportService
.update("status", report.getStatus())
.doUpdate(BenchmarkingReport.class);
// 待办环节修改
updateTasks(flow, "已完成");
myself.updateTasks(flow, "已完成");
} else {
flow.setCurrentNode(1);
addNodeTodo(flow, nextNode, report, userId);
flow.setCurrentNode(nextNode.getNodeOrder());
myself.addNodeTodo(flow, nextNode, report, userId);
}
bd.getBusinessDatabase()
@ -391,7 +395,7 @@ public class BenchmarkingReportServiceImpl implements BenchmarkingReportService
.doUpdate(ApprovalFlow.class);
}
private void addNodeTodo(ApprovalFlow flow, ApprovalConfigPojo node, BenchmarkingReport report, String createBy) {
public void addNodeTodo(ApprovalFlow flow, ApprovalConfigPojo node, BenchmarkingReport report, String createBy) {
List<String> users = JSON.parseArray(node.getAssignees()).toJavaList(String.class);
// 新增待办
List<TodoTaskPojo> list = new ArrayList<>();
@ -399,7 +403,7 @@ public class BenchmarkingReportServiceImpl implements BenchmarkingReportService
TodoTaskPojo todoTask = new TodoTaskPojo();
todoTask.setCreatedById(createBy);
todoTask.setCreatedBy(xdapDeptUsersService.selectUserByID(createBy).getUsername());
todoTask.setCurrentNode("1");
todoTask.setCurrentNode(node.getNodeName());
todoTask.setDataType("对标报告审核");
todoTask.setDocumentNo(flow.getId());
todoTask.setCreationDate(Timestamp.valueOf(LocalDateTime.now()));
@ -410,19 +414,19 @@ public class BenchmarkingReportServiceImpl implements BenchmarkingReportService
todoTask.setStatusCode(flow.getFlowStatus());
todoTask.setVersionNumber(1);
todoTask.setOwnerId(person);
todoTask.setCurrentProcessor(JSON.toJSONString(node.getAssignees()));
todoTask.setCurrentProcessor(node.getAssignees());
list.add(todoTask);
}
// 更新已办和发起的状态
updateTasks(flow, node.getNodeName());
myself.updateTasks(flow, node.getNodeName());
if (!list.isEmpty()) {
bd.getBusinessDatabase().doBatchInsert(list);
}
}
private void cancelProcess(ApprovalFlow flow, String status) {
public void cancelProcess(ApprovalFlow flow, String status) {
flow.setFlowStatus(status);
bd.getBusinessDatabase()
.rowid("id", flow.getRowId())
@ -438,10 +442,10 @@ public class BenchmarkingReportServiceImpl implements BenchmarkingReportService
.update("status", report.getStatus())
.doUpdate(BenchmarkingReport.class);
updateTasks(flow, "已拒绝");
myself.updateTasks(flow, "已拒绝");
}
private void updateTasks(ApprovalFlow flow, String status) {
public void updateTasks(ApprovalFlow flow, String status) {
// 更新已办和发起的节点状态
bd.getBusinessDatabase()
.eq("document_no", flow.getId())

View File

@ -44,8 +44,7 @@ public class ParameterServiceImpl implements ParameterService {
if (template == null) {
throw new CommonException("模板未找到");
}
//todo 假定子系统名和模板名一致
// List<String> partsNames = permissionGetter.getParamPermissions(permissionGetter.getUserId());
// Set<String> objects = new HashSet<>();
// objects.addAll(permissionGetter.getParamPermissions(template.getTemplateName()));
// objects.addAll(bd.getBusinessDatabase()

View File

@ -273,91 +273,124 @@ public class TemplateServiceImpl implements TemplateService {
// 页名和模板名不一致不允许导入
if (!Objects.equals(templateName, sheetName)) {
problems.setFlag(true);
problems.getErrors().add("\"模板导入失败:\"+Excel页名与模板名不一致");
problems.getErrors().add("模板导入失败:+Excel页名与模板名不一致");
return;
}
}
// 获取模板的最新版本
Template lastTemplate = bd.getBusinessDatabase()
.viewQueryMode(true)
.view("getNewTemplate")
// 首先查找是否有草稿版本
Template draftTemplate = bd.getBusinessDatabase()
.eq("template_name", templateName)
.eq("status", "DRAFT")
.doQueryFirst(Template.class);
// 如果有同名称模板
if (lastTemplate != null) {
switch (lastTemplate.getStatus()) {
// 最新版本为草稿
case "DRAFT":
// 查询最新模板参数
List<TemplateAndParameter> list = bd.getBusinessDatabase()
.eq("template_id", lastTemplate.getId())
.doQuery(TemplateAndParameter.class);
// 最新模板有参数
if (!list.isEmpty()) {
// insertAndUpdateParameters(List<Parameter> dataList, Template lastTemplate)
problems.setFlag(true);
problems.getErrors().add("模板导入失败:"+"模板‘"+templateName+"’已有参数,无法导入");
return;
}
break;
case "APPROVING":
problems.setFlag(true);
problems.getErrors().add("模板导入失败:"+"模板‘"+templateName+"‘的最新版本正在审核中,无法导入");
return;
// 最新版本已发布增加版本号新增
default:
lastTemplate = new Template(
templateName, lastTemplate.getVersion()+1, "DRAFT",
Timestamp.valueOf(LocalDateTime.now()), null, createBy, System.currentTimeMillis(), 0
);
bd.getBusinessDatabase()
.doInsert(lastTemplate);
}
Template targetTemplate;
if (draftTemplate != null) {
// 如果存在草稿版本使用草稿版本
targetTemplate = draftTemplate;
} else {
lastTemplate = new Template(
templateName, 1, "DRAFT", Timestamp.valueOf(LocalDateTime.now()),
null, createBy, System.currentTimeMillis(), 0
);
bd.getBusinessDatabase()
.doInsert(lastTemplate);
// 如果没有草稿版本创建新版本
Template lastTemplate = bd.getBusinessDatabase()
.viewQueryMode(true)
.view("getNewTemplate")
.eq("template_name", templateName)
.doQueryFirst(Template.class);
if (lastTemplate != null) {
// 基于最新版本创建新版本
targetTemplate = new Template(
templateName, lastTemplate.getVersion() + 1, "DRAFT",
Timestamp.valueOf(LocalDateTime.now()), null, createBy, System.currentTimeMillis(), 0
);
} else {
// 如果没有同名模板创建第一个版本
targetTemplate = new Template(
templateName, 1, "DRAFT", Timestamp.valueOf(LocalDateTime.now()),
null, createBy, System.currentTimeMillis(), 0
);
}
bd.getBusinessDatabase().doInsert(targetTemplate);
}
// 保存参数
bd.getBusinessDatabase().doBatchInsert(dataList);
// 获取目标模板的现有参数
List<Parameter> existingParameters = bd.getBusinessDatabase()
.viewQueryMode(true)
.view("selectParametersByTId")
.setVar("templateId", targetTemplate.getId())
.doQuery(Parameter.class);
Template finalLastTemplate = lastTemplate;
List<TemplateAndParameter> relations = dataList.stream()
.map(parameter -> {
TemplateAndParameter relation = new TemplateAndParameter();
relation.setTemplateId(finalLastTemplate.getId());
relation.setParameterId(parameter.getId());
return relation;
})
.collect(Collectors.toList());
// 构建现有参数的映射以参数名子系统和零部件组合作为键
Map<String, Parameter> existingParamMap = new HashMap<>();
if (existingParameters != null && !existingParameters.isEmpty()) {
existingParamMap = existingParameters.stream()
.collect(Collectors.toMap(
param -> param.getParameterName() + "|" +
(param.getSubsystemName() != null ? param.getSubsystemName() : "") + "|" +
(param.getPartsName() != null ? param.getPartsName() : ""),
param -> param,
(existing, replacement) -> existing
));
}
List<RevisionRecord> revisionRecords = dataList.stream()
.map(parameter -> {
return new RevisionRecord(
finalLastTemplate.getTemplateName(),
finalLastTemplate.getVersion(),
parameter.getParameterNumber(),
"新增参数",
finalLastTemplate.getId(),
null,
Timestamp.valueOf(LocalDateTime.now()),
parameter.getId(),
finalLastTemplate.getReturnNum()
);
})
.collect(Collectors.toList());
// 处理参数新增和更新
List<TemplateAndParameter> relationsToAdd = new ArrayList<>();
List<RevisionRecord> revisionRecords = new ArrayList<>();
// 保存关联关系
bd.getBusinessDatabase().doBatchInsert(relations);
for (Parameter newParam : dataList) {
String key = newParam.getParameterName() + "|" +
(newParam.getSubsystemName() != null ? newParam.getSubsystemName() : "") + "|" +
(newParam.getPartsName() != null ? newParam.getPartsName() : "");
Parameter existingParam = existingParamMap.get(key);
if (existingParam != null) {
newParam.setId(existingParam.getId());
bd.getBusinessDatabase()
.eq("id", newParam.getId())
.doUpdate(newParam);
// 保存修改记录
bd.getBusinessDatabase().doBatchInsert(revisionRecords);
// 记录修改记录
revisionRecords.add(new RevisionRecord(
targetTemplate.getTemplateName(),
targetTemplate.getVersion(),
newParam.getParameterNumber(),
"更新参数",
targetTemplate.getId(),
existingParam.getId(),
Timestamp.valueOf(LocalDateTime.now()),
newParam.getId(),
targetTemplate.getReturnNum()
));
} else {
newParam.setId(null);
bd.getBusinessDatabase().doInsert(newParam);
TemplateAndParameter relation = new TemplateAndParameter();
relation.setTemplateId(targetTemplate.getId());
relation.setParameterId(newParam.getId());
relationsToAdd.add(relation);
revisionRecords.add(new RevisionRecord(
targetTemplate.getTemplateName(),
targetTemplate.getVersion(),
newParam.getParameterNumber(),
"新增参数",
targetTemplate.getId(),
null,
Timestamp.valueOf(LocalDateTime.now()),
newParam.getId(),
targetTemplate.getReturnNum()
));
}
}
// 批量保存关联关系
if (!relationsToAdd.isEmpty()) {
bd.getBusinessDatabase().doBatchInsert(relationsToAdd);
}
// 批量保存修改记录
if (!revisionRecords.isEmpty()) {
bd.getBusinessDatabase().doBatchInsert(revisionRecords);
}
// 返回问题
if (problems.getHasImported().toString().equals("已完成导入:无")) {