feat(dms): 重构移动端设备管理和维修流程

- 新增 DmsBaseDeviceLedgerDTO 数据传输对象
- 集成 aucma-base 模块的设备台账服务
- 重构 getDeviceByDeviceCode 接口使用新设备模型
- 重构 likeDeviceName 接口支持模糊查询
- 添加设备实体转换辅助方法
- 在 startRepair 接口中自动创建维修工单和派工计划
- 在 completeRepair 接口中自动创建维修记录
- 添加根据故障报修ID查询维修工单的服务方法
- 完善PDA端维修流程的数据完整性处理
master
zangch@mesnac.com 2 months ago
parent 34f7f2bb59
commit db08d8425c

@ -0,0 +1,908 @@
# DmsMobileController 故障报修重构方案
> **文档版本**: 3.1
> **创建日期**: 2026-02-05
> **最后更新**: 2026-02-05
> **作者**: Claude AI
> **项目**: AUCMA-MES 设备管理系统
> **模块**: DMS 设备管理 - PDA故障报修
> **重要说明**
> 1. 本方案仅关注 DmsMobileController 的重构保持PDA完美兼容内部补全完整业务流程
> 2. DmsBillsFaultInstanceController 为Web端接口不在本次重构范围
> 3. **设备信息改为使用 BaseDeviceLedgerbase模块但返回类型为 DmsBaseDeviceLedgerdms模块需要进行字段转换**
---
## 一、重构背景
### 1.1 当前问题分析
#### 1.1.1 DmsMobileController 故障报修方法现状
**现有方法**
| 方法 | 行号范围 | 当前问题 |
|------|---------|----------|
| insertFaultInstsanceActivity | ~ | 基本正常,创建故障报修 |
| startRepair | ~ | **关键问题**:缺少维修工单和派工计划创建逻辑 |
| completeRepair | ~ | **关键问题**:缺少维修记录创建逻辑 |
| getBillsFaultInstance4Repair | ~ | 方法复杂,包含知识库匹配逻辑 |
#### 1.1.2 业务流程不完整
**PDA端当前流程**
```
PDA创建故障报修 → dms_bills_fault_instance 表
PDA开始维修 → ❌ 缺少创建维修工单dms_repair_work_order
❌ 缺少创建派工计划dms_dispatch_plan
❌ 缺少触发断点1故障报修状态→维修中
PDA完成维修 → ❌ 缺少触发断点3创建维修记录 dms_repair_record
❌ 缺少触发断点3故障报修状态→维修完成
```
**Web端完整流程**(参考):
```
故障报修 (dms_bills_fault_instance)
维修工单 (dms_repair_work_order) ← 【断点1】更新故障报修状态
派工计划 (dms_dispatch_plan) ← 【断点2】派工时自动创建
维修完成
维修记录 (dms_repair_record) ← 【断点3】自动创建更新故障报修状态
```
#### 1.1.3 问题影响
- **数据完整性缺失**PDA操作后Web端的维修工单和派工计划模块看不到数据
- **状态不一致**:故障报修、维修工单、派工计划、维修记录之间的状态无法同步
- **业务流程断裂**3个断点修复机制在PDA端无法工作
### 1.2 重构目标
1. **PDA完美兼容**PDA端不需要做任何修改接口路径和参数格式完全不变
2. **业务流程补全**DmsMobileController 内部补全维修工单和派工计划的创建
3. **数据一致性**确保4个Service之间的数据完全同步
4. **最小改动**:仅修改 DmsMobileController不涉及 Web 端的 DmsBillsFaultInstanceController
---
## 二、架构设计
### 2.1 DmsMobileController 重构架构
```
┌─────────────────────────────────────────────────────────────┐
│ PDA 端Android
└────────────────────────┬────────────────────────────────────┘
│ HTTP/Multipart
┌─────────────────────────────────────────────────────────────┐
│ DmsMobileController代理模式
├─────────────────────────────────────────────────────────────┤
│ 保持所有 /dms/mobile/* 接口路径不变 │
│ 保持所有参数格式不变 │
│ 内部转换为业务逻辑调用 │
├─────────────────────────────────────────────────────────────┤
│ 依赖注入的4个Service
│ - DmsBillsFaultInstanceService故障报修服务
│ - DmsRepairWorkOrderService维修工单服务
│ - DmsDispatchPlanService派工计划服务
│ - DmsRepairRecordService维修记录服务
└────────────────────────┬────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 业务服务层现有4个Service
├─────────────────────────────────────────────────────────────┤
│ DmsBillsFaultInstanceServiceImpl │
│ DmsRepairWorkOrderServiceImpl │
│ DmsDispatchPlanServiceImpl │
│ DmsRepairRecordServiceImpl │
└─────────────────────────────────────────────────────────────┘
```
### 2.2 核心方法改造方案
#### 2.2.1 startRepair 方法改造
**改造前**
```java
@PostMapping("/startRepair")
public AjaxResult startRepair(@RequestBody DmsFaultInstanceActivity activity) {
// 直接更新操作记录
// ❌ 缺少维修工单创建
// ❌ 缺少派工计划创建
// ❌ 缺少状态同步
}
```
**改造后**
```java
@PostMapping("/startRepair")
public AjaxResult startRepair(@RequestBody DmsFaultInstanceActivity activity) {
// 1. 查询故障报修
// 2. 检查是否已有维修工单,没有则创建
// 3. 【断点1】更新故障报修状态为"维修中"
// 4. 创建派工计划
// 5. 【断点2】自动接收派工
// 6. 更新维修工单状态为"维修中"
// 7. 更新操作记录
}
```
#### 2.2.2 completeRepair 方法改造
**改造前**
```java
@PostMapping("/completeRepair")
public AjaxResult completeRepair(...) {
// 直接更新操作记录
// ❌ 缺少维修记录创建
// ❌ 缺少状态同步
}
```
**改造后**
```java
@PostMapping("/completeRepair")
public AjaxResult completeRepair(...) {
// 1. 查询故障报修和维修工单
// 2. 更新维修工单状态为"已完成"
// 3. 【断点3】创建维修记录
// 4. 【断点3】更新故障报修状态为"维修完成"
// 5. 处理配件消耗
// 6. 更新操作记录
}
```
---
## 三、需要新建的DTO类
### 3.1 DTO清单可选用于内部转换
| 序号 | DTO类名 | 文件路径 | 用途 |
|------|---------|----------|------|
| 1 | DmsFaultRepairContext | aucma-dms/src/main/java/com/aucma/dms/dto/ | 维修上下文信息(内部使用) |
**说明**DTO类主要用于内部参数传递也可以直接使用现有的实体类。
---
## 四、DmsMobileController 重构方案
### 4.1 文件路径
**文件**: `aucma-dms/src/main/java/com/aucma/dms/controller/DmsMobileController.java`
### 4.2 依赖注入(新增)
```java
@RestController
@RequestMapping("/dms/mobile")
public class DmsMobileController extends BaseController {
// 现有依赖
@Autowired
private IDmsBillsFaultInstanceService dmsBillsFaultInstanceService;
// 【新增】维修工单服务
@Autowired
private IDmsRepairWorkOrderService dmsRepairWorkOrderService;
// 【新增】派工计划服务
@Autowired
private IDmsDispatchPlanService dmsDispatchPlanService;
// 【新增】维修记录服务
@Autowired
private IDmsRepairRecordService dmsRepairRecordService;
// 【新增】维修知识库服务(可选,用于 getBillsFaultInstance4Repair
@Autowired
private IDmsKnowledgeRepairService dmsKnowledgeRepairService;
}
```
### 4.3 startRepair 方法完整重构
```java
/**
* 开始维修
*
* 【重构说明】
* - 保持接口路径和参数格式不变
* - 内部补全维修工单和派工计划的创建逻辑
* - 触发断点1和断点2确保数据完整性
*/
@PostMapping("/startRepair")
public AjaxResult startRepair(@RequestBody DmsFaultInstanceActivity activity) {
try {
Long faultInstanceId = activity.getRepairInstanceId();
String repairer = activity.getRepairer();
log.info("PDA开始维修故障报修ID: {}, 维修人: {}", faultInstanceId, repairer);
// ========== 步骤1查询故障报修 ==========
DmsBillsFaultInstance fault = dmsBillsFaultInstanceService
.selectDmsBillsFaultInstanceByRepairInstanceId(faultInstanceId);
if (fault == null) {
return AjaxResult.error("故障报修不存在");
}
// ========== 步骤2检查是否已有维修工单 ==========
DmsRepairWorkOrder existingOrder = dmsRepairWorkOrderService
.selectByFaultInstanceId(faultInstanceId);
DmsRepairWorkOrder order;
if (existingOrder == null) {
// ========== 步骤3创建维修工单 ==========
order = new DmsRepairWorkOrder();
order.setFaultInstanceId(faultInstanceId);
order.setOrderStatus("0"); // 待派工
order.setRepairer(repairer);
order.setCreateTime(new Date());
dmsRepairWorkOrderService.insertRepairWorkOrder(order);
log.info("自动创建维修工单工单ID: {}", order.getRepairOrderId());
// 【断点1】更新故障报修状态为"维修中"
fault.setBillsStatus("1");
fault.setUpdateTime(new Date());
dmsBillsFaultInstanceService.updateDmsBillsFaultInstance(fault);
log.info("【断点1】故障报修状态已更新为维修中");
} else {
order = existingOrder;
}
// ========== 步骤4创建派工计划 ==========
DmsDispatchPlan plan = new DmsDispatchPlan();
plan.setRepairOrderId(order.getRepairOrderId());
plan.setRepairer(repairer);
plan.setReceiveStatus("0"); // 待接收
plan.setExecutionStatus("0"); // 未开始
plan.setCreateTime(new Date());
dmsDispatchPlanService.insertDispatchPlan(plan);
// 【断点2】派工时自动创建派工计划自动接收
plan.setReceiveStatus("1"); // 已接收
plan.setExecutionStatus("1"); // 维修中
plan.setReceiveTime(new Date());
plan.setUpdateTime(new Date());
dmsDispatchPlanService.updateDispatchPlan(plan);
log.info("【断点2】派工计划已创建并自动接收");
// ========== 步骤5更新维修工单状态为"维修中" ==========
order.setOrderStatus("2"); // 维修中
order.setRealBeginTime(new Date());
order.setUpdateTime(new Date());
dmsRepairWorkOrderService.updateRepairWorkOrder(order);
log.info("维修工单状态已更新为维修中");
// ========== 步骤6更新操作记录原有逻辑 ==========
activity.setProcessHandleStatus("1"); // 执行中
activity.setStartTime(new Date());
dmsBillsFaultInstanceService.updateDmsFaultInstanceActivity(activity);
return AjaxResult.success("开始维修成功");
} catch (Exception e) {
log.error("开始维修失败", e);
return AjaxResult.error("开始维修失败:" + e.getMessage());
}
}
```
### 4.4 completeRepair 方法完整重构
```java
/**
* 完成维修
*
* 【重构说明】
* - 保持接口路径和参数格式不变
* - 内部补全维修记录的创建逻辑
* - 触发断点3确保数据完整性
*/
@PostMapping("/completeRepair")
public AjaxResult completeRepair(
@RequestParam("repairInstanceId") Long repairInstanceId,
@RequestParam("instanceActivityId") Long instanceActivityId,
@RequestParam(value = "checkedFault", required = false) String checkedFault,
@RequestParam(value = "repairContent", required = false) String repairContent,
@RequestParam(value = "protectedMethod", required = false) String protectedMethod,
@RequestParam(value = "repairer", required = false) String repairer,
@RequestParam(value = "parts1", required = false) String parts1,
@RequestParam(value = "files", required = false) List<MultipartFile> files) {
try {
log.info("PDA完成维修故障报修ID: {}, 维修人: {}", repairInstanceId, repairer);
// ========== 步骤1查询故障报修和维修工单 ==========
DmsBillsFaultInstance fault = dmsBillsFaultInstanceService
.selectDmsBillsFaultInstanceByRepairInstanceId(repairInstanceId);
if (fault == null) {
return AjaxResult.error("故障报修不存在");
}
DmsRepairWorkOrder order = dmsRepairWorkOrderService
.selectByFaultInstanceId(repairInstanceId);
if (order == null) {
return AjaxResult.error("维修工单不存在,请先开始维修");
}
// ========== 步骤2更新维修工单状态为"已完成" ==========
order.setOrderStatus("3"); // 已完成
order.setRealEndTime(new Date());
order.setUpdateTime(new Date());
dmsRepairWorkOrderService.updateRepairWorkOrder(order);
log.info("维修工单状态已更新为已完成");
// ========== 步骤3【断点3】创建维修记录 ==========
DmsRepairRecord record = new DmsRepairRecord();
record.setRepairOrderId(order.getRepairOrderId());
record.setFaultInstanceId(repairInstanceId);
record.setRepairContent(repairContent);
record.setRepairer(repairer);
record.setCheckedFault(checkedFault);
record.setProtectedMethod(protectedMethod);
record.setIsArchived("0"); // 未存档
record.setRepairEndTime(new Date());
record.setCreateTime(new Date());
dmsRepairRecordService.insertDmsRepairRecord(record);
log.info("【断点3】维修记录已创建记录ID: {}", record.getRecordId());
// ========== 步骤4【断点3】更新故障报修状态为"维修完成" ==========
fault.setBillsStatus("2"); // 维修完成
fault.setRealEndTime(new Date());
fault.setUpdateTime(new Date());
dmsBillsFaultInstanceService.updateDmsBillsFaultInstance(fault);
log.info("【断点3】故障报修状态已更新为维修完成");
// ========== 步骤5处理配件消耗 ==========
if (parts1 != null && !parts1.isEmpty()) {
List<DmsFaultCompentsParts> parts = parsePartsJson(parts1);
for (DmsFaultCompentsParts part : parts) {
part.setFaultId(repairInstanceId);
// 保存配件信息
}
log.info("配件信息已保存,共{}个", parts.size());
}
// ========== 步骤6更新操作记录原有逻辑 ==========
DmsFaultInstanceActivity activity = new DmsFaultInstanceActivity();
activity.setInstanceActivityId(instanceActivityId);
activity.setCheckedFault(checkedFault);
activity.setRepairContent(repairContent);
activity.setProtectedMethod(protectedMethod);
activity.setRepairer(repairer);
activity.setProcessHandleStatus("2"); // 已完成
activity.setEndTime(new Date());
activity.setRepairConfirm(2); // 已确认
activity.setConfirmTime(new Date());
dmsBillsFaultInstanceService.updateDmsFaultInstanceActivity(activity);
return AjaxResult.success("完成维修成功");
} catch (Exception e) {
log.error("完成维修失败", e);
return AjaxResult.error("完成维修失败:" + e.getMessage());
}
}
/**
* 解析配件JSON字符串
*/
private List<DmsFaultCompentsParts> parsePartsJson(String parts1) {
try {
ObjectMapper objectMapper = new ObjectMapper();
return objectMapper.readValue(parts1,
new TypeReference<List<DmsFaultCompentsParts>>() {});
} catch (Exception e) {
log.error("解析配件JSON失败", e);
return new ArrayList<>();
}
}
```
### 4.5 设备信息字段转换(重要)
#### 4.5.1 字段差异说明
**需求**DmsMobileController 中所有设备信息改为使用 `BaseDeviceLedger`aucma-base模块但返回类型为 `DmsBaseDeviceLedger`aucma-dms模块需要进行字段转换。
**字段映射表**
| 业务含义 | BaseDeviceLedger | DmsBaseDeviceLedger | 转换规则 |
|---------|------------------|---------------------|----------|
| 主键ID | `objId` | `deviceId` | `objId → deviceId` |
| 设备编号 | `deviceCode` | `deviceCode` | 直接映射 |
| 设备名称 | `deviceName` | `deviceName` | 直接映射 |
| 设备类型 | `deviceType` | `deviceTypeId` | `deviceType → deviceTypeId` |
| 设备型号 | `deviceModel` | `deviceSpec` | `deviceModel → deviceSpec` |
| 设备状态 | `deviceStatus` | `deviceStatus` | 直接映射 |
| 设备位置 | - | `deviceLocation` | 可为空 |
| 资产编号 | - | `assetNumber` | 可为空 |
| 供应商 | `manufacturer` | - | 需映射到 `suplierName` |
#### 4.5.2 字段转换方法
```java
/**
* 将 BaseDeviceLedger 转换为 DmsBaseDeviceLedger
* 用于PDA接口返回值转换
*/
private DmsBaseDeviceLedger convertToDmsBaseDeviceLedger(BaseDeviceLedger baseLedger) {
if (baseLedger == null) {
return null;
}
DmsBaseDeviceLedger dmsLedger = new DmsBaseDeviceLedger();
// 主键映射
dmsLedger.setDeviceId(baseLedger.getObjId());
// 直接映射字段
dmsLedger.setDeviceCode(baseLedger.getDeviceCode());
dmsLedger.setDeviceName(baseLedger.getDeviceName());
dmsLedger.setDeviceStatus(baseLedger.getDeviceStatus());
// 字段名称转换
dmsLedger.setDeviceTypeId(baseLedger.getDeviceType()); // deviceType → deviceTypeId
dmsLedger.setDeviceSpec(baseLedger.getDeviceModel()); // deviceModel → deviceSpec
dmsLedger.setSuplierName(baseLedger.getManufacturer()); // manufacturer → suplierName
// 可为空字段
dmsLedger.setDeviceLocation(baseLedger.getUsedDepartment()); // 使用部门 → 设备位置
// 复制审计字段
dmsLedger.setCreateTime(baseLedger.getCreateTime());
dmsLedger.setCreateBy(baseLedger.getCreateBy());
dmsLedger.setUpdateTime(baseLedger.getUpdateTime());
dmsLedger.setUpdateBy(baseLedger.getUpdateBy());
dmsLedger.setIsFlag(baseLedger.getIsFlag());
return dmsLedger;
}
/**
* 批量转换 BaseDeviceLedger 列表
*/
private List<DmsBaseDeviceLedger> convertToDmsBaseDeviceLedgerList(List<BaseDeviceLedger> baseLedgerList) {
if (CollectionUtils.isEmpty(baseLedgerList)) {
return new ArrayList<>();
}
List<DmsBaseDeviceLedger> dmsLedgerList = new ArrayList<>();
for (BaseDeviceLedger baseLedger : baseLedgerList) {
dmsLedgerList.add(convertToDmsBaseDeviceLedger(baseLedger));
}
return dmsLedgerList;
}
```
#### 4.5.3 需要修改的方法
**方法1getDeviceByDeviceCodeLine 75-79**
**修改前**
```java
@GetMapping("/getDeviceByDeviceCode/{deviceCode}")
public AjaxResult getDeviceByDeviceCode(@PathVariable("deviceCode") String deviceCode) {
DmsBaseDeviceLedger dmsBaseDeviceLedger = baseDeviceLedgerService.selectDmsBaseDeviceLedgerByDeviceCode(deviceCode);
return success(dmsBaseDeviceLedger);
}
```
**修改后**
```java
@Autowired
private IBaseDeviceLedgerService baseDeviceLedgerService; // 改为使用 base 模块的 Service
@GetMapping("/getDeviceByDeviceCode/{deviceCode}")
public AjaxResult getDeviceByDeviceCode(@PathVariable("deviceCode") String deviceCode) {
// 1. 使用 BaseDeviceLedger 查询
BaseDeviceLedger baseLedger = baseDeviceLedgerService.selectBaseDeviceLedgerByDeviceCode(deviceCode);
// 2. 转换为 DmsBaseDeviceLedger 返回
DmsBaseDeviceLedger dmsBaseDeviceLedger = convertToDmsBaseDeviceLedger(baseLedger);
return success(dmsBaseDeviceLedger);
}
```
**方法2likeDeviceNameLine 102-106**
**修改前**
```java
@GetMapping("/likeDeviceName")
public AjaxResult likeDeviceName(String deviceName) {
List<DmsBaseDeviceLedger> deviceLedgerList = baseDeviceLedgerService.likeDeviceName(deviceName);
return success(deviceLedgerList);
}
```
**修改后**
```java
@GetMapping("/likeDeviceName")
public AjaxResult likeDeviceName(String deviceName) {
// 1. 使用 BaseDeviceLedger 查询
List<BaseDeviceLedger> baseLedgerList = baseDeviceLedgerService.likeBaseDeviceName(deviceName);
// 2. 批量转换为 DmsBaseDeviceLedger 返回
List<DmsBaseDeviceLedger> dmsLedgerList = convertToDmsBaseDeviceLedgerList(baseLedgerList);
return success(dmsLedgerList);
}
```
### 4.6 其他方法保持不变
以下方法保持原有逻辑不变:
- insertFaultInstsanceActivity - 创建故障报修
- getBillsFaultInstances - 查询故障列表
- getBillsFaultInstanceByRepairInstanceId - 查询故障详情
- updateFaultInstanceActivity - 更新故障信息
- scanDevice4Repair - 扫码设备验证
---
## 五、数据流图
### 5.1 startRepair 数据流(重构后)
```
PDA调用 startRepair(faultInstanceId, repairer)
DmsMobileController.startRepair()
1. 查询故障报修
2. 检查是否已有维修工单
├→ 没有 → 创建维修工单
│ └→ 【断点1】更新故障报修状态为"维修中"
└→ 已有 → 使用现有工单
3. 创建派工计划
└→ 【断点2】自动接收派工
4. 更新维修工单状态为"维修中"
5. 更新操作记录
返回成功
```
### 5.2 completeRepair 数据流(重构后)
```
PDA调用 completeRepair(faultInstanceId, repairContent, parts)
DmsMobileController.completeRepair()
1. 查询故障报修和维修工单
2. 更新维修工单状态为"已完成"
3. 【断点3】创建维修记录
4. 【断点3】更新故障报修状态为"维修完成"
5. 处理配件消耗
6. 更新操作记录
返回成功
```
---
## 六、测试方案
### 6.1 单元测试
```java
@SpringBootTest
class DmsMobileControllerTest {
@Autowired
private DmsMobileController dmsMobileController;
@Test
void testStartRepair() {
// 准备测试数据
DmsFaultInstanceActivity activity = new DmsFaultInstanceActivity();
activity.setRepairInstanceId(1L);
activity.setRepairer("张三");
// 调用接口
AjaxResult result = dmsMobileController.startRepair(activity);
// 验证结果
assertEquals("开始维修成功", result.get("msg"));
// 验证:维修工单已创建
DmsRepairWorkOrder order = repairWorkOrderService.selectByFaultInstanceId(1L);
assertNotNull(order);
assertEquals("2", order.getOrderStatus()); // 维修中
// 验证:派工计划已创建
DmsDispatchPlan plan = dispatchPlanService.selectByRepairOrderId(order.getRepairOrderId());
assertNotNull(plan);
assertEquals("1", plan.getReceiveStatus()); // 已接收
// 验证:故障报修状态已更新
DmsBillsFaultInstance fault = faultInstanceService.selectByRepairInstanceId(1L);
assertEquals("1", fault.getBillsStatus()); // 维修中
}
@Test
void testCompleteRepair() {
// 准备测试数据
// ...
// 调用接口
AjaxResult result = dmsMobileController.completeRepair(...);
// 验证结果
assertEquals("完成维修成功", result.get("msg"));
// 验证:维修记录已创建
DmsRepairRecord record = repairRecordService.selectByRepairOrderId(1L);
assertNotNull(record);
// 验证:故障报修状态已更新
DmsBillsFaultInstance fault = faultInstanceService.selectByRepairInstanceId(1L);
assertEquals("2", fault.getBillsStatus()); // 维修完成
}
}
```
### 6.2 PDA兼容性测试关键
| 测试场景 | 测试步骤 | 预期结果 |
|---------|----------|----------|
| PDA开始维修 | 调用 /startRepair | 1. 维修工单自动创建<br>2. 派工计划自动创建<br>3. 故障报修状态→维修中<br>4. 返回格式不变 |
| PDA完成维修 | 调用 /completeRepair | 1. 维修记录自动创建<br>2. 故障报修状态→维修完成<br>3. 返回格式不变 |
| PDA完整流程 | 创建→开始维修→完成维修 | 4个表数据完整状态同步正确 |
### 6.3 Web端数据验证
| 模块 | 验证内容 | 验证方法 |
|------|----------|----------|
| 维修工单 | PDA创建的工单可见 | 查询 dms_repair_work_order 表 |
| 派工计划 | PDA自动创建的派工可见 | 查询 dms_dispatch_plan 表 |
| 维修记录 | PDA自动创建的记录可见 | 查询 dms_repair_record 表 |
| 故障报修 | 状态同步正确 | 查询 dms_bills_fault_instance.bills_status |
---
## 七、文件清单
### 7.1 需要修改的文件1个
| 序号 | 文件路径 | 修改内容 | 影响范围 |
|------|----------|----------|----------|
| 1 | aucma-dms/src/main/java/com/aucma/dms/controller/DmsMobileController.java | **1. 新增依赖注入**<br> - IBaseDeviceLedgerServicebase模块<br> - IDmsRepairWorkOrderService<br> - IDmsDispatchPlanService<br> - IDmsRepairRecordService<br><br> **2. 新增字段转换方法**<br> - convertToDmsBaseDeviceLedger() - 单个对象转换<br> - convertToDmsBaseDeviceLedgerList() - 批量转换<br><br> **3. 修改设备查询方法**<br> - getDeviceByDeviceCode() - 改用 BaseDeviceLedger<br> - likeDeviceName() - 改用 BaseDeviceLedger<br><br> **4. 重构核心方法**<br> - startRepair() - 补全工单和派工创建<br> - completeRepair() - 补全维修记录创建<br><br> **5. 新增辅助方法**<br> - parsePartsJson() - 解析配件JSON | 仅PDA端Web端不受影响 |
**修改详细说明**
**新增导入**
```java
import com.aucma.base.domain.BaseDeviceLedger;
import com.aucma.base.service.IBaseDeviceLedgerService;
import org.springframework.beans.BeanUtils;
```
**字段转换关键点**
- 主键:`objId` → `deviceId`
- 设备类型:`deviceType` → `deviceTypeId`
- 设备型号:`deviceModel` → `deviceSpec`
- 供应商:`manufacturer` → `suplierName`
### 7.2 需要新建的文件0个
**说明**本次重构不需要新建DTO类直接使用现有实体类 + 字段转换方法即可。
### 7.3 不需要修改的文件
| 文件 | 说明 |
|------|------|
| DmsBillsFaultInstanceController.java | Web端接口不在本次重构范围 |
| DmsBillsFaultInstanceServiceImpl.java | 现有服务,直接调用 |
| DmsRepairWorkOrderServiceImpl.java | 现有服务,直接调用 |
| DmsDispatchPlanServiceImpl.java | 现有服务,直接调用 |
| DmsRepairRecordServiceImpl.java | 现有服务,直接调用 |
---
## 八、实施步骤
### 阶段1准备工作半天
- [ ] 备份 DmsMobileController.java
- [ ] 创建开发分支
- [ ] 确认4个Service的可用性
- [ ] 准备测试数据
### 阶段2代码重构1天
- [ ] 新增4个Service依赖注入
- [ ] 重构 startRepair 方法
- [ ] 重构 completeRepair 方法
- [ ] 新增 parsePartsJson 辅助方法
- [ ] 添加日志记录
### 阶段3单元测试半天
- [ ] 编写 startRepair 测试用例
- [ ] 编写 completeRepair 测试用例
- [ ] 验证数据一致性
### 阶段4集成测试1天
- [ ] PDA端联调测试
- [ ] Web端数据验证
- [ ] 完整流程测试
### 阶段5部署和验证半天
- [ ] 部署到测试环境
- [ ] PDA端功能验证
- [ ] Web端数据验证
- [ ] 性能测试
**总计3-4天**
---
## 九、风险控制
### 9.1 风险识别
| 风险 | 影响 | 概率 | 应对措施 |
|------|------|------|----------|
| PDA接口变更导致PDA无法使用 | 高 | 低 | 严格保持接口路径和参数不变 |
| 业务流程补全导致数据错误 | 高 | 中 | 充分的单元测试和集成测试 |
| 性能下降 | 中 | 低 | 优化查询,添加必要的日志 |
| 事务回滚导致数据不一致 | 中 | 低 | 添加事务注解,确保原子性 |
### 9.2 回滚方案
1. **代码备份**:重构前备份 DmsMobileController.java
2. **快速回滚**:如出现问题,立即恢复备份文件
3. **灰度发布**先在部分PDA设备上测试
4. **监控观察**:部署后密切关注日志和数据
---
## 十、成功标准
### 10.1 功能标准
- [ ] PDA端功能完全正常无需修改
- [ ] startRepair 后自动创建维修工单和派工计划
- [ ] completeRepair 后自动创建维修记录
- [ ] Web端4个模块能看到完整的PDA操作数据
- [ ] 3个断点修复机制正常工作
### 10.2 质量标准
- [ ] 单元测试覆盖率 > 80%
- [ ] 集成测试全部通过
- [ ] 数据一致性检查无错误
- [ ] PDA兼容性测试全部通过
### 10.3 性能标准
- [ ] startRepair 接口响应时间 < 500ms
- [ ] completeRepair 接口响应时间 < 500ms
- [ ] 系统吞吐量无明显下降
---
## 十一、附录
### 11.1 状态流转图
```
故障报修状态 (bills_status)
0 (待维修) ──────────────→ 1 (维修中) ──────────────→ 2 (维修完成)
↑ ↓ ↓
└──── 创建报修 └─ startRepair └─ completeRepair
维修工单状态 (order_status)
0 (待派工) ──→ 1 (已派工) ──→ 2 (维修中) ──→ 3 (已完成)
↑ ↓ ↓ ↓
└─ startRepair创建 └─ 派工 └─ 接收派工 └─ completeRepair
计划
派工计划状态 (receive_status / execution_status)
0 (待接收) ──→ 1 (已接收)
↓ ↓
└─ startRepair创建 └─ 自动接收
维修记录状态 (is_archived)
0 (未存档)
└─ completeRepair 自动创建
```
### 11.2 依赖注入清单
```java
// DmsMobileController 需要注入的Service
// 【原有】故障报修服务
@Autowired
private IDmsBillsFaultInstanceService dmsBillsFaultInstanceService;
// 【重构新增】设备台账服务base模块- 用于设备信息查询和转换
@Autowired
private IBaseDeviceLedgerService baseDeviceLedgerService;
// 【重构新增】维修工单服务 - 用于PDA端自动创建维修工单
@Autowired
private IDmsRepairWorkOrderService dmsRepairWorkOrderService;
// 【重构新增】派工计划服务 - 用于PDA端自动创建派工计划
@Autowired
private IDmsDispatchPlanService dmsDispatchPlanService;
// 【重构新增】维修记录服务 - 用于PDA端自动创建维修记录
@Autowired
private IDmsRepairRecordService dmsRepairRecordService;
```
**说明**
- `IBaseDeviceLedgerService` 来自 `com.aucma.base.service`
- 其他Service来自 `com.aucma.dms.service`
### 11.3 核心方法签名
```java
// startRepair
@PostMapping("/startRepair")
public AjaxResult startRepair(@RequestBody DmsFaultInstanceActivity activity)
// completeRepair
@PostMapping("/completeRepair")
public AjaxResult completeRepair(
@RequestParam("repairInstanceId") Long repairInstanceId,
@RequestParam("instanceActivityId") Long instanceActivityId,
@RequestParam(value = "checkedFault", required = false) String checkedFault,
@RequestParam(value = "repairContent", required = false) String repairContent,
@RequestParam(value = "protectedMethod", required = false) String protectedMethod,
@RequestParam(value = "repairer", required = false) String repairer,
@RequestParam(value = "parts1", required = false) String parts1,
@RequestParam(value = "files", required = false) List<MultipartFile> files)
```
---
## 文档变更记录
| 版本 | 日期 | 变更内容 | 作者 |
|------|------|----------|------|
| 1.0 | 2025-02-05 | 初始版本 | Claude AI |
| 2.0 | 2026-02-05 | 基于4个Service分析完全重写 | Claude AI |
| 3.0 | 2026-02-05 | **聚焦 DmsMobileController 重构,不涉及 Web 端** | Claude AI |
| 3.1 | 2026-02-05 | **新增设备信息字段转换方案BaseDeviceLedger → DmsBaseDeviceLedger** | Claude AI |
---
**文档结束**
> 本方案仅关注 DmsMobileController 的重构保持PDA完美兼容内部补全完整业务流程。DmsBillsFaultInstanceController 为Web端接口不在本次重构范围。
>
> **重要更新**:设备信息查询改为使用 BaseDeviceLedgerbase模块通过字段转换方法转换为 DmsBaseDeviceLedgerdms模块返回给PDA端。

