Browse Source

sjj 功能更新与优化

jyj_dev2
zhouhaibin 2 weeks ago
parent
commit
8034d46e5b
  1. 4
      ruoyi-admin/src/main/resources/application-dev.yml
  2. 69
      ruoyi-admin/src/main/resources/application-prod.yml
  3. 30
      zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/controller/ContractualProductInfoController.java
  4. 15
      zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/controller/JyjContractualTaskBatchController.java
  5. 1
      zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/ContractualProductInfo.java
  6. 25
      zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/ContractualProductSummary.java
  7. 7
      zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/JyjContractualTaskBatch.java
  8. 44
      zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/ProductStatisticsData.java
  9. 1
      zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/bo/ContractualProductInfoBo.java
  10. 6
      zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/bo/JyjContractualTaskBatchBo.java
  11. 1
      zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/vo/ContractualProductInfoVo.java
  12. 1
      zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/vo/ContractualTasksVo.java
  13. 15
      zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/vo/JyjContractualTaskBatchVo.java
  14. 2
      zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/mapper/ContractualInfoMapper.java
  15. 44
      zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/mapper/ContractualProductInfoMapper.java
  16. 14
      zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/IContractualProductInfoService.java
  17. 12
      zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/IJyjContractualTaskBatchService.java
  18. 169
      zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/impl/ContractualProductInfoServiceImpl.java
  19. 26
      zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/impl/ContractualTasksServiceImpl.java
  20. 73
      zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/impl/DocumentTaskResultsServiceImpl.java
  21. 345
      zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/impl/JyjContractualTaskBatchServiceImpl.java
  22. 419
      zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/utils/CompressedFileUtils.java
  23. 4
      zaojiaManagement/zaojia-productManagement/src/main/resources/mapper/productManagement/ContractualInfoMapper.xml
  24. 187
      zaojiaManagement/zaojia-productManagement/src/main/resources/mapper/productManagement/ContractualProductInfoMapper.xml
  25. 84
      zaojiaManagement/zaojia-productManagement/src/main/resources/mapper/productManagement/JyjContractualTaskBatchMapper.xml

4
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

69
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

30
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<ProductStatisticsData> getStatistics(@RequestParam(required = false) String unitName) {
ProductStatisticsData productStatisticsData =contractualProductInfoService.getStatistics(unitName);
return R.ok(productStatisticsData);
@GetMapping("/listContractualProductSummaryPage")
public TableDataInfo<ContractualProductSummary> listContractualProductSummaryPage(ContractualProductInfoBo bo, PageQuery pageQuery) {
return contractualProductInfoService.listContractualProductSummaryPage(bo, pageQuery);
}
@Log(title = "统计合同产品信息", businessType = BusinessType.DELETE)
@GetMapping("/unitStatistics")
public TableDataInfo<ContractualUnitStatistics> getUnitStatistics(@RequestParam(required = false) String unitName,PageQuery pageQuery) {
TableDataInfo<ContractualUnitStatistics> contractualUnitStatisticsTableDataInfo =contractualProductInfoService.getUnitStatistics(unitName,pageQuery);
return contractualUnitStatisticsTableDataInfo;
/**
* 获取产品统计数据
*
* @param type 设备类型(终端服务器数据库)
*/
@GetMapping("/getProductStatistics")
public R<ProductStatisticsData> getProductStatistics(@RequestParam String type) {
return R.ok(contractualProductInfoService.getProductStatistics(type));
}
}

15
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<ContractualRes> getCheckResult(@NotNull(message = "主键不能为空")
public R<Map<String, Object>> 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<Void> mergeBatches(@RequestBody JyjContractualTaskBatchBo bo) {
return toAjax(jyjContractualTaskBatchService.mergeBatches(bo));
}
}

1
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;
/**
* 数量
*/

25
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;
}

7
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;
}

