Showing
18 changed files
with
2560 additions
and
0 deletions
| 1 | +package com.apple.erp.controller; | ||
| 2 | + | ||
| 3 | +import com.apple.erp.dto.ExceptionWorkorderAddReq; | ||
| 4 | +import com.apple.erp.dto.ExceptionWorkorderQueryReq; | ||
| 5 | +import com.apple.erp.dto.ExceptionWorkorderRes; | ||
| 6 | +import com.apple.erp.dto.ExceptionWorkorderStatusUpdateReq; | ||
| 7 | +import com.apple.erp.dto.ExceptionWorkorderUpdateReq; | ||
| 8 | +import com.apple.erp.service.ExceptionWorkorderService; | ||
| 9 | +import com.apple.erp.dto.response.ApiRes; | ||
| 10 | +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; | ||
| 11 | +import io.swagger.v3.oas.annotations.Operation; | ||
| 12 | +import io.swagger.v3.oas.annotations.Parameter; | ||
| 13 | +import io.swagger.v3.oas.annotations.tags.Tag; | ||
| 14 | +import org.springframework.beans.factory.annotation.Autowired; | ||
| 15 | +import org.springframework.security.access.prepost.PreAuthorize; | ||
| 16 | +import org.springframework.validation.annotation.Validated; | ||
| 17 | +import org.springframework.web.bind.annotation.*; | ||
| 18 | + | ||
| 19 | +import javax.validation.Valid; | ||
| 20 | +import java.util.List; | ||
| 21 | + | ||
| 22 | +/** | ||
| 23 | + * 异常工单Controller | ||
| 24 | + * | ||
| 25 | + * @author Apple ERP System | ||
| 26 | + * @since 2025-01-27 | ||
| 27 | + */ | ||
| 28 | +@Tag(name = "异常工单管理", description = "异常工单相关接口") | ||
| 29 | +@RestController | ||
| 30 | +@RequestMapping("/api/exception-workorder") | ||
| 31 | +@Validated | ||
| 32 | +public class ExceptionWorkorderController { | ||
| 33 | + | ||
| 34 | + @Autowired | ||
| 35 | + private ExceptionWorkorderService exceptionWorkorderService; | ||
| 36 | + | ||
| 37 | + @Operation(summary = "分页查询异常工单列表", description = "根据条件分页查询异常工单列表") | ||
| 38 | + @GetMapping("/list") | ||
| 39 | + @PreAuthorize("hasAuthority('exception:workorder:list')") | ||
| 40 | + public ApiRes<Page<ExceptionWorkorderRes>> getExceptionWorkorderList(@Valid ExceptionWorkorderQueryReq queryReq) { | ||
| 41 | + Page<ExceptionWorkorderRes> page = exceptionWorkorderService.getExceptionWorkorderList(queryReq); | ||
| 42 | + return ApiRes.success(page); | ||
| 43 | + } | ||
| 44 | + | ||
| 45 | + @Operation(summary = "获取异常工单详情", description = "根据工单ID获取异常工单详细信息,包含处理日志") | ||
| 46 | + @GetMapping("/{workorderId}") | ||
| 47 | + @PreAuthorize("hasAuthority('exception:workorder:detail')") | ||
| 48 | + public ApiRes<ExceptionWorkorderRes> getExceptionWorkorderDetail( | ||
| 49 | + @Parameter(description = "工单ID", required = true) @PathVariable Long workorderId) { | ||
| 50 | + ExceptionWorkorderRes workorderRes = exceptionWorkorderService.getExceptionWorkorderDetail(workorderId); | ||
| 51 | + if (workorderRes != null) { | ||
| 52 | + return ApiRes.success(workorderRes); | ||
| 53 | + } | ||
| 54 | + return ApiRes.error("异常工单不存在或已删除"); | ||
| 55 | + } | ||
| 56 | + | ||
| 57 | + @Operation(summary = "新增异常工单", description = "创建新的异常工单") | ||
| 58 | + @PostMapping | ||
| 59 | + @PreAuthorize("hasAuthority('exception:workorder:add')") | ||
| 60 | + public ApiRes<Void> addExceptionWorkorder(@Valid @RequestBody ExceptionWorkorderAddReq addReq) { | ||
| 61 | + try { | ||
| 62 | + boolean result = exceptionWorkorderService.addExceptionWorkorder(addReq); | ||
| 63 | + if (result) { | ||
| 64 | + return ApiRes.success("新增异常工单成功", null); | ||
| 65 | + } else { | ||
| 66 | + return ApiRes.error("新增异常工单失败"); | ||
| 67 | + } | ||
| 68 | + } catch (Exception e) { | ||
| 69 | + return ApiRes.error("新增异常工单失败: " + e.getMessage()); | ||
| 70 | + } | ||
| 71 | + } | ||
| 72 | + | ||
| 73 | + @Operation(summary = "更新异常工单", description = "更新异常工单信息") | ||
| 74 | + @PutMapping | ||
| 75 | + @PreAuthorize("hasAuthority('exception:workorder:edit')") | ||
| 76 | + public ApiRes<Void> updateExceptionWorkorder(@Valid @RequestBody ExceptionWorkorderUpdateReq updateReq) { | ||
| 77 | + try { | ||
| 78 | + boolean result = exceptionWorkorderService.updateExceptionWorkorder(updateReq); | ||
| 79 | + if (result) { | ||
| 80 | + return ApiRes.success("更新异常工单成功", null); | ||
| 81 | + } else { | ||
| 82 | + return ApiRes.error("更新异常工单失败"); | ||
| 83 | + } | ||
| 84 | + } catch (Exception e) { | ||
| 85 | + return ApiRes.error("更新异常工单失败: " + e.getMessage()); | ||
| 86 | + } | ||
| 87 | + } | ||
| 88 | + | ||
| 89 | + @Operation(summary = "更新工单状态", description = "更新异常工单状态并记录处理日志") | ||
| 90 | + @PostMapping("/status") | ||
| 91 | + @PreAuthorize("hasAuthority('exception:workorder:edit')") | ||
| 92 | + public ApiRes<Void> updateWorkorderStatus(@Valid @RequestBody ExceptionWorkorderStatusUpdateReq statusUpdateReq) { | ||
| 93 | + try { | ||
| 94 | + boolean result = exceptionWorkorderService.updateWorkorderStatus(statusUpdateReq); | ||
| 95 | + if (result) { | ||
| 96 | + return ApiRes.success("更新工单状态成功", null); | ||
| 97 | + } else { | ||
| 98 | + return ApiRes.error("更新工单状态失败"); | ||
| 99 | + } | ||
| 100 | + } catch (Exception e) { | ||
| 101 | + return ApiRes.error("更新工单状态失败: " + e.getMessage()); | ||
| 102 | + } | ||
| 103 | + } | ||
| 104 | + | ||
| 105 | + @Operation(summary = "删除异常工单", description = "根据工单ID逻辑删除异常工单") | ||
| 106 | + @DeleteMapping("/{workorderId}") | ||
| 107 | + @PreAuthorize("hasAuthority('exception:workorder:delete')") | ||
| 108 | + public ApiRes<Void> deleteExceptionWorkorder( | ||
| 109 | + @Parameter(description = "工单ID", required = true) @PathVariable Long workorderId) { | ||
| 110 | + try { | ||
| 111 | + boolean result = exceptionWorkorderService.deleteExceptionWorkorder(workorderId); | ||
| 112 | + if (result) { | ||
| 113 | + return ApiRes.success("删除异常工单成功", null); | ||
| 114 | + } else { | ||
| 115 | + return ApiRes.error("删除异常工单失败"); | ||
| 116 | + } | ||
| 117 | + } catch (Exception e) { | ||
| 118 | + return ApiRes.error("删除异常工单失败: " + e.getMessage()); | ||
| 119 | + } | ||
| 120 | + } | ||
| 121 | + | ||
| 122 | + @Operation(summary = "批量删除异常工单", description = "根据工单ID列表批量逻辑删除异常工单") | ||
| 123 | + @DeleteMapping("/batch") | ||
| 124 | + @PreAuthorize("hasAuthority('exception:workorder:delete')") | ||
| 125 | + public ApiRes<Void> batchDeleteExceptionWorkorders( | ||
| 126 | + @Parameter(description = "工单ID列表", required = true) @RequestBody List<Long> workorderIds) { | ||
| 127 | + try { | ||
| 128 | + if (workorderIds == null || workorderIds.isEmpty()) { | ||
| 129 | + return ApiRes.error("工单ID列表不能为空"); | ||
| 130 | + } | ||
| 131 | + boolean result = exceptionWorkorderService.batchDeleteExceptionWorkorders(workorderIds); | ||
| 132 | + if (result) { | ||
| 133 | + return ApiRes.success("批量删除异常工单成功", null); | ||
| 134 | + } else { | ||
| 135 | + return ApiRes.error("批量删除异常工单失败"); | ||
| 136 | + } | ||
| 137 | + } catch (Exception e) { | ||
| 138 | + return ApiRes.error("批量删除异常工单失败: " + e.getMessage()); | ||
| 139 | + } | ||
| 140 | + } | ||
| 141 | + | ||
| 142 | + @Operation(summary = "批量更新工单状态", description = "批量更新异常工单状态") | ||
| 143 | + @PostMapping("/batch-status") | ||
| 144 | + @PreAuthorize("hasAuthority('exception:workorder:edit')") | ||
| 145 | + public ApiRes<Void> batchUpdateWorkorderStatus( | ||
| 146 | + @Parameter(description = "工单ID列表", required = true) @RequestParam List<Long> workorderIds, | ||
| 147 | + @Parameter(description = "工单状态", required = true) @RequestParam Integer workorderStatus, | ||
| 148 | + @Parameter(description = "处理人", required = true) @RequestParam String handlerUser) { | ||
| 149 | + try { | ||
| 150 | + if (workorderIds == null || workorderIds.isEmpty()) { | ||
| 151 | + return ApiRes.error("工单ID列表不能为空"); | ||
| 152 | + } | ||
| 153 | + boolean result = exceptionWorkorderService.batchUpdateWorkorderStatus(workorderIds, workorderStatus, handlerUser); | ||
| 154 | + if (result) { | ||
| 155 | + return ApiRes.success("批量更新工单状态成功", null); | ||
| 156 | + } else { | ||
| 157 | + return ApiRes.error("批量更新工单状态失败"); | ||
| 158 | + } | ||
| 159 | + } catch (Exception e) { | ||
| 160 | + return ApiRes.error("批量更新工单状态失败: " + e.getMessage()); | ||
| 161 | + } | ||
| 162 | + } | ||
| 163 | + | ||
| 164 | + @Operation(summary = "获取异常工单统计信息", description = "获取异常工单的统计信息") | ||
| 165 | + @GetMapping("/stats") | ||
| 166 | + @PreAuthorize("hasAuthority('exception:workorder:list')") | ||
| 167 | + public ApiRes<List<ExceptionWorkorderRes>> getExceptionWorkorderStats() { | ||
| 168 | + List<ExceptionWorkorderRes> stats = exceptionWorkorderService.getExceptionWorkorderStats(); | ||
| 169 | + return ApiRes.success(stats); | ||
| 170 | + } | ||
| 171 | +} |
| 1 | +package com.apple.erp.dto; | ||
| 2 | + | ||
| 3 | +import io.swagger.v3.oas.annotations.media.Schema; | ||
| 4 | +import lombok.Data; | ||
| 5 | + | ||
| 6 | +import javax.validation.constraints.NotBlank; | ||
| 7 | +import javax.validation.constraints.NotNull; | ||
| 8 | +import java.time.LocalDateTime; | ||
| 9 | + | ||
| 10 | +/** | ||
| 11 | + * 异常工单新增请求DTO | ||
| 12 | + * | ||
| 13 | + * @author Apple ERP System | ||
| 14 | + * @since 2025-01-27 | ||
| 15 | + */ | ||
| 16 | +@Data | ||
| 17 | +@Schema(description = "异常工单新增请求") | ||
| 18 | +public class ExceptionWorkorderAddReq { | ||
| 19 | + | ||
| 20 | + @NotBlank(message = "工单编号不能为空") | ||
| 21 | + @Schema(description = "工单编号", required = true) | ||
| 22 | + private String workorderNo; | ||
| 23 | + | ||
| 24 | + @Schema(description = "关联订单编号") | ||
| 25 | + private String orderNo; | ||
| 26 | + | ||
| 27 | + @Schema(description = "经销商编码") | ||
| 28 | + private String dealerCode; | ||
| 29 | + | ||
| 30 | + @Schema(description = "经销商名称") | ||
| 31 | + private String dealerName; | ||
| 32 | + | ||
| 33 | + @NotNull(message = "异常类型不能为空") | ||
| 34 | + @Schema(description = "异常类型(1-逻辑验证异常/2-源头验证异常/3-交叉验证异常)", required = true) | ||
| 35 | + private Integer exceptionType; | ||
| 36 | + | ||
| 37 | + @NotNull(message = "严重程度不能为空") | ||
| 38 | + @Schema(description = "严重程度(1-高/2-中/3-低)", required = true) | ||
| 39 | + private Integer severityLevel; | ||
| 40 | + | ||
| 41 | + @Schema(description = "工单状态(1-待处理/2-处理中/3-已解决/4-已关闭)") | ||
| 42 | + private Integer workorderStatus = 1; | ||
| 43 | + | ||
| 44 | + @Schema(description = "预计处理完成时间") | ||
| 45 | + private LocalDateTime expectCompleteTime; | ||
| 46 | + | ||
| 47 | + @Schema(description = "处理人") | ||
| 48 | + private String handlerUser; | ||
| 49 | + | ||
| 50 | + @Schema(description = "异常描述") | ||
| 51 | + private String exceptionDesc; | ||
| 52 | + | ||
| 53 | + @Schema(description = "处理建议") | ||
| 54 | + private String handleSuggest; | ||
| 55 | + | ||
| 56 | + @Schema(description = "数据来源") | ||
| 57 | + private String dataSource; | ||
| 58 | +} |
| 1 | +package com.apple.erp.dto; | ||
| 2 | + | ||
| 3 | +import com.fasterxml.jackson.annotation.JsonFormat; | ||
| 4 | +import io.swagger.v3.oas.annotations.media.Schema; | ||
| 5 | +import lombok.Data; | ||
| 6 | + | ||
| 7 | +import java.time.LocalDateTime; | ||
| 8 | + | ||
| 9 | +/** | ||
| 10 | + * 异常工单处理日志响应DTO | ||
| 11 | + * | ||
| 12 | + * @author Apple ERP System | ||
| 13 | + * @since 2025-01-27 | ||
| 14 | + */ | ||
| 15 | +@Data | ||
| 16 | +@Schema(description = "异常工单处理日志响应") | ||
| 17 | +public class ExceptionWorkorderLogRes { | ||
| 18 | + | ||
| 19 | + @Schema(description = "日志ID") | ||
| 20 | + private Long logId; | ||
| 21 | + | ||
| 22 | + @Schema(description = "关联工单ID") | ||
| 23 | + private Long workorderId; | ||
| 24 | + | ||
| 25 | + @Schema(description = "关联工单编号") | ||
| 26 | + private String workorderNo; | ||
| 27 | + | ||
| 28 | + @Schema(description = "处理人") | ||
| 29 | + private String handleUser; | ||
| 30 | + | ||
| 31 | + @Schema(description = "处理时间") | ||
| 32 | + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") | ||
| 33 | + private LocalDateTime handleTime; | ||
| 34 | + | ||
| 35 | + @Schema(description = "处理前状态") | ||
| 36 | + private Integer beforeStatus; | ||
| 37 | + | ||
| 38 | + @Schema(description = "处理前状态名称") | ||
| 39 | + private String beforeStatusName; | ||
| 40 | + | ||
| 41 | + @Schema(description = "处理后状态") | ||
| 42 | + private Integer afterStatus; | ||
| 43 | + | ||
| 44 | + @Schema(description = "处理后状态名称") | ||
| 45 | + private String afterStatusName; | ||
| 46 | + | ||
| 47 | + @Schema(description = "处理意见") | ||
| 48 | + private String handleOpinion; | ||
| 49 | + | ||
| 50 | + @Schema(description = "附件URL") | ||
| 51 | + private String attachUrl; | ||
| 52 | + | ||
| 53 | + @Schema(description = "创建者") | ||
| 54 | + private String createBy; | ||
| 55 | + | ||
| 56 | + @Schema(description = "创建时间") | ||
| 57 | + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") | ||
| 58 | + private LocalDateTime createTime; | ||
| 59 | +} |
| 1 | +package com.apple.erp.dto; | ||
| 2 | + | ||
| 3 | +import io.swagger.v3.oas.annotations.media.Schema; | ||
| 4 | +import lombok.Data; | ||
| 5 | + | ||
| 6 | +import java.time.LocalDateTime; | ||
| 7 | + | ||
| 8 | +/** | ||
| 9 | + * 异常工单查询请求DTO | ||
| 10 | + * | ||
| 11 | + * @author Apple ERP System | ||
| 12 | + * @since 2025-01-27 | ||
| 13 | + */ | ||
| 14 | +@Data | ||
| 15 | +@Schema(description = "异常工单查询请求") | ||
| 16 | +public class ExceptionWorkorderQueryReq { | ||
| 17 | + | ||
| 18 | + @Schema(description = "工单编号") | ||
| 19 | + private String workorderNo; | ||
| 20 | + | ||
| 21 | + @Schema(description = "关联订单编号") | ||
| 22 | + private String orderNo; | ||
| 23 | + | ||
| 24 | + @Schema(description = "经销商编码") | ||
| 25 | + private String dealerCode; | ||
| 26 | + | ||
| 27 | + @Schema(description = "经销商名称") | ||
| 28 | + private String dealerName; | ||
| 29 | + | ||
| 30 | + @Schema(description = "工单状态(1-待处理/2-处理中/3-已解决/4-已关闭)") | ||
| 31 | + private Integer workorderStatus; | ||
| 32 | + | ||
| 33 | + @Schema(description = "异常类型(1-逻辑验证异常/2-源头验证异常/3-交叉验证异常)") | ||
| 34 | + private Integer exceptionType; | ||
| 35 | + | ||
| 36 | + @Schema(description = "严重程度(1-高/2-中/3-低)") | ||
| 37 | + private Integer severityLevel; | ||
| 38 | + | ||
| 39 | + @Schema(description = "处理人") | ||
| 40 | + private String handlerUser; | ||
| 41 | + | ||
| 42 | + @Schema(description = "开始时间") | ||
| 43 | + private LocalDateTime startTime; | ||
| 44 | + | ||
| 45 | + @Schema(description = "结束时间") | ||
| 46 | + private LocalDateTime endTime; | ||
| 47 | + | ||
| 48 | + @Schema(description = "页码") | ||
| 49 | + private Integer pageNum = 1; | ||
| 50 | + | ||
| 51 | + @Schema(description = "每页大小") | ||
| 52 | + private Integer pageSize = 10; | ||
| 53 | +} |
| 1 | +package com.apple.erp.dto; | ||
| 2 | + | ||
| 3 | +import com.fasterxml.jackson.annotation.JsonFormat; | ||
| 4 | +import io.swagger.v3.oas.annotations.media.Schema; | ||
| 5 | +import lombok.Data; | ||
| 6 | + | ||
| 7 | +import java.time.LocalDateTime; | ||
| 8 | +import java.util.List; | ||
| 9 | + | ||
| 10 | +/** | ||
| 11 | + * 异常工单响应DTO | ||
| 12 | + * | ||
| 13 | + * @author Apple ERP System | ||
| 14 | + * @since 2025-01-27 | ||
| 15 | + */ | ||
| 16 | +@Data | ||
| 17 | +@Schema(description = "异常工单响应") | ||
| 18 | +public class ExceptionWorkorderRes { | ||
| 19 | + | ||
| 20 | + @Schema(description = "工单ID") | ||
| 21 | + private Long workorderId; | ||
| 22 | + | ||
| 23 | + @Schema(description = "工单编号") | ||
| 24 | + private String workorderNo; | ||
| 25 | + | ||
| 26 | + @Schema(description = "关联订单编号") | ||
| 27 | + private String orderNo; | ||
| 28 | + | ||
| 29 | + @Schema(description = "经销商编码") | ||
| 30 | + private String dealerCode; | ||
| 31 | + | ||
| 32 | + @Schema(description = "经销商名称") | ||
| 33 | + private String dealerName; | ||
| 34 | + | ||
| 35 | + @Schema(description = "异常类型(1-逻辑验证异常/2-源头验证异常/3-交叉验证异常)") | ||
| 36 | + private Integer exceptionType; | ||
| 37 | + | ||
| 38 | + @Schema(description = "异常类型名称") | ||
| 39 | + private String exceptionTypeName; | ||
| 40 | + | ||
| 41 | + @Schema(description = "严重程度(1-高/2-中/3-低)") | ||
| 42 | + private Integer severityLevel; | ||
| 43 | + | ||
| 44 | + @Schema(description = "严重程度名称") | ||
| 45 | + private String severityLevelName; | ||
| 46 | + | ||
| 47 | + @Schema(description = "工单状态(1-待处理/2-处理中/3-已解决/4-已关闭)") | ||
| 48 | + private Integer workorderStatus; | ||
| 49 | + | ||
| 50 | + @Schema(description = "工单状态名称") | ||
| 51 | + private String workorderStatusName; | ||
| 52 | + | ||
| 53 | + @Schema(description = "工单创建时间") | ||
| 54 | + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") | ||
| 55 | + private LocalDateTime createTime; | ||
| 56 | + | ||
| 57 | + @Schema(description = "预计处理完成时间") | ||
| 58 | + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") | ||
| 59 | + private LocalDateTime expectCompleteTime; | ||
| 60 | + | ||
| 61 | + @Schema(description = "处理人") | ||
| 62 | + private String handlerUser; | ||
| 63 | + | ||
| 64 | + @Schema(description = "异常描述") | ||
| 65 | + private String exceptionDesc; | ||
| 66 | + | ||
| 67 | + @Schema(description = "处理建议") | ||
| 68 | + private String handleSuggest; | ||
| 69 | + | ||
| 70 | + @Schema(description = "数据来源") | ||
| 71 | + private String dataSource; | ||
| 72 | + | ||
| 73 | + @Schema(description = "创建者") | ||
| 74 | + private String createBy; | ||
| 75 | + | ||
| 76 | + @Schema(description = "更新者") | ||
| 77 | + private String updateBy; | ||
| 78 | + | ||
| 79 | + @Schema(description = "更新时间") | ||
| 80 | + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") | ||
| 81 | + private LocalDateTime updateTime; | ||
| 82 | + | ||
| 83 | + @Schema(description = "处理日志列表") | ||
| 84 | + private List<ExceptionWorkorderLogRes> workorderLogs; | ||
| 85 | +} |
| 1 | +package com.apple.erp.dto; | ||
| 2 | + | ||
| 3 | +import io.swagger.v3.oas.annotations.media.Schema; | ||
| 4 | +import lombok.Data; | ||
| 5 | + | ||
| 6 | +import javax.validation.constraints.NotNull; | ||
| 7 | + | ||
| 8 | +/** | ||
| 9 | + * 异常工单状态更新请求DTO | ||
| 10 | + * | ||
| 11 | + * @author Apple ERP System | ||
| 12 | + * @since 2025-01-27 | ||
| 13 | + */ | ||
| 14 | +@Data | ||
| 15 | +@Schema(description = "异常工单状态更新请求") | ||
| 16 | +public class ExceptionWorkorderStatusUpdateReq { | ||
| 17 | + | ||
| 18 | + @NotNull(message = "工单ID不能为空") | ||
| 19 | + @Schema(description = "工单ID", required = true) | ||
| 20 | + private Long workorderId; | ||
| 21 | + | ||
| 22 | + @NotNull(message = "工单状态不能为空") | ||
| 23 | + @Schema(description = "工单状态(1-待处理/2-处理中/3-已解决/4-已关闭)", required = true) | ||
| 24 | + private Integer workorderStatus; | ||
| 25 | + | ||
| 26 | + @Schema(description = "处理人") | ||
| 27 | + private String handlerUser; | ||
| 28 | + | ||
| 29 | + @Schema(description = "处理意见") | ||
| 30 | + private String handleOpinion; | ||
| 31 | + | ||
| 32 | + @Schema(description = "附件URL") | ||
| 33 | + private String attachUrl; | ||
| 34 | +} |
| 1 | +package com.apple.erp.dto; | ||
| 2 | + | ||
| 3 | +import io.swagger.v3.oas.annotations.media.Schema; | ||
| 4 | +import lombok.Data; | ||
| 5 | + | ||
| 6 | +import javax.validation.constraints.NotNull; | ||
| 7 | +import java.time.LocalDateTime; | ||
| 8 | + | ||
| 9 | +/** | ||
| 10 | + * 异常工单更新请求DTO | ||
| 11 | + * | ||
| 12 | + * @author Apple ERP System | ||
| 13 | + * @since 2025-01-27 | ||
| 14 | + */ | ||
| 15 | +@Data | ||
| 16 | +@Schema(description = "异常工单更新请求") | ||
| 17 | +public class ExceptionWorkorderUpdateReq { | ||
| 18 | + | ||
| 19 | + @NotNull(message = "工单ID不能为空") | ||
| 20 | + @Schema(description = "工单ID", required = true) | ||
| 21 | + private Long workorderId; | ||
| 22 | + | ||
| 23 | + @Schema(description = "工单编号") | ||
| 24 | + private String workorderNo; | ||
| 25 | + | ||
| 26 | + @Schema(description = "关联订单编号") | ||
| 27 | + private String orderNo; | ||
| 28 | + | ||
| 29 | + @Schema(description = "经销商编码") | ||
| 30 | + private String dealerCode; | ||
| 31 | + | ||
| 32 | + @Schema(description = "经销商名称") | ||
| 33 | + private String dealerName; | ||
| 34 | + | ||
| 35 | + @Schema(description = "异常类型(1-逻辑验证异常/2-源头验证异常/3-交叉验证异常)") | ||
| 36 | + private Integer exceptionType; | ||
| 37 | + | ||
| 38 | + @Schema(description = "严重程度(1-高/2-中/3-低)") | ||
| 39 | + private Integer severityLevel; | ||
| 40 | + | ||
| 41 | + @Schema(description = "工单状态(1-待处理/2-处理中/3-已解决/4-已关闭)") | ||
| 42 | + private Integer workorderStatus; | ||
| 43 | + | ||
| 44 | + @Schema(description = "预计处理完成时间") | ||
| 45 | + private LocalDateTime expectCompleteTime; | ||
| 46 | + | ||
| 47 | + @Schema(description = "处理人") | ||
| 48 | + private String handlerUser; | ||
| 49 | + | ||
| 50 | + @Schema(description = "异常描述") | ||
| 51 | + private String exceptionDesc; | ||
| 52 | + | ||
| 53 | + @Schema(description = "处理建议") | ||
| 54 | + private String handleSuggest; | ||
| 55 | + | ||
| 56 | + @Schema(description = "数据来源") | ||
| 57 | + private String dataSource; | ||
| 58 | +} |
| 1 | +package com.apple.erp.entity; | ||
| 2 | + | ||
| 3 | +import com.baomidou.mybatisplus.annotation.IdType; | ||
| 4 | +import com.baomidou.mybatisplus.annotation.TableId; | ||
| 5 | +import com.baomidou.mybatisplus.annotation.TableName; | ||
| 6 | +import io.swagger.v3.oas.annotations.media.Schema; | ||
| 7 | +import lombok.Data; | ||
| 8 | +import lombok.EqualsAndHashCode; | ||
| 9 | + | ||
| 10 | +import java.time.LocalDateTime; | ||
| 11 | + | ||
| 12 | +/** | ||
| 13 | + * 异常工单表实体类 | ||
| 14 | + * | ||
| 15 | + * @author Apple ERP System | ||
| 16 | + * @since 2025-01-27 | ||
| 17 | + */ | ||
| 18 | +@Data | ||
| 19 | +@EqualsAndHashCode(callSuper = false) | ||
| 20 | +@TableName("t_exception_workorder") | ||
| 21 | +@Schema(description = "异常工单表") | ||
| 22 | +public class ExceptionWorkorder { | ||
| 23 | + | ||
| 24 | + @TableId(value = "workorder_id", type = IdType.AUTO) | ||
| 25 | + @Schema(description = "工单ID") | ||
| 26 | + private Long workorderId; | ||
| 27 | + | ||
| 28 | + @Schema(description = "工单编号") | ||
| 29 | + private String workorderNo; | ||
| 30 | + | ||
| 31 | + @Schema(description = "关联订单编号") | ||
| 32 | + private String orderNo; | ||
| 33 | + | ||
| 34 | + @Schema(description = "经销商编码") | ||
| 35 | + private String dealerCode; | ||
| 36 | + | ||
| 37 | + @Schema(description = "经销商名称") | ||
| 38 | + private String dealerName; | ||
| 39 | + | ||
| 40 | + @Schema(description = "异常类型(1-逻辑验证异常/2-源头验证异常/3-交叉验证异常)") | ||
| 41 | + private Integer exceptionType; | ||
| 42 | + | ||
| 43 | + @Schema(description = "严重程度(1-高/2-中/3-低)") | ||
| 44 | + private Integer severityLevel; | ||
| 45 | + | ||
| 46 | + @Schema(description = "工单状态(1-待处理/2-处理中/3-已解决/4-已关闭)") | ||
| 47 | + private Integer workorderStatus; | ||
| 48 | + | ||
| 49 | + @Schema(description = "工单创建时间") | ||
| 50 | + private LocalDateTime createTime; | ||
| 51 | + | ||
| 52 | + @Schema(description = "预计处理完成时间") | ||
| 53 | + private LocalDateTime expectCompleteTime; | ||
| 54 | + | ||
| 55 | + @Schema(description = "处理人") | ||
| 56 | + private String handlerUser; | ||
| 57 | + | ||
| 58 | + @Schema(description = "异常描述") | ||
| 59 | + private String exceptionDesc; | ||
| 60 | + | ||
| 61 | + @Schema(description = "处理建议") | ||
| 62 | + private String handleSuggest; | ||
| 63 | + | ||
| 64 | + @Schema(description = "数据来源") | ||
| 65 | + private String dataSource; | ||
| 66 | + | ||
| 67 | + @Schema(description = "创建者") | ||
| 68 | + private String createBy; | ||
| 69 | + | ||
| 70 | + @Schema(description = "更新者") | ||
| 71 | + private String updateBy; | ||
| 72 | + | ||
| 73 | + @Schema(description = "更新时间") | ||
| 74 | + private LocalDateTime updateTime; | ||
| 75 | + | ||
| 76 | + @Schema(description = "删除标志(0代表存在 2代表删除)") | ||
| 77 | + private String delFlag; | ||
| 78 | +} |
| 1 | +package com.apple.erp.entity; | ||
| 2 | + | ||
| 3 | +import com.baomidou.mybatisplus.annotation.IdType; | ||
| 4 | +import com.baomidou.mybatisplus.annotation.TableId; | ||
| 5 | +import com.baomidou.mybatisplus.annotation.TableName; | ||
| 6 | +import io.swagger.v3.oas.annotations.media.Schema; | ||
| 7 | +import lombok.Data; | ||
| 8 | +import lombok.EqualsAndHashCode; | ||
| 9 | + | ||
| 10 | +import java.time.LocalDateTime; | ||
| 11 | + | ||
| 12 | +/** | ||
| 13 | + * 异常工单处理日志表实体类 | ||
| 14 | + * | ||
| 15 | + * @author Apple ERP System | ||
| 16 | + * @since 2025-01-27 | ||
| 17 | + */ | ||
| 18 | +@Data | ||
| 19 | +@EqualsAndHashCode(callSuper = false) | ||
| 20 | +@TableName("t_exception_workorder_log") | ||
| 21 | +@Schema(description = "异常工单处理日志表") | ||
| 22 | +public class ExceptionWorkorderLog { | ||
| 23 | + | ||
| 24 | + @TableId(value = "log_id", type = IdType.AUTO) | ||
| 25 | + @Schema(description = "日志ID") | ||
| 26 | + private Long logId; | ||
| 27 | + | ||
| 28 | + @Schema(description = "关联工单ID") | ||
| 29 | + private Long workorderId; | ||
| 30 | + | ||
| 31 | + @Schema(description = "关联工单编号") | ||
| 32 | + private String workorderNo; | ||
| 33 | + | ||
| 34 | + @Schema(description = "处理人") | ||
| 35 | + private String handleUser; | ||
| 36 | + | ||
| 37 | + @Schema(description = "处理时间") | ||
| 38 | + private LocalDateTime handleTime; | ||
| 39 | + | ||
| 40 | + @Schema(description = "处理前状态") | ||
| 41 | + private Integer beforeStatus; | ||
| 42 | + | ||
| 43 | + @Schema(description = "处理后状态") | ||
| 44 | + private Integer afterStatus; | ||
| 45 | + | ||
| 46 | + @Schema(description = "处理意见") | ||
| 47 | + private String handleOpinion; | ||
| 48 | + | ||
| 49 | + @Schema(description = "附件URL") | ||
| 50 | + private String attachUrl; | ||
| 51 | + | ||
| 52 | + @Schema(description = "创建者") | ||
| 53 | + private String createBy; | ||
| 54 | + | ||
| 55 | + @Schema(description = "创建时间") | ||
| 56 | + private LocalDateTime createTime; | ||
| 57 | + | ||
| 58 | + @Schema(description = "更新者") | ||
| 59 | + private String updateBy; | ||
| 60 | + | ||
| 61 | + @Schema(description = "更新时间") | ||
| 62 | + private LocalDateTime updateTime; | ||
| 63 | + | ||
| 64 | + @Schema(description = "删除标志(0代表存在 2代表删除)") | ||
| 65 | + private String delFlag; | ||
| 66 | +} |
| 1 | +package com.apple.erp.mapper; | ||
| 2 | + | ||
| 3 | +import com.apple.erp.dto.ExceptionWorkorderLogRes; | ||
| 4 | +import com.apple.erp.entity.ExceptionWorkorderLog; | ||
| 5 | +import com.baomidou.mybatisplus.core.mapper.BaseMapper; | ||
| 6 | +import org.apache.ibatis.annotations.Mapper; | ||
| 7 | +import org.apache.ibatis.annotations.Param; | ||
| 8 | + | ||
| 9 | +import java.util.List; | ||
| 10 | + | ||
| 11 | +/** | ||
| 12 | + * 异常工单处理日志Mapper接口 | ||
| 13 | + * | ||
| 14 | + * @author Apple ERP System | ||
| 15 | + * @since 2025-01-27 | ||
| 16 | + */ | ||
| 17 | +@Mapper | ||
| 18 | +public interface ExceptionWorkorderLogMapper extends BaseMapper<ExceptionWorkorderLog> { | ||
| 19 | + | ||
| 20 | + /** | ||
| 21 | + * 根据工单ID获取处理日志列表 | ||
| 22 | + * | ||
| 23 | + * @param workorderId 工单ID | ||
| 24 | + * @return 处理日志列表 | ||
| 25 | + */ | ||
| 26 | + List<ExceptionWorkorderLogRes> selectWorkorderLogsByWorkorderId(@Param("workorderId") Long workorderId); | ||
| 27 | + | ||
| 28 | + /** | ||
| 29 | + * 根据工单ID列表批量获取处理日志 | ||
| 30 | + * | ||
| 31 | + * @param workorderIds 工单ID列表 | ||
| 32 | + * @return 处理日志列表 | ||
| 33 | + */ | ||
| 34 | + List<ExceptionWorkorderLogRes> selectWorkorderLogsByWorkorderIds(@Param("workorderIds") List<Long> workorderIds); | ||
| 35 | +} |
| 1 | +package com.apple.erp.mapper; | ||
| 2 | + | ||
| 3 | +import com.apple.erp.dto.ExceptionWorkorderQueryReq; | ||
| 4 | +import com.apple.erp.dto.ExceptionWorkorderRes; | ||
| 5 | +import com.apple.erp.entity.ExceptionWorkorder; | ||
| 6 | +import com.baomidou.mybatisplus.core.mapper.BaseMapper; | ||
| 7 | +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; | ||
| 8 | +import org.apache.ibatis.annotations.Mapper; | ||
| 9 | +import org.apache.ibatis.annotations.Param; | ||
| 10 | + | ||
| 11 | +import java.util.List; | ||
| 12 | + | ||
| 13 | +/** | ||
| 14 | + * 异常工单Mapper接口 | ||
| 15 | + * | ||
| 16 | + * @author Apple ERP System | ||
| 17 | + * @since 2025-01-27 | ||
| 18 | + */ | ||
| 19 | +@Mapper | ||
| 20 | +public interface ExceptionWorkorderMapper extends BaseMapper<ExceptionWorkorder> { | ||
| 21 | + | ||
| 22 | + /** | ||
| 23 | + * 分页查询异常工单列表 | ||
| 24 | + * | ||
| 25 | + * @param page 分页参数 | ||
| 26 | + * @param queryReq 查询条件 | ||
| 27 | + * @return 异常工单列表 | ||
| 28 | + */ | ||
| 29 | + Page<ExceptionWorkorderRes> selectExceptionWorkorderPage(Page<ExceptionWorkorderRes> page, @Param("query") ExceptionWorkorderQueryReq queryReq); | ||
| 30 | + | ||
| 31 | + /** | ||
| 32 | + * 根据工单ID获取异常工单详情 | ||
| 33 | + * | ||
| 34 | + * @param workorderId 工单ID | ||
| 35 | + * @return 异常工单详情 | ||
| 36 | + */ | ||
| 37 | + ExceptionWorkorderRes selectExceptionWorkorderDetail(@Param("workorderId") Long workorderId); | ||
| 38 | + | ||
| 39 | + /** | ||
| 40 | + * 获取异常工单统计信息 | ||
| 41 | + * | ||
| 42 | + * @return 统计信息 | ||
| 43 | + */ | ||
| 44 | + List<ExceptionWorkorderRes> selectExceptionWorkorderStats(); | ||
| 45 | + | ||
| 46 | + /** | ||
| 47 | + * 批量更新工单状态 | ||
| 48 | + * | ||
| 49 | + * @param workorderIds 工单ID列表 | ||
| 50 | + * @param workorderStatus 工单状态 | ||
| 51 | + * @param handlerUser 处理人 | ||
| 52 | + * @return 更新数量 | ||
| 53 | + */ | ||
| 54 | + int batchUpdateWorkorderStatus(@Param("workorderIds") List<Long> workorderIds, | ||
| 55 | + @Param("workorderStatus") Integer workorderStatus, | ||
| 56 | + @Param("handlerUser") String handlerUser); | ||
| 57 | +} |
| 1 | +package com.apple.erp.service; | ||
| 2 | + | ||
| 3 | +import com.apple.erp.dto.ExceptionWorkorderAddReq; | ||
| 4 | +import com.apple.erp.dto.ExceptionWorkorderQueryReq; | ||
| 5 | +import com.apple.erp.dto.ExceptionWorkorderRes; | ||
| 6 | +import com.apple.erp.dto.ExceptionWorkorderStatusUpdateReq; | ||
| 7 | +import com.apple.erp.dto.ExceptionWorkorderUpdateReq; | ||
| 8 | +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; | ||
| 9 | +import com.baomidou.mybatisplus.extension.service.IService; | ||
| 10 | +import com.apple.erp.entity.ExceptionWorkorder; | ||
| 11 | + | ||
| 12 | +import java.util.List; | ||
| 13 | + | ||
| 14 | +/** | ||
| 15 | + * 异常工单Service接口 | ||
| 16 | + * | ||
| 17 | + * @author Apple ERP System | ||
| 18 | + * @since 2025-01-27 | ||
| 19 | + */ | ||
| 20 | +public interface ExceptionWorkorderService extends IService<ExceptionWorkorder> { | ||
| 21 | + | ||
| 22 | + /** | ||
| 23 | + * 分页查询异常工单列表 | ||
| 24 | + * | ||
| 25 | + * @param queryReq 查询条件 | ||
| 26 | + * @return 异常工单列表(带分页信息) | ||
| 27 | + */ | ||
| 28 | + Page<ExceptionWorkorderRes> getExceptionWorkorderList(ExceptionWorkorderQueryReq queryReq); | ||
| 29 | + | ||
| 30 | + /** | ||
| 31 | + * 获取异常工单详情 | ||
| 32 | + * | ||
| 33 | + * @param workorderId 工单ID | ||
| 34 | + * @return 异常工单详情(包含处理日志) | ||
| 35 | + */ | ||
| 36 | + ExceptionWorkorderRes getExceptionWorkorderDetail(Long workorderId); | ||
| 37 | + | ||
| 38 | + /** | ||
| 39 | + * 新增异常工单 | ||
| 40 | + * | ||
| 41 | + * @param addReq 异常工单新增请求 | ||
| 42 | + * @return 是否成功 | ||
| 43 | + */ | ||
| 44 | + boolean addExceptionWorkorder(ExceptionWorkorderAddReq addReq); | ||
| 45 | + | ||
| 46 | + /** | ||
| 47 | + * 更新异常工单 | ||
| 48 | + * | ||
| 49 | + * @param updateReq 异常工单更新请求 | ||
| 50 | + * @return 是否成功 | ||
| 51 | + */ | ||
| 52 | + boolean updateExceptionWorkorder(ExceptionWorkorderUpdateReq updateReq); | ||
| 53 | + | ||
| 54 | + /** | ||
| 55 | + * 更新工单状态 | ||
| 56 | + * | ||
| 57 | + * @param statusUpdateReq 状态更新请求 | ||
| 58 | + * @return 是否成功 | ||
| 59 | + */ | ||
| 60 | + boolean updateWorkorderStatus(ExceptionWorkorderStatusUpdateReq statusUpdateReq); | ||
| 61 | + | ||
| 62 | + /** | ||
| 63 | + * 删除异常工单 | ||
| 64 | + * | ||
| 65 | + * @param workorderId 工单ID | ||
| 66 | + * @return 是否成功 | ||
| 67 | + */ | ||
| 68 | + boolean deleteExceptionWorkorder(Long workorderId); | ||
| 69 | + | ||
| 70 | + /** | ||
| 71 | + * 批量删除异常工单 | ||
| 72 | + * | ||
| 73 | + * @param workorderIds 工单ID列表 | ||
| 74 | + * @return 是否成功 | ||
| 75 | + */ | ||
| 76 | + boolean batchDeleteExceptionWorkorders(List<Long> workorderIds); | ||
| 77 | + | ||
| 78 | + /** | ||
| 79 | + * 批量更新工单状态 | ||
| 80 | + * | ||
| 81 | + * @param workorderIds 工单ID列表 | ||
| 82 | + * @param workorderStatus 工单状态 | ||
| 83 | + * @param handlerUser 处理人 | ||
| 84 | + * @return 是否成功 | ||
| 85 | + */ | ||
| 86 | + boolean batchUpdateWorkorderStatus(List<Long> workorderIds, Integer workorderStatus, String handlerUser); | ||
| 87 | + | ||
| 88 | + /** | ||
| 89 | + * 获取异常工单统计信息 | ||
| 90 | + * | ||
| 91 | + * @return 统计信息 | ||
| 92 | + */ | ||
| 93 | + List<ExceptionWorkorderRes> getExceptionWorkorderStats(); | ||
| 94 | +} |
| 1 | +package com.apple.erp.service.impl; | ||
| 2 | + | ||
| 3 | +import com.apple.erp.dto.ExceptionWorkorderAddReq; | ||
| 4 | +import com.apple.erp.dto.ExceptionWorkorderLogRes; | ||
| 5 | +import com.apple.erp.dto.ExceptionWorkorderQueryReq; | ||
| 6 | +import com.apple.erp.dto.ExceptionWorkorderRes; | ||
| 7 | +import com.apple.erp.dto.ExceptionWorkorderStatusUpdateReq; | ||
| 8 | +import com.apple.erp.dto.ExceptionWorkorderUpdateReq; | ||
| 9 | +import com.apple.erp.entity.ExceptionWorkorder; | ||
| 10 | +import com.apple.erp.entity.ExceptionWorkorderLog; | ||
| 11 | +import com.apple.erp.mapper.ExceptionWorkorderLogMapper; | ||
| 12 | +import com.apple.erp.mapper.ExceptionWorkorderMapper; | ||
| 13 | +import com.apple.erp.service.ExceptionWorkorderService; | ||
| 14 | +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | ||
| 15 | +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; | ||
| 16 | +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; | ||
| 17 | +import org.springframework.beans.BeanUtils; | ||
| 18 | +import org.springframework.beans.factory.annotation.Autowired; | ||
| 19 | +import org.springframework.stereotype.Service; | ||
| 20 | +import org.springframework.transaction.annotation.Transactional; | ||
| 21 | +import org.springframework.util.StringUtils; | ||
| 22 | + | ||
| 23 | +import java.time.LocalDateTime; | ||
| 24 | +import java.util.List; | ||
| 25 | +import java.util.stream.Collectors; | ||
| 26 | + | ||
| 27 | +/** | ||
| 28 | + * 异常工单Service实现类 | ||
| 29 | + * | ||
| 30 | + * @author Apple ERP System | ||
| 31 | + * @since 2025-01-27 | ||
| 32 | + */ | ||
| 33 | +@Service | ||
| 34 | +public class ExceptionWorkorderServiceImpl extends ServiceImpl<ExceptionWorkorderMapper, ExceptionWorkorder> implements ExceptionWorkorderService { | ||
| 35 | + | ||
| 36 | + @Autowired | ||
| 37 | + private ExceptionWorkorderMapper exceptionWorkorderMapper; | ||
| 38 | + | ||
| 39 | + @Autowired | ||
| 40 | + private ExceptionWorkorderLogMapper exceptionWorkorderLogMapper; | ||
| 41 | + | ||
| 42 | + @Override | ||
| 43 | + public Page<ExceptionWorkorderRes> getExceptionWorkorderList(ExceptionWorkorderQueryReq queryReq) { | ||
| 44 | + Page<ExceptionWorkorderRes> page = new Page<>(queryReq.getPageNum(), queryReq.getPageSize()); | ||
| 45 | + return exceptionWorkorderMapper.selectExceptionWorkorderPage(page, queryReq); | ||
| 46 | + } | ||
| 47 | + | ||
| 48 | + @Override | ||
| 49 | + public ExceptionWorkorderRes getExceptionWorkorderDetail(Long workorderId) { | ||
| 50 | + ExceptionWorkorderRes workorderRes = exceptionWorkorderMapper.selectExceptionWorkorderDetail(workorderId); | ||
| 51 | + if (workorderRes != null) { | ||
| 52 | + // 获取处理日志 | ||
| 53 | + List<ExceptionWorkorderLogRes> logs = exceptionWorkorderLogMapper.selectWorkorderLogsByWorkorderId(workorderId); | ||
| 54 | + workorderRes.setWorkorderLogs(logs); | ||
| 55 | + } | ||
| 56 | + return workorderRes; | ||
| 57 | + } | ||
| 58 | + | ||
| 59 | + @Override | ||
| 60 | + @Transactional | ||
| 61 | + public boolean addExceptionWorkorder(ExceptionWorkorderAddReq addReq) { | ||
| 62 | + ExceptionWorkorder workorder = new ExceptionWorkorder(); | ||
| 63 | + BeanUtils.copyProperties(addReq, workorder); | ||
| 64 | + workorder.setCreateTime(LocalDateTime.now()); | ||
| 65 | + workorder.setDelFlag("0"); | ||
| 66 | + | ||
| 67 | + int result = exceptionWorkorderMapper.insert(workorder); | ||
| 68 | + | ||
| 69 | + // 记录处理日志 | ||
| 70 | + if (result > 0) { | ||
| 71 | + ExceptionWorkorderLog log = new ExceptionWorkorderLog(); | ||
| 72 | + log.setWorkorderId(workorder.getWorkorderId()); | ||
| 73 | + log.setWorkorderNo(workorder.getWorkorderNo()); | ||
| 74 | + log.setHandleUser(addReq.getHandlerUser()); | ||
| 75 | + log.setHandleTime(LocalDateTime.now()); | ||
| 76 | + log.setBeforeStatus(0); | ||
| 77 | + log.setAfterStatus(workorder.getWorkorderStatus()); | ||
| 78 | + log.setHandleOpinion("工单创建"); | ||
| 79 | + log.setCreateTime(LocalDateTime.now()); | ||
| 80 | + log.setDelFlag("0"); | ||
| 81 | + exceptionWorkorderLogMapper.insert(log); | ||
| 82 | + } | ||
| 83 | + | ||
| 84 | + return result > 0; | ||
| 85 | + } | ||
| 86 | + | ||
| 87 | + @Override | ||
| 88 | + @Transactional | ||
| 89 | + public boolean updateExceptionWorkorder(ExceptionWorkorderUpdateReq updateReq) { | ||
| 90 | + ExceptionWorkorder workorder = exceptionWorkorderMapper.selectById(updateReq.getWorkorderId()); | ||
| 91 | + if (workorder == null || "2".equals(workorder.getDelFlag())) { | ||
| 92 | + return false; | ||
| 93 | + } | ||
| 94 | + | ||
| 95 | + BeanUtils.copyProperties(updateReq, workorder); | ||
| 96 | + workorder.setUpdateTime(LocalDateTime.now()); | ||
| 97 | + | ||
| 98 | + return exceptionWorkorderMapper.updateById(workorder) > 0; | ||
| 99 | + } | ||
| 100 | + | ||
| 101 | + @Override | ||
| 102 | + @Transactional | ||
| 103 | + public boolean updateWorkorderStatus(ExceptionWorkorderStatusUpdateReq statusUpdateReq) { | ||
| 104 | + ExceptionWorkorder workorder = exceptionWorkorderMapper.selectById(statusUpdateReq.getWorkorderId()); | ||
| 105 | + if (workorder == null || "2".equals(workorder.getDelFlag())) { | ||
| 106 | + return false; | ||
| 107 | + } | ||
| 108 | + | ||
| 109 | + Integer beforeStatus = workorder.getWorkorderStatus(); | ||
| 110 | + workorder.setWorkorderStatus(statusUpdateReq.getWorkorderStatus()); | ||
| 111 | + workorder.setHandlerUser(statusUpdateReq.getHandlerUser()); | ||
| 112 | + workorder.setUpdateTime(LocalDateTime.now()); | ||
| 113 | + | ||
| 114 | + int result = exceptionWorkorderMapper.updateById(workorder); | ||
| 115 | + | ||
| 116 | + // 记录处理日志 | ||
| 117 | + if (result > 0) { | ||
| 118 | + ExceptionWorkorderLog log = new ExceptionWorkorderLog(); | ||
| 119 | + log.setWorkorderId(workorder.getWorkorderId()); | ||
| 120 | + log.setWorkorderNo(workorder.getWorkorderNo()); | ||
| 121 | + log.setHandleUser(statusUpdateReq.getHandlerUser()); | ||
| 122 | + log.setHandleTime(LocalDateTime.now()); | ||
| 123 | + log.setBeforeStatus(beforeStatus); | ||
| 124 | + log.setAfterStatus(statusUpdateReq.getWorkorderStatus()); | ||
| 125 | + log.setHandleOpinion(statusUpdateReq.getHandleOpinion()); | ||
| 126 | + log.setAttachUrl(statusUpdateReq.getAttachUrl()); | ||
| 127 | + log.setCreateTime(LocalDateTime.now()); | ||
| 128 | + log.setDelFlag("0"); | ||
| 129 | + exceptionWorkorderLogMapper.insert(log); | ||
| 130 | + } | ||
| 131 | + | ||
| 132 | + return result > 0; | ||
| 133 | + } | ||
| 134 | + | ||
| 135 | + @Override | ||
| 136 | + @Transactional | ||
| 137 | + public boolean deleteExceptionWorkorder(Long workorderId) { | ||
| 138 | + ExceptionWorkorder workorder = exceptionWorkorderMapper.selectById(workorderId); | ||
| 139 | + if (workorder == null || "2".equals(workorder.getDelFlag())) { | ||
| 140 | + return false; | ||
| 141 | + } | ||
| 142 | + | ||
| 143 | + workorder.setDelFlag("2"); | ||
| 144 | + workorder.setUpdateTime(LocalDateTime.now()); | ||
| 145 | + | ||
| 146 | + return exceptionWorkorderMapper.updateById(workorder) > 0; | ||
| 147 | + } | ||
| 148 | + | ||
| 149 | + @Override | ||
| 150 | + @Transactional | ||
| 151 | + public boolean batchDeleteExceptionWorkorders(List<Long> workorderIds) { | ||
| 152 | + if (workorderIds == null || workorderIds.isEmpty()) { | ||
| 153 | + return false; | ||
| 154 | + } | ||
| 155 | + | ||
| 156 | + ExceptionWorkorder workorder = new ExceptionWorkorder(); | ||
| 157 | + workorder.setDelFlag("2"); | ||
| 158 | + workorder.setUpdateTime(LocalDateTime.now()); | ||
| 159 | + | ||
| 160 | + LambdaQueryWrapper<ExceptionWorkorder> queryWrapper = new LambdaQueryWrapper<>(); | ||
| 161 | + queryWrapper.in(ExceptionWorkorder::getWorkorderId, workorderIds); | ||
| 162 | + queryWrapper.eq(ExceptionWorkorder::getDelFlag, "0"); | ||
| 163 | + | ||
| 164 | + return exceptionWorkorderMapper.update(workorder, queryWrapper) > 0; | ||
| 165 | + } | ||
| 166 | + | ||
| 167 | + @Override | ||
| 168 | + @Transactional | ||
| 169 | + public boolean batchUpdateWorkorderStatus(List<Long> workorderIds, Integer workorderStatus, String handlerUser) { | ||
| 170 | + if (workorderIds == null || workorderIds.isEmpty()) { | ||
| 171 | + return false; | ||
| 172 | + } | ||
| 173 | + | ||
| 174 | + int result = exceptionWorkorderMapper.batchUpdateWorkorderStatus(workorderIds, workorderStatus, handlerUser); | ||
| 175 | + | ||
| 176 | + // 记录批量处理日志 | ||
| 177 | + if (result > 0) { | ||
| 178 | + for (Long workorderId : workorderIds) { | ||
| 179 | + ExceptionWorkorder workorder = exceptionWorkorderMapper.selectById(workorderId); | ||
| 180 | + if (workorder != null && "0".equals(workorder.getDelFlag())) { | ||
| 181 | + ExceptionWorkorderLog log = new ExceptionWorkorderLog(); | ||
| 182 | + log.setWorkorderId(workorderId); | ||
| 183 | + log.setWorkorderNo(workorder.getWorkorderNo()); | ||
| 184 | + log.setHandleUser(handlerUser); | ||
| 185 | + log.setHandleTime(LocalDateTime.now()); | ||
| 186 | + log.setBeforeStatus(workorder.getWorkorderStatus()); | ||
| 187 | + log.setAfterStatus(workorderStatus); | ||
| 188 | + log.setHandleOpinion("批量状态更新"); | ||
| 189 | + log.setCreateTime(LocalDateTime.now()); | ||
| 190 | + log.setDelFlag("0"); | ||
| 191 | + exceptionWorkorderLogMapper.insert(log); | ||
| 192 | + } | ||
| 193 | + } | ||
| 194 | + } | ||
| 195 | + | ||
| 196 | + return result > 0; | ||
| 197 | + } | ||
| 198 | + | ||
| 199 | + @Override | ||
| 200 | + public List<ExceptionWorkorderRes> getExceptionWorkorderStats() { | ||
| 201 | + return exceptionWorkorderMapper.selectExceptionWorkorderStats(); | ||
| 202 | + } | ||
| 203 | +} |
| 1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | +<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> | ||
| 3 | +<mapper namespace="com.apple.erp.mapper.ExceptionWorkorderLogMapper"> | ||
| 4 | + | ||
| 5 | + <!-- 根据工单ID获取处理日志列表 --> | ||
| 6 | + <select id="selectWorkorderLogsByWorkorderId" resultType="com.apple.erp.dto.ExceptionWorkorderLogRes"> | ||
| 7 | + SELECT | ||
| 8 | + ewl.log_id, | ||
| 9 | + ewl.workorder_id, | ||
| 10 | + ewl.workorder_no, | ||
| 11 | + ewl.handle_user, | ||
| 12 | + ewl.handle_time, | ||
| 13 | + ewl.before_status, | ||
| 14 | + CASE ewl.before_status | ||
| 15 | + WHEN 1 THEN '待处理' | ||
| 16 | + WHEN 2 THEN '处理中' | ||
| 17 | + WHEN 3 THEN '已解决' | ||
| 18 | + WHEN 4 THEN '已关闭' | ||
| 19 | + ELSE '未知状态' | ||
| 20 | + END AS before_status_name, | ||
| 21 | + ewl.after_status, | ||
| 22 | + CASE ewl.after_status | ||
| 23 | + WHEN 1 THEN '待处理' | ||
| 24 | + WHEN 2 THEN '处理中' | ||
| 25 | + WHEN 3 THEN '已解决' | ||
| 26 | + WHEN 4 THEN '已关闭' | ||
| 27 | + ELSE '未知状态' | ||
| 28 | + END AS after_status_name, | ||
| 29 | + ewl.handle_opinion, | ||
| 30 | + ewl.attach_url, | ||
| 31 | + ewl.create_by, | ||
| 32 | + ewl.create_time | ||
| 33 | + FROM t_exception_workorder_log ewl | ||
| 34 | + WHERE ewl.workorder_id = #{workorderId} AND ewl.del_flag = '0' | ||
| 35 | + ORDER BY ewl.handle_time DESC | ||
| 36 | + </select> | ||
| 37 | + | ||
| 38 | + <!-- 根据工单ID列表批量获取处理日志 --> | ||
| 39 | + <select id="selectWorkorderLogsByWorkorderIds" resultType="com.apple.erp.dto.ExceptionWorkorderLogRes"> | ||
| 40 | + SELECT | ||
| 41 | + ewl.log_id, | ||
| 42 | + ewl.workorder_id, | ||
| 43 | + ewl.workorder_no, | ||
| 44 | + ewl.handle_user, | ||
| 45 | + ewl.handle_time, | ||
| 46 | + ewl.before_status, | ||
| 47 | + CASE ewl.before_status | ||
| 48 | + WHEN 1 THEN '待处理' | ||
| 49 | + WHEN 2 THEN '处理中' | ||
| 50 | + WHEN 3 THEN '已解决' | ||
| 51 | + WHEN 4 THEN '已关闭' | ||
| 52 | + ELSE '未知状态' | ||
| 53 | + END AS before_status_name, | ||
| 54 | + ewl.after_status, | ||
| 55 | + CASE ewl.after_status | ||
| 56 | + WHEN 1 THEN '待处理' | ||
| 57 | + WHEN 2 THEN '处理中' | ||
| 58 | + WHEN 3 THEN '已解决' | ||
| 59 | + WHEN 4 THEN '已关闭' | ||
| 60 | + ELSE '未知状态' | ||
| 61 | + END AS after_status_name, | ||
| 62 | + ewl.handle_opinion, | ||
| 63 | + ewl.attach_url, | ||
| 64 | + ewl.create_by, | ||
| 65 | + ewl.create_time | ||
| 66 | + FROM t_exception_workorder_log ewl | ||
| 67 | + WHERE ewl.workorder_id IN | ||
| 68 | + <foreach collection="workorderIds" item="workorderId" open="(" separator="," close=")"> | ||
| 69 | + #{workorderId} | ||
| 70 | + </foreach> | ||
| 71 | + AND ewl.del_flag = '0' | ||
| 72 | + ORDER BY ewl.workorder_id, ewl.handle_time DESC | ||
| 73 | + </select> | ||
| 74 | + | ||
| 75 | +</mapper> |
| 1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | +<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> | ||
| 3 | +<mapper namespace="com.apple.erp.mapper.ExceptionWorkorderMapper"> | ||
| 4 | + | ||
| 5 | + <!-- 分页查询异常工单列表 --> | ||
| 6 | + <select id="selectExceptionWorkorderPage" resultType="com.apple.erp.dto.ExceptionWorkorderRes"> | ||
| 7 | + SELECT | ||
| 8 | + ew.workorder_id, | ||
| 9 | + ew.workorder_no, | ||
| 10 | + ew.order_no, | ||
| 11 | + ew.dealer_code, | ||
| 12 | + ew.dealer_name, | ||
| 13 | + ew.exception_type, | ||
| 14 | + CASE ew.exception_type | ||
| 15 | + WHEN 1 THEN '逻辑验证异常' | ||
| 16 | + WHEN 2 THEN '源头验证异常' | ||
| 17 | + WHEN 3 THEN '交叉验证异常' | ||
| 18 | + ELSE '未知类型' | ||
| 19 | + END AS exception_type_name, | ||
| 20 | + ew.severity_level, | ||
| 21 | + CASE ew.severity_level | ||
| 22 | + WHEN 1 THEN '高' | ||
| 23 | + WHEN 2 THEN '中' | ||
| 24 | + WHEN 3 THEN '低' | ||
| 25 | + ELSE '未知' | ||
| 26 | + END AS severity_level_name, | ||
| 27 | + ew.workorder_status, | ||
| 28 | + CASE ew.workorder_status | ||
| 29 | + WHEN 1 THEN '待处理' | ||
| 30 | + WHEN 2 THEN '处理中' | ||
| 31 | + WHEN 3 THEN '已解决' | ||
| 32 | + WHEN 4 THEN '已关闭' | ||
| 33 | + ELSE '未知状态' | ||
| 34 | + END AS workorder_status_name, | ||
| 35 | + ew.create_time, | ||
| 36 | + ew.expect_complete_time, | ||
| 37 | + ew.handler_user, | ||
| 38 | + ew.exception_desc, | ||
| 39 | + ew.handle_suggest, | ||
| 40 | + ew.data_source, | ||
| 41 | + ew.create_by, | ||
| 42 | + ew.update_by, | ||
| 43 | + ew.update_time | ||
| 44 | + FROM t_exception_workorder ew | ||
| 45 | + <where> | ||
| 46 | + ew.del_flag = '0' | ||
| 47 | + <if test="query.workorderNo != null and query.workorderNo != ''"> | ||
| 48 | + AND ew.workorder_no LIKE CONCAT('%', #{query.workorderNo}, '%') | ||
| 49 | + </if> | ||
| 50 | + <if test="query.orderNo != null and query.orderNo != ''"> | ||
| 51 | + AND ew.order_no LIKE CONCAT('%', #{query.orderNo}, '%') | ||
| 52 | + </if> | ||
| 53 | + <if test="query.dealerCode != null and query.dealerCode != ''"> | ||
| 54 | + AND ew.dealer_code = #{query.dealerCode} | ||
| 55 | + </if> | ||
| 56 | + <if test="query.dealerName != null and query.dealerName != ''"> | ||
| 57 | + AND ew.dealer_name LIKE CONCAT('%', #{query.dealerName}, '%') | ||
| 58 | + </if> | ||
| 59 | + <if test="query.workorderStatus != null"> | ||
| 60 | + AND ew.workorder_status = #{query.workorderStatus} | ||
| 61 | + </if> | ||
| 62 | + <if test="query.exceptionType != null"> | ||
| 63 | + AND ew.exception_type = #{query.exceptionType} | ||
| 64 | + </if> | ||
| 65 | + <if test="query.severityLevel != null"> | ||
| 66 | + AND ew.severity_level = #{query.severityLevel} | ||
| 67 | + </if> | ||
| 68 | + <if test="query.handlerUser != null and query.handlerUser != ''"> | ||
| 69 | + AND ew.handler_user LIKE CONCAT('%', #{query.handlerUser}, '%') | ||
| 70 | + </if> | ||
| 71 | + <if test="query.startTime != null"> | ||
| 72 | + AND ew.create_time >= #{query.startTime} | ||
| 73 | + </if> | ||
| 74 | + <if test="query.endTime != null"> | ||
| 75 | + AND ew.create_time <= #{query.endTime} | ||
| 76 | + </if> | ||
| 77 | + </where> | ||
| 78 | + ORDER BY ew.create_time DESC | ||
| 79 | + </select> | ||
| 80 | + | ||
| 81 | + <!-- 根据工单ID获取异常工单详情 --> | ||
| 82 | + <select id="selectExceptionWorkorderDetail" resultType="com.apple.erp.dto.ExceptionWorkorderRes"> | ||
| 83 | + SELECT | ||
| 84 | + ew.workorder_id, | ||
| 85 | + ew.workorder_no, | ||
| 86 | + ew.order_no, | ||
| 87 | + ew.dealer_code, | ||
| 88 | + ew.dealer_name, | ||
| 89 | + ew.exception_type, | ||
| 90 | + CASE ew.exception_type | ||
| 91 | + WHEN 1 THEN '逻辑验证异常' | ||
| 92 | + WHEN 2 THEN '源头验证异常' | ||
| 93 | + WHEN 3 THEN '交叉验证异常' | ||
| 94 | + ELSE '未知类型' | ||
| 95 | + END AS exception_type_name, | ||
| 96 | + ew.severity_level, | ||
| 97 | + CASE ew.severity_level | ||
| 98 | + WHEN 1 THEN '高' | ||
| 99 | + WHEN 2 THEN '中' | ||
| 100 | + WHEN 3 THEN '低' | ||
| 101 | + ELSE '未知' | ||
| 102 | + END AS severity_level_name, | ||
| 103 | + ew.workorder_status, | ||
| 104 | + CASE ew.workorder_status | ||
| 105 | + WHEN 1 THEN '待处理' | ||
| 106 | + WHEN 2 THEN '处理中' | ||
| 107 | + WHEN 3 THEN '已解决' | ||
| 108 | + WHEN 4 THEN '已关闭' | ||
| 109 | + ELSE '未知状态' | ||
| 110 | + END AS workorder_status_name, | ||
| 111 | + ew.create_time, | ||
| 112 | + ew.expect_complete_time, | ||
| 113 | + ew.handler_user, | ||
| 114 | + ew.exception_desc, | ||
| 115 | + ew.handle_suggest, | ||
| 116 | + ew.data_source, | ||
| 117 | + ew.create_by, | ||
| 118 | + ew.update_by, | ||
| 119 | + ew.update_time | ||
| 120 | + FROM t_exception_workorder ew | ||
| 121 | + WHERE ew.workorder_id = #{workorderId} AND ew.del_flag = '0' | ||
| 122 | + </select> | ||
| 123 | + | ||
| 124 | + <!-- 获取异常工单统计信息 --> | ||
| 125 | + <select id="selectExceptionWorkorderStats" resultType="com.apple.erp.dto.ExceptionWorkorderRes"> | ||
| 126 | + SELECT | ||
| 127 | + 'total' AS workorder_no, | ||
| 128 | + COUNT(*) AS workorder_id, | ||
| 129 | + SUM(CASE WHEN workorder_status = 1 THEN 1 ELSE 0 END) AS exception_type, | ||
| 130 | + SUM(CASE WHEN workorder_status = 2 THEN 1 ELSE 0 END) AS severity_level, | ||
| 131 | + SUM(CASE WHEN workorder_status = 3 THEN 1 ELSE 0 END) AS workorder_status, | ||
| 132 | + SUM(CASE WHEN workorder_status = 4 THEN 1 ELSE 0 END) AS handler_user, | ||
| 133 | + SUM(CASE WHEN severity_level = 1 THEN 1 ELSE 0 END) AS exception_desc, | ||
| 134 | + SUM(CASE WHEN severity_level = 2 THEN 1 ELSE 0 END) AS handle_suggest, | ||
| 135 | + SUM(CASE WHEN severity_level = 3 THEN 1 ELSE 0 END) AS data_source | ||
| 136 | + FROM t_exception_workorder | ||
| 137 | + WHERE del_flag = '0' | ||
| 138 | + </select> | ||
| 139 | + | ||
| 140 | + <!-- 批量更新工单状态 --> | ||
| 141 | + <update id="batchUpdateWorkorderStatus"> | ||
| 142 | + UPDATE t_exception_workorder | ||
| 143 | + SET workorder_status = #{workorderStatus}, | ||
| 144 | + handler_user = #{handlerUser}, | ||
| 145 | + update_time = NOW() | ||
| 146 | + WHERE workorder_id IN | ||
| 147 | + <foreach collection="workorderIds" item="workorderId" open="(" separator="," close=")"> | ||
| 148 | + #{workorderId} | ||
| 149 | + </foreach> | ||
| 150 | + AND del_flag = '0' | ||
| 151 | + </update> | ||
| 152 | + | ||
| 153 | +</mapper> |
| 1 | +-- 异常工单模块完整初始化脚本 | ||
| 2 | +-- 包含表结构创建、权限配置、测试数据插入 | ||
| 3 | + | ||
| 4 | +-- 1. 创建异常工单表 | ||
| 5 | +CREATE TABLE IF NOT EXISTS t_exception_workorder ( | ||
| 6 | + workorder_id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '工单ID', | ||
| 7 | + workorder_no VARCHAR(30) NOT NULL COMMENT '工单编号', | ||
| 8 | + order_no VARCHAR(30) COMMENT '关联订单编号', | ||
| 9 | + dealer_code VARCHAR(20) COMMENT '经销商编码', | ||
| 10 | + dealer_name VARCHAR(100) COMMENT '经销商名称', | ||
| 11 | + exception_type TINYINT NOT NULL COMMENT '异常类型(1-逻辑验证异常/2-源头验证异常/3-交叉验证异常)', | ||
| 12 | + severity_level TINYINT NOT NULL COMMENT '严重程度(1-高/2-中/3-低)', | ||
| 13 | + workorder_status TINYINT DEFAULT 1 COMMENT '工单状态(1-待处理/2-处理中/3-已解决/4-已关闭)', | ||
| 14 | + create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '工单创建时间', | ||
| 15 | + expect_complete_time DATETIME COMMENT '预计处理完成时间', | ||
| 16 | + handler_user VARCHAR(20) COMMENT '处理人', | ||
| 17 | + exception_desc VARCHAR(500) COMMENT '异常描述', | ||
| 18 | + handle_suggest VARCHAR(500) COMMENT '处理建议', | ||
| 19 | + data_source VARCHAR(20) COMMENT '数据来源', | ||
| 20 | + create_by VARCHAR(64) DEFAULT '' COMMENT '创建者', | ||
| 21 | + update_by VARCHAR(64) DEFAULT '' COMMENT '更新者', | ||
| 22 | + update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', | ||
| 23 | + del_flag CHAR(1) DEFAULT '0' COMMENT '删除标志(0代表存在 2代表删除)' | ||
| 24 | +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='异常工单表'; | ||
| 25 | + | ||
| 26 | +-- 2. 创建异常工单处理日志表 | ||
| 27 | +CREATE TABLE IF NOT EXISTS t_exception_workorder_log ( | ||
| 28 | + log_id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '日志ID', | ||
| 29 | + workorder_id BIGINT NOT NULL COMMENT '关联工单ID', | ||
| 30 | + workorder_no VARCHAR(30) NOT NULL COMMENT '关联工单编号', | ||
| 31 | + handle_user VARCHAR(20) NOT NULL COMMENT '处理人', | ||
| 32 | + handle_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '处理时间', | ||
| 33 | + before_status TINYINT NOT NULL COMMENT '处理前状态', | ||
| 34 | + after_status TINYINT NOT NULL COMMENT '处理后状态', | ||
| 35 | + handle_opinion VARCHAR(500) COMMENT '处理意见', | ||
| 36 | + attach_url VARCHAR(200) COMMENT '附件URL', | ||
| 37 | + create_by VARCHAR(64) DEFAULT '' COMMENT '创建者', | ||
| 38 | + create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', | ||
| 39 | + update_by VARCHAR(64) DEFAULT '' COMMENT '更新者', | ||
| 40 | + update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', | ||
| 41 | + del_flag CHAR(1) DEFAULT '0' COMMENT '删除标志(0代表存在 2代表删除)' | ||
| 42 | +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='异常工单处理日志表'; | ||
| 43 | + | ||
| 44 | +-- 3. 创建索引 | ||
| 45 | +-- 异常工单表索引 | ||
| 46 | +CREATE UNIQUE INDEX IF NOT EXISTS uk_workorder_no ON t_exception_workorder(workorder_no); | ||
| 47 | +CREATE INDEX IF NOT EXISTS idx_workorder_dealer_code ON t_exception_workorder(dealer_code); | ||
| 48 | +CREATE INDEX IF NOT EXISTS idx_workorder_order_no ON t_exception_workorder(order_no); | ||
| 49 | +CREATE INDEX IF NOT EXISTS idx_workorder_status ON t_exception_workorder(workorder_status); | ||
| 50 | +CREATE INDEX IF NOT EXISTS idx_workorder_exception_type ON t_exception_workorder(exception_type); | ||
| 51 | +CREATE INDEX IF NOT EXISTS idx_workorder_severity_level ON t_exception_workorder(severity_level); | ||
| 52 | +CREATE INDEX IF NOT EXISTS idx_workorder_create_time ON t_exception_workorder(create_time); | ||
| 53 | +CREATE INDEX IF NOT EXISTS idx_workorder_handler_user ON t_exception_workorder(handler_user); | ||
| 54 | + | ||
| 55 | +-- 异常工单处理日志表索引 | ||
| 56 | +CREATE INDEX IF NOT EXISTS idx_log_workorder_id ON t_exception_workorder_log(workorder_id); | ||
| 57 | +CREATE INDEX IF NOT EXISTS idx_log_workorder_no ON t_exception_workorder_log(workorder_no); | ||
| 58 | +CREATE INDEX IF NOT EXISTS idx_log_handle_user ON t_exception_workorder_log(handle_user); | ||
| 59 | +CREATE INDEX IF NOT EXISTS idx_log_handle_time ON t_exception_workorder_log(handle_time); | ||
| 60 | + | ||
| 61 | +-- 4. 创建外键约束 | ||
| 62 | +ALTER TABLE t_exception_workorder_log | ||
| 63 | +ADD CONSTRAINT IF NOT EXISTS fk_workorder_log_workorder_id | ||
| 64 | +FOREIGN KEY (workorder_id) REFERENCES t_exception_workorder(workorder_id) | ||
| 65 | +ON DELETE CASCADE ON UPDATE CASCADE; | ||
| 66 | + | ||
| 67 | +-- 5. 插入异常工单菜单 | ||
| 68 | +INSERT IGNORE INTO t_sys_menu (parent_id, menu_name, menu_type, path, icon, sort, status, perms, create_by, create_time) VALUES | ||
| 69 | +(0, '异常工单', 1, '/main/exception-workorder', '⚠️', 7, 1, 'exception:workorder:view', 'admin', NOW()); | ||
| 70 | + | ||
| 71 | +-- 获取异常工单菜单ID | ||
| 72 | +SET @exception_menu_id = LAST_INSERT_ID(); | ||
| 73 | + | ||
| 74 | +-- 6. 插入异常工单子菜单 | ||
| 75 | +INSERT IGNORE INTO t_sys_menu (parent_id, menu_name, menu_type, path, icon, sort, status, perms, create_by, create_time) VALUES | ||
| 76 | +(@exception_menu_id, '工单查询', 2, '', '', 1, 1, 'exception:workorder:list', 'admin', NOW()), | ||
| 77 | +(@exception_menu_id, '工单详情', 2, '', '', 2, 1, 'exception:workorder:detail', 'admin', NOW()), | ||
| 78 | +(@exception_menu_id, '工单新增', 2, '', '', 3, 1, 'exception:workorder:add', 'admin', NOW()), | ||
| 79 | +(@exception_menu_id, '工单编辑', 2, '', '', 4, 1, 'exception:workorder:edit', 'admin', NOW()), | ||
| 80 | +(@exception_menu_id, '工单删除', 2, '', '', 5, 1, 'exception:workorder:delete', 'admin', NOW()), | ||
| 81 | +(@exception_menu_id, '状态更新', 2, '', '', 6, 1, 'exception:workorder:status', 'admin', NOW()), | ||
| 82 | +(@exception_menu_id, '批量处理', 2, '', '', 7, 1, 'exception:workorder:batch', 'admin', NOW()), | ||
| 83 | +(@exception_menu_id, '统计查看', 2, '', '', 8, 1, 'exception:workorder:stats', 'admin', NOW()); | ||
| 84 | + | ||
| 85 | + | ||
| 86 | +-- 12. 为管理员角色分配异常工单权限 | ||
| 87 | +INSERT IGNORE INTO t_sys_role_menu (role_id, menu_id, create_by, create_time) | ||
| 88 | +SELECT r.role_id, @exception_menu_id, 'admin', NOW() | ||
| 89 | +FROM t_sys_role r | ||
| 90 | +WHERE r.role_code = 'ADMIN'; | ||
| 91 | + | ||
| 92 | +-- 13. 为管理员角色分配异常工单子菜单权限 | ||
| 93 | +INSERT IGNORE INTO t_sys_role_menu (role_id, menu_id, create_by, create_time) | ||
| 94 | +SELECT r.role_id, m.menu_id, 'admin', NOW() | ||
| 95 | +FROM t_sys_role r, t_sys_menu m | ||
| 96 | +WHERE r.role_code = 'ADMIN' | ||
| 97 | +AND m.parent_id = @exception_menu_id; | ||
| 98 | + | ||
| 99 | + | ||
| 100 | +-- 完成初始化 | ||
| 101 | +SELECT '异常工单模块初始化完成' AS message; |
frontend/src/api/exceptionWorkorder.ts
0 → 100644
| 1 | +import { request } from '../utils/request' | ||
| 2 | + | ||
| 3 | +// 异常工单相关类型定义 | ||
| 4 | +export interface ExceptionWorkorderInfo { | ||
| 5 | + workorderId: number | ||
| 6 | + workorderNo: string | ||
| 7 | + orderNo: string | ||
| 8 | + dealerCode: string | ||
| 9 | + dealerName: string | ||
| 10 | + exceptionType: number | ||
| 11 | + exceptionTypeName: string | ||
| 12 | + severityLevel: number | ||
| 13 | + severityLevelName: string | ||
| 14 | + workorderStatus: number | ||
| 15 | + workorderStatusName: string | ||
| 16 | + createTime: string | ||
| 17 | + expectCompleteTime?: string | ||
| 18 | + handlerUser?: string | ||
| 19 | + exceptionDesc?: string | ||
| 20 | + handleSuggest?: string | ||
| 21 | + dataSource?: string | ||
| 22 | + createBy?: string | ||
| 23 | + updateBy?: string | ||
| 24 | + updateTime?: string | ||
| 25 | + workorderLogs?: ExceptionWorkorderLogInfo[] | ||
| 26 | +} | ||
| 27 | + | ||
| 28 | +export interface ExceptionWorkorderLogInfo { | ||
| 29 | + logId: number | ||
| 30 | + workorderId: number | ||
| 31 | + workorderNo: string | ||
| 32 | + handleUser: string | ||
| 33 | + handleTime: string | ||
| 34 | + beforeStatus: number | ||
| 35 | + beforeStatusName: string | ||
| 36 | + afterStatus: number | ||
| 37 | + afterStatusName: string | ||
| 38 | + handleOpinion?: string | ||
| 39 | + attachUrl?: string | ||
| 40 | + createBy?: string | ||
| 41 | + createTime: string | ||
| 42 | +} | ||
| 43 | + | ||
| 44 | +export interface ExceptionWorkorderQueryReq { | ||
| 45 | + workorderNo?: string | ||
| 46 | + orderNo?: string | ||
| 47 | + dealerCode?: string | ||
| 48 | + dealerName?: string | ||
| 49 | + workorderStatus?: number | ||
| 50 | + exceptionType?: number | ||
| 51 | + severityLevel?: number | ||
| 52 | + handlerUser?: string | ||
| 53 | + startTime?: string | ||
| 54 | + endTime?: string | ||
| 55 | + pageNum?: number | ||
| 56 | + pageSize?: number | ||
| 57 | +} | ||
| 58 | + | ||
| 59 | +export interface ExceptionWorkorderAddReq { | ||
| 60 | + workorderNo: string | ||
| 61 | + orderNo?: string | ||
| 62 | + dealerCode?: string | ||
| 63 | + dealerName?: string | ||
| 64 | + exceptionType: number | ||
| 65 | + severityLevel: number | ||
| 66 | + workorderStatus?: number | ||
| 67 | + expectCompleteTime?: string | ||
| 68 | + handlerUser?: string | ||
| 69 | + exceptionDesc?: string | ||
| 70 | + handleSuggest?: string | ||
| 71 | + dataSource?: string | ||
| 72 | +} | ||
| 73 | + | ||
| 74 | +export interface ExceptionWorkorderUpdateReq { | ||
| 75 | + workorderId: number | ||
| 76 | + workorderNo?: string | ||
| 77 | + orderNo?: string | ||
| 78 | + dealerCode?: string | ||
| 79 | + dealerName?: string | ||
| 80 | + exceptionType?: number | ||
| 81 | + severityLevel?: number | ||
| 82 | + workorderStatus?: number | ||
| 83 | + expectCompleteTime?: string | ||
| 84 | + handlerUser?: string | ||
| 85 | + exceptionDesc?: string | ||
| 86 | + handleSuggest?: string | ||
| 87 | + dataSource?: string | ||
| 88 | +} | ||
| 89 | + | ||
| 90 | +export interface ExceptionWorkorderStatusUpdateReq { | ||
| 91 | + workorderId: number | ||
| 92 | + workorderStatus: number | ||
| 93 | + handlerUser?: string | ||
| 94 | + handleOpinion?: string | ||
| 95 | + attachUrl?: string | ||
| 96 | +} | ||
| 97 | + | ||
| 98 | +// 异常工单API接口 | ||
| 99 | +export const exceptionWorkorderApi = { | ||
| 100 | + // 分页查询异常工单列表 | ||
| 101 | + getExceptionWorkorderList: (params: ExceptionWorkorderQueryReq) => { | ||
| 102 | + return request.get('/api/exception-workorder/list', params) | ||
| 103 | + }, | ||
| 104 | + | ||
| 105 | + // 获取异常工单详情 | ||
| 106 | + getExceptionWorkorderDetail: (workorderId: number) => { | ||
| 107 | + return request.get(`/api/exception-workorder/${workorderId}`) | ||
| 108 | + }, | ||
| 109 | + | ||
| 110 | + // 新增异常工单 | ||
| 111 | + addExceptionWorkorder: (data: ExceptionWorkorderAddReq) => { | ||
| 112 | + return request.post('/api/exception-workorder', data) | ||
| 113 | + }, | ||
| 114 | + | ||
| 115 | + // 更新异常工单 | ||
| 116 | + updateExceptionWorkorder: (data: ExceptionWorkorderUpdateReq) => { | ||
| 117 | + return request.put('/api/exception-workorder', data) | ||
| 118 | + }, | ||
| 119 | + | ||
| 120 | + // 更新工单状态 | ||
| 121 | + updateWorkorderStatus: (data: ExceptionWorkorderStatusUpdateReq) => { | ||
| 122 | + return request.post('/api/exception-workorder/status', data) | ||
| 123 | + }, | ||
| 124 | + | ||
| 125 | + // 删除异常工单 | ||
| 126 | + deleteExceptionWorkorder: (workorderId: number) => { | ||
| 127 | + return request.delete(`/api/exception-workorder/${workorderId}`) | ||
| 128 | + }, | ||
| 129 | + | ||
| 130 | + // 批量删除异常工单 | ||
| 131 | + batchDeleteExceptionWorkorders: (workorderIds: number[]) => { | ||
| 132 | + return request.delete('/api/exception-workorder/batch', workorderIds) | ||
| 133 | + }, | ||
| 134 | + | ||
| 135 | + // 批量更新工单状态 | ||
| 136 | + batchUpdateWorkorderStatus: (workorderIds: number[], workorderStatus: number, handlerUser: string) => { | ||
| 137 | + return request.post('/api/exception-workorder/batch-status', null, { | ||
| 138 | + params: { | ||
| 139 | + workorderIds: workorderIds.join(','), | ||
| 140 | + workorderStatus, | ||
| 141 | + handlerUser | ||
| 142 | + } | ||
| 143 | + }) | ||
| 144 | + }, | ||
| 145 | + | ||
| 146 | + // 获取异常工单统计信息 | ||
| 147 | + getExceptionWorkorderStats: () => { | ||
| 148 | + return request.get('/api/exception-workorder/stats') | ||
| 149 | + } | ||
| 150 | +} | ||
| 151 | + | ||
| 152 | +// 异常类型枚举 | ||
| 153 | +export const EXCEPTION_TYPE = { | ||
| 154 | + 1: '逻辑验证异常', | ||
| 155 | + 2: '源头验证异常', | ||
| 156 | + 3: '交叉验证异常' | ||
| 157 | +} | ||
| 158 | + | ||
| 159 | +// 严重程度枚举 | ||
| 160 | +export const SEVERITY_LEVEL = { | ||
| 161 | + 1: '高', | ||
| 162 | + 2: '中', | ||
| 163 | + 3: '低' | ||
| 164 | +} | ||
| 165 | + | ||
| 166 | +// 工单状态枚举 | ||
| 167 | +export const WORKORDER_STATUS = { | ||
| 168 | + 1: '待处理', | ||
| 169 | + 2: '处理中', | ||
| 170 | + 3: '已解决', | ||
| 171 | + 4: '已关闭' | ||
| 172 | +} | ||
| 173 | + | ||
| 174 | +// 获取异常类型名称 | ||
| 175 | +export const getExceptionTypeName = (type: number): string => { | ||
| 176 | + return EXCEPTION_TYPE[type as keyof typeof EXCEPTION_TYPE] || '未知类型' | ||
| 177 | +} | ||
| 178 | + | ||
| 179 | +// 获取严重程度名称 | ||
| 180 | +export const getSeverityLevelName = (level: number): string => { | ||
| 181 | + return SEVERITY_LEVEL[level as keyof typeof SEVERITY_LEVEL] || '未知' | ||
| 182 | +} | ||
| 183 | + | ||
| 184 | +// 获取工单状态名称 | ||
| 185 | +export const getWorkorderStatusName = (status: number): string => { | ||
| 186 | + return WORKORDER_STATUS[status as keyof typeof WORKORDER_STATUS] || '未知状态' | ||
| 187 | +} | ||
| 188 | + | ||
| 189 | +// 获取严重程度颜色 | ||
| 190 | +export const getSeverityLevelColor = (level: number): string => { | ||
| 191 | + const colors = { | ||
| 192 | + 1: '#f56c6c', // 高 - 红色 | ||
| 193 | + 2: '#e6a23c', // 中 - 橙色 | ||
| 194 | + 3: '#409eff' // 低 - 蓝色 | ||
| 195 | + } | ||
| 196 | + return colors[level as keyof typeof colors] || '#909399' | ||
| 197 | +} | ||
| 198 | + | ||
| 199 | +// 获取工单状态颜色 | ||
| 200 | +export const getWorkorderStatusColor = (status: number): string => { | ||
| 201 | + const colors = { | ||
| 202 | + 1: '#909399', // 待处理 - 灰色 | ||
| 203 | + 2: '#e6a23c', // 处理中 - 橙色 | ||
| 204 | + 3: '#67c23a', // 已解决 - 绿色 | ||
| 205 | + 4: '#f56c6c' // 已关闭 - 红色 | ||
| 206 | + } | ||
| 207 | + return colors[status as keyof typeof colors] || '#909399' | ||
| 208 | +} |
| 1 | +<template> | ||
| 2 | + <div class="exception-workorder-container"> | ||
| 3 | + <!-- 搜索区域 --> | ||
| 4 | + <div class="search-section"> | ||
| 5 | + <div class="search-form"> | ||
| 6 | + <div class="form-row"> | ||
| 7 | + <div class="form-item"> | ||
| 8 | + <label>工单编号:</label> | ||
| 9 | + <el-input | ||
| 10 | + v-model="searchParams.workorderNo" | ||
| 11 | + placeholder="请输入工单编号" | ||
| 12 | + clearable | ||
| 13 | + class="search-input" | ||
| 14 | + /> | ||
| 15 | + </div> | ||
| 16 | + <div class="form-item"> | ||
| 17 | + <label>关联订单号:</label> | ||
| 18 | + <el-input | ||
| 19 | + v-model="searchParams.orderNo" | ||
| 20 | + placeholder="请输入关联订单号" | ||
| 21 | + clearable | ||
| 22 | + class="search-input" | ||
| 23 | + /> | ||
| 24 | + </div> | ||
| 25 | + <div class="form-item"> | ||
| 26 | + <label>经销商编码:</label> | ||
| 27 | + <el-input | ||
| 28 | + v-model="searchParams.dealerCode" | ||
| 29 | + placeholder="请输入经销商编码" | ||
| 30 | + clearable | ||
| 31 | + class="search-input" | ||
| 32 | + /> | ||
| 33 | + </div> | ||
| 34 | + <div class="form-item"> | ||
| 35 | + <label>经销商名称:</label> | ||
| 36 | + <el-input | ||
| 37 | + v-model="searchParams.dealerName" | ||
| 38 | + placeholder="请输入经销商名称" | ||
| 39 | + clearable | ||
| 40 | + class="search-input" | ||
| 41 | + /> | ||
| 42 | + </div> | ||
| 43 | + </div> | ||
| 44 | + <div class="form-row"> | ||
| 45 | + <div class="form-item"> | ||
| 46 | + <label>工单状态:</label> | ||
| 47 | + <el-select | ||
| 48 | + v-model="searchParams.workorderStatus" | ||
| 49 | + placeholder="请选择工单状态" | ||
| 50 | + clearable | ||
| 51 | + class="search-select" | ||
| 52 | + > | ||
| 53 | + <el-option | ||
| 54 | + v-for="(name, value) in WORKORDER_STATUS" | ||
| 55 | + :key="value" | ||
| 56 | + :label="name" | ||
| 57 | + :value="Number(value)" | ||
| 58 | + /> | ||
| 59 | + </el-select> | ||
| 60 | + </div> | ||
| 61 | + <div class="form-item"> | ||
| 62 | + <label>异常类型:</label> | ||
| 63 | + <el-select | ||
| 64 | + v-model="searchParams.exceptionType" | ||
| 65 | + placeholder="请选择异常类型" | ||
| 66 | + clearable | ||
| 67 | + class="search-select" | ||
| 68 | + > | ||
| 69 | + <el-option | ||
| 70 | + v-for="(name, value) in EXCEPTION_TYPE" | ||
| 71 | + :key="value" | ||
| 72 | + :label="name" | ||
| 73 | + :value="Number(value)" | ||
| 74 | + /> | ||
| 75 | + </el-select> | ||
| 76 | + </div> | ||
| 77 | + <div class="form-item"> | ||
| 78 | + <label>严重程度:</label> | ||
| 79 | + <el-select | ||
| 80 | + v-model="searchParams.severityLevel" | ||
| 81 | + placeholder="请选择严重程度" | ||
| 82 | + clearable | ||
| 83 | + class="search-select" | ||
| 84 | + > | ||
| 85 | + <el-option | ||
| 86 | + v-for="(name, value) in SEVERITY_LEVEL" | ||
| 87 | + :key="value" | ||
| 88 | + :label="name" | ||
| 89 | + :value="Number(value)" | ||
| 90 | + /> | ||
| 91 | + </el-select> | ||
| 92 | + </div> | ||
| 93 | + <div class="form-item"> | ||
| 94 | + <label>处理人:</label> | ||
| 95 | + <el-input | ||
| 96 | + v-model="searchParams.handlerUser" | ||
| 97 | + placeholder="请输入处理人" | ||
| 98 | + clearable | ||
| 99 | + class="search-input" | ||
| 100 | + /> | ||
| 101 | + </div> | ||
| 102 | + </div> | ||
| 103 | + <div class="form-row"> | ||
| 104 | + <div class="form-item"> | ||
| 105 | + <label>开始日期:</label> | ||
| 106 | + <el-date-picker | ||
| 107 | + v-model="searchParams.startTime" | ||
| 108 | + type="datetime" | ||
| 109 | + placeholder="选择开始日期" | ||
| 110 | + format="YYYY-MM-DD HH:mm:ss" | ||
| 111 | + value-format="YYYY-MM-DD HH:mm:ss" | ||
| 112 | + class="search-date" | ||
| 113 | + /> | ||
| 114 | + </div> | ||
| 115 | + <div class="form-item"> | ||
| 116 | + <label>结束日期:</label> | ||
| 117 | + <el-date-picker | ||
| 118 | + v-model="searchParams.endTime" | ||
| 119 | + type="datetime" | ||
| 120 | + placeholder="选择结束日期" | ||
| 121 | + format="YYYY-MM-DD HH:mm:ss" | ||
| 122 | + value-format="YYYY-MM-DD HH:mm:ss" | ||
| 123 | + class="search-date" | ||
| 124 | + /> | ||
| 125 | + </div> | ||
| 126 | + <div class="form-item"> | ||
| 127 | + <el-button type="primary" @click="handleSearch" class="search-btn"> | ||
| 128 | + <el-icon><Search /></el-icon> | ||
| 129 | + 搜索 | ||
| 130 | + </el-button> | ||
| 131 | + <el-button @click="handleReset" class="reset-btn"> | ||
| 132 | + <el-icon><Refresh /></el-icon> | ||
| 133 | + 重置 | ||
| 134 | + </el-button> | ||
| 135 | + </div> | ||
| 136 | + </div> | ||
| 137 | + </div> | ||
| 138 | + </div> | ||
| 139 | + | ||
| 140 | + <!-- 操作按钮区域 --> | ||
| 141 | + <div class="action-section"> | ||
| 142 | + <div class="action-buttons"> | ||
| 143 | + <el-button type="warning" @click="handleAdd" class="add-btn"> | ||
| 144 | + <el-icon><Plus /></el-icon> | ||
| 145 | + 新增数据 | ||
| 146 | + </el-button> | ||
| 147 | + <el-button type="success" @click="handleBatchProcess" class="batch-btn"> | ||
| 148 | + <el-icon><Operation /></el-icon> | ||
| 149 | + 批量处理 | ||
| 150 | + </el-button> | ||
| 151 | + <el-button @click="handleExport" class="export-btn"> | ||
| 152 | + <el-icon><Download /></el-icon> | ||
| 153 | + 导出 | ||
| 154 | + </el-button> | ||
| 155 | + </div> | ||
| 156 | + </div> | ||
| 157 | + | ||
| 158 | + <!-- 数据表格 --> | ||
| 159 | + <div class="table-section"> | ||
| 160 | + <el-table | ||
| 161 | + :data="workorderList" | ||
| 162 | + v-loading="loading" | ||
| 163 | + @selection-change="handleSelectionChange" | ||
| 164 | + class="data-table" | ||
| 165 | + stripe | ||
| 166 | + border | ||
| 167 | + > | ||
| 168 | + <el-table-column type="selection" width="55" /> | ||
| 169 | + <el-table-column prop="workorderId" label="工单ID" width="120" /> | ||
| 170 | + <el-table-column prop="workorderNo" label="工单编号" width="180" /> | ||
| 171 | + <el-table-column prop="orderNo" label="关联订单号" width="180" /> | ||
| 172 | + <el-table-column prop="dealerName" label="经销商名称" width="150" /> | ||
| 173 | + <el-table-column prop="workorderStatusName" label="工单状态" width="100"> | ||
| 174 | + <template #default="{ row }"> | ||
| 175 | + <el-tag :color="getWorkorderStatusColor(row.workorderStatus)"> | ||
| 176 | + {{ row.workorderStatusName }} | ||
| 177 | + </el-tag> | ||
| 178 | + </template> | ||
| 179 | + </el-table-column> | ||
| 180 | + <el-table-column prop="exceptionTypeName" label="异常类型" width="120" /> | ||
| 181 | + <el-table-column prop="severityLevelName" label="严重程度" width="100"> | ||
| 182 | + <template #default="{ row }"> | ||
| 183 | + <el-tag :color="getSeverityLevelColor(row.severityLevel)"> | ||
| 184 | + {{ row.severityLevelName }} | ||
| 185 | + </el-tag> | ||
| 186 | + </template> | ||
| 187 | + </el-table-column> | ||
| 188 | + <el-table-column prop="createTime" label="日期" width="180" sortable> | ||
| 189 | + <template #default="{ row }"> | ||
| 190 | + {{ formatDateTime(row.createTime) }} | ||
| 191 | + </template> | ||
| 192 | + </el-table-column> | ||
| 193 | + <el-table-column label="操作" width="200" fixed="right"> | ||
| 194 | + <template #default="{ row }"> | ||
| 195 | + <el-button | ||
| 196 | + type="primary" | ||
| 197 | + size="small" | ||
| 198 | + @click="handleEditStatus(row)" | ||
| 199 | + class="action-btn" | ||
| 200 | + > | ||
| 201 | + 编辑状态 | ||
| 202 | + </el-button> | ||
| 203 | + <el-button | ||
| 204 | + type="info" | ||
| 205 | + size="small" | ||
| 206 | + @click="handleViewLogs(row)" | ||
| 207 | + class="action-btn" | ||
| 208 | + > | ||
| 209 | + 处理日志 | ||
| 210 | + </el-button> | ||
| 211 | + <el-button | ||
| 212 | + type="success" | ||
| 213 | + size="small" | ||
| 214 | + @click="handleViewDetail(row)" | ||
| 215 | + class="action-btn" | ||
| 216 | + > | ||
| 217 | + 详情 | ||
| 218 | + </el-button> | ||
| 219 | + </template> | ||
| 220 | + </el-table-column> | ||
| 221 | + </el-table> | ||
| 222 | + </div> | ||
| 223 | + | ||
| 224 | + <!-- 分页 --> | ||
| 225 | + <div class="pagination-section"> | ||
| 226 | + <el-pagination | ||
| 227 | + v-model:current-page="pagination.pageNum" | ||
| 228 | + v-model:page-size="pagination.pageSize" | ||
| 229 | + :page-sizes="[10, 20, 50, 100]" | ||
| 230 | + :total="pagination.total" | ||
| 231 | + layout="total, sizes, prev, pager, next, jumper" | ||
| 232 | + @size-change="handleSizeChange" | ||
| 233 | + @current-change="handleCurrentChange" | ||
| 234 | + class="pagination" | ||
| 235 | + /> | ||
| 236 | + </div> | ||
| 237 | + | ||
| 238 | + <!-- 新增/编辑对话框 --> | ||
| 239 | + <el-dialog | ||
| 240 | + v-model="addDialogVisible" | ||
| 241 | + :title="isEdit ? '编辑异常工单' : '新增异常工单'" | ||
| 242 | + width="600px" | ||
| 243 | + class="add-dialog" | ||
| 244 | + > | ||
| 245 | + <el-form | ||
| 246 | + ref="addFormRef" | ||
| 247 | + :model="addFormData" | ||
| 248 | + :rules="addFormRules" | ||
| 249 | + label-width="120px" | ||
| 250 | + class="add-form" | ||
| 251 | + > | ||
| 252 | + <el-form-item label="工单编号" prop="workorderNo"> | ||
| 253 | + <el-input v-model="addFormData.workorderNo" placeholder="请输入工单编号" /> | ||
| 254 | + </el-form-item> | ||
| 255 | + <el-form-item label="关联订单号" prop="orderNo"> | ||
| 256 | + <el-input v-model="addFormData.orderNo" placeholder="请输入关联订单号" /> | ||
| 257 | + </el-form-item> | ||
| 258 | + <el-form-item label="经销商编码" prop="dealerCode"> | ||
| 259 | + <el-input v-model="addFormData.dealerCode" placeholder="请输入经销商编码" /> | ||
| 260 | + </el-form-item> | ||
| 261 | + <el-form-item label="经销商名称" prop="dealerName"> | ||
| 262 | + <el-input v-model="addFormData.dealerName" placeholder="请输入经销商名称" /> | ||
| 263 | + </el-form-item> | ||
| 264 | + <el-form-item label="异常类型" prop="exceptionType"> | ||
| 265 | + <el-select v-model="addFormData.exceptionType" placeholder="请选择异常类型"> | ||
| 266 | + <el-option | ||
| 267 | + v-for="(name, value) in EXCEPTION_TYPE" | ||
| 268 | + :key="value" | ||
| 269 | + :label="name" | ||
| 270 | + :value="Number(value)" | ||
| 271 | + /> | ||
| 272 | + </el-select> | ||
| 273 | + </el-form-item> | ||
| 274 | + <el-form-item label="严重程度" prop="severityLevel"> | ||
| 275 | + <el-select v-model="addFormData.severityLevel" placeholder="请选择严重程度"> | ||
| 276 | + <el-option | ||
| 277 | + v-for="(name, value) in SEVERITY_LEVEL" | ||
| 278 | + :key="value" | ||
| 279 | + :label="name" | ||
| 280 | + :value="Number(value)" | ||
| 281 | + /> | ||
| 282 | + </el-select> | ||
| 283 | + </el-form-item> | ||
| 284 | + <el-form-item label="工单状态" prop="workorderStatus"> | ||
| 285 | + <el-select v-model="addFormData.workorderStatus" placeholder="请选择工单状态"> | ||
| 286 | + <el-option | ||
| 287 | + v-for="(name, value) in WORKORDER_STATUS" | ||
| 288 | + :key="value" | ||
| 289 | + :label="name" | ||
| 290 | + :value="Number(value)" | ||
| 291 | + /> | ||
| 292 | + </el-select> | ||
| 293 | + </el-form-item> | ||
| 294 | + <el-form-item label="处理人" prop="handlerUser"> | ||
| 295 | + <el-input v-model="addFormData.handlerUser" placeholder="请输入处理人" /> | ||
| 296 | + </el-form-item> | ||
| 297 | + <el-form-item label="预计完成时间" prop="expectCompleteTime"> | ||
| 298 | + <el-date-picker | ||
| 299 | + v-model="addFormData.expectCompleteTime" | ||
| 300 | + type="datetime" | ||
| 301 | + placeholder="选择预计完成时间" | ||
| 302 | + format="YYYY-MM-DD HH:mm:ss" | ||
| 303 | + value-format="YYYY-MM-DD HH:mm:ss" | ||
| 304 | + style="width: 100%" | ||
| 305 | + /> | ||
| 306 | + </el-form-item> | ||
| 307 | + <el-form-item label="异常描述" prop="exceptionDesc"> | ||
| 308 | + <el-input | ||
| 309 | + v-model="addFormData.exceptionDesc" | ||
| 310 | + type="textarea" | ||
| 311 | + :rows="3" | ||
| 312 | + placeholder="请输入异常描述" | ||
| 313 | + /> | ||
| 314 | + </el-form-item> | ||
| 315 | + <el-form-item label="处理建议" prop="handleSuggest"> | ||
| 316 | + <el-input | ||
| 317 | + v-model="addFormData.handleSuggest" | ||
| 318 | + type="textarea" | ||
| 319 | + :rows="3" | ||
| 320 | + placeholder="请输入处理建议" | ||
| 321 | + /> | ||
| 322 | + </el-form-item> | ||
| 323 | + <el-form-item label="数据来源" prop="dataSource"> | ||
| 324 | + <el-input v-model="addFormData.dataSource" placeholder="请输入数据来源" /> | ||
| 325 | + </el-form-item> | ||
| 326 | + </el-form> | ||
| 327 | + <template #footer> | ||
| 328 | + <div class="dialog-footer"> | ||
| 329 | + <el-button @click="closeAddDialog">取消</el-button> | ||
| 330 | + <el-button type="primary" @click="handleSubmitAdd">确定</el-button> | ||
| 331 | + </div> | ||
| 332 | + </template> | ||
| 333 | + </el-dialog> | ||
| 334 | + | ||
| 335 | + <!-- 状态更新对话框 --> | ||
| 336 | + <el-dialog | ||
| 337 | + v-model="statusDialogVisible" | ||
| 338 | + title="编辑状态" | ||
| 339 | + width="500px" | ||
| 340 | + class="status-dialog" | ||
| 341 | + > | ||
| 342 | + <el-form | ||
| 343 | + ref="statusFormRef" | ||
| 344 | + :model="statusFormData" | ||
| 345 | + :rules="statusFormRules" | ||
| 346 | + label-width="100px" | ||
| 347 | + class="status-form" | ||
| 348 | + > | ||
| 349 | + <el-form-item label="工单状态" prop="workorderStatus"> | ||
| 350 | + <el-select v-model="statusFormData.workorderStatus" placeholder="请选择工单状态"> | ||
| 351 | + <el-option | ||
| 352 | + v-for="(name, value) in WORKORDER_STATUS" | ||
| 353 | + :key="value" | ||
| 354 | + :label="name" | ||
| 355 | + :value="Number(value)" | ||
| 356 | + /> | ||
| 357 | + </el-select> | ||
| 358 | + </el-form-item> | ||
| 359 | + <el-form-item label="处理人" prop="handlerUser"> | ||
| 360 | + <el-input v-model="statusFormData.handlerUser" placeholder="请输入处理人" /> | ||
| 361 | + </el-form-item> | ||
| 362 | + <el-form-item label="处理意见" prop="handleOpinion"> | ||
| 363 | + <el-input | ||
| 364 | + v-model="statusFormData.handleOpinion" | ||
| 365 | + type="textarea" | ||
| 366 | + :rows="3" | ||
| 367 | + placeholder="请输入处理意见" | ||
| 368 | + /> | ||
| 369 | + </el-form-item> | ||
| 370 | + <el-form-item label="附件URL" prop="attachUrl"> | ||
| 371 | + <el-input v-model="statusFormData.attachUrl" placeholder="请输入附件URL" /> | ||
| 372 | + </el-form-item> | ||
| 373 | + </el-form> | ||
| 374 | + <template #footer> | ||
| 375 | + <div class="dialog-footer"> | ||
| 376 | + <el-button @click="closeStatusDialog">取消</el-button> | ||
| 377 | + <el-button type="primary" @click="handleSubmitStatus">确定</el-button> | ||
| 378 | + </div> | ||
| 379 | + </template> | ||
| 380 | + </el-dialog> | ||
| 381 | + | ||
| 382 | + <!-- 详情对话框 --> | ||
| 383 | + <el-dialog | ||
| 384 | + v-model="detailDialogVisible" | ||
| 385 | + title="异常工单详情" | ||
| 386 | + width="800px" | ||
| 387 | + class="detail-dialog" | ||
| 388 | + > | ||
| 389 | + <div v-if="workorderDetail" class="detail-content"> | ||
| 390 | + <div class="detail-section"> | ||
| 391 | + <h4>工单基本信息</h4> | ||
| 392 | + <div class="detail-grid"> | ||
| 393 | + <div class="detail-item"> | ||
| 394 | + <label>工单编号:</label> | ||
| 395 | + <span>{{ workorderDetail.workorderNo }}</span> | ||
| 396 | + </div> | ||
| 397 | + <div class="detail-item"> | ||
| 398 | + <label>关联订单号:</label> | ||
| 399 | + <span>{{ workorderDetail.orderNo }}</span> | ||
| 400 | + </div> | ||
| 401 | + <div class="detail-item"> | ||
| 402 | + <label>经销商编码:</label> | ||
| 403 | + <span>{{ workorderDetail.dealerCode }}</span> | ||
| 404 | + </div> | ||
| 405 | + <div class="detail-item"> | ||
| 406 | + <label>经销商名称:</label> | ||
| 407 | + <span>{{ workorderDetail.dealerName }}</span> | ||
| 408 | + </div> | ||
| 409 | + <div class="detail-item"> | ||
| 410 | + <label>异常类型:</label> | ||
| 411 | + <span>{{ workorderDetail.exceptionTypeName }}</span> | ||
| 412 | + </div> | ||
| 413 | + <div class="detail-item"> | ||
| 414 | + <label>严重程度:</label> | ||
| 415 | + <span>{{ workorderDetail.severityLevelName }}</span> | ||
| 416 | + </div> | ||
| 417 | + <div class="detail-item"> | ||
| 418 | + <label>工单状态:</label> | ||
| 419 | + <span>{{ workorderDetail.workorderStatusName }}</span> | ||
| 420 | + </div> | ||
| 421 | + <div class="detail-item"> | ||
| 422 | + <label>处理人:</label> | ||
| 423 | + <span>{{ workorderDetail.handlerUser || '未分配' }}</span> | ||
| 424 | + </div> | ||
| 425 | + <div class="detail-item"> | ||
| 426 | + <label>创建时间:</label> | ||
| 427 | + <span>{{ formatDateTime(workorderDetail.createTime) }}</span> | ||
| 428 | + </div> | ||
| 429 | + <div class="detail-item"> | ||
| 430 | + <label>预计完成时间:</label> | ||
| 431 | + <span>{{ workorderDetail.expectCompleteTime ? formatDateTime(workorderDetail.expectCompleteTime) : '未设置' }}</span> | ||
| 432 | + </div> | ||
| 433 | + </div> | ||
| 434 | + </div> | ||
| 435 | + | ||
| 436 | + <div class="detail-section" v-if="workorderDetail.exceptionDesc"> | ||
| 437 | + <h4>异常描述</h4> | ||
| 438 | + <p class="detail-text">{{ workorderDetail.exceptionDesc }}</p> | ||
| 439 | + </div> | ||
| 440 | + | ||
| 441 | + <div class="detail-section" v-if="workorderDetail.handleSuggest"> | ||
| 442 | + <h4>处理建议</h4> | ||
| 443 | + <p class="detail-text">{{ workorderDetail.handleSuggest }}</p> | ||
| 444 | + </div> | ||
| 445 | + | ||
| 446 | + <div class="detail-section" v-if="workorderDetail.workorderLogs && workorderDetail.workorderLogs.length > 0"> | ||
| 447 | + <h4>处理日志</h4> | ||
| 448 | + <el-table :data="workorderDetail.workorderLogs" class="log-table"> | ||
| 449 | + <el-table-column prop="handleUser" label="处理人" width="120" /> | ||
| 450 | + <el-table-column prop="handleTime" label="处理时间" width="180"> | ||
| 451 | + <template #default="{ row }"> | ||
| 452 | + {{ formatDateTime(row.handleTime) }} | ||
| 453 | + </template> | ||
| 454 | + </el-table-column> | ||
| 455 | + <el-table-column prop="beforeStatusName" label="处理前状态" width="120" /> | ||
| 456 | + <el-table-column prop="afterStatusName" label="处理后状态" width="120" /> | ||
| 457 | + <el-table-column prop="handleOpinion" label="处理意见" /> | ||
| 458 | + </el-table> | ||
| 459 | + </div> | ||
| 460 | + </div> | ||
| 461 | + </el-dialog> | ||
| 462 | + | ||
| 463 | + <!-- 处理日志对话框 --> | ||
| 464 | + <el-dialog | ||
| 465 | + v-model="logsDialogVisible" | ||
| 466 | + title="处理日志" | ||
| 467 | + width="900px" | ||
| 468 | + class="logs-dialog" | ||
| 469 | + > | ||
| 470 | + <el-table :data="workorderLogs" class="logs-table"> | ||
| 471 | + <el-table-column prop="handleUser" label="处理人" width="120" /> | ||
| 472 | + <el-table-column prop="handleTime" label="处理时间" width="180"> | ||
| 473 | + <template #default="{ row }"> | ||
| 474 | + {{ formatDateTime(row.handleTime) }} | ||
| 475 | + </template> | ||
| 476 | + </el-table-column> | ||
| 477 | + <el-table-column prop="beforeStatusName" label="处理前状态" width="120" /> | ||
| 478 | + <el-table-column prop="afterStatusName" label="处理后状态" width="120" /> | ||
| 479 | + <el-table-column prop="handleOpinion" label="处理意见" /> | ||
| 480 | + <el-table-column prop="attachUrl" label="附件" width="100"> | ||
| 481 | + <template #default="{ row }"> | ||
| 482 | + <el-button v-if="row.attachUrl" type="primary" size="small" @click="handleDownload(row.attachUrl)"> | ||
| 483 | + 下载 | ||
| 484 | + </el-button> | ||
| 485 | + </template> | ||
| 486 | + </el-table-column> | ||
| 487 | + </el-table> | ||
| 488 | + </el-dialog> | ||
| 489 | + </div> | ||
| 490 | +</template> | ||
| 491 | + | ||
| 492 | +<script setup lang="ts"> | ||
| 493 | +import { ref, reactive, computed, onMounted } from 'vue' | ||
| 494 | +import { ElMessage, ElMessageBox } from 'element-plus' | ||
| 495 | +import { Search, Refresh, Plus, Operation, Download } from '@element-plus/icons-vue' | ||
| 496 | +import { | ||
| 497 | + exceptionWorkorderApi, | ||
| 498 | + type ExceptionWorkorderInfo, | ||
| 499 | + type ExceptionWorkorderQueryReq, | ||
| 500 | + type ExceptionWorkorderAddReq, | ||
| 501 | + type ExceptionWorkorderStatusUpdateReq, | ||
| 502 | + EXCEPTION_TYPE, | ||
| 503 | + SEVERITY_LEVEL, | ||
| 504 | + WORKORDER_STATUS, | ||
| 505 | + getSeverityLevelColor, | ||
| 506 | + getWorkorderStatusColor | ||
| 507 | +} from '../../api/exceptionWorkorder' | ||
| 508 | +import dayjs from 'dayjs' | ||
| 509 | + | ||
| 510 | +// 响应式数据 | ||
| 511 | +const loading = ref(false) | ||
| 512 | +const workorderList = ref<ExceptionWorkorderInfo[]>([]) | ||
| 513 | +const selectedWorkorders = ref<ExceptionWorkorderInfo[]>([]) | ||
| 514 | +const workorderDetail = ref<ExceptionWorkorderInfo | null>(null) | ||
| 515 | +const workorderLogs = ref<any[]>([]) | ||
| 516 | + | ||
| 517 | +// 分页数据 | ||
| 518 | +const pagination = reactive({ | ||
| 519 | + pageNum: 1, | ||
| 520 | + pageSize: 10, | ||
| 521 | + total: 0 | ||
| 522 | +}) | ||
| 523 | + | ||
| 524 | +// 搜索参数 | ||
| 525 | +const searchParams = reactive<ExceptionWorkorderQueryReq>({ | ||
| 526 | + workorderNo: '', | ||
| 527 | + orderNo: '', | ||
| 528 | + dealerCode: '', | ||
| 529 | + dealerName: '', | ||
| 530 | + workorderStatus: undefined, | ||
| 531 | + exceptionType: undefined, | ||
| 532 | + severityLevel: undefined, | ||
| 533 | + handlerUser: '', | ||
| 534 | + startTime: '', | ||
| 535 | + endTime: '', | ||
| 536 | + pageNum: 1, | ||
| 537 | + pageSize: 10 | ||
| 538 | +}) | ||
| 539 | + | ||
| 540 | +// 对话框状态 | ||
| 541 | +const addDialogVisible = ref(false) | ||
| 542 | +const statusDialogVisible = ref(false) | ||
| 543 | +const detailDialogVisible = ref(false) | ||
| 544 | +const logsDialogVisible = ref(false) | ||
| 545 | +const isEdit = ref(false) | ||
| 546 | + | ||
| 547 | +// 新增表单数据 | ||
| 548 | +const addFormData = reactive<ExceptionWorkorderAddReq>({ | ||
| 549 | + workorderNo: '', | ||
| 550 | + orderNo: '', | ||
| 551 | + dealerCode: '', | ||
| 552 | + dealerName: '', | ||
| 553 | + exceptionType: 1, | ||
| 554 | + severityLevel: 1, | ||
| 555 | + workorderStatus: 1, | ||
| 556 | + expectCompleteTime: '', | ||
| 557 | + handlerUser: '', | ||
| 558 | + exceptionDesc: '', | ||
| 559 | + handleSuggest: '', | ||
| 560 | + dataSource: '' | ||
| 561 | +}) | ||
| 562 | + | ||
| 563 | +// 状态更新表单数据 | ||
| 564 | +const statusFormData = reactive<ExceptionWorkorderStatusUpdateReq>({ | ||
| 565 | + workorderId: 0, | ||
| 566 | + workorderStatus: 1, | ||
| 567 | + handlerUser: '', | ||
| 568 | + handleOpinion: '', | ||
| 569 | + attachUrl: '' | ||
| 570 | +}) | ||
| 571 | + | ||
| 572 | +// 表单验证规则 | ||
| 573 | +const addFormRules = { | ||
| 574 | + workorderNo: [ | ||
| 575 | + { required: true, message: '请输入工单编号', trigger: 'blur' } | ||
| 576 | + ], | ||
| 577 | + exceptionType: [ | ||
| 578 | + { required: true, message: '请选择异常类型', trigger: 'change' } | ||
| 579 | + ], | ||
| 580 | + severityLevel: [ | ||
| 581 | + { required: true, message: '请选择严重程度', trigger: 'change' } | ||
| 582 | + ] | ||
| 583 | +} | ||
| 584 | + | ||
| 585 | +const statusFormRules = { | ||
| 586 | + workorderStatus: [ | ||
| 587 | + { required: true, message: '请选择工单状态', trigger: 'change' } | ||
| 588 | + ] | ||
| 589 | +} | ||
| 590 | + | ||
| 591 | +// 获取异常工单列表 | ||
| 592 | +const fetchWorkorders = async () => { | ||
| 593 | + try { | ||
| 594 | + loading.value = true | ||
| 595 | + const params = { | ||
| 596 | + ...searchParams, | ||
| 597 | + pageNum: pagination.pageNum, | ||
| 598 | + pageSize: pagination.pageSize | ||
| 599 | + } | ||
| 600 | + const response = await exceptionWorkorderApi.getExceptionWorkorderList(params) as any | ||
| 601 | + console.log('异常工单列表API响应:', response) | ||
| 602 | + | ||
| 603 | + if (response && response.records) { | ||
| 604 | + workorderList.value = response.records | ||
| 605 | + pagination.total = response.total | ||
| 606 | + } else { | ||
| 607 | + workorderList.value = [] | ||
| 608 | + pagination.total = 0 | ||
| 609 | + } | ||
| 610 | + } catch (error) { | ||
| 611 | + console.error('获取异常工单列表失败:', error) | ||
| 612 | + ElMessage.error('获取异常工单列表失败') | ||
| 613 | + } finally { | ||
| 614 | + loading.value = false | ||
| 615 | + } | ||
| 616 | +} | ||
| 617 | + | ||
| 618 | +// 搜索 | ||
| 619 | +const handleSearch = () => { | ||
| 620 | + pagination.pageNum = 1 | ||
| 621 | + fetchWorkorders() | ||
| 622 | +} | ||
| 623 | + | ||
| 624 | +// 重置 | ||
| 625 | +const handleReset = () => { | ||
| 626 | + Object.assign(searchParams, { | ||
| 627 | + workorderNo: '', | ||
| 628 | + orderNo: '', | ||
| 629 | + dealerCode: '', | ||
| 630 | + dealerName: '', | ||
| 631 | + workorderStatus: undefined, | ||
| 632 | + exceptionType: undefined, | ||
| 633 | + severityLevel: undefined, | ||
| 634 | + handlerUser: '', | ||
| 635 | + startTime: '', | ||
| 636 | + endTime: '' | ||
| 637 | + }) | ||
| 638 | + pagination.pageNum = 1 | ||
| 639 | + fetchWorkorders() | ||
| 640 | +} | ||
| 641 | + | ||
| 642 | +// 新增 | ||
| 643 | +const handleAdd = () => { | ||
| 644 | + isEdit.value = false | ||
| 645 | + Object.assign(addFormData, { | ||
| 646 | + workorderNo: '', | ||
| 647 | + orderNo: '', | ||
| 648 | + dealerCode: '', | ||
| 649 | + dealerName: '', | ||
| 650 | + exceptionType: 1, | ||
| 651 | + severityLevel: 1, | ||
| 652 | + workorderStatus: 1, | ||
| 653 | + expectCompleteTime: '', | ||
| 654 | + handlerUser: '', | ||
| 655 | + exceptionDesc: '', | ||
| 656 | + handleSuggest: '', | ||
| 657 | + dataSource: '' | ||
| 658 | + }) | ||
| 659 | + addDialogVisible.value = true | ||
| 660 | +} | ||
| 661 | + | ||
| 662 | +// 编辑状态 | ||
| 663 | +const handleEditStatus = (row: ExceptionWorkorderInfo) => { | ||
| 664 | + statusFormData.workorderId = row.workorderId | ||
| 665 | + statusFormData.workorderStatus = row.workorderStatus | ||
| 666 | + statusFormData.handlerUser = row.handlerUser || '' | ||
| 667 | + statusFormData.handleOpinion = '' | ||
| 668 | + statusFormData.attachUrl = '' | ||
| 669 | + statusDialogVisible.value = true | ||
| 670 | +} | ||
| 671 | + | ||
| 672 | +// 查看详情 | ||
| 673 | +const handleViewDetail = async (row: ExceptionWorkorderInfo) => { | ||
| 674 | + try { | ||
| 675 | + const response = await exceptionWorkorderApi.getExceptionWorkorderDetail(row.workorderId) as any | ||
| 676 | + console.log('异常工单详情API响应:', response) | ||
| 677 | + | ||
| 678 | + if (response && response.workorderId) { | ||
| 679 | + workorderDetail.value = response | ||
| 680 | + detailDialogVisible.value = true | ||
| 681 | + } else { | ||
| 682 | + ElMessage.error('获取异常工单详情失败') | ||
| 683 | + } | ||
| 684 | + } catch (error) { | ||
| 685 | + console.error('获取异常工单详情失败:', error) | ||
| 686 | + ElMessage.error('获取异常工单详情失败, 请重试') | ||
| 687 | + } | ||
| 688 | +} | ||
| 689 | + | ||
| 690 | +// 查看处理日志 | ||
| 691 | +const handleViewLogs = async (row: ExceptionWorkorderInfo) => { | ||
| 692 | + try { | ||
| 693 | + const response = await exceptionWorkorderApi.getExceptionWorkorderDetail(row.workorderId) as any | ||
| 694 | + console.log('处理日志API响应:', response) | ||
| 695 | + | ||
| 696 | + if (response && response.workorderLogs) { | ||
| 697 | + workorderLogs.value = response.workorderLogs | ||
| 698 | + logsDialogVisible.value = true | ||
| 699 | + } else { | ||
| 700 | + ElMessage.error('获取处理日志失败') | ||
| 701 | + } | ||
| 702 | + } catch (error) { | ||
| 703 | + console.error('获取处理日志失败:', error) | ||
| 704 | + ElMessage.error('获取处理日志失败, 请重试') | ||
| 705 | + } | ||
| 706 | +} | ||
| 707 | + | ||
| 708 | +// 批量处理 | ||
| 709 | +const handleBatchProcess = () => { | ||
| 710 | + if (selectedWorkorders.value.length === 0) { | ||
| 711 | + ElMessage.warning('请选择要处理的工单') | ||
| 712 | + return | ||
| 713 | + } | ||
| 714 | + | ||
| 715 | + ElMessageBox.confirm( | ||
| 716 | + `确定要批量处理选中的 ${selectedWorkorders.value.length} 个工单吗?`, | ||
| 717 | + '批量处理确认', | ||
| 718 | + { | ||
| 719 | + confirmButtonText: '确定', | ||
| 720 | + cancelButtonText: '取消', | ||
| 721 | + type: 'warning' | ||
| 722 | + } | ||
| 723 | + ).then(async () => { | ||
| 724 | + try { | ||
| 725 | + const workorderIds = selectedWorkorders.value.map(item => item.workorderId) | ||
| 726 | + await exceptionWorkorderApi.batchUpdateWorkorderStatus(workorderIds, 2, '系统管理员') | ||
| 727 | + ElMessage.success('批量处理成功') | ||
| 728 | + fetchWorkorders() | ||
| 729 | + } catch (error) { | ||
| 730 | + console.error('批量处理失败:', error) | ||
| 731 | + ElMessage.error('批量处理失败') | ||
| 732 | + } | ||
| 733 | + }) | ||
| 734 | +} | ||
| 735 | + | ||
| 736 | +// 导出 | ||
| 737 | +const handleExport = () => { | ||
| 738 | + ElMessage.info('导出功能开发中...') | ||
| 739 | +} | ||
| 740 | + | ||
| 741 | +// 提交新增 | ||
| 742 | +const handleSubmitAdd = async () => { | ||
| 743 | + try { | ||
| 744 | + await exceptionWorkorderApi.addExceptionWorkorder(addFormData) | ||
| 745 | + ElMessage.success('新增异常工单成功') | ||
| 746 | + closeAddDialog() | ||
| 747 | + fetchWorkorders() | ||
| 748 | + } catch (error) { | ||
| 749 | + console.error('新增异常工单失败:', error) | ||
| 750 | + ElMessage.error('新增异常工单失败') | ||
| 751 | + } | ||
| 752 | +} | ||
| 753 | + | ||
| 754 | +// 提交状态更新 | ||
| 755 | +const handleSubmitStatus = async () => { | ||
| 756 | + try { | ||
| 757 | + await exceptionWorkorderApi.updateWorkorderStatus(statusFormData) | ||
| 758 | + ElMessage.success('更新工单状态成功') | ||
| 759 | + closeStatusDialog() | ||
| 760 | + fetchWorkorders() | ||
| 761 | + } catch (error) { | ||
| 762 | + console.error('更新工单状态失败:', error) | ||
| 763 | + ElMessage.error('更新工单状态失败') | ||
| 764 | + } | ||
| 765 | +} | ||
| 766 | + | ||
| 767 | +// 关闭对话框 | ||
| 768 | +const closeAddDialog = () => { | ||
| 769 | + addDialogVisible.value = false | ||
| 770 | +} | ||
| 771 | + | ||
| 772 | +const closeStatusDialog = () => { | ||
| 773 | + statusDialogVisible.value = false | ||
| 774 | +} | ||
| 775 | + | ||
| 776 | +// 选择变化 | ||
| 777 | +const handleSelectionChange = (selection: ExceptionWorkorderInfo[]) => { | ||
| 778 | + selectedWorkorders.value = selection | ||
| 779 | +} | ||
| 780 | + | ||
| 781 | +// 分页变化 | ||
| 782 | +const handleSizeChange = (size: number) => { | ||
| 783 | + pagination.pageSize = size | ||
| 784 | + pagination.pageNum = 1 | ||
| 785 | + fetchWorkorders() | ||
| 786 | +} | ||
| 787 | + | ||
| 788 | +const handleCurrentChange = (page: number) => { | ||
| 789 | + pagination.pageNum = page | ||
| 790 | + fetchWorkorders() | ||
| 791 | +} | ||
| 792 | + | ||
| 793 | +// 下载附件 | ||
| 794 | +const handleDownload = (url: string) => { | ||
| 795 | + window.open(url, '_blank') | ||
| 796 | +} | ||
| 797 | + | ||
| 798 | +// 格式化日期时间 | ||
| 799 | +const formatDateTime = (dateTime: string) => { | ||
| 800 | + return dayjs(dateTime).format('YYYY-MM-DD HH:mm:ss') | ||
| 801 | +} | ||
| 802 | + | ||
| 803 | +// 组件挂载 | ||
| 804 | +onMounted(() => { | ||
| 805 | + fetchWorkorders() | ||
| 806 | +}) | ||
| 807 | +</script> | ||
| 808 | + | ||
| 809 | +<style scoped> | ||
| 810 | +.exception-workorder-container { | ||
| 811 | + padding: 20px; | ||
| 812 | + background: #f5f5f5; | ||
| 813 | + min-height: 100vh; | ||
| 814 | +} | ||
| 815 | + | ||
| 816 | +.search-section { | ||
| 817 | + background: white; | ||
| 818 | + padding: 20px; | ||
| 819 | + border-radius: 8px; | ||
| 820 | + margin-bottom: 20px; | ||
| 821 | + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); | ||
| 822 | +} | ||
| 823 | + | ||
| 824 | +.search-form { | ||
| 825 | + display: flex; | ||
| 826 | + flex-direction: column; | ||
| 827 | + gap: 15px; | ||
| 828 | +} | ||
| 829 | + | ||
| 830 | +.form-row { | ||
| 831 | + display: flex; | ||
| 832 | + gap: 20px; | ||
| 833 | + align-items: center; | ||
| 834 | + flex-wrap: wrap; | ||
| 835 | +} | ||
| 836 | + | ||
| 837 | +.form-item { | ||
| 838 | + display: flex; | ||
| 839 | + align-items: center; | ||
| 840 | + gap: 8px; | ||
| 841 | + min-width: 200px; | ||
| 842 | +} | ||
| 843 | + | ||
| 844 | +.form-item label { | ||
| 845 | + font-weight: 500; | ||
| 846 | + color: #333; | ||
| 847 | + white-space: nowrap; | ||
| 848 | + min-width: 80px; | ||
| 849 | +} | ||
| 850 | + | ||
| 851 | +.search-input, | ||
| 852 | +.search-select, | ||
| 853 | +.search-date { | ||
| 854 | + width: 200px; | ||
| 855 | +} | ||
| 856 | + | ||
| 857 | +.search-btn, | ||
| 858 | +.reset-btn { | ||
| 859 | + margin-left: 10px; | ||
| 860 | +} | ||
| 861 | + | ||
| 862 | +.action-section { | ||
| 863 | + background: white; | ||
| 864 | + padding: 15px 20px; | ||
| 865 | + border-radius: 8px; | ||
| 866 | + margin-bottom: 20px; | ||
| 867 | + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); | ||
| 868 | +} | ||
| 869 | + | ||
| 870 | +.action-buttons { | ||
| 871 | + display: flex; | ||
| 872 | + gap: 10px; | ||
| 873 | +} | ||
| 874 | + | ||
| 875 | +.table-section { | ||
| 876 | + background: white; | ||
| 877 | + border-radius: 8px; | ||
| 878 | + overflow: hidden; | ||
| 879 | + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); | ||
| 880 | + margin-bottom: 20px; | ||
| 881 | +} | ||
| 882 | + | ||
| 883 | +.data-table { | ||
| 884 | + width: 100%; | ||
| 885 | +} | ||
| 886 | + | ||
| 887 | +.action-btn { | ||
| 888 | + margin-right: 5px; | ||
| 889 | +} | ||
| 890 | + | ||
| 891 | +.pagination-section { | ||
| 892 | + display: flex; | ||
| 893 | + justify-content: center; | ||
| 894 | + background: white; | ||
| 895 | + padding: 20px; | ||
| 896 | + border-radius: 8px; | ||
| 897 | + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); | ||
| 898 | +} | ||
| 899 | + | ||
| 900 | +.add-dialog, | ||
| 901 | +.status-dialog, | ||
| 902 | +.detail-dialog, | ||
| 903 | +.logs-dialog { | ||
| 904 | + .el-dialog__body { | ||
| 905 | + padding: 20px; | ||
| 906 | + } | ||
| 907 | +} | ||
| 908 | + | ||
| 909 | +.add-form, | ||
| 910 | +.status-form { | ||
| 911 | + .el-form-item { | ||
| 912 | + margin-bottom: 20px; | ||
| 913 | + } | ||
| 914 | +} | ||
| 915 | + | ||
| 916 | +.detail-content { | ||
| 917 | + .detail-section { | ||
| 918 | + margin-bottom: 30px; | ||
| 919 | + } | ||
| 920 | + | ||
| 921 | + .detail-section h4 { | ||
| 922 | + color: #333; | ||
| 923 | + margin-bottom: 15px; | ||
| 924 | + padding-bottom: 8px; | ||
| 925 | + border-bottom: 2px solid #409eff; | ||
| 926 | + } | ||
| 927 | + | ||
| 928 | + .detail-grid { | ||
| 929 | + display: grid; | ||
| 930 | + grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); | ||
| 931 | + gap: 15px; | ||
| 932 | + } | ||
| 933 | + | ||
| 934 | + .detail-item { | ||
| 935 | + display: flex; | ||
| 936 | + align-items: center; | ||
| 937 | + gap: 10px; | ||
| 938 | + } | ||
| 939 | + | ||
| 940 | + .detail-item label { | ||
| 941 | + font-weight: 500; | ||
| 942 | + color: #666; | ||
| 943 | + min-width: 120px; | ||
| 944 | + } | ||
| 945 | + | ||
| 946 | + .detail-item span { | ||
| 947 | + color: #333; | ||
| 948 | + } | ||
| 949 | + | ||
| 950 | + .detail-text { | ||
| 951 | + color: #333; | ||
| 952 | + line-height: 1.6; | ||
| 953 | + background: #f8f9fa; | ||
| 954 | + padding: 15px; | ||
| 955 | + border-radius: 4px; | ||
| 956 | + border-left: 4px solid #409eff; | ||
| 957 | + } | ||
| 958 | + | ||
| 959 | + .log-table, | ||
| 960 | + .logs-table { | ||
| 961 | + margin-top: 15px; | ||
| 962 | + } | ||
| 963 | +} | ||
| 964 | + | ||
| 965 | +.dialog-footer { | ||
| 966 | + text-align: right; | ||
| 967 | +} | ||
| 968 | + | ||
| 969 | +.dialog-footer .el-button { | ||
| 970 | + margin-left: 10px; | ||
| 971 | +} | ||
| 972 | +</style> |
-
Please register or login to post a comment