@ -5,12 +5,14 @@ import com.aucma.common.core.controller.BaseController;
import com.aucma.common.core.domain.AjaxResult;
import com.aucma.common.core.page.TableDataInfo;
import com.aucma.dms.domain.*;
import com.aucma.dms.domain.dto.DmsBaseDeviceLedgerDTO;
import com.aucma.dms.domain.vo.DmsBillsFaultInstanceScanVo;
import com.aucma.dms.domain.vo.DmsBillsInspectInstanceScanVo;
import com.aucma.dms.service.IDmsBillsFaultInstanceService;
import com.aucma.dms.service.IDmsBillsInspectInstanceService;
import com.aucma.dms.service.IDmsBillsLubeInstanceService;
import com.aucma.dms.service.IDmsBillsMaintInstanceService;
import com.aucma.base.domain.BaseDeviceLedger;
import com.aucma.base.service.IBaseDeviceLedgerService;
import com.aucma.dms.service.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
@ -35,64 +37,178 @@ import java.util.List;
@RequestMapping("/dms/mobile")
public class DmsMobileController extends BaseController {
private static final Logger log = LoggerFactory.getLogger(DmsMobileController.class);
@Autowired
private IDmsBillsFaultInstanceService dmsBillsFaultInstanceService;
@Autowired
private IDmsBillsInspectInstanceService dmsBillsInspectInstanceService;
@Autowired
private IDmsBillsMaintInstanceService dmsBillsMaintInstanceService;
@Autowired
private IDmsBillsLubeInstanceService dmsBillsLubeInstanceService;
/* @Resource
private RemoteFileService remoteFileService;*//*
// 【重构新增】维修工单服务 - 用于PDA端自动创建维修工单
@Autowired
private IDmsRepairWorkOrderService dmsRepairWorkOrderService;
// 【重构新增】派工计划服务 - 用于PDA端自动创建派工计划
@Autowired
private IDmsDispatchPlanService dmsDispatchPlanService;
*/
/**
// 【重构新增】维修记录服务 - 用于PDA端自动创建维修记录
@Autowired
private IDmsRepairRecordService dmsRepairRecordService;
// 【重构新增】基础设备台账服务 - 使用aucma-base模块的设备信息
@Autowired
private IBaseDeviceLedgerService baseDeviceLedgerService;
/**
*
* 使aucma-baseBaseDeviceLedgerDmsBaseDeviceLedger
*
* @return
*//*
// //@PreAuthorize("@ss.hasPermi('qms:checkrule:list')" )
* @param deviceCode
* @return
*/
@GetMapping("/getDeviceByDeviceCode/{deviceCode}")
public AjaxResult getDeviceByDeviceCode(@PathVariable("deviceCode") String deviceCode) {
DmsBaseDeviceLedger dmsBaseDeviceLedger = baseDeviceLedgerService.selectDmsBaseDeviceLedgerByDeviceCode(deviceCode);
return success(dmsBaseDeviceLedger);
BaseDeviceLedger query = new BaseDeviceLedger();
query.setDeviceCode(deviceCode);
query.setIsFlag(1L); // 只查询有效设备
List<BaseDeviceLedger> list = baseDeviceLedgerService.selectBaseDeviceLedgerList(query);
if (CollectionUtils.isEmpty(list)) {
return success(null);
}
// 转换为DmsBaseDeviceLedger返回保持PDA兼容性
DmsBaseDeviceLedger result = convertToDeviceLedger(list.get(0));
return success(convertDeviceLedgerToDto(result));
}
*/
/**
*
*
* @return
*//*
// //@PreAuthorize("@ss.hasPermi('qms:checkrule:list')" )
@GetMapping("/getOutsrcInfos")
public AjaxResult getOutsrcInfos() {
DmsBaseOutsrcInfo queryBaseOutsrcInfo = new DmsBaseOutsrcInfo();
queryBaseOutsrcInfo.setOutsrcStatus(DmsConstants.DMS_BASE_OUTSRC_INFO_STATUS_NROMAL);
List<DmsBaseOutsrcInfo> baseOutsrcInfos = dmsBaseOutsrcInfoService.selectDmsBaseOutsrcInfoList(queryBaseOutsrcInfo);
return success(baseOutsrcInfos);
}
*/
/**
/**
*
*//*
* 使aucma-baseBaseDeviceLedgerDmsBaseDeviceLedger
*
* @param deviceName
* @return
*/
@GetMapping("/likeDeviceName")
public AjaxResult likeDeviceName(String deviceName) {
List<DmsBaseDeviceLedger> deviceLedgerList = baseDeviceLedgerService.likeDeviceName(deviceName);
return success(deviceLedgerList);
BaseDeviceLedger query = new BaseDeviceLedger();
query.setDeviceName(deviceName);
query.setIsFlag(1L); // 只查询有效设备
List<BaseDeviceLedger> list = baseDeviceLedgerService.selectBaseDeviceLedgerList(query);
// 转换为DmsBaseDeviceLedger列表返回保持PDA兼容性
List<DmsBaseDeviceLedgerDTO> resultList = new ArrayList<>();
if (!CollectionUtils.isEmpty(list)) {
for (BaseDeviceLedger base : list) {
resultList.add(convertDeviceLedgerToDto(convertToDeviceLedger(base)));
}
}
return success(resultList);
}
*/
/**
* BaseDeviceLedgerDmsBaseDeviceLedger
* PDA
*
* @param base aucma-base
* @return DMS
*/
private DmsBaseDeviceLedger convertToDeviceLedger(BaseDeviceLedger base) {
if (base == null) {
return null;
}
DmsBaseDeviceLedger dms = new DmsBaseDeviceLedger();
dms.setDeviceId(base.getObjId());
dms.setDeviceCode(base.getDeviceCode());
dms.setDeviceName(base.getDeviceName());
dms.setDeviceTypeId(base.getDeviceType());
dms.setDeviceStatus(base.getDeviceStatus());
dms.setAssetNumber(base.getAssetCode());
dms.setIsFlag(base.getIsFlag());
dms.setSuplierName(base.getManufacturer());
dms.setDeviceSpec(base.getDeviceModel()); // 设备型号映射到设备规格
dms.setDeviceLocation(base.getUsedDepartment()); // 使用部门映射到设备位置
// 时间字段映射
dms.setCreateBy(parseLongSafely(base.getCreatedBy()));
dms.setCreateTime(base.getCreatedTime());
dms.setUpdateBy(parseLongSafely(base.getUpdatedBy()));
dms.setUpdateTime(base.getUpdatedTime());
return dms;
}
/**
* DmsBaseDeviceLedgerDmsBaseDeviceLedgerDTO
*
* @param entity DmsBaseDeviceLedger
* @return DTO
*/
private DmsBaseDeviceLedgerDTO convertDeviceLedgerToDto(DmsBaseDeviceLedger entity) {
if (entity == null) {
return null;
}
DmsBaseDeviceLedgerDTO dto = new DmsBaseDeviceLedgerDTO();
dto.setDeviceId(entity.getDeviceId());
dto.setDeviceCode(entity.getDeviceCode());
dto.setDeviceName(entity.getDeviceName());
dto.setStationId(entity.getStationId());
dto.setAssetNumber(entity.getAssetNumber());
dto.setDeviceLocation(entity.getDeviceLocation());
dto.setDeviceTypeId(entity.getDeviceTypeId());
dto.setDeviceSpec(entity.getDeviceSpec());
dto.setSupplierId(entity.getSupplierId());
dto.setDeviceStatus(entity.getDeviceStatus());
dto.setIsFlag(entity.getIsFlag());
dto.setSuplierName(entity.getSuplierName());
return dto;
}
/**
* StringLong
* @param value
* @return Longnull
*/
private Long parseLongSafely(String value) {
if (value == null || value.isEmpty()) {
return null;
}
try {
return Long.valueOf(value);
} catch (NumberFormatException e) {
return null;
}
}
/**
* DmsBaseDeviceLedgerDTODmsBaseDeviceLedger
*
* @param dto DTO
* @return DmsBaseDeviceLedger
*/
private DmsBaseDeviceLedger convertDtoToDeviceLedger(DmsBaseDeviceLedgerDTO dto) {
if (dto == null) {
return null;
}
DmsBaseDeviceLedger dms = new DmsBaseDeviceLedger();
dms.setDeviceId(dto.getDeviceId());
dms.setDeviceCode(dto.getDeviceCode());
dms.setDeviceName(dto.getDeviceName());
dms.setStationId(dto.getStationId());
dms.setAssetNumber(dto.getAssetNumber());
dms.setDeviceLocation(dto.getDeviceLocation());
dms.setDeviceTypeId(dto.getDeviceTypeId());
dms.setDeviceSpec(dto.getDeviceSpec());
dms.setSupplierId(dto.getSupplierId());
dms.setDeviceStatus(dto.getDeviceStatus());
dms.setIsFlag(dto.getIsFlag());
dms.setSuplierName(dto.getSuplierName());
return dms;
}
/**
* PDA-
@ -198,35 +314,194 @@ public class DmsMobileController extends BaseController {
/**
*
*
*
* - PDA
* -
* - 12
*/
// //@PreAuthorize("@ss.hasPermi('qms:checkresultdetail:add')" )
////@Log(title = "故障报修工单", businessType = BusinessType.START)
@PostMapping("/startRepair")
public AjaxResult startRepair(@RequestBody DmsFaultInstanceActivity dmsFaultInstanceActivity) {
return success(dmsBillsFaultInstanceService.startRepair(dmsFaultInstanceActivity));
try {
Long repairInstanceId = dmsFaultInstanceActivity.getRepairInstanceId();
String repairer = dmsFaultInstanceActivity.getRepairer();
log.info("PDA开始维修故障报修ID: {}, 维修人: {}", repairInstanceId, repairer);
// ========== 步骤1调用原有的开始维修逻辑 ==========
int result = dmsBillsFaultInstanceService.startRepair(dmsFaultInstanceActivity);
// ========== 步骤2查询故障报修详情 ==========
DmsBillsFaultInstance fault = dmsBillsFaultInstanceService
.selectDmsBillsFaultInstanceByRepairInstanceId(repairInstanceId);
if (fault == null) {
log.warn("故障报修[{}]不存在", repairInstanceId);
return success(result);
}
// ========== 步骤3检查是否已有维修工单 ==========
DmsRepairWorkOrder existingOrder = dmsRepairWorkOrderService.selectByFaultInstanceId(repairInstanceId);
if (existingOrder == null) {
// ========== 步骤4【断点1】自动创建维修工单 ==========
DmsRepairWorkOrder newOrder = new DmsRepairWorkOrder();
newOrder.setFaultInstanceId(repairInstanceId);
newOrder.setDeviceId(fault.getDeviceId());
newOrder.setFaultType(fault.getFaultType());
newOrder.setFaultDescription(fault.getFaultDescription());
newOrder.setRepairType(fault.getRepairType());
newOrder.setOrderStatus("2"); // 直接设为维修中PDA开始维修即进入维修状态
newOrder.setPriority("3"); // 默认中优先级
newOrder.setActualStartTime(new Date());
// 设置执行人信息
if (dmsFaultInstanceActivity.getHandleUserId() != null) {
newOrder.setExecutorId(dmsFaultInstanceActivity.getHandleUserId());
}
if (repairer != null && !repairer.isEmpty()) {
newOrder.setExecutorName(repairer);
}
dmsRepairWorkOrderService.insertDmsRepairWorkOrder(newOrder);
log.info("【断点1】PDA自动创建维修工单工单ID: {}, 工单编号: {}",
newOrder.getWorkOrderId(), newOrder.getWorkOrderCode());
// ========== 步骤5【断点2】自动创建派工计划并接收 ==========
DmsDispatchPlan plan = new DmsDispatchPlan();
plan.setWorkOrderId(newOrder.getWorkOrderId());
plan.setWorkOrderCode(newOrder.getWorkOrderCode());
plan.setDeviceId(fault.getDeviceId());
plan.setDispatchType("1"); // 单人派工
plan.setReceiveStatus("1"); // 直接设为已接收PDA开始维修即表示已接收
plan.setExecutionStatus("1"); // 执行中
if (dmsFaultInstanceActivity.getHandleUserId() != null) {
plan.setExecutorId(dmsFaultInstanceActivity.getHandleUserId());
}
if (repairer != null && !repairer.isEmpty()) {
plan.setExecutorName(repairer);
}
plan.setDispatchNotes("由PDA端开始维修自动生成");
dmsDispatchPlanService.insertDmsDispatchPlan(plan);
log.info("【断点2】PDA自动创建派工计划并接收计划ID: {}", plan.getPlanId());
} else {
// 已有维修工单,更新状态为维修中
if (!"2".equals(existingOrder.getOrderStatus()) && !"3".equals(existingOrder.getOrderStatus())) {
DmsRepairWorkOrder updateOrder = new DmsRepairWorkOrder();
updateOrder.setWorkOrderId(existingOrder.getWorkOrderId());
updateOrder.setOrderStatus("2"); // 维修中
updateOrder.setActualStartTime(new Date());
if (dmsFaultInstanceActivity.getHandleUserId() != null) {
updateOrder.setExecutorId(dmsFaultInstanceActivity.getHandleUserId());
}
if (repairer != null && !repairer.isEmpty()) {
updateOrder.setExecutorName(repairer);
}
dmsRepairWorkOrderService.updateDmsRepairWorkOrder(updateOrder);
log.info("PDA更新已有维修工单[{}]状态为维修中", existingOrder.getWorkOrderCode());
}
}
return success(result);
} catch (Exception e) {
log.error("PDA开始维修失败", e);
return error("开始维修失败:" + e.getMessage());
}
}
/**
*
*
*
* - PDA
* -
* - 3
*/
// //@PreAuthorize("@ss.hasPermi('qms:checkresultdetail:add')" )
////@Log(title = "故障报修工单", businessType = BusinessType.COMPLETE)
@PostMapping("/completeRepair")
public AjaxResult completeRepair(DmsFaultInstanceActivity dmsFaultInstanceActivity,@RequestParam(value = "files", required = false) List<MultipartFile> files) throws JsonProcessingException {
dmsFaultInstanceActivity.setRepairConfirm(2);
dmsFaultInstanceActivity.setConfirmTime(new Date());
String parts1 = dmsFaultInstanceActivity.getParts1();
ObjectMapper objectMapper = new ObjectMapper();
List<DmsFaultCompentsParts> parts2 = objectMapper.readValue(parts1, new TypeReference<List<DmsFaultCompentsParts>>() {});
dmsFaultInstanceActivity.setParts(parts2);
List < String > fileUrls = new ArrayList<>();
/* for (MultipartFile file : files) {
R<SysFile> sysFileR = remoteFileService.upload(file);
SysFile sysFile = sysFileR.getData();
fileUrls.add(sysFile.getUrl());
}*/
dmsFaultInstanceActivity.setFileUrls(fileUrls);
return success(dmsBillsFaultInstanceService.completeRepair(dmsFaultInstanceActivity));
public AjaxResult completeRepair(DmsFaultInstanceActivity dmsFaultInstanceActivity, @RequestParam(value = "files", required = false) List<MultipartFile> files) throws JsonProcessingException {
try {
Long repairInstanceId = dmsFaultInstanceActivity.getRepairInstanceId();
String repairer = dmsFaultInstanceActivity.getRepairer();
log.info("PDA完成维修故障报修ID: {}, 维修人: {}", repairInstanceId, repairer);
// ========== 步骤1原有逻辑 - 设置确认信息和解析配件 ==========
dmsFaultInstanceActivity.setRepairConfirm(2);
dmsFaultInstanceActivity.setConfirmTime(new Date());
String parts1 = dmsFaultInstanceActivity.getParts1();
if (parts1 != null && !parts1.isEmpty()) {
ObjectMapper objectMapper = new ObjectMapper();
List<DmsFaultCompentsParts> parts2 = objectMapper.readValue(parts1, new TypeReference<List<DmsFaultCompentsParts>>() {});
dmsFaultInstanceActivity.setParts(parts2);
}
List<String> fileUrls = new ArrayList<>();
dmsFaultInstanceActivity.setFileUrls(fileUrls);
// ========== 步骤2调用原有的完成维修逻辑 ==========
int result = dmsBillsFaultInstanceService.completeRepair(dmsFaultInstanceActivity);
// ========== 步骤3查询关联的维修工单 ==========
DmsRepairWorkOrder workOrder = dmsRepairWorkOrderService.selectByFaultInstanceId(repairInstanceId);
if (workOrder != null) {
// ========== 步骤4更新维修工单状态为已完成 ==========
DmsRepairWorkOrder updateOrder = new DmsRepairWorkOrder();
updateOrder.setWorkOrderId(workOrder.getWorkOrderId());
updateOrder.setOrderStatus("3"); // 已完成
updateOrder.setActualEndTime(new Date());
updateOrder.setRepairResult(dmsFaultInstanceActivity.getRepairContent());
dmsRepairWorkOrderService.updateDmsRepairWorkOrder(updateOrder);
log.info("PDA更新维修工单[{}]状态为已完成", workOrder.getWorkOrderCode());
// ========== 步骤5【断点3】自动创建维修记录 ==========
DmsRepairRecord record = new DmsRepairRecord();
record.setWorkOrderId(workOrder.getWorkOrderId());
record.setWorkOrderCode(workOrder.getWorkOrderCode());
record.setDeviceId(workOrder.getDeviceId());
record.setDeviceCode(workOrder.getDeviceCode());
record.setDeviceName(workOrder.getDeviceName());
record.setFaultPhenomenon(workOrder.getFaultDescription());
// 维修人员信息
if (dmsFaultInstanceActivity.getHandleUserId() != null) {
record.setRepairerId(dmsFaultInstanceActivity.getHandleUserId());
} else if (workOrder.getExecutorId() != null) {
record.setRepairerId(workOrder.getExecutorId());
}
if (repairer != null && !repairer.isEmpty()) {
record.setRepairerName(repairer);
} else if (workOrder.getExecutorName() != null) {
record.setRepairerName(workOrder.getExecutorName());
}
// 维修时间
record.setStartTime(workOrder.getActualStartTime());
record.setEndTime(new Date());
// 维修内容
record.setRepairResult(dmsFaultInstanceActivity.getRepairContent());
// 默认未存档
record.setIsArchived("0");
dmsRepairRecordService.insertDmsRepairRecord(record);
log.info("【断点3】PDA自动创建维修记录记录ID: {}", record.getRecordId());
// ========== 步骤6更新派工计划状态为已完成 ==========
DmsDispatchPlan queryPlan = new DmsDispatchPlan();
queryPlan.setWorkOrderId(workOrder.getWorkOrderId());
List<DmsDispatchPlan> plans = dmsDispatchPlanService.selectDmsDispatchPlanList(queryPlan);
if (!CollectionUtils.isEmpty(plans)) {
DmsDispatchPlan updatePlan = new DmsDispatchPlan();
updatePlan.setPlanId(plans.get(0).getPlanId());
updatePlan.setExecutionStatus("2"); // 已完成
dmsDispatchPlanService.updateDmsDispatchPlan(updatePlan);
log.info("PDA更新派工计划[{}]状态为已完成", plans.get(0).getPlanCode());
}
} else {
log.warn("故障报修[{}]无关联维修工单,跳过维修记录创建", repairInstanceId);
}
return success(result);
} catch (Exception e) {
log.error("PDA完成维修失败", e);
return error("完成维修失败:" + e.getMessage());
}
}

@ -0,0 +1,186 @@
package com.aucma.dms.domain.dto;
import com.aucma.common.annotation.Excel;
import com.aucma.dms.domain.DmsBaseEntity;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import java.io.Serializable;
public class DmsBaseDeviceLedgerDTO implements Serializable {
private static final long serialVersionUID = 1L;
/** 主键标识 */
private Long deviceId;
/** 设备编号 */
@Excel(name = "设备编号")
private String deviceCode;
/** 设备名称 */
@Excel(name = "设备名称")
private String deviceName;
/** 所属工位,关联pd_base_station_info的station_id */
@Excel(name = "所属工位,关联pd_base_station_info的station_id")
private String stationId;
/** 资产编号 */
@Excel(name = "资产编号")
private String assetNumber;
/** 设备位置 */
@Excel(name = "设备位置")
private String deviceLocation;
/** 设备类型,关联dm_base_device_type的device_type_id */
@Excel(name = "设备类型,关联dm_base_device_type的device_type_id")
private String deviceTypeId;
/** 设备规格 */
@Excel(name = "设备规格")
private String deviceSpec;
/** 供应商,关联dm_base_device_supplier的supplier_id */
@Excel(name = "供应商,关联dm_base_device_supplier的supplier_id")
private String supplierId;
/** 设备状态 */
@Excel(name = "设备状态")
private Long deviceStatus;
/** 是否标识1-是2-否 */
@Excel(name = "是否标识1-是2-否")
private Long isFlag;
private String suplierName;
public String getSuplierName() {
return suplierName;
}
public void setSuplierName(String suplierName) {
this.suplierName = suplierName;
}
public void setDeviceId(Long deviceId)
{
this.deviceId = deviceId;
}
public Long getDeviceId()
{
return deviceId;
}
public void setDeviceCode(String deviceCode)
{
this.deviceCode = deviceCode;
}
public String getDeviceCode()
{
return deviceCode;
}
public void setDeviceName(String deviceName)
{
this.deviceName = deviceName;
}
public String getDeviceName()
{
return deviceName;
}
public void setStationId(String stationId)
{
this.stationId = stationId;
}
public String getStationId()
{
return stationId;
}
public void setAssetNumber(String assetNumber)
{
this.assetNumber = assetNumber;
}
public String getAssetNumber()
{
return assetNumber;
}
public void setDeviceLocation(String deviceLocation)
{
this.deviceLocation = deviceLocation;
}
public String getDeviceLocation()
{
return deviceLocation;
}
public void setDeviceTypeId(String deviceTypeId)
{
this.deviceTypeId = deviceTypeId;
}
public String getDeviceTypeId()
{
return deviceTypeId;
}
public void setDeviceSpec(String deviceSpec)
{
this.deviceSpec = deviceSpec;
}
public String getDeviceSpec()
{
return deviceSpec;
}
public void setSupplierId(String supplierId)
{
this.supplierId = supplierId;
}
public String getSupplierId()
{
return supplierId;
}
public void setDeviceStatus(Long deviceStatus)
{
this.deviceStatus = deviceStatus;
}
public Long getDeviceStatus()
{
return deviceStatus;
}
public void setIsFlag(Long isFlag)
{
this.isFlag = isFlag;
}
public Long getIsFlag()
{
return isFlag;
}
@Override
public String toString() {
return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
.append("deviceId", getDeviceId())
.append("deviceCode", getDeviceCode())
.append("deviceName", getDeviceName())
.append("stationId", getStationId())
.append("assetNumber", getAssetNumber())
.append("deviceLocation", getDeviceLocation())
.append("deviceTypeId", getDeviceTypeId())
.append("deviceSpec", getDeviceSpec())
.append("supplierId", getSupplierId())
.append("deviceStatus", getDeviceStatus())
.append("isFlag", getIsFlag())
.toString();
}
}

@ -91,4 +91,12 @@ public interface IDmsRepairWorkOrderService {
* @return
*/
int approveWorkOrder(DmsRepairWorkOrder dmsRepairWorkOrder);
/**
* ID
*
* @param faultInstanceId ID
* @return
*/
DmsRepairWorkOrder selectByFaultInstanceId(Long faultInstanceId);
}

@ -442,4 +442,15 @@ public class DmsRepairWorkOrderServiceImpl implements IDmsRepairWorkOrderService
log.error("为维修工单[{}]创建维修记录失败: {}", workOrder.getWorkOrderCode(), e.getMessage());
}
}
/**
* ID
*
* @param faultInstanceId ID
* @return
*/
@Override
public DmsRepairWorkOrder selectByFaultInstanceId(Long faultInstanceId) {
return dmsRepairWorkOrderMapper.selectByFaultInstanceId(faultInstanceId);
}
}

Loading…
Cancel
Save