44
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<EquipmentStat> equipmentStats;
/**
* 设备统计项 (内部类)
* 供应商占比数据
*/
@Data
public static class EquipmentStat {
/** 设备类型名称 */
private String name;
private List<StatItem> vendors;
/** 设备总数量 */
private Long totalCount;
/**
* 品牌型号占比数据
*/
private List<StatItem> models;
/** 品牌统计列表 */
private List<BrandStat> brands;
}
/**
* CPU品牌型号数据
*/
private List<StatItem> cpus;
/**
* 品牌统计项 (内部类)
* 操作系统品牌版本数据
*/
@Data
public static class BrandStat {
private List<StatItem> os;
/** 品牌名称 */
@Data
public static class StatItem {
/**
* 名称
*/
private String name;
/** 数量 */
private Long count;
/**
* 数量/
*/
private Integer value;
}
}

1
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;
}

6
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;
}

1
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;
}

1
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;
}

15
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<JyjContractualTaskBatchVo> children;
/**
* 任务名称
*/
@ -123,4 +137,5 @@ public class JyjContractualTaskBatchVo implements Serializable {
private String processingTime;
private Date latestTime;
private String requirementType;
}

2
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<ContractualInfo, ContractualInfoVo> {
ContractualInfoVo selectContractualInfoByTaskId(String taskId);
}

44
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<Contractual
* @param queryParam 查询参数
* @return 产品信息集合
*/
List<ContractualProductInfo> selectProductInfoForStatistics(@Param("unitName") String unitName);
Page<ContractualProductInfoVo> selectProductInfoPage(@Param("page") Page<ContractualProductInfo> page, @Param("queryParam") ContractualProductInfoBo queryParam);
Page<ContractualUnitStatistics> getUnitStatisticsPage(@Param("page") Page<ContractualProductInfo> page, @Param("unitName") String unitName);
/**
* 查询产品统计信息按文档名称分组
*
* @param type 设备类型终端服务器等
* @return 统计信息列表
*/
List<ContractualProductSummary> selectProductSummaryByDocumentName(@Param("type") String type);
/**
* 根据类型查询供应商统计
*
* @param type 设备类型终端服务器数据库
* @return 供应商统计列表
*/
List<Map<String, Object>> selectVendorStatistics(@Param("type") String type);
/**
* 根据类型查询品牌型号统计
*
* @param type 设备类型终端服务器数据库
* @return 品牌型号统计列表
*/
List<Map<String, Object>> selectModelStatistics(@Param("type") String type);
/**
* 根据类型查询CPU统计
*
* @param type 设备类型终端服务器数据库
* @return CPU统计列表
*/
List<Map<String, Object>> selectCpuStatistics(@Param("type") String type);
/**
* 根据类型查询操作系统统计
*
* @param type 设备类型终端服务器数据库
* @return 操作系统统计列表
*/
List<Map<String, Object>> selectOsStatistics(@Param("type") String type);
}

14
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<Long> ids, Boolean isValid);
ProductStatisticsData getStatistics(String unitName);
TableDataInfo<ContractualUnitStatistics> getUnitStatistics(String unitName, PageQuery pageQuery);
TableDataInfo<ContractualProductSummary> listContractualProductSummaryPage(ContractualProductInfoBo bo, PageQuery pageQuery);
/**
* 获取产品统计数据
*
* @param type 设备类型(终端服务器数据库)
* @return 产品统计数据
*/
ProductStatisticsData getProductStatistics(String type);
}

12
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<Long> ids, Boolean isValid);
HashMap<String,String> uploadFile(MultipartFile file) throws IOException;
ContractualRes getContractulResultById(Long id) throws JsonProcessingException;
Map<String, Object> getContractulResultById(Long id) throws JsonProcessingException;
void getContractulPdf(Long id, HttpServletResponse response) throws UnsupportedEncodingException;
@ -92,4 +93,13 @@ public interface IJyjContractualTaskBatchService {
* @param response 响应对象
*/
void exportResultById(String documentName, String batchName, String resultType,String problemPoint, HttpServletResponse response);
/**
* 合并批次
*
* @param bo 包含要合并的批次信息
* @return 是否合并成功
*/
Boolean mergeBatches(JyjContractualTaskBatchBo bo);
}

