From 91c8edd53e3f659a4136a5f78b8a2395690023df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E9=B9=8F=E9=A3=9E?= Date: Mon, 8 Dec 2025 18:07:16 +0800 Subject: [PATCH] =?UTF-8?q?fix(dispatch):=20=E4=BF=AE=E6=AD=A3=E5=AE=8C?= =?UTF-8?q?=E6=88=90=E6=B4=BE=E5=B7=A5=E5=8D=95=E7=9A=84=E7=8A=B6=E6=80=81?= =?UTF-8?q?=E5=88=A4=E6=96=AD=E5=92=8C=E9=99=84=E4=BB=B6=E4=BF=9D=E5=AD=98?= =?UTF-8?q?=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 修正完成派工单时状态判断逻辑,禁止状态为0的派工单完成 - 优化附件保存逻辑,过滤已存在附件避免重复保存 - 完成派工单时仅在状态为1时更新完成时间和状态 feat(ticket): 新增获取工单案例图片接口 - 新增根据工单ID获取案例照片接口,支持标签过滤 - 支持案例图片选中状态返回,基于工单关联图片列表 - 异常情况返回空列表或错误提示 feat(solution): 支持解决措施上传案例照片标签管理 - 在解决措施保存请求中新增案例照片字段 - 保存时更新附件标签为“案例照片” - 新建SolutionImageVO用于案例图片展示 refactor(entity): 添加FileUploadRecord标签字段支持 - FileUploadRecord实体新增标签字段,用于附件分类管理 --- .../request/SolutionMeasuresSaveRequest.java | 5 +++ .../gongfu/controller/DispatchController.java | 43 +++++++++++++------ .../gongfu/controller/TicketController.java | 38 ++++++++++++++++ .../gongfu/pojo/vo/SolutionImageVO.java | 29 +++++++++++++ .../repository/entity/FileUploadRecord.java | 5 +++ .../impl/TicketSolutionServiceImpl.java | 10 +++++ 6 files changed, 116 insertions(+), 14 deletions(-) create mode 100644 nflg-mobilebroken-gongfu/src/main/java/com/nflg/mobilebroken/gongfu/pojo/vo/SolutionImageVO.java diff --git a/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/request/SolutionMeasuresSaveRequest.java b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/request/SolutionMeasuresSaveRequest.java index 4297a321..e40bc9e8 100644 --- a/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/request/SolutionMeasuresSaveRequest.java +++ b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/request/SolutionMeasuresSaveRequest.java @@ -33,6 +33,11 @@ public class SolutionMeasuresSaveRequest { @NotBlank private String reason; + /** + * 案例照片 + */ + private List imageIds; + /** * 解决措施 */ diff --git a/nflg-mobilebroken-gongfu/src/main/java/com/nflg/mobilebroken/gongfu/controller/DispatchController.java b/nflg-mobilebroken-gongfu/src/main/java/com/nflg/mobilebroken/gongfu/controller/DispatchController.java index 28e61c2e..48b2a276 100644 --- a/nflg-mobilebroken-gongfu/src/main/java/com/nflg/mobilebroken/gongfu/controller/DispatchController.java +++ b/nflg-mobilebroken-gongfu/src/main/java/com/nflg/mobilebroken/gongfu/controller/DispatchController.java @@ -9,6 +9,7 @@ import com.nflg.mobilebroken.common.pojo.ApiResult; import com.nflg.mobilebroken.common.pojo.PageData; import com.nflg.mobilebroken.common.pojo.request.*; import com.nflg.mobilebroken.common.pojo.vo.DispatchVO; +import com.nflg.mobilebroken.common.pojo.vo.FileUploadVO; import com.nflg.mobilebroken.common.pojo.vo.GongfuFileVO; import com.nflg.mobilebroken.common.util.AdminUserUtil; import com.nflg.mobilebroken.common.util.DateTimeUtil; @@ -151,7 +152,7 @@ public class DispatchController extends ControllerBase { public ApiResult complete(@Valid @RequestBody DispatchCompleteRequest request) { GongfuDispatch dispatch = dispatchService.getById(request.getTicketId()); VUtils.trueThrowBusinessError(Objects.isNull(dispatch)).throwMessage("派工单不存在"); - VUtils.trueThrowBusinessError(!Objects.equals(dispatch.getState(), 1)).throwMessage("当前派工单状态不允许完成"); + VUtils.trueThrowBusinessError(Objects.equals(dispatch.getState(), 0)).throwMessage("当前派工单状态不允许完成"); VUtils.trueThrowBusinessError(!Objects.equals(dispatch.getHandlerUserId(), AdminUserUtil.getUserId()) && !Objects.equals(dispatch.getCreateById(), AdminUserUtil.getUserId())) .throwMessage("无权限完成派工单"); @@ -161,23 +162,37 @@ public class DispatchController extends ControllerBase { .exists() ).throwMessage("延期申请审核中,不能完成派工单"); if (CollectionUtil.isNotEmpty(request.getAttachments())) { - fileService.saveBatch(request.getAttachments().stream().map(it -> new GongfuFile() - .setType(0) - .setSourceId(dispatch.getId()) - .setNo(dispatch.getNo()) - .setFileName(it.getFileName()) - .setFileUrl(it.getUrl()) - .setFileSuffix(FilenameUtils.getExtension(it.getFileName())) - .setFileSize(it.getFileSize()) - .setCreateBy(AdminUserUtil.getUserName()) - .setCreateTime(LocalDateTime.now()) - ).collect(Collectors.toList())); + List fids = fileService.lambdaQuery() + .eq(GongfuFile::getSourceId, request.getTicketId()) + .list() + .stream() + .map(GongfuFile::getId) + .collect(Collectors.toList()); + List ups = request.getAttachments().stream() + .filter(it -> !fids.contains(it.getId().longValue())) + .collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(ups)) { + fileService.saveBatch(ups.stream() + .map(it -> new GongfuFile() + .setType(0) + .setSourceId(dispatch.getId()) + .setNo(dispatch.getNo()) + .setFileName(it.getFileName()) + .setFileUrl(it.getUrl()) + .setFileSuffix(FilenameUtils.getExtension(it.getFileName())) + .setFileSize(it.getFileSize()) + .setCreateBy(AdminUserUtil.getUserName()) + .setCreateTime(LocalDateTime.now()) + ).collect(Collectors.toList())); + } } dispatch.setSolution(request.getSolution()); dispatch.setSuggestion(request.getSuggestion()); dispatch.setActualEndDate(DateTimeUtil.format(request.getActualEndDate(), "yyyy-MM-dd")); - dispatch.setCompleteDate(LocalDateTime.now()); - dispatch.setState(2); + if (dispatch.getState() == 1) { + dispatch.setCompleteDate(LocalDateTime.now()); + dispatch.setState(2); + } dispatchService.updateById(dispatch); dispatchEventPublisher.publishDispatchComplate(dispatch); return ApiResult.success(); diff --git a/nflg-mobilebroken-gongfu/src/main/java/com/nflg/mobilebroken/gongfu/controller/TicketController.java b/nflg-mobilebroken-gongfu/src/main/java/com/nflg/mobilebroken/gongfu/controller/TicketController.java index 862d2c40..2d83c652 100644 --- a/nflg-mobilebroken-gongfu/src/main/java/com/nflg/mobilebroken/gongfu/controller/TicketController.java +++ b/nflg-mobilebroken-gongfu/src/main/java/com/nflg/mobilebroken/gongfu/controller/TicketController.java @@ -16,6 +16,7 @@ import com.nflg.mobilebroken.common.pojo.request.*; import com.nflg.mobilebroken.common.pojo.vo.*; import com.nflg.mobilebroken.common.util.*; import com.nflg.mobilebroken.gongfu.annotation.ApiMark; +import com.nflg.mobilebroken.gongfu.pojo.vo.SolutionImageVO; import com.nflg.mobilebroken.gongfu.publisher.TicketEventPublisher; import com.nflg.mobilebroken.gongfu.service.ShengWangService; import com.nflg.mobilebroken.gongfu.service.SsePushService; @@ -1448,4 +1449,41 @@ public class TicketController extends ControllerBase { public ApiResult> getHandlerForSelect() { return ApiResult.success(adminUserService.lambdaQuery().eq(AdminUser::isGongFuHandler, true).list()); } + + /** + * 获取工单案例图片 + * @param id 工单ID + * @return 工单案例图片 + */ + @GetMapping("getSolutionImages") + public ApiResult> getSolutionImages(@RequestParam Long id) { + List images = fileUploadRecordService.lambdaQuery() + .eq(FileUploadRecord::getSource, (byte) 0) + .eq(FileUploadRecord::getSourceId, id) + .eq(FileUploadRecord::getTag, "案例照片") + .list(); + if (CollectionUtil.isNotEmpty(images)) { + return ApiResult.success(images.stream() + .map(image -> Convert.convert(SolutionImageVO.class, image)) + .collect(Collectors.toList()) + ); + } + GongfuTicket ticket = ticketService.getById(id); + VUtils.trueThrowBusinessError(Objects.isNull(ticket)).throwMessage("工单不存在"); + images = fileUploadRecordService.lambdaQuery() + .eq(FileUploadRecord::getSource, (byte) 0) + .eq(FileUploadRecord::getSourceId, id) + .list(); + if (CollectionUtil.isEmpty(images)) { + return ApiResult.success(Collections.emptyList()); + } + int[] mids = StrUtil.splitToInt(ticket.getImages(), ","); + return ApiResult.success( + images.stream().map(image -> { + SolutionImageVO vo = Convert.convert(SolutionImageVO.class, image); + vo.setSelected(Arrays.stream(mids).anyMatch(mid -> mid == image.getId())); + return vo; + }).collect(Collectors.toList()) + ); + } } \ No newline at end of file diff --git a/nflg-mobilebroken-gongfu/src/main/java/com/nflg/mobilebroken/gongfu/pojo/vo/SolutionImageVO.java b/nflg-mobilebroken-gongfu/src/main/java/com/nflg/mobilebroken/gongfu/pojo/vo/SolutionImageVO.java new file mode 100644 index 00000000..5e39a139 --- /dev/null +++ b/nflg-mobilebroken-gongfu/src/main/java/com/nflg/mobilebroken/gongfu/pojo/vo/SolutionImageVO.java @@ -0,0 +1,29 @@ +package com.nflg.mobilebroken.gongfu.pojo.vo; + +import lombok.Data; + +@Data +public class SolutionImageVO { + + private Integer id; + + /** + * 文件名称 + */ + private String fileName; + + /** + * 文件类型 + */ + private String fileType; + + /** + * 访问地址 + */ + private String url; + + /** + * 是否选中 + */ + private boolean selected = true; +} diff --git a/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/entity/FileUploadRecord.java b/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/entity/FileUploadRecord.java index 55f0219b..2fce515d 100644 --- a/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/entity/FileUploadRecord.java +++ b/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/entity/FileUploadRecord.java @@ -61,6 +61,11 @@ public class FileUploadRecord implements Serializable { @TableField("`from`") private String from; + /** + * 标签 + */ + private String tag; + /** * 上传人 */ diff --git a/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/impl/TicketSolutionServiceImpl.java b/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/impl/TicketSolutionServiceImpl.java index 66cb8da2..53590771 100644 --- a/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/impl/TicketSolutionServiceImpl.java +++ b/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/impl/TicketSolutionServiceImpl.java @@ -53,6 +53,9 @@ public class TicketSolutionServiceImpl extends ServiceImpl