From 736978c29fe8b814be3ed472546c69de29d1d8bb Mon Sep 17 00:00:00 2001 From: 10001392 <1055202292@qq.com> Date: Thu, 12 Mar 2026 08:57:08 +0800 Subject: [PATCH] =?UTF-8?q?=E7=A6=85=E9=81=93=E4=BC=98=E5=8C=96=201?= =?UTF-8?q?=E3=80=81=E5=B7=A5=E6=9C=8D=E6=A8=A1=E5=9D=97=E5=B7=A5=E5=8D=95?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E5=88=97=E8=A1=A8=E5=A2=9E=E5=8A=A0=E4=BA=8B?= =?UTF-8?q?=E6=95=85=E7=AD=89=E7=BA=A7=E5=B1=95=E7=A4=BA=EF=BC=9B=E6=B4=BE?= =?UTF-8?q?=E5=B7=A5=E7=AE=A1=E7=90=86=E5=88=97=E8=A1=A8=E4=B8=AD=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E6=98=AF=E5=90=A6=E6=8C=89=E6=97=B6=E5=AE=8C=E6=88=90?= =?UTF-8?q?=E5=AD=97=E6=AE=B5=202=E3=80=81=E7=A7=BB=E5=8A=A8=E7=A0=B4?= =?UTF-8?q?=E5=92=8C=E5=B7=A5=E6=9C=8D=E7=AE=A1=E7=90=86=E7=9A=84=E5=B7=A5?= =?UTF-8?q?=E5=8D=95=E7=AE=A1=E7=90=86=E4=B8=AD=EF=BC=8C=E5=B7=A5=E5=8D=95?= =?UTF-8?q?=E6=A0=87=E9=A2=98=E7=9A=84=E7=BF=BB=E8=AF=91=E5=88=97=EF=BC=8C?= =?UTF-8?q?=E5=8F=AF=E5=90=A6=E5=B1=95=E7=A4=BA=E5=88=B0=E5=B7=A5=E5=8D=95?= =?UTF-8?q?=E5=88=97=E8=A1=A8=E4=B8=8A=EF=BC=8C=E6=88=96=E8=80=85=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E4=B8=AA=E5=A4=87=E6=B3=A8=E5=88=97=EF=BC=9F=203?= =?UTF-8?q?=E3=80=81=E5=B7=A5=E6=9C=8D=E7=AE=A1=E7=90=86=E7=9A=84=E6=B4=BE?= =?UTF-8?q?=E5=B7=A5=E7=AE=A1=E7=90=86=EF=BC=8C=E5=A2=9E=E5=8A=A0=E8=AE=BE?= =?UTF-8?q?=E5=A4=87=E7=BC=96=E5=8F=B7=E7=AD=9B=E9=80=89=E5=AD=97=E6=AE=B5?= =?UTF-8?q?=204=E3=80=81=E6=B4=BE=E5=B7=A5=E4=B8=AD=EF=BC=8C=E8=A6=81?= =?UTF-8?q?=E6=B1=82=E5=A2=9E=E5=8A=A0=E5=AF=BC=E5=87=BA=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=EF=BC=8C=E5=9C=A8=E6=9C=89=E9=80=89=E4=B8=AD=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E7=9A=84=E6=83=85=E5=86=B5=E4=B8=8B=EF=BC=8C=E5=AF=BC=E5=87=BA?= =?UTF-8?q?=E6=89=80=E9=80=89=E6=95=B0=E6=8D=AE=E5=88=97=E8=A1=A8=E3=80=82?= =?UTF-8?q?=E5=9C=A8=E6=9C=AA=E9=80=89=E4=B8=AD=E6=95=B0=E6=8D=AE=E7=9A=84?= =?UTF-8?q?=E6=83=85=E5=86=B5=E4=B8=8B=EF=BC=8C=E9=BB=98=E8=AE=A4=E5=AF=BC?= =?UTF-8?q?=E5=87=BA=E6=89=80=E6=9C=89=E6=B4=BE=E5=B7=A5=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pojo/request/DispatchSearchRequest.java | 3 + .../common/pojo/vo/AdminTicketVO.java | 3 + .../gongfu/controller/DispatchController.java | 80 ++++++- .../gongfu/controller/TicketController.java | 27 ++- .../gongfu/pojo/dto/DispatchDTO.java | 196 ++++++++++++++++++ .../resources/mapper/GongfuDispatchMapper.xml | 6 + .../resources/mapper/GongfuTicketMapper.xml | 2 +- 7 files changed, 311 insertions(+), 6 deletions(-) create mode 100644 nflg-mobilebroken-gongfu/src/main/java/com/nflg/mobilebroken/gongfu/pojo/dto/DispatchDTO.java diff --git a/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/request/DispatchSearchRequest.java b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/request/DispatchSearchRequest.java index 337366ce..4d612383 100644 --- a/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/request/DispatchSearchRequest.java +++ b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/request/DispatchSearchRequest.java @@ -3,6 +3,7 @@ package com.nflg.mobilebroken.common.pojo.request; import lombok.Data; import java.time.LocalDate; +import java.util.List; @Data public class DispatchSearchRequest extends PageRequest { @@ -51,4 +52,6 @@ public class DispatchSearchRequest extends PageRequest { * 结束时间 */ private LocalDate endDate; + + private List ids; } diff --git a/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/vo/AdminTicketVO.java b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/vo/AdminTicketVO.java index 06221df0..0a3d2460 100644 --- a/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/vo/AdminTicketVO.java +++ b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/vo/AdminTicketVO.java @@ -29,6 +29,9 @@ public class AdminTicketVO { @ExcelColumn("标题") private String title; + @ExcelColumn("标题翻译") + private String titleTranslate = ""; + //工单状态 @JsonIgnore @IgnoreExport 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 37309db1..444c44e5 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 @@ -1,11 +1,15 @@ package com.nflg.mobilebroken.gongfu.controller; +import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.convert.Convert; +import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; import com.nflg.mobilebroken.common.constant.MessageSubType; import com.nflg.mobilebroken.common.constant.MessageType; +import com.nflg.mobilebroken.common.constant.TicketState; import com.nflg.mobilebroken.common.pojo.ApiResult; import com.nflg.mobilebroken.common.pojo.PageData; import com.nflg.mobilebroken.common.pojo.request.*; @@ -15,26 +19,36 @@ import com.nflg.mobilebroken.common.pojo.vo.GongfuFileVO; import com.nflg.mobilebroken.common.util.AdminUserUtil; import com.nflg.mobilebroken.common.util.DateTimeUtil; import com.nflg.mobilebroken.common.util.VUtils; +import com.nflg.mobilebroken.gongfu.annotation.ApiMark; +import com.nflg.mobilebroken.gongfu.pojo.dto.DispatchDTO; import com.nflg.mobilebroken.gongfu.pojo.vo.ApplyforAuditVO; import com.nflg.mobilebroken.gongfu.pojo.vo.DispatchApplyforAuditVO; import com.nflg.mobilebroken.gongfu.publisher.DispatchEventPublisher; -import com.nflg.mobilebroken.repository.entity.AdminMessage; -import com.nflg.mobilebroken.repository.entity.GongfuDispatch; -import com.nflg.mobilebroken.repository.entity.GongfuDispatchApplyfor; -import com.nflg.mobilebroken.repository.entity.GongfuFile; +import com.nflg.mobilebroken.repository.entity.*; import com.nflg.mobilebroken.repository.service.*; import lombok.extern.slf4j.Slf4j; import org.apache.commons.io.FilenameUtils; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.*; +import org.ttzero.excel.entity.ListSheet; +import org.ttzero.excel.entity.Workbook; import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; import javax.validation.Valid; import javax.validation.constraints.NotEmpty; +import java.io.IOException; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; import java.time.LocalDate; import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; import java.util.List; import java.util.Objects; +import java.util.Optional; +import java.util.Set; import java.util.stream.Collectors; /** @@ -62,6 +76,8 @@ public class DispatchController extends ControllerBase { @Resource private IAdminMessageService adminMessageService; + @Resource + private IDictionaryItemService dictionaryItemService; /** * 新增派工单 @@ -362,4 +378,60 @@ public class DispatchController extends ControllerBase { ); return ApiResult.success(); } + + /** + * 导出选中的派工 + * @param ids 选中的id集合 + */ + @PostMapping("exportSelect") + @ApiMark(moduleName = "派工管理", apiName = "导出选中的派工") + public void exportSelect(HttpServletResponse response, @RequestBody @NotEmpty List ids) throws Exception { + DispatchSearchRequest request = new DispatchSearchRequest(); + request.setIds(ids); + handleExportData(response, request); + } + + private void handleExportData(HttpServletResponse response, DispatchSearchRequest request) throws IOException { + request.setPage(1); + request.setPageSize(Integer.MAX_VALUE); + IPage page = dispatchService.search(request, AdminUserUtil.getUserId()); + List list = page.getRecords(); + Set typeSet = list.stream().map(DispatchVO::getType).collect(Collectors.toSet()); + List dictionaryItems = dictionaryItemService.listByIds(typeSet); +// List applyforList = dispatchApplyforService.lambdaQuery().in(GongfuDispatchApplyfor::getTicketId, list.stream().map(DispatchVO::getId).collect(Collectors.toList())).list(); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + List datas = list.stream().map(d -> { + DispatchDTO data = new DispatchDTO(); + BeanUtil.copyProperties(d, data); + TicketState ticketState = TicketState.findByValue(data.getState().byteValue()); + if (ObjectUtil.isNotEmpty(ticketState)) { + data.setStateDesc(ticketState.getDescription()); + } + Optional itemOptional = dictionaryItems.stream().filter(di -> di.getId().equals(data.getType())).findFirst(); + itemOptional.ifPresent(dictionaryItem -> data.setTypeDesc(dictionaryItem.getName())); + data.setIsDelayDesc(data.isDelay() ? "是" : "否"); +// if (CollectionUtil.isNotEmpty(applyforList)) { +// Optional applyforOptional = applyforList.stream().filter(a -> a.getTicketId().equals(data.getId())).findFirst(); +// applyforOptional.ifPresent(applyfor -> data.setDelayEndDate(applyfor.getEndDate())); +// } + if (ObjectUtil.isNotEmpty(data.getActualEndDate()) && ObjectUtil.isNotEmpty(data.getPlanEndDate())) { + data.setIsOntime(LocalDate.parse(data.getActualEndDate(), formatter).isAfter(LocalDate.parse(data.getPlanEndDate(), formatter)) + ? "否" : (ObjectUtil.isNotEmpty(data.getActualEndDate()) ? "是" : "")); + } + data.setAssetInfo(data.getCustomerName() + "(" + data.getDeviceNo() + ")"); + return data; + }).collect(Collectors.toList()); + response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE); + response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + URLEncoder.encode("派工导出.xlsx", StandardCharsets.UTF_8)); + new Workbook().addSheet(new ListSheet<>(datas)).writeTo(response.getOutputStream()); + } + + /** + * 导出派工列表 + * @param request + */ + @PostMapping("exportSearch") + public void exportSearch(HttpServletResponse response, @RequestBody DispatchSearchRequest request) throws IOException { + handleExportData(response, request); + } } \ No newline at end of file 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 42f25a9a..49c9fb65 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 @@ -2,6 +2,8 @@ package com.nflg.mobilebroken.gongfu.controller; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.convert.Convert; +import cn.hutool.core.lang.Validator; +import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import com.itextpdf.text.pdf.BaseFont; import com.nflg.mobilebroken.common.constant.*; @@ -24,6 +26,7 @@ import com.nflg.mobilebroken.repository.entity.*; import com.nflg.mobilebroken.repository.service.*; import com.nflg.mobilebroken.starter.annotation.MethodInfoMark; import com.nflg.mobilebroken.starter.service.UniPushService; +import com.nflg.mobilebroken.starter.service.impl.DeepSeekTranslate; import lombok.extern.slf4j.Slf4j; import org.apache.poi.ss.usermodel.*; import org.apache.poi.ss.util.CellRangeAddress; @@ -42,6 +45,7 @@ import org.thymeleaf.templateresolver.ClassLoaderTemplateResolver; import org.xhtmlrenderer.pdf.ITextRenderer; import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.validation.Valid; import javax.validation.constraints.NotEmpty; @@ -138,6 +142,11 @@ public class TicketController extends ControllerBase { @Resource private ITicketSolutionAuditService ticketSolutionAuditService; + @Resource + private DeepSeekTranslate deepSeekTranslate; + @Resource + private ILanguageService languageService; + /** * 获取问题类型 * @return 问题类型列表 @@ -271,9 +280,25 @@ public class TicketController extends ControllerBase { */ @PostMapping("searchTicket") @ApiMark(moduleName = "工单管理", apiName = "搜索工单") - public ApiResult> searchTicket(@Valid @RequestBody AdminTicketSearchRequest request) { + public ApiResult> searchTicket(@Valid @RequestBody AdminTicketSearchRequest request, HttpServletRequest request2) { + // 20260311 工单标题,在列表页面把它的翻译列展示出来 + String languageCode = request2.getHeader("language"); + Language language; + if (StrUtil.isNotBlank(languageCode)) { + language = languageService.lambdaQuery().eq(Language::getCode, languageCode).one(); + } else { + language = null; + } return ApiResult.success(PageUtil.convert(ticketService.searchPage(request), d -> { d.setEvaluate(getTicketEvaluateForList(d.getId())); + // 标题字符串不含中文才翻译 + if (ObjectUtil.isNotEmpty(d.getTitle()) && !Validator.hasChinese(d.getTitle())) { + String text = d.getTitle().replaceAll("
", ","); + if (language != null && language.getName() != null) { + String titleTranslate = deepSeekTranslate.translateWord(text, "auto", language.getName(), "text"); + d.setTitleTranslate(titleTranslate); + } + } return d; })); } diff --git a/nflg-mobilebroken-gongfu/src/main/java/com/nflg/mobilebroken/gongfu/pojo/dto/DispatchDTO.java b/nflg-mobilebroken-gongfu/src/main/java/com/nflg/mobilebroken/gongfu/pojo/dto/DispatchDTO.java new file mode 100644 index 00000000..96edd15f --- /dev/null +++ b/nflg-mobilebroken-gongfu/src/main/java/com/nflg/mobilebroken/gongfu/pojo/dto/DispatchDTO.java @@ -0,0 +1,196 @@ +package com.nflg.mobilebroken.gongfu.pojo.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; +import org.ttzero.excel.annotation.ExcelColumn; + +import java.time.LocalDateTime; + +@EqualsAndHashCode(callSuper = false) +@Data +@Accessors(chain = true) +public class DispatchDTO { + + /** + * id + */ +// @ExcelColumn("id") + private Long id; + + /** + * 派工编号 + */ + @ExcelColumn("派工编号") + private String code; + + /** + * 派工名称 + */ + @ExcelColumn("派工名称") + private String title; + + /** + * 状态:0:待处理;1:处理中;2:完成 + */ + private Integer state; + + /** + * 单据状态 + */ + @ExcelColumn("单据状态") + private String stateDesc; + + /** + * 类型:0:工单;1:定检;2:培训;3:个案;4:回访;5:安装调试 + */ + private Integer type; + + /** + * 类型描述 + */ + @ExcelColumn("派工类型") + private String typeDesc; + + /** + * 设备编号 + */ + @ExcelColumn("设备编号") + private String deviceNo; + + @ExcelColumn("资产信息") + private String assetInfo; + + /** + * 客户名称 + */ + @ExcelColumn("客户名称") + private String customerName; + + /** + * 地址 + */ + @ExcelColumn("派工地址") + private String address; + + /** + * 执行人类型,1:内部用户;2:外部用户 + */ + private Integer handlerUserType; + + /** + * 执行人id + */ + private Long handlerUserId; + + /** + * 执行人 + */ + @ExcelColumn("派工执行人") + private String handlerUserName; + + /** + * 描述 + */ + @ExcelColumn("派工任务描述") + private String remark; + + /** + * 代理商名称 + */ + @ExcelColumn("代理商名称") + private String agentName; + + /** + * 计划开始日期 + */ + @ExcelColumn("计划开始日期") + private String planStartDate; + + /** + * 计划完成日期 + */ + @ExcelColumn("计划完成日期") + private String planEndDate; + + /** + * 实际开始日期 + */ + @ExcelColumn("实际开始日期") + private String actualStartDate; + + /** + * 实际结束日期 + */ + @ExcelColumn("实际结束日期") + private String actualEndDate; + + /** + * 是否延期 + */ + @JsonProperty("isDelay") + private boolean isDelay; + + /** + * 是否延期 + */ + @ExcelColumn("是否延期") + private String isDelayDesc; + + /** + * 延期结束日期 + */ +// @ExcelColumn("延期日期") + private String delayEndDate; + + /** + * 完成时间 + */ + @ExcelColumn("完结时间") + private LocalDateTime completeDate; + + /** + * 计划执行天数 + */ + @ExcelColumn("计划执行天数") + private long planNum; + + /** + * 是否按时完成 + */ + @ExcelColumn("是否按时完成") + private String isOntime = ""; + + /** + * 延期原因 + */ + private String delayReason; + + /** + * 实际执行天数 + */ + private Long actualNum; + + /** + * 创建人id + */ + private Integer createById; + + /** + * 创建人 + */ + @ExcelColumn("派单人") + private String createBy; + + /** + * 创建时间 + */ + @ExcelColumn("派单日期") + private LocalDateTime createTime; + + /** + * 延期申请id + */ + private Long applyforId; +} diff --git a/nflg-mobilebroken-repository/src/main/resources/mapper/GongfuDispatchMapper.xml b/nflg-mobilebroken-repository/src/main/resources/mapper/GongfuDispatchMapper.xml index 0ac6ea3f..aadce096 100644 --- a/nflg-mobilebroken-repository/src/main/resources/mapper/GongfuDispatchMapper.xml +++ b/nflg-mobilebroken-repository/src/main/resources/mapper/GongfuDispatchMapper.xml @@ -43,6 +43,12 @@ or dv.customer_name like concat('%',#{request.key},'%') ) + + AND da.id in + + #{item} + + ORDER BY usort DESC,da.state,da.plan_start_date DESC,da.id DESC diff --git a/nflg-mobilebroken-repository/src/main/resources/mapper/GongfuTicketMapper.xml b/nflg-mobilebroken-repository/src/main/resources/mapper/GongfuTicketMapper.xml index c86879fd..eaa912af 100644 --- a/nflg-mobilebroken-repository/src/main/resources/mapper/GongfuTicketMapper.xml +++ b/nflg-mobilebroken-repository/src/main/resources/mapper/GongfuTicketMapper.xml @@ -161,7 +161,7 @@ ,t.create_time AS 'createTime',t.solve_time AS 'completeTime',di.name AS 'warrantyStatusDesc',d.device_type AS 'deviceType' ,d.model_no AS 'equipmentModel',d.shipment_date AS 'shipmentDate',IF(tf.id IS NULL, false, true) AS 'followed' ,auc.user_name AS 'cqm',t.update_time AS 'closeTime',auh.user_name AS 'currentHandle',dt2.cqm_person_name AS 'cqms' - ,t.handle_name AS 'handle',t.description,t.throughput + ,t.handle_name AS 'handle',t.description,t.throughput,t.accident_level FROM gongfu_ticket t LEFT JOIN app_user u ON t.user_id=u.id LEFT JOIN admin_user au ON t.user_id=au.id