169
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<ProductStatisticsData.EquipmentStat> equipmentStats = new ArrayList<>();
// 查询所有符合条件的产品数据
List<ContractualProductInfo> productList = baseMapper.selectProductInfoForStatistics(unitName);
// 按类型分组统计
Map<String, List<ContractualProductInfo>> typeMap = productList.stream()
.collect(Collectors.groupingBy(ContractualProductInfo::getType));
// 处理每种设备类型
for (Map.Entry<String, List<ContractualProductInfo>> entry : typeMap.entrySet()) {
String type = entry.getKey();
List<ContractualProductInfo> 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<String, List<ContractualProductInfo>> brandMap = typeProducts.stream()
.collect(Collectors.groupingBy(ContractualProductInfo::getBrand));
List<ProductStatisticsData.BrandStat> brandStats = new ArrayList<>();
for (Map.Entry<String, List<ContractualProductInfo>> brandEntry : brandMap.entrySet()) {
String brand = brandEntry.getKey();
List<ContractualProductInfo> 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);
@Override
public TableDataInfo<ContractualProductSummary> listContractualProductSummaryPage(ContractualProductInfoBo bo, PageQuery pageQuery) {
// 修改策略:先获取所有记录,按DocumentName分组后再分页
List<ContractualProductSummary> summaryList = baseMapper.selectProductSummaryByDocumentName(bo.getType());
return TableDataInfo.build(summaryList);
}
// 按数量降序排序
// 按数量降序排序
brandStats.sort((a, b) -> Long.compare(b.getCount(), a.getCount()));
equipmentStat.setBrands(brandStats);
equipmentStats.add(equipmentStat);
/**
* 获取产品统计数据
*
* @param type 设备类型(终端服务器数据库)
* @return 产品统计数据
*/
@Override
public ProductStatisticsData getProductStatistics(String type) {
ProductStatisticsData statisticsData = new ProductStatisticsData();
// 获取供应商占比数据
List<Map<String, Object>> vendorStats = baseMapper.selectVendorStatistics(type);
List<ProductStatisticsData.StatItem> vendors = convertToStatItems(vendorStats);
statisticsData.setVendors(vendors);
// 获取品牌型号占比数据
List<Map<String, Object>> modelStats = baseMapper.selectModelStatistics(type);
List<ProductStatisticsData.StatItem> models = convertToStatItems(modelStats);
statisticsData.setModels(models);
// 对于数据库类型,只需要统计前两项
if (!"数据库".equals(type)) {
// 获取CPU品牌型号数据
List<Map<String, Object>> cpuStats = baseMapper.selectCpuStatistics(type);
List<ProductStatisticsData.StatItem> cpus = convertToStatItems(cpuStats);
statisticsData.setCpus(cpus);
// 获取操作系统品牌版本数据
List<Map<String, Object>> osStats = baseMapper.selectOsStatistics(type);
List<ProductStatisticsData.StatItem> os = convertToStatItems(osStats);
statisticsData.setOs(os);
}
// 添加CPU型号统计
ProductStatisticsData.EquipmentStat cpuModelStat = new ProductStatisticsData.EquipmentStat();
cpuModelStat.setName("技术路线CPU");
// 按CPU型号分组统计,过滤掉空值和null
Map<String, List<ContractualProductInfo>> cpuModelMap = productList.stream()
.filter(product -> product.getCpuModel() != null && !product.getCpuModel().isEmpty())
.collect(Collectors.groupingBy(ContractualProductInfo::getCpuModel));
List<ProductStatisticsData.BrandStat> cpuStats = new ArrayList<>();
for (Map.Entry<String, List<ContractualProductInfo>> cpuEntry : cpuModelMap.entrySet()) {
String cpuModel = cpuEntry.getKey();
List<ContractualProductInfo> 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);
return statisticsData;
}
// 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;
/**
* 将Map列表转换为StatItem列表
*/
private List<ProductStatisticsData.StatItem> convertToStatItems(List<Map<String, Object>> mapList) {
List<ProductStatisticsData.StatItem> statItems = new ArrayList<>();
for (Map<String, Object> 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
}
}
}
@Override
public TableDataInfo<ContractualUnitStatistics> getUnitStatistics(String unitName, PageQuery pageQuery) {
Page<ContractualUnitStatistics> contractualUnitStatisticsPage = baseMapper.getUnitStatisticsPage(pageQuery.build(), unitName);
return TableDataInfo.build(contractualUnitStatisticsPage);
item.setValue(value);
statItems.add(item);
}
return statItems;
}
}

