diff --git a/ruoyi-admin/src/main/resources/application-dev.yml b/ruoyi-admin/src/main/resources/application-dev.yml index f00e907..0735e3a 100644 --- a/ruoyi-admin/src/main/resources/application-dev.yml +++ b/ruoyi-admin/src/main/resources/application-dev.yml @@ -52,8 +52,8 @@ spring: # url: jdbc:mysql://localhost:3306/jyjtable?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # username: root # password: root - url: jdbc:mysql://10.1.21.250:3306/jyjtable?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true -# url: jdbc:mysql://218.0.1.42:53306/aitable?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true +# url: jdbc:mysql://10.1.21.250:3306/jyjtable?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true + url: jdbc:mysql://218.0.1.42:53306/jyjtable?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # url: jdbc:mysql://10.1.21.251:3306/jyjtable?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # url: jdbc:mysql://222.75.18.225:2881/jyjtable?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true username: root diff --git a/ruoyi-admin/src/main/resources/application-prod.yml b/ruoyi-admin/src/main/resources/application-prod.yml index e64adfb..c05227a 100644 --- a/ruoyi-admin/src/main/resources/application-prod.yml +++ b/ruoyi-admin/src/main/resources/application-prod.yml @@ -15,7 +15,7 @@ spring.boot.admin.client: password: 123456 server: # 端口号 - port: 8081 + port: 8079 --- # snail-job 配置 snail-job: enabled: false @@ -29,9 +29,7 @@ snail-job: # 详见 script/sql/snail_job.sql `sj_namespace` 表 namespace: ${spring.profiles.active} # 随主应用端口飘逸 - port: 2${server.port} - # 客户端ip指定 - host: + port: 3${server.port} --- # 数据源配置 spring: @@ -52,35 +50,37 @@ spring: driverClassName: com.mysql.cj.jdbc.Driver # jdbc 所有参数配置参考 https://lionli.blog.csdn.net/article/details/122018562 # rewriteBatchedStatements=true 批处理优化 大幅提升批量插入更新删除性能(对数据库有性能损耗 使用批量操作应考虑性能问题) - url: jdbc:mysql://localhost:3306/zaojia?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true + url: jdbc:mysql://localhost:3306/jyjtable?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true username: root - password: root + # password: + password: 'HXj-6nR|D8xy*h#!I&:(' + # 从库数据源 - slave: - lazy: true - type: ${spring.datasource.type} - driverClassName: com.mysql.cj.jdbc.Driver - url: jdbc:mysql://116.62.210.190:3306/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true - username: root - password: Guoyan83086775 -# oracle: -# type: ${spring.datasource.type} -# driverClassName: oracle.jdbc.OracleDriver -# url: jdbc:oracle:thin:@//localhost:1521/XE -# username: ROOT -# password: root -# postgres: -# type: ${spring.datasource.type} -# driverClassName: org.postgresql.Driver -# url: jdbc:postgresql://localhost:5432/postgres?useUnicode=true&characterEncoding=utf8&useSSL=true&autoReconnect=true&reWriteBatchedInserts=true -# username: root -# password: root -# sqlserver: -# type: ${spring.datasource.type} -# driverClassName: com.microsoft.sqlserver.jdbc.SQLServerDriver -# url: jdbc:sqlserver://localhost:1433;DatabaseName=tempdb;SelectMethod=cursor;encrypt=false;rewriteBatchedStatements=true -# username: SA -# password: root + # slave: + # lazy: true + # type: ${spring.datasource.type} + # driverClassName: com.mysql.cj.jdbc.Driver + # url: jdbc:mysql://116.62.210.190:3306/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true + # username: root + # password: Guoyan83086775 + # oracle: + # type: ${spring.datasource.type} + # driverClassName: oracle.jdbc.OracleDriver + # url: jdbc:oracle:thin:@//localhost:1521/XE + # username: ROOT + # password: root + # postgres: + # type: ${spring.datasource.type} + # driverClassName: org.postgresql.Driver + # url: jdbc:postgresql://localhost:5432/postgres?useUnicode=true&characterEncoding=utf8&useSSL=true&autoReconnect=true&reWriteBatchedInserts=true + # username: root + # password: root + # sqlserver: + # type: ${spring.datasource.type} + # driverClassName: com.microsoft.sqlserver.jdbc.SQLServerDriver + # url: jdbc:sqlserver://localhost:1433;DatabaseName=tempdb;SelectMethod=cursor;encrypt=false;rewriteBatchedStatements=true + # username: SA + # password: root hikari: # 最大连接池数量 maxPoolSize: 20 @@ -107,7 +107,7 @@ spring.data: # 数据库索引 database: 0 # redis 密码必须配置 - password: root + password: F*Nx=BZli+ZCCI-Fil+3 # 连接超时时间 timeout: 10s # 是否开启ssl @@ -284,5 +284,6 @@ justauth: # maxConnectNumPerRoute: 100 chat: # 聊天机器人配置 - filePath: /usr/app/tempFile - chatUrl: http://183.136.156.2:50000 + filePath: /guoYanXinXi/data/software/minio/data/ruoyi/ + tempfilePath: /guoYanXinXi/data/software/app/tempfile/ + chatUrl: http://127.0.0.1:8081 diff --git a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/controller/ContractualProductInfoController.java b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/controller/ContractualProductInfoController.java index f9dcf1a..7e5d755 100644 --- a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/controller/ContractualProductInfoController.java +++ b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/controller/ContractualProductInfoController.java @@ -6,8 +6,10 @@ import lombok.RequiredArgsConstructor; import jakarta.servlet.http.HttpServletResponse; import jakarta.validation.constraints.*; import cn.dev33.satoken.annotation.SaCheckPermission; +import org.dromara.productManagement.domain.ContractualProductSummary; import org.dromara.productManagement.domain.ContractualUnitStatistics; import org.dromara.productManagement.domain.ProductStatisticsData; +import org.dromara.productManagement.domain.bo.JyjContractualTaskBatchBo; import org.springframework.web.bind.annotation.*; import org.springframework.validation.annotation.Validated; import org.dromara.common.idempotent.annotation.RepeatSubmit; @@ -104,21 +106,23 @@ public class ContractualProductInfoController extends BaseController { @PathVariable Long[] ids) { return toAjax(contractualProductInfoService.deleteWithValidByIds(List.of(ids), true)); } + + /** - * 统计合同产品信息 - * - * @param ids 主键串 + * 查询合同产品统计列表 */ - @Log(title = "统计合同产品信息", businessType = BusinessType.DELETE) - @GetMapping("/statistics") - public R getStatistics(@RequestParam(required = false) String unitName) { - ProductStatisticsData productStatisticsData =contractualProductInfoService.getStatistics(unitName); - return R.ok(productStatisticsData); + @GetMapping("/listContractualProductSummaryPage") + public TableDataInfo listContractualProductSummaryPage(ContractualProductInfoBo bo, PageQuery pageQuery) { + return contractualProductInfoService.listContractualProductSummaryPage(bo, pageQuery); } - @Log(title = "统计合同产品信息", businessType = BusinessType.DELETE) - @GetMapping("/unitStatistics") - public TableDataInfo getUnitStatistics(@RequestParam(required = false) String unitName,PageQuery pageQuery) { - TableDataInfo contractualUnitStatisticsTableDataInfo =contractualProductInfoService.getUnitStatistics(unitName,pageQuery); - return contractualUnitStatisticsTableDataInfo; + + /** + * 获取产品统计数据 + * + * @param type 设备类型(终端、服务器、数据库) + */ + @GetMapping("/getProductStatistics") + public R getProductStatistics(@RequestParam String type) { + return R.ok(contractualProductInfoService.getProductStatistics(type)); } } diff --git a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/controller/JyjContractualTaskBatchController.java b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/controller/JyjContractualTaskBatchController.java index a754928..87428af 100644 --- a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/controller/JyjContractualTaskBatchController.java +++ b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/controller/JyjContractualTaskBatchController.java @@ -4,6 +4,7 @@ import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.HashMap; import java.util.List; +import java.util.Map; import cn.hutool.core.io.resource.InputStreamResource; import com.fasterxml.jackson.core.JsonProcessingException; @@ -123,7 +124,7 @@ public class JyjContractualTaskBatchController extends BaseController { * 根据id获取合同的审查结果 */ @GetMapping("/getContractulResultById/{id}") - public R getCheckResult(@NotNull(message = "主键不能为空") + public R> getCheckResult(@NotNull(message = "主键不能为空") @PathVariable Long id) throws JsonProcessingException { return R.ok(jyjContractualTaskBatchService.getContractulResultById(id)); } @@ -154,4 +155,16 @@ public class JyjContractualTaskBatchController extends BaseController { HttpServletResponse response) { jyjContractualTaskBatchService.exportResultById(documentName, batchName, resultType, problemPoint, response); } + + /** + * 合并批次 + */ + // @SaCheckPermission("productManagement:JyjcontractualTaskBatch:merge") + @Log(title = "合并批次", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PostMapping("/merge") + public R mergeBatches(@RequestBody JyjContractualTaskBatchBo bo) { + return toAjax(jyjContractualTaskBatchService.mergeBatches(bo)); + } + } diff --git a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/ContractualProductInfo.java b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/ContractualProductInfo.java index a2cdc94..54110fb 100644 --- a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/ContractualProductInfo.java +++ b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/ContractualProductInfo.java @@ -57,6 +57,7 @@ public class ContractualProductInfo extends TenantEntity { */ private String priceUnit; private String cpuModel; + private String os; /** * 数量 */ diff --git a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/ContractualProductSummary.java b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/ContractualProductSummary.java new file mode 100644 index 0000000..8454529 --- /dev/null +++ b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/ContractualProductSummary.java @@ -0,0 +1,25 @@ +package org.dromara.productManagement.domain; + +import lombok.Data; + +/** + * 合同产品统计信息对象 + * + * @author ruoyi + */ +@Data +public class ContractualProductSummary { + private static final long serialVersionUID = 1L; + + /** 区县名称 */ + private String countyName; + + /** 合同数量 */ + private Integer contractCount; + + /** 设备数量 */ + private Integer deviceCount; + + /** 金额总计 */ + private Double totalAmount; +} diff --git a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/JyjContractualTaskBatch.java b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/JyjContractualTaskBatch.java index 294b1cc..a186cea 100644 --- a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/JyjContractualTaskBatch.java +++ b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/JyjContractualTaskBatch.java @@ -104,10 +104,6 @@ public class JyjContractualTaskBatch extends TenantEntity { * 进度(百分比) */ private String progress; - /** - * 处理时间 - */ - private String processingTime; /** * 批次名称 @@ -117,5 +113,6 @@ public class JyjContractualTaskBatch extends TenantEntity { * 备注 */ private String remark; - private Date latestTime; + private Long parentId; + private String requirementType; } diff --git a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/ProductStatisticsData.java b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/ProductStatisticsData.java index f3990ff..ed8ae4f 100644 --- a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/ProductStatisticsData.java +++ b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/ProductStatisticsData.java @@ -4,40 +4,40 @@ import java.util.List; import lombok.Data; /** - * 合同产品统计数据 + * 产品统计数据对象 */ @Data public class ProductStatisticsData { - - /** 设备统计列表 */ - private List equipmentStats; - /** - * 设备统计项 (内部类) + * 供应商占比数据 */ - @Data - public static class EquipmentStat { - - /** 设备类型名称 */ - private String name; - - /** 设备总数量 */ - private Long totalCount; - - /** 品牌统计列表 */ - private List brands; - } - + private List vendors; + /** - * 品牌统计项 (内部类) + * 品牌型号占比数据 */ - @Data - public static class BrandStat { + private List models; + + /** + * CPU品牌型号数据 + */ + private List cpus; + + /** + * 操作系统品牌版本数据 + */ + private List os; - /** 品牌名称 */ + @Data + public static class StatItem { + /** + * 名称 + */ private String name; - - /** 数量 */ - private Long count; + + /** + * 数量/值 + */ + private Integer value; } } diff --git a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/bo/ContractualProductInfoBo.java b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/bo/ContractualProductInfoBo.java index 1123dac..75bfe68 100644 --- a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/bo/ContractualProductInfoBo.java +++ b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/bo/ContractualProductInfoBo.java @@ -71,6 +71,7 @@ public class ContractualProductInfoBo extends BaseEntity { */ private String type; public String unitName; + private String os; } diff --git a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/bo/JyjContractualTaskBatchBo.java b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/bo/JyjContractualTaskBatchBo.java index d64962e..680d19b 100644 --- a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/bo/JyjContractualTaskBatchBo.java +++ b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/bo/JyjContractualTaskBatchBo.java @@ -104,4 +104,10 @@ public class JyjContractualTaskBatchBo extends BaseEntity { private Date latestTime; private String requirementType; + private Long parentId; + + /** + * 用于批次合并的ID数组 + */ + private Long[] ids; } diff --git a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/vo/ContractualProductInfoVo.java b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/vo/ContractualProductInfoVo.java index b41aec5..bab6c2f 100644 --- a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/vo/ContractualProductInfoVo.java +++ b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/vo/ContractualProductInfoVo.java @@ -90,5 +90,6 @@ public class ContractualProductInfoVo implements Serializable { private String type; public String unitName; + private String os; } diff --git a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/vo/ContractualTasksVo.java b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/vo/ContractualTasksVo.java index f7e871e..21d9b38 100644 --- a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/vo/ContractualTasksVo.java +++ b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/vo/ContractualTasksVo.java @@ -47,5 +47,6 @@ public class ContractualTasksVo extends BaseTaskVo implements Serializable { private String resultType; private String batchName; private String problemPoint; + private String unitName; } diff --git a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/vo/JyjContractualTaskBatchVo.java b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/vo/JyjContractualTaskBatchVo.java index e83e2b8..a172512 100644 --- a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/vo/JyjContractualTaskBatchVo.java +++ b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/vo/JyjContractualTaskBatchVo.java @@ -28,7 +28,21 @@ public class JyjContractualTaskBatchVo implements Serializable { @Serial private static final long serialVersionUID = 1L; + /** + * 主键ID + */ private Long id; + + /** + * 父ID + */ + private Long parentId; + + /** + * 子记录列表 + */ + private List children; + /** * 任务名称 */ @@ -123,4 +137,5 @@ public class JyjContractualTaskBatchVo implements Serializable { private String processingTime; private Date latestTime; + private String requirementType; } diff --git a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/mapper/ContractualInfoMapper.java b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/mapper/ContractualInfoMapper.java index 9c96864..eb1fb6e 100644 --- a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/mapper/ContractualInfoMapper.java +++ b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/mapper/ContractualInfoMapper.java @@ -12,5 +12,5 @@ import org.dromara.productManagement.domain.vo.ContractualInfoVo; * @date 2025-03-10 */ public interface ContractualInfoMapper extends BaseMapperPlus { - + ContractualInfoVo selectContractualInfoByTaskId(String taskId); } diff --git a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/mapper/ContractualProductInfoMapper.java b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/mapper/ContractualProductInfoMapper.java index 6907147..a5647bb 100644 --- a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/mapper/ContractualProductInfoMapper.java +++ b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/mapper/ContractualProductInfoMapper.java @@ -7,8 +7,10 @@ import org.dromara.productManagement.domain.ContractualUnitStatistics; import org.dromara.productManagement.domain.bo.ContractualProductInfoBo; import org.dromara.productManagement.domain.vo.ContractualProductInfoVo; import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; +import org.dromara.productManagement.domain.ContractualProductSummary; import java.util.List; +import java.util.Map; /** * 合同产品信息Mapper接口 @@ -23,7 +25,45 @@ public interface ContractualProductInfoMapper extends BaseMapperPlus selectProductInfoForStatistics(@Param("unitName") String unitName); Page selectProductInfoPage(@Param("page") Page page, @Param("queryParam") ContractualProductInfoBo queryParam); - Page getUnitStatisticsPage(@Param("page") Page page, @Param("unitName") String unitName); + + /** + * 查询产品统计信息,按文档名称分组 + * + * @param type 设备类型(终端、服务器等) + * @return 统计信息列表 + */ + List selectProductSummaryByDocumentName(@Param("type") String type); + + /** + * 根据类型查询供应商统计 + * + * @param type 设备类型(终端、服务器、数据库) + * @return 供应商统计列表 + */ + List> selectVendorStatistics(@Param("type") String type); + + /** + * 根据类型查询品牌型号统计 + * + * @param type 设备类型(终端、服务器、数据库) + * @return 品牌型号统计列表 + */ + List> selectModelStatistics(@Param("type") String type); + + /** + * 根据类型查询CPU统计 + * + * @param type 设备类型(终端、服务器、数据库) + * @return CPU统计列表 + */ + List> selectCpuStatistics(@Param("type") String type); + + /** + * 根据类型查询操作系统统计 + * + * @param type 设备类型(终端、服务器、数据库) + * @return 操作系统统计列表 + */ + List> selectOsStatistics(@Param("type") String type); } diff --git a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/IContractualProductInfoService.java b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/IContractualProductInfoService.java index e82af65..ed54edb 100644 --- a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/IContractualProductInfoService.java +++ b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/IContractualProductInfoService.java @@ -1,7 +1,9 @@ package org.dromara.productManagement.service; +import org.dromara.productManagement.domain.ContractualProductSummary; import org.dromara.productManagement.domain.ContractualUnitStatistics; import org.dromara.productManagement.domain.ProductStatisticsData; +import org.dromara.productManagement.domain.bo.JyjContractualTaskBatchBo; import org.dromara.productManagement.domain.vo.ContractualProductInfoVo; import org.dromara.productManagement.domain.bo.ContractualProductInfoBo; import org.dromara.common.mybatis.core.page.TableDataInfo; @@ -68,7 +70,15 @@ public interface IContractualProductInfoService { */ Boolean deleteWithValidByIds(Collection ids, Boolean isValid); - ProductStatisticsData getStatistics(String unitName); - TableDataInfo getUnitStatistics(String unitName, PageQuery pageQuery); + + TableDataInfo listContractualProductSummaryPage(ContractualProductInfoBo bo, PageQuery pageQuery); + + /** + * 获取产品统计数据 + * + * @param type 设备类型(终端、服务器、数据库) + * @return 产品统计数据 + */ + ProductStatisticsData getProductStatistics(String type); } diff --git a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/IJyjContractualTaskBatchService.java b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/IJyjContractualTaskBatchService.java index f3d0597..eed9288 100644 --- a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/IJyjContractualTaskBatchService.java +++ b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/IJyjContractualTaskBatchService.java @@ -17,6 +17,7 @@ import java.io.UnsupportedEncodingException; import java.util.Collection; import java.util.HashMap; import java.util.List; +import java.util.Map; /** * 合同批处理记录Service接口 @@ -77,7 +78,7 @@ public interface IJyjContractualTaskBatchService { Boolean deleteWithValidByIds(Collection ids, Boolean isValid); HashMap uploadFile(MultipartFile file) throws IOException; - ContractualRes getContractulResultById(Long id) throws JsonProcessingException; + Map getContractulResultById(Long id) throws JsonProcessingException; void getContractulPdf(Long id, HttpServletResponse response) throws UnsupportedEncodingException; @@ -85,11 +86,20 @@ public interface IJyjContractualTaskBatchService { /** * 根据ID导出合同批处理结果 - * + * * @param documentName 文档名称 * @param batchName 批次名称 * @param resultType 结果类型 * @param response 响应对象 */ void exportResultById(String documentName, String batchName, String resultType,String problemPoint, HttpServletResponse response); + + /** + * 合并批次 + * + * @param bo 包含要合并的批次信息 + * @return 是否合并成功 + */ + Boolean mergeBatches(JyjContractualTaskBatchBo bo); + } diff --git a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/impl/ContractualProductInfoServiceImpl.java b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/impl/ContractualProductInfoServiceImpl.java index 674e57b..f500749 100644 --- a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/impl/ContractualProductInfoServiceImpl.java +++ b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/impl/ContractualProductInfoServiceImpl.java @@ -8,13 +8,12 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import lombok.RequiredArgsConstructor; -import org.dromara.productManagement.domain.ContractualUnitStatistics; -import org.dromara.productManagement.domain.DocumentTaskGroup; -import org.dromara.productManagement.domain.ProductStatisticsData; +import org.dromara.productManagement.domain.*; +import org.dromara.productManagement.domain.bo.JyjContractualTaskBatchBo; +import org.dromara.productManagement.mapper.JyjContractualTaskBatchMapper; import org.springframework.stereotype.Service; import org.dromara.productManagement.domain.bo.ContractualProductInfoBo; import org.dromara.productManagement.domain.vo.ContractualProductInfoVo; -import org.dromara.productManagement.domain.ContractualProductInfo; import org.dromara.productManagement.mapper.ContractualProductInfoMapper; import org.dromara.productManagement.service.IContractualProductInfoService; @@ -23,6 +22,8 @@ import java.util.List; import java.util.Map; import java.util.Collection; import java.util.stream.Collectors; +import java.util.HashMap; +import org.springframework.beans.factory.annotation.Autowired; /** * 合同产品信息Service业务层处理 @@ -35,6 +36,7 @@ import java.util.stream.Collectors; public class ContractualProductInfoServiceImpl implements IContractualProductInfoService { private final ContractualProductInfoMapper baseMapper; + private final JyjContractualTaskBatchMapper jyjContractualTaskBatchMapper; /** * 查询合同产品信息 @@ -141,106 +143,83 @@ public class ContractualProductInfoServiceImpl implements IContractualProductInf return baseMapper.deleteByIds(ids) > 0; } - @Override - public ProductStatisticsData getStatistics(String unitName) { - ProductStatisticsData statistics = new ProductStatisticsData(); - List equipmentStats = new ArrayList<>(); - // 查询所有符合条件的产品数据 - List productList = baseMapper.selectProductInfoForStatistics(unitName); - - // 按类型分组统计 - Map> typeMap = productList.stream() - .collect(Collectors.groupingBy(ContractualProductInfo::getType)); - - // 处理每种设备类型 - for (Map.Entry> entry : typeMap.entrySet()) { - String type = entry.getKey(); - List typeProducts = entry.getValue(); - - ProductStatisticsData.EquipmentStat equipmentStat = new ProductStatisticsData.EquipmentStat(); - equipmentStat.setName(type); - - // 计算总数量(累加quantity字段) - Long totalCount = typeProducts.stream() - .mapToLong(product -> product.getQuantity() != null ? product.getQuantity() : 0) - .sum(); - equipmentStat.setTotalCount(totalCount); - - // 按品牌分组统计 - Map> brandMap = typeProducts.stream() - .collect(Collectors.groupingBy(ContractualProductInfo::getBrand)); - - List brandStats = new ArrayList<>(); - for (Map.Entry> brandEntry : brandMap.entrySet()) { - String brand = brandEntry.getKey(); - List brandProducts = brandEntry.getValue(); - - ProductStatisticsData.BrandStat brandStat = new ProductStatisticsData.BrandStat(); - brandStat.setName(brand); - - // 计算品牌数量(累加quantity字段) - Long brandCount = brandProducts.stream() - .mapToLong(product -> product.getQuantity() != null ? product.getQuantity() : 0) - .sum(); - brandStat.setCount(brandCount); - - brandStats.add(brandStat); - } - - // 按数量降序排序 - // 按数量降序排序 - brandStats.sort((a, b) -> Long.compare(b.getCount(), a.getCount())); - equipmentStat.setBrands(brandStats); - equipmentStats.add(equipmentStat); - } - // 添加CPU型号统计 - ProductStatisticsData.EquipmentStat cpuModelStat = new ProductStatisticsData.EquipmentStat(); - cpuModelStat.setName("技术路线CPU"); - - // 按CPU型号分组统计,过滤掉空值和null - Map> cpuModelMap = productList.stream() - .filter(product -> product.getCpuModel() != null && !product.getCpuModel().isEmpty()) - .collect(Collectors.groupingBy(ContractualProductInfo::getCpuModel)); - - List cpuStats = new ArrayList<>(); - for (Map.Entry> cpuEntry : cpuModelMap.entrySet()) { - String cpuModel = cpuEntry.getKey(); - List cpuProducts = cpuEntry.getValue(); - - ProductStatisticsData.BrandStat cpuStat = new ProductStatisticsData.BrandStat(); - cpuStat.setName(cpuModel); - - // 计算该CPU型号的数量 - Long cpuCount = cpuProducts.stream() - .mapToLong(product -> product.getQuantity() != null ? product.getQuantity() : 0) - .sum(); - cpuStat.setCount(cpuCount); - cpuStats.add(cpuStat); - } - - // CPU型号按数量降序排序 - cpuStats.sort((a, b) -> Long.compare(b.getCount(), a.getCount())); - cpuModelStat.setBrands(cpuStats); - - // 计算CPU总数(只计算有CPU型号的产品) - Long cpuTotalCount = productList.stream() - .filter(product -> product.getCpuModel() != null && !product.getCpuModel().isEmpty()) - .mapToLong(product -> product.getQuantity() != null ? product.getQuantity() : 0) - .sum(); - cpuModelStat.setTotalCount(cpuTotalCount); - - equipmentStats.add(cpuModelStat); - statistics.setEquipmentStats(equipmentStats); - return statistics; + @Override + public TableDataInfo listContractualProductSummaryPage(ContractualProductInfoBo bo, PageQuery pageQuery) { + // 修改策略:先获取所有记录,按DocumentName分组后再分页 + List summaryList = baseMapper.selectProductSummaryByDocumentName(bo.getType()); + return TableDataInfo.build(summaryList); } + /** + * 获取产品统计数据 + * + * @param type 设备类型(终端、服务器、数据库) + * @return 产品统计数据 + */ @Override - public TableDataInfo getUnitStatistics(String unitName, PageQuery pageQuery) { - Page contractualUnitStatisticsPage = baseMapper.getUnitStatisticsPage(pageQuery.build(), unitName); - return TableDataInfo.build(contractualUnitStatisticsPage); - - - + public ProductStatisticsData getProductStatistics(String type) { + ProductStatisticsData statisticsData = new ProductStatisticsData(); + + // 获取供应商占比数据 + List> vendorStats = baseMapper.selectVendorStatistics(type); + List vendors = convertToStatItems(vendorStats); + statisticsData.setVendors(vendors); + + // 获取品牌型号占比数据 + List> modelStats = baseMapper.selectModelStatistics(type); + List models = convertToStatItems(modelStats); + statisticsData.setModels(models); + + // 对于数据库类型,只需要统计前两项 + if (!"数据库".equals(type)) { + // 获取CPU品牌型号数据 + List> cpuStats = baseMapper.selectCpuStatistics(type); + List cpus = convertToStatItems(cpuStats); + statisticsData.setCpus(cpus); + + // 获取操作系统品牌版本数据 + List> osStats = baseMapper.selectOsStatistics(type); + List os = convertToStatItems(osStats); + statisticsData.setOs(os); + } + + return statisticsData; + } + + /** + * 将Map列表转换为StatItem列表 + */ + private List convertToStatItems(List> mapList) { + List statItems = new ArrayList<>(); + + for (Map map : mapList) { + ProductStatisticsData.StatItem item = new ProductStatisticsData.StatItem(); + + // 名称可能为空,需要处理 + String name = map.get("name") != null ? map.get("name").toString() : "未知"; + item.setName(name); + + // 数值转换,处理各种可能的数值类型 + Object valueObj = map.get("value"); + Integer value = 0; + + if (valueObj != null) { + if (valueObj instanceof Number) { + value = ((Number) valueObj).intValue(); + } else { + try { + value = Integer.parseInt(valueObj.toString()); + } catch (NumberFormatException e) { + // 忽略转换异常,使用默认值0 + } + } + } + + item.setValue(value); + statItems.add(item); + } + + return statItems; } } diff --git a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/impl/ContractualTasksServiceImpl.java b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/impl/ContractualTasksServiceImpl.java index 8ae6232..e836def 100644 --- a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/impl/ContractualTasksServiceImpl.java +++ b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/impl/ContractualTasksServiceImpl.java @@ -14,13 +14,11 @@ import org.dromara.productManagement.common.service.BaseTaskService; import org.dromara.productManagement.domain.*; import org.dromara.productManagement.domain.bo.ContractualTaskSupplementBo; import org.dromara.productManagement.domain.bo.DocumentTasksBo; +import org.dromara.productManagement.domain.vo.ContractualInfoVo; import org.dromara.productManagement.domain.vo.ContractualTasksVo; import org.dromara.productManagement.domain.vo.DocumentTasksVo; import org.dromara.productManagement.enums.TaskEnum; -import org.dromara.productManagement.mapper.DocumentTasksMapper; -import org.dromara.productManagement.mapper.DocumentTasksPermissionsMapper; -import org.dromara.productManagement.mapper.ModelPromptsMapper; -import org.dromara.productManagement.mapper.ModelUserPromptssettingMapper; +import org.dromara.productManagement.mapper.*; import org.dromara.productManagement.service.IContractualTaskSupplementService; import org.dromara.productManagement.service.IDocumentTasksPermissionsService; import org.dromara.productManagement.service.IDocumentTasksService; @@ -59,6 +57,8 @@ public class ContractualTasksServiceImpl extends BaseTaskService lqw = buildQueryWrapper(documentTasksBo); lqw.eq(DocumentTasks::getTaskType, TaskEnum.TaskType.CONTRACT_REVIEW.getValue()); - // 获取 DocumentTasksVo 的分页结果 Page documentTasksPage = documentTasksMapper.selectVoPage(pageQuery.build(), lqw); - // 创建新的 ContractualTasksVo 的 Page 对象 Page result = new Page<>(); // 复制分页信息 @@ -93,12 +91,21 @@ public class ContractualTasksServiceImpl extends BaseTaskService contractualTasksVoList = documentTasksPage.getRecords().stream() .map(documentTasksVo -> { + ContractualTasksVo contractualTasksVo = new ContractualTasksVo(); BeanUtils.copyProperties(documentTasksVo, contractualTasksVo); - // 设置创建用户信息 - Long createBy = contractualTasksVo.getCreateBy(); - contractualTasksVo.setCreateUser(userService.selectUserById(createBy).getNickName()); + // 设置创建用户信息,目前不需要 +// Long createBy = contractualTasksVo.getCreateBy(); +// contractualTasksVo.setCreateUser(userService.selectUserById(createBy).getNickName()); + //获取单位名称 + String unitName = ""; + + ContractualInfoVo contractualInfo = contractualInfoMapper.selectContractualInfoByTaskId(documentTasksVo.getId()); + if (contractualInfo!= null) { + unitName = contractualInfo.getPurchaserName(); + } + contractualTasksVo.setUnitName(unitName); // 计算任务持续时间 String formattedDuration = ""; if (!contractualTasksVo.getProgressStatus().equals("PENDING") @@ -126,6 +133,7 @@ public class ContractualTasksServiceImpl extends BaseTaskService0){ documentTasks.setResultType("reviewFail"); - documentTasks.setProblemPoint("人工干预"); + String problemTitle=""; + for(int i=0;i0; } diff --git a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/impl/JyjContractualTaskBatchServiceImpl.java b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/impl/JyjContractualTaskBatchServiceImpl.java index 9041c5b..63cf29b 100644 --- a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/impl/JyjContractualTaskBatchServiceImpl.java +++ b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/impl/JyjContractualTaskBatchServiceImpl.java @@ -18,9 +18,7 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers; import lombok.RequiredArgsConstructor; import org.dromara.productManagement.domain.*; import org.dromara.productManagement.domain.vo.RequirementEntityVo; -import org.dromara.productManagement.mapper.ContractualInfoMapper; -import org.dromara.productManagement.mapper.DocumentTaskResultsMapper; -import org.dromara.productManagement.mapper.DocumentTasksMapper; +import org.dromara.productManagement.mapper.*; import org.dromara.productManagement.utils.CompressedFileUtils; import org.dromara.productManagement.utils.MyHttpUtils; import org.dromara.productManagement.utils.MyTimeUtils; @@ -31,8 +29,8 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.dromara.productManagement.domain.bo.JyjContractualTaskBatchBo; import org.dromara.productManagement.domain.vo.JyjContractualTaskBatchVo; -import org.dromara.productManagement.mapper.JyjContractualTaskBatchMapper; import org.dromara.productManagement.service.IJyjContractualTaskBatchService; +import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; import java.io.*; @@ -50,12 +48,14 @@ import java.util.*; @RequiredArgsConstructor @Service @Slf4j +@Transactional(rollbackFor = Exception.class) public class JyjContractualTaskBatchServiceImpl implements IJyjContractualTaskBatchService { private final JyjContractualTaskBatchMapper baseMapper; protected final ISysOssService ossService; private final DocumentTasksMapper documentTasksMapper; private final DocumentTaskResultsMapper documentTaskResultsMapper; + private final ContractualProductInfoMapper contractualProductInfoMapper; private final ContractualInfoMapper contractualInfoMapper; @Value("${chat.chatUrl}") protected String chatUrl; @@ -81,20 +81,79 @@ public class JyjContractualTaskBatchServiceImpl implements IJyjContractualTaskBa public TableDataInfo queryPageList(JyjContractualTaskBatchBo bo, PageQuery pageQuery) { LambdaQueryWrapper lqw = buildQueryWrapper(bo); Page result = baseMapper.getBatchStatistics(pageQuery.build(), bo); + + // 处理处理时间 result.getRecords().forEach(vo -> { - //获取文件路径 - Long id = vo.getId(); - LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); - wrapper.eq(DocumentTasks::getGroupId, id); - List documentTasksList = documentTasksMapper.selectList(wrapper); - if(documentTasksList.size() > 0){ - //获取documentTasksList中最大的updateTime - Date maxUpdateTime = documentTasksList.stream().max(Comparator.comparing(DocumentTasks::getCreateTime)).get().getCreateTime(); - String timeDifference = MyTimeUtils.formatTimeDifference(vo.getLatestTime(), maxUpdateTime); - vo.setProcessingTime(timeDifference); + List childrenList = vo.getChildren(); + if (childrenList != null && !childrenList.isEmpty()) { + // 存储所有子记录的处理时间,用于比较 + List childTimeDifferences = new ArrayList<>(); + + for (JyjContractualTaskBatchVo child : childrenList) { + Long childId = child.getId(); + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(DocumentTasks::getGroupId, childId); + List documentTasksList = documentTasksMapper.selectList(wrapper); + if (documentTasksList.size() > 0) { + // 获取最早的更新时间 + Date minUpdateTime = documentTasksList.stream() + .min(Comparator.comparing(DocumentTasks::getUpdateTime)) + .get() + .getUpdateTime(); + + // 获取最晚的更新时间 + Date maxUpdateTime = documentTasksList.stream() + .max(Comparator.comparing(DocumentTasks::getUpdateTime)) + .get() + .getUpdateTime(); + + // 计算最早更新时间和最晚更新时间之间的差值 + String timeDifference = MyTimeUtils.formatTimeDifference(minUpdateTime, maxUpdateTime); + child.setProcessingTime(timeDifference); + childTimeDifferences.add(timeDifference); + } + } + + // 找出处理时间最长的子记录时间 + if (!childTimeDifferences.isEmpty()) { + // 根据实际时间长度排序,而不是字符串长度 + String longestTimeDifference = childTimeDifferences.stream() + .max((time1, time2) -> { + // 提取时间值的小时和分钟 + long minutes1 = extractTotalMinutes(time1); + long minutes2 = extractTotalMinutes(time2); + // 比较总分钟数 + return Long.compare(minutes1, minutes2); + }) + .orElse(""); + vo.setProcessingTime(longestTimeDifference); + } + } else { + // 如果没有子记录,直接计算父记录的处理时间 + Long id = vo.getId(); + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(DocumentTasks::getGroupId, id); + List documentTasksList = documentTasksMapper.selectList(wrapper); + if (documentTasksList.size() > 0) { + // 获取最早的更新时间 + Date minUpdateTime = documentTasksList.stream() + .min(Comparator.comparing(DocumentTasks::getUpdateTime)) + .get() + .getUpdateTime(); + + // 获取最晚的更新时间 + Date maxUpdateTime = documentTasksList.stream() + .max(Comparator.comparing(DocumentTasks::getUpdateTime)) + .get() + .getUpdateTime(); + + // 计算最早更新时间和最晚更新时间之间的差值 + String timeDifference = MyTimeUtils.formatTimeDifference(minUpdateTime, maxUpdateTime); + vo.setProcessingTime(timeDifference); + } } - //获取documentTasksList中最大的updateTime对应的documentTaskResults }); + return TableDataInfo.build(result); } @@ -134,13 +193,34 @@ public class JyjContractualTaskBatchServiceImpl implements IJyjContractualTaskBa String fileName = fileInfo.getOriginalName(); CompressedFileUtils.FileValidationResult fileValidationResult = CompressedFileUtils.processCompressedFileFromMinio(fileInfo); - int size = fileValidationResult.getValidFiles().size(); - add.setDocumentName(fileName); - add.setTotalContracts(Long.valueOf(size)); + CompressedFileUtils.FolderStructure folderStructure = fileValidationResult.getFolderStructure(); + + // 检查是否有子目录 + List childFolders = folderStructure.getChildFolders(); + if (childFolders == null || childFolders.isEmpty()) { + throw new ServiceException("压缩包中未找到有效的子目录"); + } + + // 计算所有子文件夹中的文件总数 + long totalFileCount = 0; + for (File childFolder : childFolders) { + File[] files = childFolder.listFiles((dir, name) -> + name.toLowerCase().endsWith(".pdf") || name.toLowerCase().endsWith(".ofd")); + totalFileCount += (files != null ? files.length : 0); + } + + // 检查是否有有效的文件 + if (totalFileCount == 0) { + throw new ServiceException("压缩包中未找到有效的PDF或OFD文件"); + } + + // 保存父记录 + add.setDocumentName(folderStructure.getParentName()); + add.setTotalContracts(totalFileCount); + //批次名称未填.系统填写 if(!StringUtils.isNotBlank(add.getBatchName())){ //查询当天的上传记录次数 - // 使用数据库的日期函数进行比较(这里以MySQL为例) LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); lqw.apply("DATE(create_time) = CURRENT_DATE()"); @@ -150,27 +230,52 @@ public class JyjContractualTaskBatchServiceImpl implements IJyjContractualTaskBa SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日第"); String batchName = sdf.format(new Date()) + count + "批"; add.setBatchName(batchName); - } + + // 保存父记录 boolean flag = baseMapper.insert(add) > 0; - for(File file : fileValidationResult.getValidFiles()){ - //每个文件起一个任务 - DocumentTasks documentTasks = new DocumentTasks(); - documentTasks.setTaskName(bo.getTaskName()); - documentTasks.setDocumentName(file.getName()); - documentTasks.setProgressStatus("PENDING"); - documentTasks.setTaskType(bo.getTaskType()); - documentTasks.setGroupId(add.getId()); - documentTasks.setBatchName(add.getBatchName()); - documentTasks.setRequirementType(bo.getRequirementType()); - // 在插入数据库前调用扩展点 - documentTasksMapper.insert(documentTasks); - // 在发送消息前调用扩展点 - Long priority = 1L; - MyHttpUtils.sendTaskStartMessage(chatUrl + "/back/taskStart", - documentTasks.getId(), bo.getTaskName(), file.getAbsolutePath(), priority); + if (flag) { + // 保存子记录 + List childNames = folderStructure.getChildNames(); + + for (int i = 0; i < childNames.size(); i++) { + // 保存子文件夹记录 + JyjContractualTaskBatch child = new JyjContractualTaskBatch(); + child.setDocumentName(childNames.get(i)); + child.setParentId(add.getId()); + child.setBatchName(add.getBatchName()); + child.setTaskName(bo.getTaskName()); + child.setTaskType(bo.getTaskType()); + + // 计算子文件夹中的文件数量 + File childFolder = childFolders.get(i); + File[] files = childFolder.listFiles((dir, name) -> + name.toLowerCase().endsWith(".pdf") || name.toLowerCase().endsWith(".ofd")); + child.setTotalContracts(Long.valueOf(files != null ? files.length : 0)); + + baseMapper.insert(child); + + // 为子文件夹中的每个文件创建任务 + if (files != null) { + for (File file : files) { + DocumentTasks documentTasks = new DocumentTasks(); + documentTasks.setTaskName(bo.getTaskName()); + documentTasks.setDocumentName(file.getName()); + documentTasks.setProgressStatus("PENDING"); + documentTasks.setTaskType(bo.getTaskType()); + documentTasks.setGroupId(child.getId()); // 使用子记录的ID作为GroupId + documentTasks.setBatchName(add.getBatchName()); + documentTasks.setRequirementType(bo.getRequirementType()); + documentTasksMapper.insert(documentTasks); + // 发送任务开始消息 + Long priority = 1L; + MyHttpUtils.sendTaskStartMessage(chatUrl + "/back/taskStart", + documentTasks.getId(), bo.getTaskName(), file.getAbsolutePath(), priority); + } + } + } } if (flag) { @@ -211,7 +316,46 @@ public class JyjContractualTaskBatchServiceImpl implements IJyjContractualTaskBa if(isValid){ //TODO 做一些业务上的校验,判断是否需要校验 } - return baseMapper.deleteByIds(ids) > 0; + ArrayList longs = new ArrayList<>(); + longs.addAll(ids); + for (Long id : ids) { + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(JyjContractualTaskBatch::getParentId, id); + List childList = baseMapper.selectList(wrapper); + if (childList.size() > 0) { + for (JyjContractualTaskBatch child : childList) { + deleteDocTasks(child.getId()); + longs.add(child.getId()); + } + }else{ + deleteDocTasks(id); + } + } + + // 根据documentTasksList 删除documentTasks + return baseMapper.deleteByIds(longs)>0; + } + private void deleteDocTasks(Long id) { + //根据id 查询documentTasks + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); // 构建查询条件 + wrapper.eq(DocumentTasks::getGroupId, id); + List documentTasksList = documentTasksMapper.selectList(wrapper); + for (DocumentTasks documentTasks : documentTasksList){ + Long documentTaskId = documentTasks.getId(); + LambdaQueryWrapper resultsWrapper = new LambdaQueryWrapper<>(); + resultsWrapper.eq(DocumentTaskResults::getDocumentTaskId, documentTaskId); + documentTaskResultsMapper.delete(resultsWrapper); + documentTasksMapper.deleteById(documentTaskId); + // 删除合同信息 + LambdaQueryWrapper contractualInfoWrapper = new LambdaQueryWrapper<>(); + contractualInfoWrapper.eq(ContractualInfo::getTaskId, documentTaskId); + contractualInfoMapper.delete(contractualInfoWrapper); + // 删除合同产品信息 + LambdaQueryWrapper contractualProductInfoWrapper = new LambdaQueryWrapper<>(); + contractualProductInfoWrapper.eq(ContractualProductInfo::getTaskId, documentTaskId); + contractualProductInfoMapper.delete(contractualProductInfoWrapper); + } + } @Override public HashMap uploadFile(MultipartFile file) throws IOException { @@ -231,7 +375,7 @@ public class JyjContractualTaskBatchServiceImpl implements IJyjContractualTaskBa } @Override - public ContractualRes getContractulResultById(Long id) throws JsonProcessingException { + public Map getContractulResultById(Long id) throws JsonProcessingException { LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); wrapper.eq(DocumentTaskResults::getDocumentTaskId, id); DocumentTaskResults documentTaskResults = documentTaskResultsMapper.selectOne(wrapper); @@ -239,7 +383,34 @@ public class JyjContractualTaskBatchServiceImpl implements IJyjContractualTaskBa //json 字符串转ContractualRes ObjectMapper mapper = new ObjectMapper(); ContractualRes response = mapper.readValue(result, new TypeReference() {}); - return response; + String resultJson = documentTaskResults.getResultJson(); + + // 创建包含当前记录和历史记录的Map + Map resultMap = new HashMap<>(); + resultMap.put("result", response); + if (resultJson != null && !resultJson.isEmpty()) { + try { + // 尝试解析为列表 + List> resultList = mapper.readValue(resultJson, new TypeReference>>() {}); + resultMap.put("historyresultList", resultList); + } catch (JsonProcessingException e) { + // 如果解析为列表失败,尝试解析为单个对象 + try { + Map resultObject = mapper.readValue(resultJson, new TypeReference>() {}); + List> resultList = new ArrayList<>(); + resultList.add(resultObject); + resultMap.put("historyresultList", resultList); + } catch (JsonProcessingException ex) { + // 如果两种解析都失败,返回空列表 + resultMap.put("historyresultList", new ArrayList<>()); + log.error("解析resultJson失败: {}", ex.getMessage()); + } + } + } else { + resultMap.put("historyresultList", new ArrayList<>()); + } + + return resultMap; } @Override @@ -320,6 +491,9 @@ public class JyjContractualTaskBatchServiceImpl implements IJyjContractualTaskBa LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); wrapper.eq(ContractualInfo::getTaskId, id); ContractualInfo contractualInfo = contractualInfoMapper.selectOne(wrapper); + if (contractualInfo == null) { + return "获取合同文本内容失败"; + } String text = contractualInfo.getText(); return text; } @@ -365,4 +539,127 @@ public class JyjContractualTaskBatchServiceImpl implements IJyjContractualTaskBa throw new ServiceException("导出Excel失败,请联系管理员"); } } + + /** + * 合并批次 + * + * @param bo 包含要合并的批次信息 + * @return 是否合并成功 + */ + @Override + public Boolean mergeBatches(JyjContractualTaskBatchBo bo) { + if (bo.getIds() == null || bo.getIds().length < 2) { + throw new ServiceException("请至少选择两个批次进行合并"); + } + + // 检查所选批次的状态 + List batches = baseMapper.selectBatchIds(Arrays.asList(bo.getIds())); + for (JyjContractualTaskBatch batch : batches) { + if (batch.getParentId() != null) { + throw new ServiceException("只能合并父级批次"); + } + } + + // 创建新的父批次记录 + JyjContractualTaskBatch newParent = new JyjContractualTaskBatch(); + newParent.setDocumentName(bo.getDocumentName()); + newParent.setBatchName(bo.getBatchName()); + + // 计算合并后的总数 + long totalContracts = batches.stream() + .mapToLong(JyjContractualTaskBatch::getTotalContracts) + .sum(); + newParent.setTotalContracts(totalContracts); + + // 保存新的父批次 + boolean flag = baseMapper.insert(newParent) > 0; + if (!flag) { + throw new ServiceException("创建合并批次失败"); + } + + // 更新所有批次 + for (JyjContractualTaskBatch batch : batches) { + // 查找原批次的所有子批次 + LambdaQueryWrapper childWrapper = new LambdaQueryWrapper<>(); + childWrapper.eq(JyjContractualTaskBatch::getParentId, batch.getId()); + List children = baseMapper.selectList(childWrapper); + + if (children != null && !children.isEmpty()) { + // 如果有子批次,更新子批次的父ID和批次名称 + for (JyjContractualTaskBatch child : children) { + child.setParentId(newParent.getId()); + child.setBatchName(newParent.getBatchName()); + baseMapper.updateById(child); + + // 更新关联的任务记录 + updateTasksBatchName(child.getId(), newParent.getBatchName()); + } + // 删除原批次 + baseMapper.deleteById(batch.getId()); + } else { + // 如果没有子批次,将当前批次作为子批次 + batch.setParentId(newParent.getId()); + batch.setBatchName(newParent.getBatchName()); + baseMapper.updateById(batch); + + // 更新关联的任务记录 + updateTasksBatchName(batch.getId(), newParent.getBatchName()); + } + } + + return true; + } + + /** + * 更新任务的批次名称 + * + * @param groupId 组ID + * @param batchName 新的批次名称 + */ + private void updateTasksBatchName(Long groupId, String batchName) { + LambdaQueryWrapper taskWrapper = new LambdaQueryWrapper<>(); + taskWrapper.eq(DocumentTasks::getGroupId, groupId); + List tasks = documentTasksMapper.selectList(taskWrapper); + for (DocumentTasks task : tasks) { + task.setBatchName(batchName); + documentTasksMapper.updateById(task); + } + } + + /** + * 从时间字符串中提取总分钟数 + * 支持两种格式:"XX小时XX分钟" 和 "XX分钟" + * + * @param time 时间字符串,如 "2小时30分钟" 或 "45分钟" + * @return 总分钟数 + */ + private long extractTotalMinutes(String time) { + if (time == null || time.isEmpty()) { + return 0; + } + + long hours = 0; + long minutes = 0; + + // 处理包含"小时"的情况 + if (time.contains("小时")) { + String[] hourParts = time.split("小时"); + hours = Long.parseLong(hourParts[0]); + + // 如果还有分钟部分 + if (hourParts.length > 1 && hourParts[1].contains("分钟")) { + String minuteStr = hourParts[1].replace("分钟", "").trim(); + if (!minuteStr.isEmpty()) { + minutes = Long.parseLong(minuteStr); + } + } + } + // 处理只有"分钟"的情况 + else if (time.contains("分钟")) { + String minuteStr = time.replace("分钟", "").trim(); + minutes = Long.parseLong(minuteStr); + } + + return hours * 60 + minutes; + } } diff --git a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/utils/CompressedFileUtils.java b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/utils/CompressedFileUtils.java index 79240fd..dbbb2f6 100644 --- a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/utils/CompressedFileUtils.java +++ b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/utils/CompressedFileUtils.java @@ -1,314 +1,3 @@ -//package org.dromara.productManagement.utils; -// -//import java.io.*; -//import java.nio.charset.Charset; -//import java.nio.charset.StandardCharsets; -//import java.util.ArrayList; -//import java.util.List; -//import java.util.UUID; -//import java.util.zip.ZipEntry; -//import java.util.zip.ZipFile; -//import java.util.Enumeration; -//import java.util.zip.ZipInputStream; -// -//import com.github.junrar.rarfile.FileHeader; -//import jakarta.annotation.PostConstruct; -//import lombok.extern.slf4j.Slf4j; -//import org.apache.commons.io.FileUtils; -//import org.dromara.common.core.utils.SpringUtils; -//import org.dromara.common.oss.core.OssClient; -//import org.dromara.system.domain.SysOss; -//import org.dromara.system.domain.vo.SysOssVo; -//import org.mozilla.universalchardet.UniversalDetector; -//import org.springframework.beans.factory.annotation.Value; -//import org.dromara.common.oss.factory.OssFactory; -//import org.springframework.stereotype.Component; -// -///** -// * 压缩文件处理工具类 -// * 仅支持处理ZIP格式的压缩文件 -// */ -//@Component -//@Slf4j -//public class CompressedFileUtils { -// -// private static final List ALLOWED_EXTENSIONS = new ArrayList<>(List.of(".pdf", ".ofd")); -// private static String tempfilePath; // 保持为静态变量 -// -// @Value("${chat.tempfilePath}") // 默认值为 D:\\ce\\tempfile -// private String tempFilePathValue; // 用于注入的变量 -// -// @PostConstruct -// public void init() { -// tempfilePath = (tempFilePathValue != null) ? tempFilePathValue : null; // 设置默认值 -// } -// -// /** -// * 文件验证结果类 -// */ -// public static class FileValidationResult { -// private final List validFiles; -// private final List warnings; -// -// public FileValidationResult() { -// this.validFiles = new ArrayList<>(); -// this.warnings = new ArrayList<>(); -// } -// -// public List getValidFiles() { -// return validFiles; -// } -// -// public List getWarnings() { -// return warnings; -// } -// -// public void addWarning(String warning) { -// this.warnings.add(warning); -// } -// -// public void addValidFile(File file) { -// this.validFiles.add(file); -// } -// } -// -// /** -// * 从MinIO下载并处理压缩文件 -// */ -// public static FileValidationResult processCompressedFileFromMinio(SysOssVo sysOss) { -// FileValidationResult result = new FileValidationResult(); -// File tempFile = null; -// OssClient instance = OssFactory.instance(sysOss.getService()); -// -// try { -// try (InputStream inputStream = instance.getObjectContent(sysOss.getFileName())) { -// String originalFileName = sysOss.getOriginalName(); -// tempFile = new File(tempfilePath, "temp_" + System.currentTimeMillis() + "_" + originalFileName); -// createParentDirectories(tempFile); -// -// try (FileOutputStream fileOutputStream = new FileOutputStream(tempFile)) { -// copyStream(inputStream, fileOutputStream); -// } -// -// result = processCompressedFile(tempFile.getAbsolutePath(), tempfilePath); -// } -// } catch (Exception e) { -// result.addWarning("从MinIO下载或处理文件时发生错误: " + e.getMessage()); -// log.error("从MinIO下载或处理文件时发生错误: " + e.getMessage()); -// -// } finally { -// if (tempFile != null) { -// tempFile.deleteOnExit(); -// if (!tempFile.delete()) { -// result.addWarning("临时文件将在JVM退出时删除: " + tempFile.getAbsolutePath()); -// log.warn("临时文件将在JVM退出时删除: " + tempFile.getAbsolutePath()); -// } -// } -// } -// return result; -// } -// -// /** -// * 处理压缩文件并返回处理结果 -// */ -// public static FileValidationResult processCompressedFile(String compressedFilePath, String extractPath) throws IOException { -// FileValidationResult result = new FileValidationResult(); -// File compressedFile = new File(compressedFilePath); -// -// if (!compressedFile.exists()) { -// result.addWarning("压缩文件不存在:" + compressedFilePath); -// return result; -// } -// -// if (!compressedFilePath.toLowerCase().endsWith(".zip")) { -// result.addWarning("不支持的压缩文件格式,仅支持 ZIP 格式"); -// return result; -// } -// -// processZipFile(compressedFilePath, extractPath, result); -// return result; -// } -// -// private static void processZipFile(String zipFile, String extractPath, FileValidationResult result) throws IOException { -// InputStream inputStream = new FileInputStream(zipFile); -// Charset charset = detectCharset(inputStream); -// try (ZipFile zip = new ZipFile(zipFile, charset)) { -// // 创建以压缩包名命名的文件夹 -// String zipFileName = new File(zipFile).getName(); -// String folderName = zipFileName.toLowerCase().endsWith(".zip") -// ? zipFileName.substring(0, zipFileName.length() - 4) -// : zipFileName; -// String newExtractPath = new File(extractPath, folderName).getAbsolutePath(); -// -// Enumeration entries = zip.entries(); -// while (entries.hasMoreElements()) { -// ZipEntry entry = entries.nextElement(); -// if (!entry.isDirectory()) { -// String entryName = entry.getName(); -// if (isValidFileType(entryName)) { -// // 保持原始路径结构 -// File extractedFile = new File(newExtractPath, entryName); -// // 确保父目录存在 -// extractedFile.getParentFile().mkdirs(); -// extractZipEntry(zip, entry, extractedFile); -// result.addValidFile(extractedFile); -// } else { -// result.addWarning("跳过不支持的文件类型: " + entryName); -// } -// } -// } -// } catch (IOException e) { -// result.addWarning("处理ZIP文件时发生错误: " + e.getMessage()); -// } -// } -// -// private static File extractZipEntry(ZipFile zipFile, ZipEntry entry, File outputFile) throws IOException { -// try (InputStream inputStream = zipFile.getInputStream(entry); -// FileOutputStream outputStream = new FileOutputStream(outputFile)) { -// copyStream(inputStream, outputStream); -// } -// return outputFile; -// } -// /** -// * 创建父目录 -// */ -// private static void createParentDirectories(File file) { -// File parentFile = file.getParentFile(); -// if (parentFile != null && !parentFile.exists()) { -// parentFile.mkdirs(); -// } -// } -// -// /** -// * 复制流数据 -// */ -// private static void copyStream(InputStream input, OutputStream output) throws IOException { -// byte[] buffer = new byte[8192]; -// int length; -// while ((length = input.read(buffer)) > 0) { -// output.write(buffer, 0, length); -// } -// } -// -// /** -// * 检查文件类型是否有效 -// */ -// private static boolean isValidFileType(String fileName) { -// return ALLOWED_EXTENSIONS.stream() -// .anyMatch(ext -> fileName.toLowerCase().endsWith(ext)); -// } -// -// /** -// * 添加允许的文件扩展名 -// */ -// public static void addAllowedExtension(String extension) { -// if (extension != null && extension.startsWith(".")) { -// ALLOWED_EXTENSIONS.add(extension.toLowerCase()); -// } -// } -// -// /** -// * 获取当前支持的文件扩展名列表 -// */ -// public static List getAllowedExtensions() { -// return new ArrayList<>(ALLOWED_EXTENSIONS); -// } -// -// /** -// * 清除所有允许的文件扩展名 -// */ -// public static void clearAllowedExtensions() { -// ALLOWED_EXTENSIONS.clear(); -// } -// -// /** -// * 移除指定的允许文件扩展名 -// */ -// public static void removeAllowedExtension(String extension) { -// if (extension != null) { -// ALLOWED_EXTENSIONS.remove(extension.toLowerCase()); -// } -// } -// public static class FileStatistics { -// private int validFileCount; -// private int invalidFileCount; -// private List invalidFileNames; -// -// public FileStatistics() { -// this.validFileCount = 0; -// this.invalidFileCount = 0; -// this.invalidFileNames = new ArrayList<>(); -// } -// -// public int getValidFileCount() { -// return validFileCount; -// } -// -// public int getInvalidFileCount() { -// return invalidFileCount; -// } -// -// public List getInvalidFileNames() { -// return invalidFileNames; -// } -// -// public void incrementValidCount() { -// this.validFileCount++; -// } -// -// public void addInvalidFile(String fileName) { -// this.invalidFileCount++; -// this.invalidFileNames.add(fileName); -// } -// } -// -// /** -// * 获取压缩文件中的文件统计数据 -// */ -// public static FileStatistics getFileStatistics(SysOssVo sysOss) throws IOException { -// FileStatistics statistics = new FileStatistics(); -// OssClient instance = OssFactory.instance(sysOss.getService()); -// -// InputStream checkInputStream = instance.getObjectContent(sysOss.getFileName()); -// Charset charset = detectCharset(checkInputStream); // 动态检测字符集,会消耗流的内容 -// InputStream inputStream = instance.getObjectContent(sysOss.getFileName()); -// ZipInputStream zipInputStream = new ZipInputStream(inputStream, charset); -// ZipEntry entry; -// while ((entry = zipInputStream.getNextEntry()) != null) { -// if (!entry.isDirectory()) { -// String entryName = entry.getName(); -// if (isValidFileType(entryName)) { -// statistics.incrementValidCount(); -// } else { -// statistics.addInvalidFile(entryName); -// } -// } -// zipInputStream.closeEntry(); -// } -// -// return statistics; -// -// } -// -// -// private static Charset detectCharset(InputStream inputStream) throws IOException { -// UniversalDetector detector = new UniversalDetector(null); -// byte[] buf = new byte[4096]; -// int nread; -// inputStream.read(buf); -// detector.handleData(buf, 0, buf.length); -// detector.dataEnd(); -// -// String encoding = detector.getDetectedCharset(); -// detector.reset(); -// -// if (encoding != null) { -// return Charset.forName(encoding); -// } -// // 默认返回 UTF-8 -// return Charset.forName("GBK"); -// } -//} package org.dromara.productManagement.utils; import java.io.*; @@ -348,20 +37,67 @@ public class CompressedFileUtils { tempfilePath = (tempFilePathValue != null) ? tempFilePathValue : null; // 设置默认值 } + /** + * 文件夹结构类 + */ + public static class FolderStructure { + private String parentName; // 父文件夹名称(压缩包名称) + private List childNames; // 子文件夹名称列表 + private File parentFolder; // 父文件夹对象 + private List childFolders; // 子文件夹对象列表 + + public FolderStructure() { + this.childNames = new ArrayList<>(); + this.childFolders = new ArrayList<>(); + } + + public String getParentName() { + return parentName; + } + + public void setParentName(String parentName) { + this.parentName = parentName; + } + + public List getChildNames() { + return childNames; + } + + public void addChildName(String childName) { + this.childNames.add(childName); + } + + public File getParentFolder() { + return parentFolder; + } + + public void setParentFolder(File parentFolder) { + this.parentFolder = parentFolder; + } + + public List getChildFolders() { + return childFolders; + } + + public void addChildFolder(File childFolder) { + this.childFolders.add(childFolder); + } + } + /** * 文件验证结果类 */ public static class FileValidationResult { - private final List validFiles; + private final FolderStructure folderStructure; private final List warnings; public FileValidationResult() { - this.validFiles = new ArrayList<>(); + this.folderStructure = new FolderStructure(); this.warnings = new ArrayList<>(); } - public List getValidFiles() { - return validFiles; + public FolderStructure getFolderStructure() { + return folderStructure; } public List getWarnings() { @@ -371,10 +107,6 @@ public class CompressedFileUtils { public void addWarning(String warning) { this.warnings.add(warning); } - - public void addValidFile(File file) { - this.validFiles.add(file); - } } /** @@ -395,12 +127,56 @@ public class CompressedFileUtils { copyStream(inputStream, fileOutputStream); } - result = processCompressedFile(tempFile.getAbsolutePath(), tempfilePath); + // 解压文件到临时目录 + String extractPath = tempfilePath + File.separator + "extract_" + System.currentTimeMillis(); + File extractDir = new File(extractPath); + extractDir.mkdirs(); + + // 设置父文件夹名称(压缩包名称) + String parentName = originalFileName; + if (parentName.toLowerCase().endsWith(".zip")) { + parentName = parentName.substring(0, parentName.length() - 4); + } + result.getFolderStructure().setParentName(parentName); + result.getFolderStructure().setParentFolder(extractDir); + + // 使用Zip4j解压文件 + ZipFile zip4jFile = new ZipFile(tempFile); + + // 根据操作系统设置字符集 + Charset charset = getOsSpecificCharset(); + log.info("当前操作系统: {}, 使用字符集: {}", System.getProperty("os.name"), charset.name()); + zip4jFile.setCharset(charset); + zip4jFile.extractAll(extractPath); + // 分析文件夹结构 + File[] topLevelDirs = extractDir.listFiles(File::isDirectory); + if (topLevelDirs != null && topLevelDirs.length > 0) { + // 如果顶层有多个文件夹,直接使用这些文件夹作为子文件夹 + if (topLevelDirs.length > 1) { + for (File dir : topLevelDirs) { + result.getFolderStructure().addChildName(dir.getName()); + result.getFolderStructure().addChildFolder(dir); + } + } else { + // 如果只有一个顶层文件夹,进入该文件夹并获取其子文件夹 + File singleTopDir = topLevelDirs[0]; + File[] subDirs = singleTopDir.listFiles(File::isDirectory); + if (subDirs != null && subDirs.length > 0) { + for (File subDir : subDirs) { + result.getFolderStructure().addChildName(subDir.getName()); + result.getFolderStructure().addChildFolder(subDir); + } + } else { + // 如果没有子文件夹,则使用顶层文件夹 + result.getFolderStructure().addChildName(singleTopDir.getName()); + result.getFolderStructure().addChildFolder(singleTopDir); + } + } + } } } catch (Exception e) { result.addWarning("从MinIO下载或处理文件时发生错误: " + e.getMessage()); log.error("从MinIO下载或处理文件时发生错误: " + e.getMessage()); - } finally { if (tempFile != null) { tempFile.deleteOnExit(); @@ -458,7 +234,6 @@ public class CompressedFileUtils { // 提取文件 zipFile.extractFile(fileHeader, newExtractPath); - result.addValidFile(extractedFile); } else { result.addWarning("跳过不支持的文件类型: " + entryName); } diff --git a/zaojiaManagement/zaojia-productManagement/src/main/resources/mapper/productManagement/ContractualInfoMapper.xml b/zaojiaManagement/zaojia-productManagement/src/main/resources/mapper/productManagement/ContractualInfoMapper.xml index cfc4510..73ec36a 100644 --- a/zaojiaManagement/zaojia-productManagement/src/main/resources/mapper/productManagement/ContractualInfoMapper.xml +++ b/zaojiaManagement/zaojia-productManagement/src/main/resources/mapper/productManagement/ContractualInfoMapper.xml @@ -3,5 +3,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> - + diff --git a/zaojiaManagement/zaojia-productManagement/src/main/resources/mapper/productManagement/ContractualProductInfoMapper.xml b/zaojiaManagement/zaojia-productManagement/src/main/resources/mapper/productManagement/ContractualProductInfoMapper.xml index 4411374..a0400d9 100644 --- a/zaojiaManagement/zaojia-productManagement/src/main/resources/mapper/productManagement/ContractualProductInfoMapper.xml +++ b/zaojiaManagement/zaojia-productManagement/src/main/resources/mapper/productManagement/ContractualProductInfoMapper.xml @@ -3,33 +3,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> - - SELECT - ci.purchaser_name AS unitName, - SUM(CASE WHEN lp.type = '便携式计算机' THEN lp.quantity ELSE 0 END) AS laptopCount, - SUM(CASE WHEN lp.type = '台式计算机' THEN lp.quantity ELSE 0 END) AS desktopCount, - SUM(CASE WHEN lp.type = '服务器' THEN lp.quantity ELSE 0 END) AS serverCount, - SUM(CASE WHEN lp.type = '服务器操作系统' THEN lp.quantity ELSE 0 END) AS osCount, - SUM(CASE WHEN lp.type = '数据库' THEN lp.quantity ELSE 0 END) AS dbCount + b.document_name AS countyName, + COUNT(DISTINCT dt.id) AS contractCount, + SUM(CASE + WHEN #{type} = '终端' THEN + CASE WHEN p.type IN ('台式计算机', '便携式计算机') THEN p.quantity ELSE 0 END + WHEN #{type} = '服务器' THEN + CASE WHEN p.type = '服务器' THEN p.quantity ELSE 0 END + WHEN #{type} = '数据库' THEN + CASE WHEN p.type = '数据库' THEN p.quantity ELSE 0 END + ELSE 0 + END) AS deviceCount, + SUM(p.total_price) AS totalAmount FROM - (SELECT t1.* - FROM contractual_product_info t1 - INNER JOIN ( - SELECT file_name, MAX(create_time) as max_create_time - FROM contractual_product_info - WHERE del_flag = '0' - GROUP BY file_name - ) t2 ON t1.file_name = t2.file_name AND t1.create_time = t2.max_create_time - WHERE t1.del_flag = '0') lp - LEFT JOIN contractual_info ci ON lp.task_id = ci.task_id + jyj_contractual_task_batch b + LEFT JOIN + document_tasks dt ON b.id = dt.group_id + LEFT JOIN + contractual_product_info p ON dt.id = p.task_id WHERE - ci.del_flag = '0' - - AND ci.purchaser_name LIKE CONCAT('%', #{unitName}, '%') - + b.parent_id IS NOT NULL + AND + CASE + WHEN #{type} = '终端' THEN p.type IN ('台式计算机', '便携式计算机') + WHEN #{type} = '服务器' THEN p.type = '服务器' + WHEN #{type} = '数据库' THEN p.type = '数据库' + ELSE 1=1 + END GROUP BY - ci.purchaser_name + b.document_name + + + + + + + + + diff --git a/zaojiaManagement/zaojia-productManagement/src/main/resources/mapper/productManagement/JyjContractualTaskBatchMapper.xml b/zaojiaManagement/zaojia-productManagement/src/main/resources/mapper/productManagement/JyjContractualTaskBatchMapper.xml index 66a5063..883e1e3 100644 --- a/zaojiaManagement/zaojia-productManagement/src/main/resources/mapper/productManagement/JyjContractualTaskBatchMapper.xml +++ b/zaojiaManagement/zaojia-productManagement/src/main/resources/mapper/productManagement/JyjContractualTaskBatchMapper.xml @@ -4,48 +4,92 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> - + SELECT + b.id, + b.document_name, + b.batch_name, + b.total_contracts, + b.create_time as latest_time, + b.parent_id, + COUNT(CASE WHEN fr.result_type = 'reviewSuccess' THEN 1 END) AS pass_count, + COUNT(CASE WHEN fr.result_type = 'reviewFail' THEN 1 END) AS reject_count, + COUNT(CASE WHEN fr.result_type = 'notReviewable' THEN 1 END) AS irrelevant_count, + COUNT(CASE WHEN fr.progress_status = 'FAILURE' THEN 1 END) AS fail_count, + COUNT(CASE WHEN fr.progress_status IN ('SUCCESS', 'FAILURE') THEN 1 END) AS approved_count, + CASE + WHEN b.total_contracts > 0 THEN + CONCAT(FLOOR(COUNT(CASE WHEN fr.progress_status IN ('SUCCESS', 'FAILURE') THEN 1 END) * 100.0 / b.total_contracts), '%') + ELSE '0%' + END AS progress, + CASE + WHEN b.total_contracts > 0 AND + COUNT(CASE WHEN fr.progress_status IN ('SUCCESS', 'FAILURE') THEN 1 END) = b.total_contracts THEN 'SUCCESS' + ELSE 'STARTED' + END AS progress_status + FROM jyj_contractual_task_batch b + LEFT JOIN document_tasks fr ON b.id = fr.group_id + WHERE b.del_flag = 0 + AND b.parent_id IS NULL + + AND b.document_name LIKE CONCAT('%', #{bo.documentName}, '%') + + + AND b.batch_name LIKE CONCAT('%', #{bo.batchName}, '%') + + GROUP BY b.id, b.document_name, b.batch_name, b.total_contracts, b.create_time - having - progress_status=#{bo.progressStatus} + HAVING progress_status = #{bo.progressStatus} - ORDER BY b.create_time DESC + ORDER BY latest_time DESC + + +