From fe9b485b663ccc57b42286eeda2b7f0f7d5cc5c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E9=B9=8F=E9=A3=9E?= Date: Wed, 17 Dec 2025 18:01:15 +0800 Subject: [PATCH] =?UTF-8?q?feat(bi):=20=E6=96=B0=E5=A2=9E=E5=B7=A5?= =?UTF-8?q?=E5=8D=95=E5=8F=8A=E6=B4=BE=E5=B7=A5=E7=9B=B8=E5=85=B3=E4=B8=9A?= =?UTF-8?q?=E5=8A=A1=E6=8C=87=E6=A0=87=E7=BB=9F=E8=AE=A1=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 增加工单处理状态统计功能,返回未完成数、完成数及平均处理时长 - 实现责任人绩效统计,支持按处理数量或平均时长排序分页返回 - 新增出差天数统计,区分国内外出差并返回人员出差详情 - 增加计划达成率统计,按人员汇总完成情况及计划总数 - 实现人员派工统计,支持分页查询并返回进行中状态及未完成数量 - 添加BIDispatchQuery查询参数,支持按部门、用户名及状态筛选 - 扩展GongfuDispatchService支持BIDispatchQuery的业务数据查询 - ApiResult新增分页数据封装success方法支持分页参数返回 feat(common): 新增HEIC图片格式转换PNG工具及支持 - 新增ImageUtil工具类,通过ImageMagick命令行将HEIC格式图片转换为PNG格式 - 文件上传模块(Admin及CFS)支持HEIC图片自动转换为PNG再上传 - 调整文件格式后缀统一为小写,处理HEIC上传时文件类型自动换为.png - 移除对commons-imaging和imageio-heif依赖,改用外部ImageMagick工具实现转换 - 增加readme.md说明服务器需安装ImageMagick以及HEIC支持相关环境依赖和源码编译步骤 fix(dispatch): 修正派工相关编码及消息通知中派工单编号字段 - 派工单编码统一使用code字段替代原no字段用于消息通知及文件关联 - 去除DispatchAddRequest中deviceNo的@NotBlank注解,添加手动校验规则 - 优化DispatchController,新增机台编号非空校验逻辑 - 修复部分代码重复设置CurrentHandle现象,确保责任人数据准确传递 refactor(common): 细节优化及代码规范调整 - DateTimeUtil新增日期差计算及字符串解析方法 - DeviceVO添加客户名称属性,设备查询接口支持按设备名称模糊搜索 - API请求与返回VO新增及规范化,实现各统计视图对应VO结构 - 优化分页查询基础类PageBaseQuery格式及默认值设置 - 文件上传相关异常处理及流关闭逻辑完善,统一代码风格及格式 - GongfuTicketServiceImpl修正责任人ID设置,确保工单处理流程数据一致性 --- nflg-mobilebroken-admin/pom.xml | 11 - .../admin/controller/FileController.java | 21 +- .../cfs/controller/FileController.java | 28 ++- .../mobilebroken/common/pojo/ApiResult.java | 14 +- .../common/pojo/query/BIDispatchQuery.java | 27 +++ .../pojo/query/HandlePerformanceQuery.java | 16 ++ .../common/pojo/query/PageBaseQuery.java | 4 +- .../pojo/request/DispatchAddRequest.java | 1 - .../pojo/request/SearchDeviceRequest.java | 3 + .../common/pojo/vo/DaysOnBusinessTripVO.java | 38 ++++ .../mobilebroken/common/pojo/vo/DeviceVO.java | 3 + .../common/pojo/vo/HandlePerformanceVO.java | 74 +++++++ .../common/pojo/vo/PlanAchievementRateVO.java | 44 ++++ .../common/pojo/vo/StateStatisticsVO.java | 33 +++ .../common/pojo/vo/UserStatisticsVO.java | 39 ++++ .../common/util/DateTimeUtil.java | 31 ++- .../mobilebroken/common/util/ImageUtil.java | 59 +++++ .../gongfu/controller/BiController.java | 202 +++++++++++++++++- .../gongfu/controller/DispatchController.java | 5 +- .../gongfu/controller/TicketController.java | 1 + .../gongfu/event/DispatchApplyforEvent.java | 2 +- .../mapper/GongfuDispatchMapper.java | 5 + .../service/IGongfuDispatchService.java | 5 + .../impl/GongfuDispatchServiceImpl.java | 7 + .../service/impl/GongfuTicketServiceImpl.java | 3 +- .../main/resources/mapper/DeviceMapper.xml | 7 +- .../resources/mapper/GongfuDispatchMapper.xml | 22 ++ readme.md | 33 +++ 28 files changed, 685 insertions(+), 53 deletions(-) create mode 100644 nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/query/BIDispatchQuery.java create mode 100644 nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/query/HandlePerformanceQuery.java create mode 100644 nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/vo/DaysOnBusinessTripVO.java create mode 100644 nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/vo/HandlePerformanceVO.java create mode 100644 nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/vo/PlanAchievementRateVO.java create mode 100644 nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/vo/StateStatisticsVO.java create mode 100644 nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/vo/UserStatisticsVO.java create mode 100644 nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/util/ImageUtil.java create mode 100644 readme.md diff --git a/nflg-mobilebroken-admin/pom.xml b/nflg-mobilebroken-admin/pom.xml index b1a8a4f5..4f88735a 100644 --- a/nflg-mobilebroken-admin/pom.xml +++ b/nflg-mobilebroken-admin/pom.xml @@ -141,17 +141,6 @@ - - - org.apache.commons - commons-imaging - 1.0.0-alpha6 - - - com.github.gotson.nightmonkeys - imageio-heif - 1.1.0 - diff --git a/nflg-mobilebroken-admin/src/main/java/com/nflg/mobilebroken/admin/controller/FileController.java b/nflg-mobilebroken-admin/src/main/java/com/nflg/mobilebroken/admin/controller/FileController.java index db95c63d..63b81dfd 100644 --- a/nflg-mobilebroken-admin/src/main/java/com/nflg/mobilebroken/admin/controller/FileController.java +++ b/nflg-mobilebroken-admin/src/main/java/com/nflg/mobilebroken/admin/controller/FileController.java @@ -15,6 +15,7 @@ import com.nflg.mobilebroken.common.pojo.vo.FileUploadVO; import com.nflg.mobilebroken.common.pojo.vo.FileVO; import com.nflg.mobilebroken.common.util.AdminUserUtil; import com.nflg.mobilebroken.common.util.DateTimeUtil; +import com.nflg.mobilebroken.common.util.ImageUtil; import com.nflg.mobilebroken.common.util.VUtils; import com.nflg.mobilebroken.repository.entity.FileUploadRecord; import com.nflg.mobilebroken.repository.service.IFileUploadRecordService; @@ -22,7 +23,6 @@ import com.nflg.mobilebroken.starter.service.FileUploadService; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; -import org.apache.commons.imaging.Imaging; import org.apache.commons.io.FilenameUtils; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; @@ -32,13 +32,14 @@ import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; -import javax.imageio.ImageIO; import javax.validation.Valid; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; -import java.awt.image.BufferedImage; -import java.io.*; +import java.io.ByteArrayInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; import java.time.LocalDateTime; @@ -89,7 +90,7 @@ public class FileController extends ControllerBase { InputStream is; if (fileType.equals(".heic")) { is = convertHeic(file); - fileType = ".jpg"; + fileType = ".png"; } else { is = file.getInputStream(); } @@ -103,11 +104,7 @@ public class FileController extends ControllerBase { } private InputStream convertHeic(MultipartFile file) throws IOException { - BufferedImage image = Imaging.getBufferedImage(file.getBytes()); - ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - ImageIO.write(image, "PNG", outputStream); - byte[] imageBytes = outputStream.toByteArray(); - return new ByteArrayInputStream(imageBytes); + return new ByteArrayInputStream(ImageUtil.heicToPng(file.getBytes())); } private String buildFilePath(String fileType) { @@ -136,7 +133,7 @@ public class FileController extends ControllerBase { InputStream is; if (fileType.equals(".heic")) { is = convertHeic(file); - fileType = ".jpg"; + fileType = ".png"; } else { is = file.getInputStream(); } @@ -169,7 +166,7 @@ public class FileController extends ControllerBase { } private String getFileType(String fileName) { - return "." + FilenameUtils.getExtension(fileName); + return "." + FilenameUtils.getExtension(fileName).toLowerCase(); } private FileUploadRecord buildFileUploadRecord(Byte source, Long sourceId, String fileName, String fileType, String url) { diff --git a/nflg-mobilebroken-cfs-app/src/main/java/com/nflg/mobilebroken/cfs/controller/FileController.java b/nflg-mobilebroken-cfs-app/src/main/java/com/nflg/mobilebroken/cfs/controller/FileController.java index 3f6a32e4..4acf579f 100644 --- a/nflg-mobilebroken-cfs-app/src/main/java/com/nflg/mobilebroken/cfs/controller/FileController.java +++ b/nflg-mobilebroken-cfs-app/src/main/java/com/nflg/mobilebroken/cfs/controller/FileController.java @@ -8,6 +8,7 @@ import com.nflg.mobilebroken.common.exception.NflgException; import com.nflg.mobilebroken.common.pojo.ApiResult; import com.nflg.mobilebroken.common.pojo.vo.FileUploadVO; import com.nflg.mobilebroken.common.util.AppUserUtil; +import com.nflg.mobilebroken.common.util.ImageUtil; import com.nflg.mobilebroken.common.util.SaTokenAppUtil; import com.nflg.mobilebroken.repository.entity.FileUploadRecord; import com.nflg.mobilebroken.repository.service.IFileUploadRecordService; @@ -23,6 +24,9 @@ import javax.annotation.Resource; import javax.validation.Valid; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; @@ -59,7 +63,14 @@ public class FileController extends ControllerBase { try { String fileName = file.getOriginalFilename(); String fileType = getFileType(fileName); - String url = fileUploadService.upload(buildFilePath(fileType), file); + InputStream is; + if (fileType.equals(".heic")) { + is = convertHeic(file); + fileType = ".png"; + } else { + is = file.getInputStream(); + } + String url = fileUploadService.upload(buildFilePath(fileType), is); FileUploadRecord record = buildFileUploadRecord(source, sourceId, fileName, fileType, url); fileUploadRecordService.save(record); return ApiResult.success(new FileUploadVO(record.getId(), fileName, url, file.getSize())); @@ -68,6 +79,10 @@ public class FileController extends ControllerBase { } } + private InputStream convertHeic(MultipartFile file) throws IOException { + return new ByteArrayInputStream(ImageUtil.heicToPng(file.getBytes())); + } + private String buildFilePath(String fileType) { if (SaTokenAppUtil.isLogin()) { return StrUtil.format("cfs/{}/{}/{}/{}{}", LocalDateTime.now().format(FORMATTER) @@ -94,7 +109,14 @@ public class FileController extends ControllerBase { for (MultipartFile file : files) { String fileName = file.getOriginalFilename(); String fileType = getFileType(fileName); - String url = fileUploadService.upload(buildFilePath(fileType), file); + InputStream is; + if (fileType.equals(".heic")) { + is = convertHeic(file); + fileType = ".png"; + } else { + is = file.getInputStream(); + } + String url = fileUploadService.upload(buildFilePath(fileType), is); FileUploadRecord record = buildFileUploadRecord(source, sourceId, fileName, fileType, url); fileUploadRecordService.save(record); list.add(new FileUploadVO(record.getId(), fileName, url, file.getSize())); @@ -123,7 +145,7 @@ public class FileController extends ControllerBase { } private String getFileType(String fileName) { - return "." + FilenameUtils.getExtension(fileName); + return "." + FilenameUtils.getExtension(fileName).toLowerCase(); } private FileUploadRecord buildFileUploadRecord(Byte source, Long sourceId, String fileName, String fileType, String url) { diff --git a/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/ApiResult.java b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/ApiResult.java index ca346263..ab2b4cf2 100644 --- a/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/ApiResult.java +++ b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/ApiResult.java @@ -53,7 +53,6 @@ public class ApiResult implements Serializable { return vo; } - public static ApiResult error(int state,String msg,T value) { ApiResult vo = new ApiResult<>(); vo.result = value; @@ -101,4 +100,17 @@ public class ApiResult implements Serializable { public static ApiResult error(int msgCode, String msg) { return error(msgCode, msg, msg); } + + public static ApiResult> success(Collection datas, int pageIndex, int pageSize) { + ApiResult> vo = new ApiResult<>(); + PageData pageData = new PageData<>(); + pageData.setPage(pageIndex); + pageData.setPageSize(pageSize); + pageData.setTotal(datas.size()); + pageData.setItems(datas); + vo.setCode(STATE.Success.getState()); + vo.setType(STATE.Success.getType()); + vo.setResult(pageData); + return vo; + } } diff --git a/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/query/BIDispatchQuery.java b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/query/BIDispatchQuery.java new file mode 100644 index 00000000..4b24aa7d --- /dev/null +++ b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/query/BIDispatchQuery.java @@ -0,0 +1,27 @@ +package com.nflg.mobilebroken.common.pojo.query; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import lombok.Data; + +import java.util.List; + +@Data +public class BIDispatchQuery extends BIBaseQuery { + + /** + * 部门id + */ + private Long deptId; + + /** + * 用户名 + */ + private String userName; + + @JsonIgnore + private List states = List.of(2); + + private Integer page = 1; + + private Integer pageSize = 20; +} diff --git a/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/query/HandlePerformanceQuery.java b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/query/HandlePerformanceQuery.java new file mode 100644 index 00000000..ccfb44a7 --- /dev/null +++ b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/query/HandlePerformanceQuery.java @@ -0,0 +1,16 @@ +package com.nflg.mobilebroken.common.pojo.query; + +import lombok.Data; + +@Data +public class HandlePerformanceQuery extends BIBaseQuery { + + /** + * 排序方式,0:处理数量;1:平均处理时长 + */ + private Integer sortType = 0; + + private Integer page = 1; + + private Integer pageSize = 20; +} diff --git a/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/query/PageBaseQuery.java b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/query/PageBaseQuery.java index 49a7a82e..0fe2da54 100644 --- a/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/query/PageBaseQuery.java +++ b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/query/PageBaseQuery.java @@ -5,7 +5,7 @@ import lombok.Data; @Data public class PageBaseQuery { - private Integer page=1; + private Integer page = 1; - private Integer pageSize=20; + private Integer pageSize = 20; } diff --git a/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/request/DispatchAddRequest.java b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/request/DispatchAddRequest.java index 1d52d299..4c6f8cc1 100644 --- a/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/request/DispatchAddRequest.java +++ b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/request/DispatchAddRequest.java @@ -30,7 +30,6 @@ public class DispatchAddRequest { /** * 设备编号 */ - @NotBlank private String deviceNo; /** diff --git a/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/request/SearchDeviceRequest.java b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/request/SearchDeviceRequest.java index e180859f..6950c1b4 100644 --- a/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/request/SearchDeviceRequest.java +++ b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/request/SearchDeviceRequest.java @@ -26,4 +26,7 @@ public class SearchDeviceRequest extends PageRequest { //客户名称 private String customerName; + + //设备名称 + private String deviceName; } diff --git a/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/vo/DaysOnBusinessTripVO.java b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/vo/DaysOnBusinessTripVO.java new file mode 100644 index 00000000..54767cb6 --- /dev/null +++ b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/vo/DaysOnBusinessTripVO.java @@ -0,0 +1,38 @@ +package com.nflg.mobilebroken.common.pojo.vo; + +import lombok.Data; +import lombok.experimental.Accessors; + +@Data +@Accessors(chain = true) +public class DaysOnBusinessTripVO { + + /** + * 用户id + */ + private Long userId; + + /** + * 处理人 + */ + private String userName; + + /** + * 国内出差天数 + */ + private int daysForInternal; + + /** + * 国外出差天数 + */ + private int daysForForeign; + + /** + * 总出差天数 + */ + private int totalDays; + + public int getTotalDays() { + return daysForInternal + daysForForeign; + } +} diff --git a/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/vo/DeviceVO.java b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/vo/DeviceVO.java index 52f3a6e7..3c53928f 100644 --- a/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/vo/DeviceVO.java +++ b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/vo/DeviceVO.java @@ -26,4 +26,7 @@ public class DeviceVO { // 销售日期 private LocalDate shipmentDate; + + // 客户名称 + private String customerName; } diff --git a/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/vo/HandlePerformanceVO.java b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/vo/HandlePerformanceVO.java new file mode 100644 index 00000000..eae1143f --- /dev/null +++ b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/vo/HandlePerformanceVO.java @@ -0,0 +1,74 @@ +package com.nflg.mobilebroken.common.pojo.vo; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import lombok.Getter; +import lombok.Setter; +import lombok.experimental.Accessors; + +@Accessors(chain = true) +public class HandlePerformanceVO { + + /** + * 处理人 + */ + @Getter + @Setter + private String userName; + + /** + * 工单数量 + */ + @Getter + @Setter + private Integer total = 0; + + /** + * 工单完成率 + */ + private String completionRate; + + public String getCompletionRate() { + if (total == 0) { + return "0"; + } + double rate = (double) completes * 100 / total; + return String.format("%.2f", rate).replaceAll("\\.?0+$", ""); + } + + /** + * 工单处理平均时长,单位:小时 + */ + private String averageProcessingTime; + + public String getAverageProcessingTime() { + if (completes == 0) { + return "0"; + } + double rate = (double) processingTime / completes / 60.0; + return String.format("%.2f", rate).replaceAll("\\.?0+$", ""); + } + + /** + * 用户id + */ + @Getter + @Setter + @JsonIgnore + private Integer userId; + + /** + * 已完成工单数量 + */ + @Getter + @Setter + @JsonIgnore + private int completes = 0; + + /** + * 工单处理时长,单位:分钟 + */ + @Getter + @Setter + @JsonIgnore + private long processingTime = 0; +} diff --git a/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/vo/PlanAchievementRateVO.java b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/vo/PlanAchievementRateVO.java new file mode 100644 index 00000000..31d7f504 --- /dev/null +++ b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/vo/PlanAchievementRateVO.java @@ -0,0 +1,44 @@ +package com.nflg.mobilebroken.common.pojo.vo; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import lombok.Data; +import lombok.experimental.Accessors; + +@Data +@Accessors(chain = true) +public class PlanAchievementRateVO { + + /** + * 用户id + */ + private Long userId; + + /** + * 处理人 + */ + private String userName; + + /** + * 计划完成率 + */ + private int planAchievementRate; + + public int getPlanAchievementRate() { + if (total == 0) { + return 0; + } + return completes * 100 / total; + } + + /** + * 总工单数量 + */ + @JsonIgnore + private int total; + + /** + * 已完成工单数量 + */ + @JsonIgnore + private int completes; +} diff --git a/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/vo/StateStatisticsVO.java b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/vo/StateStatisticsVO.java new file mode 100644 index 00000000..0d146cf5 --- /dev/null +++ b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/vo/StateStatisticsVO.java @@ -0,0 +1,33 @@ +package com.nflg.mobilebroken.common.pojo.vo; + +import lombok.Data; +import lombok.experimental.Accessors; + +@Data +@Accessors(chain = true) +public class StateStatisticsVO { + + /** + * 未完成工单数量 + */ + private int unaccomplished; + + /** + * 已完成工单数量 + */ + private int completes; + + /** + * 总工单数量 + */ + private int total; + + public int getTotal() { + return unaccomplished + completes; + } + + /** + * 工单处理平均时长,单位:小时 + */ + private Double averageProcessingTime; +} diff --git a/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/vo/UserStatisticsVO.java b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/vo/UserStatisticsVO.java new file mode 100644 index 00000000..91305654 --- /dev/null +++ b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/vo/UserStatisticsVO.java @@ -0,0 +1,39 @@ +package com.nflg.mobilebroken.common.pojo.vo; + +import lombok.Data; +import lombok.experimental.Accessors; + +@Data +@Accessors(chain = true) +public class UserStatisticsVO { + + /** + * 用户id + */ + private Long userId; + + /** + * 处理人 + */ + private String userName; + + /** + * 产品线 + */ + private String productLine; + + /** + * 当前是否在派工中 + */ + private boolean inProgress; + + /** + * 最近一次派工时间 + */ + private String recentDispatchTime; + + /** + * 未完成工单数量 + */ + private int unfinishedNum; +} diff --git a/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/util/DateTimeUtil.java b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/util/DateTimeUtil.java index 65546537..8fddfd05 100644 --- a/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/util/DateTimeUtil.java +++ b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/util/DateTimeUtil.java @@ -7,35 +7,36 @@ import java.time.LocalDateTime; import java.time.ZoneId; import java.time.ZoneOffset; import java.time.format.DateTimeFormatter; +import java.time.temporal.ChronoUnit; import java.util.Objects; public class DateTimeUtil { - private static final DateTimeFormatter FORMATTER=DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_PATTERN); + private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_PATTERN); - public static String format(LocalDateTime dateTime){ - if (Objects.isNull(dateTime)){ + public static String format(LocalDateTime dateTime) { + if (Objects.isNull(dateTime)) { return ""; } return dateTime.format(FORMATTER); } - public static String format(LocalDateTime dateTime,String pattern){ - if (Objects.isNull(dateTime)){ + public static String format(LocalDateTime dateTime, String pattern) { + if (Objects.isNull(dateTime)) { return ""; } return dateTime.format(DateTimeFormatter.ofPattern(pattern)); } - public static String format(LocalDate date,String pattern){ - if (Objects.isNull(date)){ + public static String format(LocalDate date, String pattern) { + if (Objects.isNull(date)) { return ""; } return date.format(DateTimeFormatter.ofPattern(pattern)); } - public static LocalDate asSystemDate(LocalDate date){ - if (Objects.isNull(date)){ + public static LocalDate asSystemDate(LocalDate date) { + if (Objects.isNull(date)) { return null; } return date.atStartOfDay(ZoneOffset.UTC) @@ -43,12 +44,20 @@ public class DateTimeUtil { .toLocalDate(); } - public static LocalDateTime asSystemDateTime(LocalDateTime datetime){ - if (Objects.isNull(datetime)){ + public static LocalDateTime asSystemDateTime(LocalDateTime datetime) { + if (Objects.isNull(datetime)) { return null; } return datetime.atZone(ZoneOffset.UTC) .withZoneSameInstant(ZoneId.systemDefault()) .toLocalDateTime(); } + + public static LocalDate parse(String dateStr) { + return LocalDate.parse(dateStr, DateTimeFormatter.ofPattern(DatePattern.NORM_DATE_PATTERN)); + } + + public static int between(LocalDate date1, LocalDate date2) { + return (int) ChronoUnit.DAYS.between(date1, date2) + 1; + } } diff --git a/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/util/ImageUtil.java b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/util/ImageUtil.java new file mode 100644 index 00000000..5d631861 --- /dev/null +++ b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/util/ImageUtil.java @@ -0,0 +1,59 @@ +package com.nflg.mobilebroken.common.util; + +import java.io.*; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; + +public class ImageUtil { + + public static byte[] heicToPng(byte[] heicBytes) throws IOException { + ProcessBuilder pb = new ProcessBuilder("magick", "-", "png:-"); + Process process = pb.start(); + try (OutputStream stdin = process.getOutputStream(); + InputStream stdout = process.getInputStream(); + InputStream stderr = process.getErrorStream()) { + // 4. 在单独的线程中读取标准错误,防止缓冲区填满导致死锁 + ExecutorService executor = Executors.newSingleThreadExecutor(); + Future stderrFuture = executor.submit(() -> readStreamAsString(stderr)); + executor.shutdown(); // 不再接受新任务 + // 5. 将HEIC字节数组写入到进程的标准输入 + stdin.write(heicBytes); + stdin.flush(); // 确保数据被写入 + stdin.close(); // 关闭输入流,表示输入结束 + // 6. 从进程的标准输出读取转换后的PNG数据 + ByteArrayOutputStream pngBuffer = new ByteArrayOutputStream(); + byte[] buffer = new byte[8192]; // 8KB 缓冲区 + int bytesRead; + while ((bytesRead = stdout.read(buffer)) != -1) { + pngBuffer.write(buffer, 0, bytesRead); + } + // 7. 等待进程执行完成 + int exitCode = process.waitFor(); + // 8. 检查退出码,如果不为0,说明转换失败 + if (exitCode != 0) { + // 获取错误信息 + String errorOutput = stderrFuture.get(5, TimeUnit.SECONDS); + throw new IOException("ImageMagick conversion failed with exit code " + exitCode + ".\nError: " + errorOutput); + } + + return pngBuffer.toByteArray(); + } catch (Exception e) { + // 确保进程被销毁 + process.destroyForcibly(); + throw new IOException("HEIC转换失败", e); + } + } + + private static String readStreamAsString(InputStream inputStream) throws IOException { + try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) { + StringBuilder stringBuilder = new StringBuilder(); + String line; + while ((line = reader.readLine()) != null) { + stringBuilder.append(line).append(System.lineSeparator()); + } + return stringBuilder.toString(); + } + } +} diff --git a/nflg-mobilebroken-gongfu/src/main/java/com/nflg/mobilebroken/gongfu/controller/BiController.java b/nflg-mobilebroken-gongfu/src/main/java/com/nflg/mobilebroken/gongfu/controller/BiController.java index 5afe1e0a..e0b3f8fc 100644 --- a/nflg-mobilebroken-gongfu/src/main/java/com/nflg/mobilebroken/gongfu/controller/BiController.java +++ b/nflg-mobilebroken-gongfu/src/main/java/com/nflg/mobilebroken/gongfu/controller/BiController.java @@ -1,11 +1,21 @@ package com.nflg.mobilebroken.gongfu.controller; +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.date.LocalDateTimeUtil; 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.query.BIBaseQuery; +import com.nflg.mobilebroken.common.pojo.query.BIDispatchQuery; import com.nflg.mobilebroken.common.pojo.query.EquipmentFailureRankingSearchQuery; -import com.nflg.mobilebroken.common.pojo.vo.EquipmentFailureRankingVO; +import com.nflg.mobilebroken.common.pojo.query.HandlePerformanceQuery; +import com.nflg.mobilebroken.common.pojo.vo.*; +import com.nflg.mobilebroken.common.util.DateTimeUtil; +import com.nflg.mobilebroken.repository.entity.AdminUser; +import com.nflg.mobilebroken.repository.entity.GongfuDispatch; import com.nflg.mobilebroken.repository.entity.GongfuTicket; +import com.nflg.mobilebroken.repository.service.IAdminUserService; +import com.nflg.mobilebroken.repository.service.IGongfuDispatchService; import com.nflg.mobilebroken.repository.service.IGongfuTicketService; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.PostMapping; @@ -15,7 +25,11 @@ import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; import javax.validation.Valid; +import java.time.temporal.ChronoUnit; +import java.util.ArrayList; +import java.util.Comparator; import java.util.List; +import java.util.Objects; import java.util.stream.Collectors; /** @@ -29,6 +43,12 @@ public class BiController extends ControllerBase { @Resource private IGongfuTicketService ticketService; + @Resource + private IAdminUserService adminUserService; + + @Resource + private IGongfuDispatchService dispatchService; + /** * 设备故障排名 */ @@ -37,16 +57,184 @@ public class BiController extends ControllerBase { return ApiResult.success(ticketService.getEquipmentFailureRanking(qo)); } - public ApiResult getStateStatistics(@Valid @RequestBody BIBaseQuery qo) { - List datas = ticketService.lambdaQuery() + /** + * 工单处理状态 + */ + @PostMapping("ticket/getStateStatistics") + public ApiResult getStateStatistics(@Valid @RequestBody BIBaseQuery qo) { + long unaccomplished = ticketService.lambdaQuery() .ne(GongfuTicket::getState, TicketState.Revoked.getState()) + .lt(GongfuTicket::getState, TicketState.ProcessingCompleted.getState()) + .ge(GongfuTicket::getCreateTime, qo.getStartDate()) + .lt(GongfuTicket::getCreateTime, qo.getEndDate()) + .count(); + List completes = ticketService.lambdaQuery() + .select(GongfuTicket::getCreateTime, GongfuTicket::getSolveTime) + .ne(GongfuTicket::getState, TicketState.Revoked.getState()) + .in(GongfuTicket::getState, List.of(TicketState.ProcessingCompleted.getState(), TicketState.Closed.getState())) .ge(GongfuTicket::getCreateTime, qo.getStartDate()) .lt(GongfuTicket::getCreateTime, qo.getEndDate()) .list(); - List completes = datas.stream() - .filter(it -> it.getState() >= TicketState.ProcessingCompleted.getState()) - .collect(Collectors.toList()); + StateStatisticsVO vo = new StateStatisticsVO() + .setUnaccomplished((int) unaccomplished) + .setCompletes(completes.size()) + .setAverageProcessingTime(completes.stream() + .map(t -> LocalDateTimeUtil.between(t.getCreateTime(), t.getSolveTime(), ChronoUnit.MINUTES) / 60.0) + .mapToDouble(Double::doubleValue) + .average() + .orElse(0) + ); + return ApiResult.success(vo); + } - return ApiResult.success(); + /** + * 责任人绩效 + */ + @PostMapping("ticket/getHandlePerformance") + public ApiResult> getHandlePerformance(@Valid @RequestBody HandlePerformanceQuery qo) { + List tickets = ticketService.lambdaQuery() + .select(GongfuTicket::getCurrentHandle, GongfuTicket::getState, GongfuTicket::getCreateTime, GongfuTicket::getSolveTime) + .notIn(GongfuTicket::getState, List.of(TicketState.Revoked.getState(), TicketState.PendingProcessing.getState())) + .ge(GongfuTicket::getCreateTime, qo.getStartDate()) + .lt(GongfuTicket::getCreateTime, qo.getEndDate()) + .list(); + if (CollectionUtil.isEmpty(tickets)) { + return ApiResult.success(new PageData<>()); + } + List users = adminUserService.lambdaQuery() + .in(AdminUser::getId, tickets.stream().map(GongfuTicket::getCurrentHandle).collect(Collectors.toSet())) + .list(); + List vos = new ArrayList<>(); + tickets.forEach(ticket -> { + HandlePerformanceVO vo = vos.stream() + .filter(v -> Objects.equals(v.getUserId(), ticket.getCurrentHandle())) + .findFirst() + .orElseGet(() -> { + HandlePerformanceVO v = new HandlePerformanceVO() + .setUserId(ticket.getCurrentHandle()) + .setUserName(users.stream() + .filter(user -> Objects.equals(user.getId(), ticket.getCurrentHandle())) + .findFirst() + .orElse(new AdminUser().setUserName("无效用户")) + .getUserName() + ); + vos.add(v); + return v; + }); + vo.setTotal(vo.getTotal() + 1); + if (Objects.equals(TicketState.ProcessingCompleted.getState(), ticket.getState()) + || Objects.equals(TicketState.Closed.getState(), ticket.getState())) { + vo.setCompletes(vo.getCompletes() + 1); + vo.setProcessingTime(vo.getProcessingTime() + LocalDateTimeUtil.between(ticket.getCreateTime(), ticket.getSolveTime(), ChronoUnit.MINUTES)); + } + }); + if (qo.getSortType() == 0) { + vos.sort(Comparator.comparingInt(HandlePerformanceVO::getTotal).reversed()); + } else if (qo.getSortType() == 1) { + vos.sort(Comparator.comparing(HandlePerformanceVO::getAverageProcessingTime)); + } + return ApiResult.success(vos, qo.getPage(), qo.getPageSize()); + } + + /** + * 出差天数 + */ + @PostMapping("dispatch/getDaysOnBusinessTrip") + public ApiResult> getDaysOnBusinessTrip(@Valid @RequestBody BIDispatchQuery qo) { + List dispatches = dispatchService.getForBI(qo); + return ApiResult.success(dispatches.stream() + .collect(Collectors.groupingBy(GongfuDispatch::getHandlerUserId)) + .values() + .stream() + .map(ds -> new DaysOnBusinessTripVO() + .setUserId(ds.get(0).getHandlerUserId()) + .setUserName(ds.get(0).getHandlerUserName()) + .setDaysForInternal(ds.stream() + .filter(d -> Objects.equals(d.getCategory(), 0)) + .map(d -> DateTimeUtil.between(DateTimeUtil.parse(d.getPlanStartDate()), DateTimeUtil.parse(d.getPlanEndDate()))) + .mapToInt(Integer::intValue) + .sum() + ) + .setDaysForForeign(ds.stream() + .filter(d -> Objects.equals(d.getCategory(), 1)) + .map(d -> DateTimeUtil.between(DateTimeUtil.parse(d.getPlanStartDate()), DateTimeUtil.parse(d.getPlanEndDate()))) + .mapToInt(Integer::intValue) + .sum() + )) + .sorted(Comparator.comparingInt(DaysOnBusinessTripVO::getTotalDays).reversed()) + .collect(Collectors.toList()) + ); + } + + /** + * 计划达成率 + */ + @PostMapping("dispatch/getPlanAchievementRate") + public ApiResult> getPlanAchievementRate(@Valid @RequestBody BIDispatchQuery qo) { + qo.setStates(List.of(1, 2)); + List dispatches = dispatchService.getForBI(qo); + return ApiResult.success(dispatches.stream() + .collect(Collectors.groupingBy(GongfuDispatch::getHandlerUserId)) + .values() + .stream() + .map(ds -> new PlanAchievementRateVO() + .setUserId(ds.get(0).getHandlerUserId()) + .setUserName(ds.get(0).getHandlerUserName()) + .setTotal(ds.size()) + .setCompletes(Math.toIntExact(ds.stream() + .filter(d -> Objects.equals(d.getState(), 2)) + .count() + ) + ) + ) + .sorted(Comparator.comparingInt(PlanAchievementRateVO::getPlanAchievementRate).reversed()) + .collect(Collectors.toList()) + ); + } + + /** + * 人员派工统计 + */ + @PostMapping("dispatch/getUserStatistics") + public ApiResult> getUserStatistics(@Valid @RequestBody BIDispatchQuery qo) { + qo.setStates(List.of(1)); + List dispatches = dispatchService.getForBI(qo); + if (CollectionUtil.isEmpty(dispatches)) { + return ApiResult.success(new PageData<>()); + } + List users = adminUserService.lambdaQuery() + .in(AdminUser::getId, dispatches.stream().map(GongfuDispatch::getHandlerUserId).collect(Collectors.toSet())) + .list(); + List vos = dispatches.stream() + .collect(Collectors.groupingBy(GongfuDispatch::getHandlerUserId)) + .values() + .stream() + .map(ds -> new UserStatisticsVO() + .setUserId(ds.get(0).getHandlerUserId()) + .setUserName(ds.get(0).getHandlerUserName()) + .setProductLine( + users.stream() + .filter(user -> Objects.equals(user.getId(), Math.toIntExact(ds.get(0).getHandlerUserId()))) + .findFirst() + .orElse(new AdminUser().setUserName("无效用户")) + .getProductLine() + ) + .setInProgress(ds.stream().anyMatch(d -> Objects.equals(d.getState(), 1))) + .setRecentDispatchTime( + ds.stream() + .filter(d -> Objects.equals(d.getState(), 1)) + .max(Comparator.comparing(GongfuDispatch::getPlanStartDate)) + .map(GongfuDispatch::getPlanStartDate) + .orElse("") + ) + .setUnfinishedNum( + Math.toIntExact(ds.stream() + .filter(d -> Objects.equals(d.getState(), 1)) + .count()) + ) + ) + .sorted(Comparator.comparingInt(UserStatisticsVO::getUnfinishedNum).reversed()) + .collect(Collectors.toList()); + return ApiResult.success(vos, qo.getPage(), qo.getPageSize()); } } 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 ec823981..4751da58 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 @@ -2,6 +2,7 @@ package com.nflg.mobilebroken.gongfu.controller; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.convert.Convert; +import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.nflg.mobilebroken.common.constant.MessageSubType; import com.nflg.mobilebroken.common.constant.MessageType; @@ -67,6 +68,8 @@ public class DispatchController extends ControllerBase { */ @PostMapping("/add") public ApiResult add(@Valid @RequestBody DispatchAddRequest request) { + VUtils.trueThrowBusinessError(!Objects.equals(request.getType(), 4) && StrUtil.isBlank(request.getDeviceNo())) + .throwMessage("机台编号需必填"); GongfuDispatch dispatch = new GongfuDispatch() .setTitle(request.getTitle()) .setType(request.getType()) @@ -180,7 +183,7 @@ public class DispatchController extends ControllerBase { .map(it -> new GongfuFile() .setType(0) .setSourceId(dispatch.getId()) - .setNo(dispatch.getNo()) + .setNo(dispatch.getCode()) .setFileName(it.getFileName()) .setFileUrl(it.getUrl()) .setFileSuffix(FilenameUtils.getExtension(it.getFileName())) 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 f359d2cd..f5487d11 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 @@ -1474,6 +1474,7 @@ public class TicketController extends ControllerBase { images = fileUploadRecordService.lambdaQuery() .eq(FileUploadRecord::getSource, (byte) 0) .eq(FileUploadRecord::getSourceId, id) + .in(FileUploadRecord::getFileType, List.of(".jpg", ".png", ".heic", ".jpeg", ".webp")) .list(); if (CollectionUtil.isEmpty(images)) { return ApiResult.success(Collections.emptyList()); diff --git a/nflg-mobilebroken-gongfu/src/main/java/com/nflg/mobilebroken/gongfu/event/DispatchApplyforEvent.java b/nflg-mobilebroken-gongfu/src/main/java/com/nflg/mobilebroken/gongfu/event/DispatchApplyforEvent.java index 95f082f3..9a4afb88 100644 --- a/nflg-mobilebroken-gongfu/src/main/java/com/nflg/mobilebroken/gongfu/event/DispatchApplyforEvent.java +++ b/nflg-mobilebroken-gongfu/src/main/java/com/nflg/mobilebroken/gongfu/event/DispatchApplyforEvent.java @@ -41,7 +41,7 @@ public class DispatchApplyforEvent extends ApplicationEvent implements Applicati GongfuDispatch dispatch = dispatchService.getById(applyfor.getTicketId()); adminMessageService.add( new AdminMessage() - .setNo(dispatch.getNo()) + .setNo(dispatch.getCode()) .setTitle(dispatch.getTitle()) .setUserId(dispatch.getCreateById()) .setSourceId(applyfor.getId()) diff --git a/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/mapper/GongfuDispatchMapper.java b/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/mapper/GongfuDispatchMapper.java index fe6b1d6d..a8fbe581 100644 --- a/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/mapper/GongfuDispatchMapper.java +++ b/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/mapper/GongfuDispatchMapper.java @@ -3,10 +3,13 @@ package com.nflg.mobilebroken.repository.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.nflg.mobilebroken.common.pojo.query.BIDispatchQuery; import com.nflg.mobilebroken.common.pojo.request.DispatchSearchRequest; import com.nflg.mobilebroken.common.pojo.vo.DispatchVO; import com.nflg.mobilebroken.repository.entity.GongfuDispatch; +import java.util.List; + /** *

* 派工单 Mapper 接口 @@ -19,4 +22,6 @@ public interface GongfuDispatchMapper extends BaseMapper { IPage search(DispatchSearchRequest request, Page objectPage); DispatchVO getInfo(Long id); + + List getForBI(BIDispatchQuery qo); } diff --git a/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/IGongfuDispatchService.java b/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/IGongfuDispatchService.java index 8c18dde2..0e4366aa 100644 --- a/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/IGongfuDispatchService.java +++ b/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/IGongfuDispatchService.java @@ -2,10 +2,13 @@ package com.nflg.mobilebroken.repository.service; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.service.IService; +import com.nflg.mobilebroken.common.pojo.query.BIDispatchQuery; import com.nflg.mobilebroken.common.pojo.request.DispatchSearchRequest; import com.nflg.mobilebroken.common.pojo.vo.DispatchVO; import com.nflg.mobilebroken.repository.entity.GongfuDispatch; +import java.util.List; + /** *

* 派工单 服务类 @@ -20,4 +23,6 @@ public interface IGongfuDispatchService extends IService { DispatchVO getInfo(Long id); String getMaxCode(); + + List getForBI(BIDispatchQuery qo); } diff --git a/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/impl/GongfuDispatchServiceImpl.java b/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/impl/GongfuDispatchServiceImpl.java index 2b3f72c5..710c93fc 100644 --- a/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/impl/GongfuDispatchServiceImpl.java +++ b/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/impl/GongfuDispatchServiceImpl.java @@ -3,6 +3,7 @@ package com.nflg.mobilebroken.repository.service.impl; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.nflg.mobilebroken.common.pojo.query.BIDispatchQuery; import com.nflg.mobilebroken.common.pojo.request.DispatchSearchRequest; import com.nflg.mobilebroken.common.pojo.vo.DispatchVO; import com.nflg.mobilebroken.repository.entity.GongfuDispatch; @@ -10,6 +11,7 @@ import com.nflg.mobilebroken.repository.mapper.GongfuDispatchMapper; import com.nflg.mobilebroken.repository.service.IGongfuDispatchService; import org.springframework.stereotype.Service; +import java.util.List; import java.util.Objects; /** @@ -41,4 +43,9 @@ public class GongfuDispatchServiceImpl extends ServiceImpl getForBI(BIDispatchQuery qo) { + return baseMapper.getForBI(qo); + } } diff --git a/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/impl/GongfuTicketServiceImpl.java b/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/impl/GongfuTicketServiceImpl.java index faa99d0c..351b23e9 100644 --- a/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/impl/GongfuTicketServiceImpl.java +++ b/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/impl/GongfuTicketServiceImpl.java @@ -95,6 +95,7 @@ public class GongfuTicketServiceImpl extends ServiceImpl diff --git a/nflg-mobilebroken-repository/src/main/resources/mapper/GongfuDispatchMapper.xml b/nflg-mobilebroken-repository/src/main/resources/mapper/GongfuDispatchMapper.xml index 766d3a13..964c4dad 100644 --- a/nflg-mobilebroken-repository/src/main/resources/mapper/GongfuDispatchMapper.xml +++ b/nflg-mobilebroken-repository/src/main/resources/mapper/GongfuDispatchMapper.xml @@ -53,4 +53,26 @@ left join v_dispatch_applyfor af on da.id=af.ticket_id where da.id = #{id} + + diff --git a/readme.md b/readme.md new file mode 100644 index 00000000..f67dd115 --- /dev/null +++ b/readme.md @@ -0,0 +1,33 @@ +## 服务器需要安装的软件 + +- ImageMagick + +> 用于将苹果的HEIC图片格式转换为PNG图片格式,必须源码编译,否则不支持HEIC格式 + +```bash +yum install -y epel-release +rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-7.rpm +yum install -y yum-utils +yum-config-manager --enable remi +wget https://download1.rpmfusion.org/free/el/rpmfusion-free-release-7.noarch.rpm +wget https://download1.rpmfusion.org/nonfree/el/rpmfusion-nonfree-release-7.noarch.rpm +rpm -Uvh rpmfusion-free-release-7.noarch.rpm rpmfusion-nonfree-release-7.noarch.rpm +yum clean all +yum install -y libde265 libx265 +yum install -y libheif-devel +yum install -y libtool-ltdl-devel +# 源码编译安装ImageMagick +yum groupinstall -y "Development Tools" +yum install -y libjpeg-turbo-devel libpng-devel freetype-devel libtiff-devel giflib-devel +yum install -y libheif-devel libde265-devel x265-devel +wget https://github.com/ImageMagick/ImageMagick/archive/refs/tags/7.1.2-11.tar.gz +tar xf 7.1.2-11.tar.gz +cd ImageMagick-7.1.2-11/ +./configure --with-heif=yes --with-modules --enable-hdri +make -j$(nproc) +make install +which magick +ln -s /usr/local/bin/magick /usr/bin/magick +magick -version +magick -list format | grep HEIC +``` \ No newline at end of file