26
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<ContractualTask
private IDocumentTasksService documentTasksService;
@Autowired
private IContractualTaskSupplementService contractualTaskSupplementService;
@Autowired
private ContractualInfoMapper contractualInfoMapper;
@Override
@ -79,10 +79,8 @@ public class ContractualTasksServiceImpl extends BaseTaskService<ContractualTask
BeanUtils.copyProperties(bo, documentTasksBo);
LambdaQueryWrapper<DocumentTasks> lqw = buildQueryWrapper(documentTasksBo);
lqw.eq(DocumentTasks::getTaskType, TaskEnum.TaskType.CONTRACT_REVIEW.getValue());
// 获取 DocumentTasksVo 的分页结果
Page<DocumentTasksVo> documentTasksPage = documentTasksMapper.selectVoPage(pageQuery.build(), lqw);
// 创建新的 ContractualTasksVo 的 Page 对象
Page<ContractualTasksVo> result = new Page<>();
// 复制分页信息
@ -93,12 +91,21 @@ public class ContractualTasksServiceImpl extends BaseTaskService<ContractualTask
// 转换记录列表
List<ContractualTasksVo> 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 BaseTaskService<ContractualTask
lqw.eq(StringUtils.isNotBlank(bo.getProgressStatus()), DocumentTasks::getProgressStatus, bo.getProgressStatus());
lqw.eq(StringUtils.isNotBlank(bo.getResultType()),DocumentTasks::getResultType, bo.getResultType());
lqw.like(StringUtils.isNotBlank(bo.getProblemPoint()), DocumentTasks::getProblemPoint, bo.getProblemPoint());
lqw.eq(bo.getGroupId()!=null, DocumentTasks::getGroupId, bo.getGroupId());
lqw.orderByDesc(DocumentTasks::getUpdateTime);
lqw.orderByDesc(DocumentTasks::getProgressStatus);
return lqw;

73
zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/impl/DocumentTaskResultsServiceImpl.java

@ -1,6 +1,7 @@
package org.dromara.productManagement.service.impl;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.lowagie.text.html.simpleparser.StyleSheet;
import com.lowagie.text.pdf.BaseFont;
import com.openhtmltopdf.pdfboxout.PdfRendererBuilder;
@ -263,15 +264,81 @@ public class DocumentTaskResultsServiceImpl implements IDocumentTaskResultsServi
documentTasks.setId(documentTaskId);
if(size>0){
documentTasks.setResultType("reviewFail");
documentTasks.setProblemPoint("人工干预");
String problemTitle="";
for(int i=0;i<size;i++){
if(StringUtils.isNotBlank(contractualRes.getResults().get(0).getContentList().get(i).getProblemTitle())){
problemTitle+=contractualRes.getResults().get(0).getContentList().get(i).getProblemTitle();
if(i<size-1){
problemTitle+=",";
}
}
}
documentTasks.setProblemPoint(problemTitle);
}else{
documentTasks.setResultType("reviewSuccess");
documentTasks.setProblemPoint("");
}
documentTasksMapper.updateById(documentTasks);
// 使用 Jackson 或 Fastjson 将对象转换为 JSON 字符串
String jsonString = JSON.toJSONString(contractualRes);
results.setResultJson(results.getResult());
// 将当前结果存入ResultJson字段
String currentResult = results.getResult();
// 检查ResultJson是否为空
if (StringUtils.isBlank(results.getResultJson())) {
// 如果为空,创建新的JSON数组并添加当前结果
JSONArray jsonArray = new JSONArray();
if (StringUtils.isNotBlank(currentResult)) {
// 先尝试解析currentResult为JSON对象,如果是JSON字符串则转换为对象
try {
Object obj = JSON.parse(currentResult);
jsonArray.add(obj);
} catch (Exception e) {
jsonArray.add(currentResult);
}
}
results.setResultJson(jsonArray.toJSONString());
} else {
// 如果不为空,解析现有JSON并添加当前结果
try {
// 尝试解析为JSONArray
Object jsonObj = JSON.parse(results.getResultJson());
JSONArray jsonArray;
if (jsonObj instanceof JSONArray) {
// 如果是JSONArray,直接使用
jsonArray = (JSONArray) jsonObj;
} else {
// 如果是JSONObject或其他类型,创建新数组并添加原对象
jsonArray = new JSONArray();
jsonArray.add(jsonObj);
}
// 添加当前结果到数组
if (StringUtils.isNotBlank(currentResult)) {
// 先尝试解析currentResult为JSON对象,如果是JSON字符串则转换为对象
try {
Object obj = JSON.parse(currentResult);
jsonArray.add(obj);
} catch (Exception e) {
jsonArray.add(currentResult);
}
}
results.setResultJson(jsonArray.toJSONString());
} catch (Exception e) {
// 如果解析失败,创建新的JSON数组
JSONArray jsonArray = new JSONArray();
if (StringUtils.isNotBlank(currentResult)) {
// 先尝试解析currentResult为JSON对象,如果是JSON字符串则转换为对象
try {
Object obj = JSON.parse(currentResult);
jsonArray.add(obj);
} catch (Exception ex) {
jsonArray.add(currentResult);
}
}
results.setResultJson(jsonArray.toJSONString());
}
}
results.setResult(jsonString);
return baseMapper.updateById(results)>0;
}

345
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<JyjContractualTaskBatchVo> queryPageList(JyjContractualTaskBatchBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<JyjContractualTaskBatch> lqw = buildQueryWrapper(bo);
Page<JyjContractualTaskBatchVo> result = baseMapper.getBatchStatistics(pageQuery.build(), bo);
// 处理处理时间
result.getRecords().forEach(vo -> {
//获取文件路径
List<JyjContractualTaskBatchVo> childrenList = vo.getChildren();
if (childrenList != null && !childrenList.isEmpty()) {
// 存储所有子记录的处理时间,用于比较
List<String> childTimeDifferences = new ArrayList<>();
for (JyjContractualTaskBatchVo child : childrenList) {
Long childId = child.getId();
LambdaQueryWrapper<DocumentTasks> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(DocumentTasks::getGroupId, childId);
List<DocumentTasks> 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<DocumentTasks> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(DocumentTasks::getGroupId, id);
List<DocumentTasks> 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);
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<File> 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<JyjContractualTaskBatch> 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()){
//每个文件起一个任务
if (flag) {
// 保存子记录
List<String> 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(add.getId());
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<Long> longs = new ArrayList<>();
longs.addAll(ids);
for (Long id : ids) {
LambdaQueryWrapper<JyjContractualTaskBatch> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(JyjContractualTaskBatch::getParentId, id);
List<JyjContractualTaskBatch> 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<DocumentTasks> wrapper = new LambdaQueryWrapper<>(); // 构建查询条件
wrapper.eq(DocumentTasks::getGroupId, id);
List<DocumentTasks> documentTasksList = documentTasksMapper.selectList(wrapper);
for (DocumentTasks documentTasks : documentTasksList){
Long documentTaskId = documentTasks.getId();
LambdaQueryWrapper<DocumentTaskResults> resultsWrapper = new LambdaQueryWrapper<>();
resultsWrapper.eq(DocumentTaskResults::getDocumentTaskId, documentTaskId);
documentTaskResultsMapper.delete(resultsWrapper);
documentTasksMapper.deleteById(documentTaskId);
// 删除合同信息
LambdaQueryWrapper<ContractualInfo> contractualInfoWrapper = new LambdaQueryWrapper<>();
contractualInfoWrapper.eq(ContractualInfo::getTaskId, documentTaskId);
contractualInfoMapper.delete(contractualInfoWrapper);
// 删除合同产品信息
LambdaQueryWrapper<ContractualProductInfo> contractualProductInfoWrapper = new LambdaQueryWrapper<>();
contractualProductInfoWrapper.eq(ContractualProductInfo::getTaskId, documentTaskId);
contractualProductInfoMapper.delete(contractualProductInfoWrapper);
}
}
@Override
public HashMap<String,String> uploadFile(MultipartFile file) throws IOException {
@ -231,7 +375,7 @@ public class JyjContractualTaskBatchServiceImpl implements IJyjContractualTaskBa
}
@Override
public ContractualRes getContractulResultById(Long id) throws JsonProcessingException {
public Map<String, Object> getContractulResultById(Long id) throws JsonProcessingException {
LambdaQueryWrapper<DocumentTaskResults> 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<ContractualRes>() {});
return response;
String resultJson = documentTaskResults.getResultJson();
// 创建包含当前记录和历史记录的Map
Map<String, Object> resultMap = new HashMap<>();
resultMap.put("result", response);
if (resultJson != null && !resultJson.isEmpty()) {
try {
// 尝试解析为列表
List<Map<String, Object>> resultList = mapper.readValue(resultJson, new TypeReference<List<Map<String, Object>>>() {});
resultMap.put("historyresultList", resultList);
} catch (JsonProcessingException e) {
// 如果解析为列表失败,尝试解析为单个对象
try {
Map<String, Object> resultObject = mapper.readValue(resultJson, new TypeReference<Map<String, Object>>() {});
List<Map<String, Object>> 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<ContractualInfo> 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<JyjContractualTaskBatch> 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<JyjContractualTaskBatch> childWrapper = new LambdaQueryWrapper<>();
childWrapper.eq(JyjContractualTaskBatch::getParentId, batch.getId());
List<JyjContractualTaskBatch> 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<DocumentTasks> taskWrapper = new LambdaQueryWrapper<>();
taskWrapper.eq(DocumentTasks::getGroupId, groupId);
List<DocumentTasks> 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;
}
}

419
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<String> 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<File> validFiles;
// private final List<String> warnings;
//
// public FileValidationResult() {
// this.validFiles = new ArrayList<>();
// this.warnings = new ArrayList<>();
// }
//
// public List<File> getValidFiles() {
// return validFiles;
// }
//
// public List<String> 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<? extends ZipEntry> 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<String> 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<String> 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<String> 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<String> childNames; // 子文件夹名称列表
private File parentFolder; // 父文件夹对象
private List<File> 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<String> 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<File> getChildFolders() {
return childFolders;
}
public void addChildFolder(File childFolder) {
this.childFolders.add(childFolder);
}
}
/**
* 文件验证结果类
*/
public static class FileValidationResult {
private final List<File> validFiles;
private final FolderStructure folderStructure;
private final List<String> warnings;
public FileValidationResult() {
this.validFiles = new ArrayList<>();
this.folderStructure = new FolderStructure();
this.warnings = new ArrayList<>();
}
public List<File> getValidFiles() {
return validFiles;
public FolderStructure getFolderStructure() {
return folderStructure;
}
public List<String> 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);
}

4
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">
<mapper namespace="org.dromara.productManagement.mapper.ContractualInfoMapper">
<select id="selectContractualInfoByTaskId" resultType="org.dromara.productManagement.domain.vo.ContractualInfoVo">
SELECT * FROM contractual_info WHERE task_id = #{taskId}
</select>
</mapper>

187
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">
<mapper namespace="org.dromara.productManagement.mapper.ContractualProductInfoMapper">
<select id="selectProductInfoForStatistics" resultType="org.dromara.productManagement.domain.ContractualProductInfo">
SELECT
p.id,
p.task_id,
p.file_name,
p.brand,
p.version_str,
p.unit_price,
p.price_unit,
p.quantity,
p.total_price,
p.type,
p.cpu_model,
i.purchaser_name AS unitName
FROM
contractual_product_info p
INNER JOIN
contractual_info i ON p.task_id = i.task_id
<where>
<if test="unitName != null and unitName != ''">
AND i.purchaser_name LIKE CONCAT('%', #{unitName}, '%')
</if>
AND p.del_flag = '0'
</where>
ORDER BY
p.type, p.brand
</select>
<select id="selectProductInfoPage" resultType="org.dromara.productManagement.domain.vo.ContractualProductInfoVo">
SELECT
p.id,
@ -46,13 +19,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
FROM
contractual_product_info p
INNER JOIN contractual_info i ON p.task_id = i.task_id
LEFT JOIN document_tasks dt ON p.task_id = dt.id
LEFT JOIN jyj_contractual_task_batch b ON dt.group_id = b.id
<where>
b.document_name = #{queryParam.unitName}
<if test="queryParam.fileName != null and queryParam.fileName != ''">
AND p.file_name LIKE CONCAT('%', #{queryParam.fileName}, '%')
</if>
<if test="queryParam.unitName != null and queryParam.unitName != ''">
AND i.purchaser_name LIKE CONCAT('%', #{queryParam.unitName}, '%')
</if>
<if test="queryParam.brand != null and queryParam.brand != ''">
AND p.brand LIKE CONCAT('%', #{queryParam.brand}, '%')
</if>
@ -63,7 +36,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
AND p.cpu_model LIKE CONCAT('%', #{queryParam.cpuModel}, '%')
</if>
<if test="queryParam.type != null and queryParam.type != ''">
AND p.type LIKE CONCAT('%', #{queryParam.type}, '%')
AND
CASE
WHEN #{queryParam.type} = '终端' THEN p.type IN ('台式计算机', '便携式计算机')
WHEN #{queryParam.type} = '服务器' THEN p.type = '服务器'
WHEN #{queryParam.type} = '数据库' THEN p.type = '数据库'
ELSE 1=1
END
</if>
<if test="queryParam.unitPrice != null and queryParam.unitPrice != ''">
AND p.unit_price = #{queryParam.unitPrice}
@ -71,33 +50,133 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
AND p.del_flag = '0'
</where>
ORDER BY
p.type, p.brand
i.purchaser_name,p.type, p.brand
</select>
<select id="getUnitStatisticsPage" resultType="org.dromara.productManagement.domain.ContractualUnitStatistics">
<select id="selectProductSummaryByDocumentName" resultType="org.dromara.productManagement.domain.ContractualProductSummary">
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'
<if test="unitName != null and unitName != ''">
AND ci.purchaser_name LIKE CONCAT('%', #{unitName}, '%')
</if>
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
b.document_name
</select>
<select id="selectVendorStatistics" resultType="map">
SELECT
ci.supplier_name AS name,
COUNT(1) AS value
FROM
contractual_product_info p
INNER JOIN
document_tasks dt ON p.task_id = dt.id AND dt.progress_status = 'SUCCESS'
INNER JOIN
contractual_info ci ON p.task_id = ci.task_id
WHERE
CASE
WHEN #{type} = '终端' THEN p.type IN ('台式计算机', '便携式计算机')
WHEN #{type} = '服务器' THEN p.type = '服务器'
WHEN #{type} = '数据库' THEN p.type = '数据库'
ELSE 1=1
END
AND p.del_flag = '0'
GROUP BY
ci.supplier_name
ORDER BY
value DESC
</select>
<select id="selectModelStatistics" resultType="map">
SELECT
CONCAT(p.brand, ' ', p.version_str) AS name,
SUM(p.quantity) AS value
FROM
contractual_product_info p
INNER JOIN
document_tasks dt ON p.task_id = dt.id AND dt.progress_status = 'SUCCESS'
WHERE
CASE
WHEN #{type} = '终端' THEN p.type IN ('台式计算机', '便携式计算机')
WHEN #{type} = '服务器' THEN p.type = '服务器'
WHEN #{type} = '数据库' THEN p.type = '数据库'
ELSE 1=1
END
AND p.del_flag = '0'
GROUP BY
p.brand, p.version_str
ORDER BY
value DESC
</select>
<select id="selectCpuStatistics" resultType="map">
SELECT
p.cpu_model AS name,
SUM(p.quantity) AS value
FROM
contractual_product_info p
INNER JOIN
document_tasks dt ON p.task_id = dt.id AND dt.progress_status = 'SUCCESS'
WHERE
CASE
WHEN #{type} = '终端' THEN p.type IN ('台式计算机', '便携式计算机')
WHEN #{type} = '服务器' THEN p.type = '服务器'
WHEN #{type} = '数据库' THEN p.type = '数据库'
ELSE 1=1
END
AND p.cpu_model IS NOT NULL
AND p.cpu_model != ''
AND p.del_flag = '0'
GROUP BY
ci.purchaser_name
p.cpu_model
ORDER BY
value DESC
</select>
<select id="selectOsStatistics" resultType="map">
SELECT
p.os AS name,
SUM(p.quantity) AS value
FROM
contractual_product_info p
INNER JOIN
document_tasks dt ON p.task_id = dt.id AND dt.progress_status = 'SUCCESS'
WHERE
CASE
WHEN #{type} = '终端' THEN p.type IN ('台式计算机', '便携式计算机')
WHEN #{type} = '服务器' THEN p.type = '服务器'
WHEN #{type} = '数据库' THEN p.type = '数据库'
ELSE 1=1
END
AND p.os IS NOT NULL
AND p.os != ''
AND p.del_flag = '0'
GROUP BY
p.os
ORDER BY
value DESC
</select>
</mapper>

84
zaojiaManagement/zaojia-productManagement/src/main/resources/mapper/productManagement/JyjContractualTaskBatchMapper.xml

@ -4,13 +4,31 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.dromara.productManagement.mapper.JyjContractualTaskBatchMapper">
<select id="getBatchStatistics" resultType="org.dromara.productManagement.domain.vo.JyjContractualTaskBatchVo">
<resultMap id="BatchResultMap" type="org.dromara.productManagement.domain.vo.JyjContractualTaskBatchVo">
<id property="id" column="id"/>
<result property="documentName" column="document_name"/>
<result property="batchName" column="batch_name"/>
<result property="totalContracts" column="total_contracts"/>
<result property="latestTime" column="latest_time"/>
<result property="passCount" column="pass_count"/>
<result property="rejectCount" column="reject_count"/>
<result property="irrelevantCount" column="irrelevant_count"/>
<result property="failCount" column="fail_count"/>
<result property="approvedCount" column="approved_count"/>
<result property="progress" column="progress"/>
<result property="progressStatus" column="progress_status"/>
<collection property="children" ofType="org.dromara.productManagement.domain.vo.JyjContractualTaskBatchVo"
select="getChildBatches" column="id"/>
</resultMap>
<select id="getBatchStatistics" resultMap="BatchResultMap">
SELECT
b.id AS id,
b.document_name AS document_name,
b.batch_name AS batch_name,
b.total_contracts AS total_contracts,
MAX(b.create_time) as latest_time,
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,
@ -26,26 +44,52 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
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>
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
<if test="bo.documentName!= null and bo.documentName!= ''">
and b.document_name LIKE CONCAT('%', #{bo.documentName}, '%')
AND b.document_name LIKE CONCAT('%', #{bo.documentName}, '%')
</if>
<if test="bo.batchName!= null and bo.batchName!= ''">
and b.batch_name LIKE CONCAT('%', #{bo.batchName}, '%')
AND b.batch_name LIKE CONCAT('%', #{bo.batchName}, '%')
</if>
</where>
GROUP BY
b.id,b.document_name, b.batch_name, b.total_contracts, b.create_time
GROUP BY b.id, b.document_name, b.batch_name, b.total_contracts, b.create_time
<if test="bo.progressStatus != null and bo.progressStatus != ''">
having
progress_status=#{bo.progressStatus}
HAVING progress_status = #{bo.progressStatus}
</if>
ORDER BY b.create_time DESC
ORDER BY latest_time DESC
</select>
<select id="getChildBatches" resultType="org.dromara.productManagement.domain.vo.JyjContractualTaskBatchVo">
SELECT
c.id,
c.document_name,
c.batch_name,
c.total_contracts,
c.create_time as latest_time,
c.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 c.total_contracts > 0 THEN
CONCAT(FLOOR(COUNT(CASE WHEN fr.progress_status IN ('SUCCESS', 'FAILURE') THEN 1 END) * 100.0 / c.total_contracts), '%')
ELSE '0%'
END AS progress,
CASE
WHEN c.total_contracts > 0 AND
COUNT(CASE WHEN fr.progress_status IN ('SUCCESS', 'FAILURE') THEN 1 END) = c.total_contracts THEN 'SUCCESS'
ELSE 'STARTED'
END AS progress_status
FROM jyj_contractual_task_batch c
LEFT JOIN document_tasks fr ON c.id = fr.group_id
WHERE c.del_flag = 0
AND c.parent_id = #{id}
GROUP BY c.id, c.document_name, c.batch_name, c.total_contracts, c.create_time
ORDER BY c.create_time DESC
</select>
</mapper>

Loading…
Cancel
Save