Browse Source

新增jyj合同审批

jyj_dev
zhouhaibin 2 months ago
parent
commit
d9e3612925
  1. 3
      ruoyi-admin/src/main/resources/application-dev.yml
  2. 2
      ruoyi-admin/src/main/resources/application-test.yml
  3. 10
      zaojiaManagement/zaojia-productManagement/pom.xml
  4. 27
      zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/common/service/BaseTaskService.java
  5. 107
      zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/controller/ContractualInfoController.java
  6. 3
      zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/controller/ContractualTasksController.java
  7. 5
      zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/controller/DocumentTaskResultsController.java
  8. 133
      zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/controller/JyjContractualTaskBatchController.java
  9. 83
      zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/ContractualInfo.java
  10. 24
      zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/ContractualRes.java
  11. 4
      zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/DocumentTasks.java
  12. 121
      zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/JyjContractualTaskBatch.java
  13. 55
      zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/bo/ContractualInfoBo.java
  14. 4
      zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/bo/ContractualTasksBo.java
  15. 5
      zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/bo/DocumentTasksBo.java
  16. 105
      zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/bo/JyjContractualTaskBatchBo.java
  17. 1
      zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/vo/BaseTaskVo.java
  18. 60
      zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/vo/ContractualInfoVo.java
  19. 4
      zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/vo/ContractualTasksVo.java
  20. 5
      zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/vo/DocumentTasksVo.java
  21. 127
      zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/vo/JyjContractualTaskBatchVo.java
  22. 16
      zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/mapper/ContractualInfoMapper.java
  23. 30
      zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/mapper/JyjContractualTaskBatchMapper.java
  24. 70
      zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/IContractualInfoService.java
  25. 1
      zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/IContractualTasksService.java
  26. 3
      zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/IDocumentTaskResultsService.java
  27. 82
      zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/IJyjContractualTaskBatchService.java
  28. 134
      zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/impl/ContractualInfoServiceImpl.java
  29. 18
      zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/impl/ContractualTasksServiceImpl.java
  30. 26
      zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/impl/DocumentTaskResultsServiceImpl.java
  31. 42
      zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/impl/DocumentTasksServiceImpl.java
  32. 265
      zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/impl/JyjContractualTaskBatchServiceImpl.java
  33. 351
      zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/utils/CompressedFileUtils.java
  34. 152
      zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/utils/ZipFileUtils.java
  35. 7
      zaojiaManagement/zaojia-productManagement/src/main/resources/mapper/productManagement/ContractualInfoMapper.xml
  36. 51
      zaojiaManagement/zaojia-productManagement/src/main/resources/mapper/productManagement/JyjContractualTaskBatchMapper.xml

3
ruoyi-admin/src/main/resources/application-dev.yml

@ -52,8 +52,9 @@ spring:
# 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
# username: root
# password: root
url: jdbc:mysql://10.1.21.250:3306/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/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.251:3306/jyjtable?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true
username: root
password: 'HXj-6nR|D8xy*h#!I&:('
# 从库数据源

2
ruoyi-admin/src/main/resources/application-test.yml

@ -50,7 +50,7 @@ spring:
driverClassName: com.mysql.cj.jdbc.Driver
# jdbc 所有参数配置参考 https://lionli.blog.csdn.net/article/details/122018562
# rewriteBatchedStatements=true 批处理优化 大幅提升批量插入更新删除性能(对数据库有性能损耗 使用批量操作应考虑性能问题)
url: jdbc:mysql://localhost:3306/aitable?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: HXj-6nR|D8xy*h#!I&:(
# 从库数据源

10
zaojiaManagement/zaojia-productManagement/pom.xml

@ -116,6 +116,16 @@
<artifactId>flying-saucer-pdf</artifactId>
<version>9.1.22</version>
</dependency>
<dependency>
<groupId>com.github.junrar</groupId>
<artifactId>junrar</artifactId>
<version>7.5.4</version>
</dependency>
<dependency>
<groupId>com.googlecode.juniversalchardet</groupId>
<artifactId>juniversalchardet</artifactId>
<version>1.0.3</version>
</dependency>
</dependencies>

27
zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/common/service/BaseTaskService.java

@ -86,15 +86,15 @@ public abstract class BaseTaskService<T extends BaseTaskBo> {
protected Boolean handleTask(T bo, String taskType) throws IOException, InterruptedException {
List<String> taskNames = bo.getTaskNameList();
Long userId = LoginHelper.getUserId();
// 校验提示词
validatePrompts(taskNames, bo, taskType);
// 处理用户提示词设置
handleUserPromptsSetting(userId, bo, taskType);
// 验证用户任务权限
documentTasksPermissionsService.validateUserTaskPermissions(taskType,taskNames, userId);
//
// // 校验提示词
// validatePrompts(taskNames, bo, taskType);
//
// // 处理用户提示词设置
// handleUserPromptsSetting(userId, bo, taskType);
//
// // 验证用户任务权限
// documentTasksPermissionsService.validateUserTaskPermissions(taskType,taskNames, userId);
// 处理文件相关操作
FileProcessResult fileResult = processFile(bo.getOssId());
@ -152,9 +152,9 @@ public abstract class BaseTaskService<T extends BaseTaskBo> {
String filePath = fileRootPath + fileInfo.getFileName();
// 处理文件转换
if(!fileName.toLowerCase().endsWith(".docx")) {
filePath = convertToDocx(filePath, fileName);
}
// if(!fileName.toLowerCase().endsWith(".docx")) {
// filePath = convertToDocx(filePath, fileName);
// }
return new FileProcessResult(fileInfo.getOriginalName(), filePath);
}
@ -230,6 +230,9 @@ public abstract class BaseTaskService<T extends BaseTaskBo> {
// 在发送消息前调用扩展点
beforeTaskMessageSent(add.getId(), taskName, bo);
Long priority = calculatePriority(taskName);
if(taskName.equals("contractualReview")){
taskName="batchReview";
}
MyHttpUtils.sendTaskStartMessage(chatUrl + "/back/taskStart",
add.getId(), taskName, fileResult.getFilePath(), priority);

107
zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/controller/ContractualInfoController.java

@ -0,0 +1,107 @@
package org.dromara.productManagement.controller;
import java.util.List;
import lombok.RequiredArgsConstructor;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.dromara.productManagement.domain.ContractualInfo;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import org.dromara.common.idempotent.annotation.RepeatSubmit;
import org.dromara.common.log.annotation.Log;
import org.dromara.common.web.core.BaseController;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.excel.utils.ExcelUtil;
import org.dromara.productManagement.domain.vo.ContractualInfoVo;
import org.dromara.productManagement.domain.bo.ContractualInfoBo;
import org.dromara.productManagement.service.IContractualInfoService;
import org.dromara.common.mybatis.core.page.TableDataInfo;
/**
* 合同信息保存
*
* @author Lion Li
* @date 2025-03-10
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/productManagement/ContractualInfo")
public class ContractualInfoController extends BaseController {
private final IContractualInfoService ContractualInfoService;
/**
* 查询合同信息保存列表
*/
@SaCheckPermission("productManagement:ContractualInfo:list")
@GetMapping("/list")
public TableDataInfo<ContractualInfoVo> list(ContractualInfoBo bo, PageQuery pageQuery) {
return ContractualInfoService.queryPageList(bo, pageQuery);
}
/**
* 导出合同信息保存列表
*/
@SaCheckPermission("productManagement:ContractualInfo:export")
@Log(title = "合同信息保存", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(ContractualInfoBo bo, HttpServletResponse response) {
List<ContractualInfoVo> list = ContractualInfoService.queryList(bo);
ExcelUtil.exportExcel(list, "合同信息保存", ContractualInfoVo.class, response);
}
/**
* 获取合同信息保存详细信息
*
* @param id 主键
*/
@SaCheckPermission("productManagement:ContractualInfo:query")
@GetMapping("/{id}")
public R<ContractualInfoVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(ContractualInfoService.queryById(id));
}
/**
* 新增合同信息保存
*/
@SaCheckPermission("productManagement:ContractualInfo:add")
@Log(title = "合同信息保存", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody ContractualInfoBo bo) {
return toAjax(ContractualInfoService.insertByBo(bo));
}
/**
* 修改合同信息保存
*/
@SaCheckPermission("productManagement:ContractualInfo:edit")
@Log(title = "合同信息保存", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody ContractualInfoBo bo) {
return toAjax(ContractualInfoService.updateByBo(bo));
}
/**
* 删除合同信息保存
*
* @param ids 主键串
*/
@SaCheckPermission("productManagement:ContractualInfo:remove")
@Log(title = "合同信息保存", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(ContractualInfoService.deleteWithValidByIds(List.of(ids), true));
}
}

3
zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/controller/ContractualTasksController.java

@ -7,6 +7,7 @@ import lombok.RequiredArgsConstructor;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.dromara.productManagement.domain.ContractualRes;
import org.dromara.productManagement.domain.DocumentTaskGroup;
import org.dromara.productManagement.domain.vo.DocumentTasksVo;
import org.springframework.web.bind.annotation.*;
@ -105,4 +106,6 @@ public class ContractualTasksController extends BaseController {
@PathVariable Long[] ids) {
return toAjax(contractualTasksService.deleteWithValidByIds(List.of(ids), true));
}
}

5
zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/controller/DocumentTaskResultsController.java

@ -6,6 +6,7 @@ import lombok.RequiredArgsConstructor;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.dromara.productManagement.domain.ContractualRes;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import org.dromara.common.idempotent.annotation.RepeatSubmit;
@ -124,4 +125,8 @@ public class DocumentTaskResultsController extends BaseController {
@PathVariable Long[] ids,HttpServletResponse response) {
documentTaskResultsService.downloadResult(ids,response);
}
@PutMapping("/modifyContractReview/{documentTaskGroupId}")
public R<Void> modifyContractReview(@PathVariable Long documentTaskGroupId, @RequestBody ContractualRes contractualRes) {
return toAjax(documentTaskResultsService.modifyContractReview(documentTaskGroupId, contractualRes));
}
}

133
zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/controller/JyjContractualTaskBatchController.java

@ -0,0 +1,133 @@
package org.dromara.productManagement.controller;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import cn.hutool.core.io.resource.InputStreamResource;
import com.fasterxml.jackson.core.JsonProcessingException;
import lombok.RequiredArgsConstructor;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.dromara.productManagement.domain.ContractualRes;
import org.dromara.system.domain.vo.SysOssUploadVo;
import org.dromara.system.domain.vo.SysOssVo;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import org.dromara.common.idempotent.annotation.RepeatSubmit;
import org.dromara.common.log.annotation.Log;
import org.dromara.common.web.core.BaseController;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.excel.utils.ExcelUtil;
import org.dromara.productManagement.domain.vo.JyjContractualTaskBatchVo;
import org.dromara.productManagement.domain.bo.JyjContractualTaskBatchBo;
import org.dromara.productManagement.service.IJyjContractualTaskBatchService;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.springframework.web.multipart.MultipartFile;
/**
* 合同批处理记录
*
* @author Lion Li
* @date 2025-03-05
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/productManagement/JyjcontractualTaskBatch")
public class JyjContractualTaskBatchController extends BaseController {
private final IJyjContractualTaskBatchService jyjContractualTaskBatchService;
/**
* 查询合同批处理记录列表
*/
@SaCheckPermission("productManagement:JyjcontractualTaskBatch:list")
@GetMapping("/list")
public TableDataInfo<JyjContractualTaskBatchVo> list(JyjContractualTaskBatchBo bo, PageQuery pageQuery) {
return jyjContractualTaskBatchService.queryPageList(bo, pageQuery);
}
/**
* 导出合同批处理记录列表
*/
@SaCheckPermission("productManagement:JyjcontractualTaskBatch:export")
@Log(title = "合同批处理记录", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(JyjContractualTaskBatchBo bo, HttpServletResponse response) {
List<JyjContractualTaskBatchVo> list = jyjContractualTaskBatchService.queryList(bo);
ExcelUtil.exportExcel(list, "合同批处理记录", JyjContractualTaskBatchVo.class, response);
}
/**
* 获取合同批处理记录详细信息
*
* @param id 主键
*/
@SaCheckPermission("productManagement:JyjcontractualTaskBatch:query")
@GetMapping("/{id}")
public R<JyjContractualTaskBatchVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(jyjContractualTaskBatchService.queryById(id));
}
/**
* 新增合同批处理记录
*/
@SaCheckPermission("productManagement:JyjcontractualTaskBatch:add")
@Log(title = "合同批处理记录", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody JyjContractualTaskBatchBo bo) {
return toAjax(jyjContractualTaskBatchService.insertByBo(bo));
}
/**
* 修改合同批处理记录
*/
@SaCheckPermission("productManagement:JyjcontractualTaskBatch:edit")
@Log(title = "合同批处理记录", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody JyjContractualTaskBatchBo bo) {
return toAjax(jyjContractualTaskBatchService.updateByBo(bo));
}
/**
* 删除合同批处理记录
*
* @param ids 主键串
*/
@SaCheckPermission("productManagement:JyjcontractualTaskBatch:remove")
@Log(title = "合同批处理记录", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(jyjContractualTaskBatchService.deleteWithValidByIds(List.of(ids), true));
}
@PostMapping(value = "/back/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public R<HashMap<String,String>> uploadFile(@RequestPart(name = "file") MultipartFile file) throws IOException, InterruptedException {
HashMap<String,String> uploadVo = jyjContractualTaskBatchService.uploadFile(file);
return R.ok(uploadVo);
}
/**
* 根据id获取合同的审查结果
*/
@GetMapping("/getContractulResultById/{id}")
public R<ContractualRes> getCheckResult(@NotNull(message = "主键不能为空")
@PathVariable Long id) throws JsonProcessingException {
return R.ok(jyjContractualTaskBatchService.getContractulResultById(id));
}
@GetMapping("/getContractulPdf/{id}")
public void getContractulPdf(@PathVariable Long id, HttpServletResponse response) {
jyjContractualTaskBatchService.getContractulPdf(id,response);
}
}

83
zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/ContractualInfo.java

@ -0,0 +1,83 @@
package org.dromara.productManagement.domain;
import org.dromara.common.tenant.core.TenantEntity;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.Date;
import java.io.Serial;
/**
* 合同信息保存对象 contractul_info
*
* @author Lion Li
* @date 2025-03-10
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("contractual_info")
public class ContractualInfo extends TenantEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
* id
*/
@TableId(value = "id")
private Long id;
/**
* 合同任务id
*/
private Long taskId;
/**
* 合同名称
*/
private String fileName;
/**
* 合同文本
*/
private String text;
/**
* 采购人名称
*/
private String purchaserName;
/**
* 供应商名称或姓名
*/
private String supplierName;
/**
* 合同签订时间
*/
private String signDate;
/**
* 合同金额
*/
private String contractAmount;
/**
* 预算资金
*/
private String budgetAmount;
/**
* 删除标志
*/
@TableLogic
private String delFlag;
/**
* 文件名称
*/
private String filePath;
}

24
zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/ContractualRes.java

@ -0,0 +1,24 @@
package org.dromara.productManagement.domain;
import lombok.Data;
import java.util.List;
@Data
public class ContractualRes {
private List<ContractReviewResult> results;
@Data
public static class ContractReviewResult {
private String title;
private List<ProblemDetail> contentList;
}
@Data
public static class ProblemDetail {
private String problemTitle;
private String text;
private String problemDesc;
private Boolean isPosition;
private String accord;
}
}

4
zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/DocumentTasks.java

@ -79,5 +79,7 @@ public class DocumentTasks extends TenantEntity {
* 模型所属行业
*/
private String taskIndustry;
private Long groupId;
private String resultType;
private String batchName;
}

121
zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/JyjContractualTaskBatch.java

@ -0,0 +1,121 @@
package org.dromara.productManagement.domain;
import com.alibaba.excel.annotation.ExcelProperty;
import org.dromara.common.tenant.core.TenantEntity;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serial;
import java.util.Date;
/**
* 合同批处理记录对象 jyj_contractual_task_batch
*
* @author Lion Li
* @date 2025-03-05
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("jyj_contractual_task_batch")
public class JyjContractualTaskBatch extends TenantEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
@TableId(value = "id")
private Long id;
/**
* 任务名称
*/
private String taskName;
/**
* 任务类型
*/
private String taskType;
/**
* 文档名称
*/
private String documentName;
/**
* OSS文件ID
*/
private Long ossId;
/**
* 进度状态
*/
private String progressStatus;
/**
* 删除标志
*/
@TableLogic
private String delFlag;
/**
* 版本号
*/
@Version
private Long version;
/**
* 列队任务id
*/
private String groupId;
/**
* 合同总数
*/
private Long totalContracts;
/**
* 已审批总数
*/
private Long approvedCount;
/**
* 审核通过数量
*/
private Long passCount;
/**
* 审核不通过数量
*/
private Long rejectCount;
/**
* 非审查范围数量
*/
private Long irrelevantCount;
/**
* 审核失败数量
*/
private Long failCount;
/**
* 进度(百分比)
*/
private String progress;
/**
* 处理时间
*/
private String processingTime;
/**
* 批次名称
*/
private String batchName;
/**
* 备注
*/
private String remark;
private Date latestTime;
}

55
zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/bo/ContractualInfoBo.java

@ -0,0 +1,55 @@
package org.dromara.productManagement.domain.bo;
import org.dromara.productManagement.domain.ContractualInfo;
import org.dromara.common.mybatis.core.domain.BaseEntity;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import lombok.EqualsAndHashCode;
import jakarta.validation.constraints.*;
import java.util.Date;
/**
* 合同信息保存业务对象 contractul_info
*
* @author Lion Li
* @date 2025-03-10
*/
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = ContractualInfo.class, reverseConvertGenerate = false)
public class ContractualInfoBo extends BaseEntity {
private Long id;
/**
* 合同名称
*/
@NotBlank(message = "合同名称不能为空", groups = { AddGroup.class, EditGroup.class })
private String fileName;
/**
* 采购人名称
*/
@NotBlank(message = "采购人名称不能为空", groups = { AddGroup.class, EditGroup.class })
private String purchaserName;
/**
* 供应商名称或姓名
*/
@NotBlank(message = "供应商名称或姓名不能为空", groups = { AddGroup.class, EditGroup.class })
private String supplierName;
/**
* 合同签订时间
*/
@NotNull(message = "合同签订时间不能为空", groups = { AddGroup.class, EditGroup.class })
private String signDate;
/**
* 合同金额
*/
@NotBlank(message = "合同金额不能为空", groups = { AddGroup.class, EditGroup.class })
private String contractAmount;
}

4
zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/bo/ContractualTasksBo.java

@ -32,8 +32,10 @@ public class ContractualTasksBo extends BaseTaskBo {
/**
* 合同角色
*/
@NotBlank(message = "合同角色不能为空", groups = { AddGroup.class, EditGroup.class })
private String contractPartyRole;
private Long groupId;
private String resultType;
private String batchName;
// /**
// * 模型所属行业
// */

5
zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/bo/DocumentTasksBo.java

@ -29,8 +29,9 @@ public class DocumentTasksBo extends BaseTaskBo {
* 主键
*/
private String id;
private Long groupId;
private String resultType;
private String batchName;

105
zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/bo/JyjContractualTaskBatchBo.java

@ -0,0 +1,105 @@
package org.dromara.productManagement.domain.bo;
import com.alibaba.excel.annotation.ExcelProperty;
import org.dromara.productManagement.domain.JyjContractualTaskBatch;
import org.dromara.common.mybatis.core.domain.BaseEntity;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import lombok.EqualsAndHashCode;
import jakarta.validation.constraints.*;
import java.util.Date;
/**
* 合同批处理记录业务对象 jyj_contractual_task_batch
*
* @author Lion Li
* @date 2025-03-05
*/
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = JyjContractualTaskBatch.class, reverseConvertGenerate = false)
public class JyjContractualTaskBatchBo extends BaseEntity {
private Long id;
/**
* 任务名称
*/
private String taskName;
/**
* 任务类型
*/
private String taskType;
/**
* 文档名称
*/
private String documentName;
/**
* OSS文件ID
*/
@NotNull(message = "文档不能为空", groups = { AddGroup.class, EditGroup.class })
private Long ossId;
/**
* 进度状态
*/
private String progressStatus;
/**
* 列队任务id
*/
private String groupId;
/**
* 合同总数
*/
private Long totalContracts;
/**
* 已审批总数
*/
private Long approvedCount;
/**
* 审核通过数量
*/
private Long passCount;
/**
* 审核不通过数量
*/
private Long rejectCount;
/**
* 非审查范围数量
*/
private Long irrelevantCount;
/**
* 审核失败数量
*/
private Long failCount;
/**
* 进度(百分比)
*/
private String progress;
/**
* 批次名称
*/
private String batchName;
/**
* 备注
*/
private String remark;
/**
* 处理时间
*/
private String processingTime;
private Date latestTime;
}

1
zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/vo/BaseTaskVo.java

@ -9,6 +9,7 @@ import java.util.Date;
@Data
public class BaseTaskVo {
/**
* 任务名称
*/

60
zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/vo/ContractualInfoVo.java

@ -0,0 +1,60 @@
package org.dromara.productManagement.domain.vo;
import java.util.Date;
import org.dromara.productManagement.domain.ContractualInfo;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
/**
* 合同信息保存视图对象 contractul_info
*
* @author Lion Li
* @date 2025-03-10
*/
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = ContractualInfo.class)
public class ContractualInfoVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
private Long id;
/**
* 合同名称
*/
@ExcelProperty(value = "合同名称")
private String fileName;
/**
* 采购人名称
*/
@ExcelProperty(value = "采购人名称")
private String purchaserName;
/**
* 供应商名称或姓名
*/
@ExcelProperty(value = "供应商名称或姓名")
private String supplierName;
/**
* 合同签订时间
*/
@ExcelProperty(value = "合同签订时间")
private String signDate;
/**
* 合同金额
*/
@ExcelProperty(value = "合同金额")
private String contractAmount;
}

4
zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/vo/ContractualTasksVo.java

@ -43,5 +43,7 @@ public class ContractualTasksVo extends BaseTaskVo implements Serializable {
*/
@ExcelProperty(value = "合同角色")
private String contractPartyRole;
private Long groupId;
private String resultType;
private String batchName;
}

5
zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/vo/DocumentTasksVo.java

@ -31,6 +31,7 @@ public class DocumentTasksVo extends BaseTaskVo implements Serializable {
private static final long serialVersionUID = 1L;
@ExcelProperty(value = "主键")
private String id;
private Long groupId;
private String resultType;
private String batchName;
}

127
zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/vo/JyjContractualTaskBatchVo.java

@ -0,0 +1,127 @@
package org.dromara.productManagement.domain.vo;
import org.dromara.productManagement.domain.JyjContractualTaskBatch;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import org.dromara.common.excel.annotation.ExcelDictFormat;
import org.dromara.common.excel.convert.ExcelDictConvert;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
/**
* 合同批处理记录视图对象 jyj_contractual_task_batch
*
* @author Lion Li
* @date 2025-03-05
*/
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = JyjContractualTaskBatch.class)
public class JyjContractualTaskBatchVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
private Long id;
/**
* 任务名称
*/
@ExcelProperty(value = "任务名称", converter = ExcelDictConvert.class)
@ExcelDictFormat(dictType = "contract_review")
private String taskName;
/**
* 任务类型
*/
@ExcelProperty(value = "任务类型", converter = ExcelDictConvert.class)
@ExcelDictFormat(dictType = "task_type")
private String taskType;
/**
* 文档名称
*/
@ExcelProperty(value = "文档名称")
private String documentName;
/**
* OSS文件ID
*/
@ExcelProperty(value = "OSS文件ID")
private Long ossId;
/**
* 进度状态
*/
@ExcelProperty(value = "进度状态")
private String progressStatus;
/**
* 列队任务id
*/
@ExcelProperty(value = "列队任务id")
private String groupId;
/**
* 合同总数
*/
@ExcelProperty(value = "合同总数")
private Long totalContracts;
/**
* 已审批总数
*/
@ExcelProperty(value = "已审批总数")
private Long approvedCount;
/**
* 审核通过数量
*/
@ExcelProperty(value = "审核通过数量")
private Long passCount;
/**
* 审核不通过数量
*/
@ExcelProperty(value = "审核不通过数量")
private Long rejectCount;
/**
* 非审查范围数量
*/
@ExcelProperty(value = "非审查范围数量")
private Long irrelevantCount;
/**
* 审核失败数量
*/
@ExcelProperty(value = "审核失败数量")
private Long failCount;
/**
* 进度(百分比)
*/
@ExcelProperty(value = "进度(百分比)")
private String progress;
/**
* 批次名称
*/
@ExcelProperty(value = "批次名称")
private String batchName;
/**
* 备注
*/
@ExcelProperty(value = "备注")
private String remark;
/**
* 处理时间
*/
@ExcelProperty(value = "处理时间")
private String processingTime;
private Date latestTime;
}

16
zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/mapper/ContractualInfoMapper.java

@ -0,0 +1,16 @@
package org.dromara.productManagement.mapper;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
import org.dromara.productManagement.domain.ContractualInfo;
import org.dromara.productManagement.domain.vo.ContractualInfoVo;
/**
* 合同信息保存Mapper接口
*
* @author Lion Li
* @date 2025-03-10
*/
public interface ContractualInfoMapper extends BaseMapperPlus<ContractualInfo, ContractualInfoVo> {
}

30
zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/mapper/JyjContractualTaskBatchMapper.java

@ -0,0 +1,30 @@
package org.dromara.productManagement.mapper;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Param;
import org.dromara.common.mybatis.annotation.DataColumn;
import org.dromara.common.mybatis.annotation.DataPermission;
import org.dromara.productManagement.domain.DocumentTaskGroup;
import org.dromara.productManagement.domain.DocumentTasks;
import org.dromara.productManagement.domain.JyjContractualTaskBatch;
import org.dromara.productManagement.domain.bo.JyjContractualTaskBatchBo;
import org.dromara.productManagement.domain.vo.JyjContractualTaskBatchVo;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
/**
* 合同批处理记录Mapper接口
*
* @author Lion Li
* @date 2025-03-05
*/
@DataPermission({
// @DataColumn(key = "deptName", value = "dept_id"),
@DataColumn(key = "userName", value = "create_by")
})
public interface JyjContractualTaskBatchMapper extends BaseMapperPlus<JyjContractualTaskBatch, JyjContractualTaskBatchVo> {
Page<JyjContractualTaskBatchVo> getBatchStatistics(@Param("page") Page<DocumentTasks> page, JyjContractualTaskBatchBo bo);
}

70
zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/IContractualInfoService.java

@ -0,0 +1,70 @@
package org.dromara.productManagement.service;
import org.dromara.productManagement.domain.vo.ContractualInfoVo;
import org.dromara.productManagement.domain.bo.ContractualInfoBo;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import java.util.Collection;
import java.util.List;
/**
* 合同信息保存Service接口
*
* @author Lion Li
* @date 2025-03-10
*/
public interface IContractualInfoService {
/**
* 查询合同信息保存
*
* @param id 主键
* @return 合同信息保存
*/
ContractualInfoVo queryById(Long id);
/**
* 分页查询合同信息保存列表
*
* @param bo 查询条件
* @param pageQuery 分页参数
* @return 合同信息保存分页列表
*/
TableDataInfo<ContractualInfoVo> queryPageList(ContractualInfoBo bo, PageQuery pageQuery);
/**
* 查询符合条件的合同信息保存列表
*
* @param bo 查询条件
* @return 合同信息保存列表
*/
List<ContractualInfoVo> queryList(ContractualInfoBo bo);
/**
* 新增合同信息保存
*
* @param bo 合同信息保存
* @return 是否新增成功
*/
Boolean insertByBo(ContractualInfoBo bo);
/**
* 修改合同信息保存
*
* @param bo 合同信息保存
* @return 是否修改成功
*/
Boolean updateByBo(ContractualInfoBo bo);
/**
* 校验并批量删除合同信息保存信息
*
* @param ids 待删除的主键集合
* @param isValid 是否进行有效性校验
* @return 是否删除成功
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
}

1
zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/IContractualTasksService.java

@ -1,5 +1,6 @@
package org.dromara.productManagement.service;
import org.dromara.productManagement.domain.ContractualRes;
import org.dromara.productManagement.domain.bo.ContractualTasksBo;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;

3
zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/IDocumentTaskResultsService.java

@ -1,6 +1,7 @@
package org.dromara.productManagement.service;
import jakarta.servlet.http.HttpServletResponse;
import org.dromara.productManagement.domain.ContractualRes;
import org.dromara.productManagement.domain.vo.DocumentTaskResultsVo;
import org.dromara.productManagement.domain.bo.DocumentTaskResultsBo;
import org.dromara.common.mybatis.core.page.TableDataInfo;
@ -70,4 +71,6 @@ public interface IDocumentTaskResultsService {
DocumentTaskResultsVo queryByTaskId(String id);
void downloadResult(Long[] ids, HttpServletResponse response);
Boolean modifyContractReview(Long documentTaskGroupId, ContractualRes contractualRes);
}

82
zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/IJyjContractualTaskBatchService.java

@ -0,0 +1,82 @@
package org.dromara.productManagement.service;
import cn.hutool.core.io.resource.InputStreamResource;
import com.fasterxml.jackson.core.JsonProcessingException;
import jakarta.servlet.http.HttpServletResponse;
import org.dromara.productManagement.domain.ContractualRes;
import org.dromara.productManagement.domain.vo.JyjContractualTaskBatchVo;
import org.dromara.productManagement.domain.bo.JyjContractualTaskBatchBo;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.system.domain.vo.SysOssVo;
import org.springframework.http.ResponseEntity;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
/**
* 合同批处理记录Service接口
*
* @author Lion Li
* @date 2025-03-05
*/
public interface IJyjContractualTaskBatchService {
/**
* 查询合同批处理记录
*
* @param id 主键
* @return 合同批处理记录
*/
JyjContractualTaskBatchVo queryById(Long id);
/**
* 分页查询合同批处理记录列表
*
* @param bo 查询条件
* @param pageQuery 分页参数
* @return 合同批处理记录分页列表
*/
TableDataInfo<JyjContractualTaskBatchVo> queryPageList(JyjContractualTaskBatchBo bo, PageQuery pageQuery);
/**
* 查询符合条件的合同批处理记录列表
*
* @param bo 查询条件
* @return 合同批处理记录列表
*/
List<JyjContractualTaskBatchVo> queryList(JyjContractualTaskBatchBo bo);
/**
* 新增合同批处理记录
*
* @param bo 合同批处理记录
* @return 是否新增成功
*/
Boolean insertByBo(JyjContractualTaskBatchBo bo);
/**
* 修改合同批处理记录
*
* @param bo 合同批处理记录
* @return 是否修改成功
*/
Boolean updateByBo(JyjContractualTaskBatchBo bo);
/**
* 校验并批量删除合同批处理记录信息
*
* @param ids 待删除的主键集合
* @param isValid 是否进行有效性校验
* @return 是否删除成功
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
HashMap<String,String> uploadFile(MultipartFile file) throws IOException;
ContractualRes getContractulResultById(Long id) throws JsonProcessingException;
void getContractulPdf(Long id, HttpServletResponse response);
}

134
zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/impl/ContractualInfoServiceImpl.java

@ -0,0 +1,134 @@
package org.dromara.productManagement.service.impl;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
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.service.IContractualInfoService;
import org.springframework.stereotype.Service;
import org.dromara.productManagement.domain.bo.ContractualInfoBo;
import org.dromara.productManagement.domain.vo.ContractualInfoVo;
import org.dromara.productManagement.domain.ContractualInfo;
import org.dromara.productManagement.mapper.ContractualInfoMapper;
import java.util.List;
import java.util.Map;
import java.util.Collection;
/**
* 合同信息保存Service业务层处理
*
* @author Lion Li
* @date 2025-03-10
*/
@RequiredArgsConstructor
@Service
public class ContractualInfoServiceImpl implements IContractualInfoService {
private final ContractualInfoMapper baseMapper;
/**
* 查询合同信息保存
*
* @param id 主键
* @return 合同信息保存
*/
@Override
public ContractualInfoVo queryById(Long id){
return baseMapper.selectVoById(id);
}
/**
* 分页查询合同信息保存列表
*
* @param bo 查询条件
* @param pageQuery 分页参数
* @return 合同信息保存分页列表
*/
@Override
public TableDataInfo<ContractualInfoVo> queryPageList(ContractualInfoBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<ContractualInfo> lqw = buildQueryWrapper(bo);
Page<ContractualInfoVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
/**
* 查询符合条件的合同信息保存列表
*
* @param bo 查询条件
* @return 合同信息保存列表
*/
@Override
public List<ContractualInfoVo> queryList(ContractualInfoBo bo) {
LambdaQueryWrapper<ContractualInfo> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
private LambdaQueryWrapper<ContractualInfo> buildQueryWrapper(ContractualInfoBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<ContractualInfo> lqw = Wrappers.lambdaQuery();
lqw.like(StringUtils.isNotBlank(bo.getFileName()), ContractualInfo::getFileName, bo.getFileName());
lqw.like(StringUtils.isNotBlank(bo.getPurchaserName()), ContractualInfo::getPurchaserName, bo.getPurchaserName());
lqw.like(StringUtils.isNotBlank(bo.getSupplierName()), ContractualInfo::getSupplierName, bo.getSupplierName());
lqw.eq(bo.getSignDate() != null, ContractualInfo::getSignDate, bo.getSignDate());
lqw.eq(StringUtils.isNotBlank(bo.getContractAmount()), ContractualInfo::getContractAmount, bo.getContractAmount());
lqw.orderByDesc(ContractualInfo::getCreateTime);
return lqw;
}
/**
* 新增合同信息保存
*
* @param bo 合同信息保存
* @return 是否新增成功
*/
@Override
public Boolean insertByBo(ContractualInfoBo bo) {
ContractualInfo add = MapstructUtils.convert(bo, ContractualInfo.class);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setId(add.getId());
}
return flag;
}
/**
* 修改合同信息保存
*
* @param bo 合同信息保存
* @return 是否修改成功
*/
@Override
public Boolean updateByBo(ContractualInfoBo bo) {
ContractualInfo update = MapstructUtils.convert(bo, ContractualInfo.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}
/**
* 保存前的数据校验
*/
private void validEntityBeforeSave(ContractualInfo entity){
//TODO 做一些数据校验,如唯一约束
}
/**
* 校验并批量删除合同信息保存信息
*
* @param ids 待删除的主键集合
* @param isValid 是否进行有效性校验
* @return 是否删除成功
*/
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if(isValid){
//TODO 做一些业务上的校验,判断是否需要校验
}
return baseMapper.deleteByIds(ids) > 0;
}
}

18
zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/impl/ContractualTasksServiceImpl.java

@ -1,8 +1,10 @@
package org.dromara.productManagement.service.impl;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.dromara.common.core.service.DictService;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@ -93,9 +95,6 @@ public class ContractualTasksServiceImpl extends BaseTaskService<ContractualTask
.map(documentTasksVo -> {
ContractualTasksVo contractualTasksVo = new ContractualTasksVo();
BeanUtils.copyProperties(documentTasksVo, contractualTasksVo);
//查询合同角色
String contractPartyRole = contractualTaskSupplementService.queryContractPartyRole(documentTasksVo.getId());
contractualTasksVo.setContractPartyRole(contractPartyRole);
// 设置创建用户信息
Long createBy = contractualTasksVo.getCreateBy();
contractualTasksVo.setCreateUser(userService.selectUserById(createBy).getNickName());
@ -119,7 +118,17 @@ public class ContractualTasksServiceImpl extends BaseTaskService<ContractualTask
return TableDataInfo.build(result);
}
@Override
protected LambdaQueryWrapper<DocumentTasks> buildQueryWrapper(DocumentTasksBo bo) {
LambdaQueryWrapper<DocumentTasks> lqw = Wrappers.lambdaQuery();
lqw.like(StringUtils.isNotBlank(bo.getDocumentName()), DocumentTasks::getDocumentName, bo.getDocumentName());
lqw.like(StringUtils.isNotBlank(bo.getBatchName()), DocumentTasks::getBatchName, bo.getBatchName());
lqw.eq(StringUtils.isNotBlank(bo.getProgressStatus()), DocumentTasks::getProgressStatus, bo.getProgressStatus());
lqw.eq(StringUtils.isNotBlank(bo.getResultType()),DocumentTasks::getResultType, bo.getResultType());
lqw.orderByDesc(DocumentTasks::getUpdateTime);
lqw.orderByDesc(DocumentTasks::getProgressStatus);
return lqw;
}
/**
* 查询符合条件的合同任务列表
*
@ -196,6 +205,7 @@ public class ContractualTasksServiceImpl extends BaseTaskService<ContractualTask
}
@Override
protected void beforeTaskMessageSent(Long taskId, String taskName,ContractualTasksBo bo) {
String contractPartyRole = bo.getContractPartyRole();

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

@ -1,5 +1,6 @@
package org.dromara.productManagement.service.impl;
import com.alibaba.fastjson.JSON;
import com.lowagie.text.html.simpleparser.StyleSheet;
import com.lowagie.text.pdf.BaseFont;
import com.openhtmltopdf.pdfboxout.PdfRendererBuilder;
@ -20,8 +21,11 @@ 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.ContractualRes;
import org.dromara.productManagement.domain.DocumentTasks;
import org.dromara.productManagement.domain.vo.DocumentTasksVo;
import org.dromara.productManagement.enums.TaskEnum;
import org.dromara.productManagement.mapper.DocumentTasksMapper;
import org.dromara.productManagement.service.IDocumentTasksService;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
@ -56,6 +60,7 @@ import java.util.zip.ZipOutputStream;
public class DocumentTaskResultsServiceImpl implements IDocumentTaskResultsService {
private final DocumentTaskResultsMapper baseMapper;
private final DocumentTasksMapper documentTasksMapper;
private final IDocumentTasksService documentTasksService;
private final DictService dictTypeService;
@ -248,6 +253,27 @@ public class DocumentTaskResultsServiceImpl implements IDocumentTaskResultsServi
}
}
@Override
public Boolean modifyContractReview(Long documentTaskId, ContractualRes contractualRes) {
LambdaQueryWrapper<DocumentTaskResults> lqw = Wrappers.lambdaQuery();
lqw.eq(DocumentTaskResults::getDocumentTaskId, documentTaskId);
DocumentTaskResults results = baseMapper.selectOne(lqw);
int size=contractualRes.getResults().get(0).getContentList().size();
DocumentTasks documentTasks = new DocumentTasks();
documentTasks.setId(documentTaskId);
if(size>0){
documentTasks.setResultType("reviewFail");
}else{
documentTasks.setResultType("reviewSuccess");
}
documentTasksMapper.updateById(documentTasks);
// 使用 Jackson 或 Fastjson 将对象转换为 JSON 字符串
String jsonString = JSON.toJSONString(contractualRes);
results.setResultJson(results.getResult());
results.setResult(jsonString);
return baseMapper.updateById(results)>0;
}
// Markdown转PDF方法
private void convertMarkdownToPdf(String markdown, String outputPath) throws Exception {
// 使用flexmark-java解析Markdown

42
zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/impl/DocumentTasksServiceImpl.java

@ -122,6 +122,8 @@ public class DocumentTasksServiceImpl extends BaseTaskService implements IDocume
}
lqw.like(StringUtils.isNotBlank(bo.getDocumentName()), DocumentTasks::getDocumentName, bo.getDocumentName());
lqw.eq(StringUtils.isNotBlank(bo.getProgressStatus()), DocumentTasks::getProgressStatus, bo.getProgressStatus());
lqw.eq(StringUtils.isNotBlank(bo.getResultType()), DocumentTasks::getResultType, bo.getResultType());
lqw.eq(StringUtils.isNotBlank(bo.getBatchName()), DocumentTasks::getBatchName, bo.getBatchName());
lqw.orderByDesc(DocumentTasks::getCreateTime);
//分组,作为父项
lqw.groupBy(DocumentTasks::getDocumentName,
@ -236,26 +238,26 @@ public class DocumentTasksServiceImpl extends BaseTaskService implements IDocume
String destPath = destDir + File.separator + originalfileName;
File destFile = new File(destPath);
FileUtil.writeFromStream(file.getInputStream(), destFile);
if (!suffix.equals(".docx")) {
// ProcessBuilder builder = new ProcessBuilder("unoconv", "-o", destDir, "-f", "docx", destFile.getAbsolutePath());
ProcessBuilder builder = new ProcessBuilder("libreoffice", "--headless", "--convert-to", "docx",destPath, "--outdir", destDir);
Process process = builder.start();
int completed = process.waitFor();
if (completed != 0) {
InputStream errorStream = process.getErrorStream();
String errorMessage = new String(errorStream.readAllBytes());
process.destroyForcibly();
String failMsg = suffix + "转docx失败,可以尝试用WORD或WPS打开文件,另存为docx文件,再尝试上传。 错误信息: " + errorMessage;
throw new RuntimeException(failMsg);
} else {
process.destroyForcibly();
destPath = destPath.substring(0, destPath.lastIndexOf(".")) + ".docx";
}
}
//校验文件是否可用
if(!MyHttpUtils.sendFileCheckMessage(chatUrl + "/back/checkFile", destPath)){
throw new RuntimeException("文件无法正常打开。可以尝试用WORD或WPS打开文件,进行修复并另存,用另存的文件再做一次尝试。");
}
// if (!suffix.equals(".docx")) {
//// ProcessBuilder builder = new ProcessBuilder("unoconv", "-o", destDir, "-f", "docx", destFile.getAbsolutePath());
// ProcessBuilder builder = new ProcessBuilder("libreoffice", "--headless", "--convert-to", "docx",destPath, "--outdir", destDir);
// Process process = builder.start();
// int completed = process.waitFor();
// if (completed != 0) {
// InputStream errorStream = process.getErrorStream();
// String errorMessage = new String(errorStream.readAllBytes());
// process.destroyForcibly();
// String failMsg = suffix + "转docx失败,可以尝试用WORD或WPS打开文件,另存为docx文件,再尝试上传。 错误信息: " + errorMessage;
// throw new RuntimeException(failMsg);
// } else {
// process.destroyForcibly();
// destPath = destPath.substring(0, destPath.lastIndexOf(".")) + ".docx";
// }
// }
// //校验文件是否可用
// if(!MyHttpUtils.sendFileCheckMessage(chatUrl + "/back/checkFile", destPath)){
// throw new RuntimeException("文件无法正常打开。可以尝试用WORD或WPS打开文件,进行修复并另存,用另存的文件再做一次尝试。");
// }
SysOssVo upload = ossService.upload(new File(destPath));
return upload;
}

265
zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/impl/JyjContractualTaskBatchServiceImpl.java

@ -0,0 +1,265 @@
package org.dromara.productManagement.service.impl;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
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.*;
import org.dromara.productManagement.mapper.ContractualInfoMapper;
import org.dromara.productManagement.mapper.DocumentTaskResultsMapper;
import org.dromara.productManagement.mapper.DocumentTasksMapper;
import org.dromara.productManagement.utils.CompressedFileUtils;
import org.dromara.productManagement.utils.MyHttpUtils;
import org.dromara.productManagement.utils.MyTimeUtils;
import org.dromara.system.domain.vo.SysOssVo;
import org.dromara.system.service.ISysOssService;
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.web.multipart.MultipartFile;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* 合同批处理记录Service业务层处理
*
* @author Lion Li
* @date 2025-03-05
*/
@RequiredArgsConstructor
@Service
@Slf4j
public class JyjContractualTaskBatchServiceImpl implements IJyjContractualTaskBatchService {
private final JyjContractualTaskBatchMapper baseMapper;
protected final ISysOssService ossService;
private final DocumentTasksMapper documentTasksMapper;
private final DocumentTaskResultsMapper documentTaskResultsMapper;
private final ContractualInfoMapper contractualInfoMapper;
@Value("${chat.chatUrl}")
protected String chatUrl;
/**
* 查询合同批处理记录
*
* @param id 主键
* @return 合同批处理记录
*/
@Override
public JyjContractualTaskBatchVo queryById(Long id){
return baseMapper.selectVoById(id);
}
/**
* 分页查询合同批处理记录列表
*
* @param bo 查询条件
* @param pageQuery 分页参数
* @return 合同批处理记录分页列表
*/
@Override
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 -> {
//获取文件路径
Long id = vo.getId();
LambdaQueryWrapper<DocumentTasks> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(DocumentTasks::getGroupId, id);
List<DocumentTasks> documentTasksList = documentTasksMapper.selectList(wrapper);
//获取documentTasksList中最大的updateTime
Date maxUpdateTime = documentTasksList.stream().max(Comparator.comparing(DocumentTasks::getUpdateTime)).get().getUpdateTime();
String timeDifference = MyTimeUtils.formatTimeDifference(vo.getLatestTime(), maxUpdateTime);
vo.setProcessingTime(timeDifference);
//获取documentTasksList中最大的updateTime对应的documentTaskResults
});
return TableDataInfo.build(result);
}
/**
* 查询符合条件的合同批处理记录列表
*
* @param bo 查询条件
* @return 合同批处理记录列表
*/
@Override
public List<JyjContractualTaskBatchVo> queryList(JyjContractualTaskBatchBo bo) {
LambdaQueryWrapper<JyjContractualTaskBatch> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
private LambdaQueryWrapper<JyjContractualTaskBatch> buildQueryWrapper(JyjContractualTaskBatchBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<JyjContractualTaskBatch> lqw = Wrappers.lambdaQuery();
lqw.like(StringUtils.isNotBlank(bo.getDocumentName()), JyjContractualTaskBatch::getDocumentName, bo.getDocumentName());
lqw.eq(StringUtils.isNotBlank(bo.getProgressStatus()), JyjContractualTaskBatch::getProgressStatus, bo.getProgressStatus());
lqw.like(StringUtils.isNotBlank(bo.getBatchName()), JyjContractualTaskBatch::getBatchName, bo.getBatchName());
lqw.orderByDesc(JyjContractualTaskBatch::getCreateTime);
return lqw;
}
/**
* 新增合同批处理记录
*
* @param bo 合同批处理记录
* @return 是否新增成功
*/
@Override
public Boolean insertByBo(JyjContractualTaskBatchBo bo) {
JyjContractualTaskBatch add = MapstructUtils.convert(bo, JyjContractualTaskBatch.class);
//获取文件路径
SysOssVo fileInfo = ossService.getById(bo.getOssId());
String fileName = fileInfo.getOriginalName();
CompressedFileUtils.FileValidationResult fileValidationResult = CompressedFileUtils.processCompressedFileFromMinio(fileInfo);
int size = fileValidationResult.getValidFiles().size();
add.setDocumentName(fileName);
add.setTotalContracts(Long.valueOf(size));
//批次名称未填.系统填写
if(!StringUtils.isNotBlank(add.getBatchName())){
//查询当天的上传记录次数
// 使用数据库的日期函数进行比较(这里以MySQL为例)
LambdaQueryWrapper<JyjContractualTaskBatch> lqw = Wrappers.lambdaQuery();
lqw.apply("DATE(create_time) = CURRENT_DATE()");
Long count = baseMapper.selectCount(lqw);
count = count + 1;
// 格式化批次名称
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());
// 在插入数据库前调用扩展点
documentTasksMapper.insert(documentTasks);
// 在发送消息前调用扩展点
Long priority = 1L;
MyHttpUtils.sendTaskStartMessage(chatUrl + "/back/taskStart",
documentTasks.getId(), bo.getTaskName(), file.getAbsolutePath(), priority);
}
if (flag) {
bo.setId(add.getId());
}
return flag;
}
/**
* 修改合同批处理记录
*
* @param bo 合同批处理记录
* @return 是否修改成功
*/
@Override
public Boolean updateByBo(JyjContractualTaskBatchBo bo) {
JyjContractualTaskBatch update = MapstructUtils.convert(bo, JyjContractualTaskBatch.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}
/**
* 保存前的数据校验
*/
private void validEntityBeforeSave(JyjContractualTaskBatch entity){
//TODO 做一些数据校验,如唯一约束
}
/**
* 校验并批量删除合同批处理记录信息
*
* @param ids 待删除的主键集合
* @param isValid 是否进行有效性校验
* @return 是否删除成功
*/
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if(isValid){
//TODO 做一些业务上的校验,判断是否需要校验
}
return baseMapper.deleteByIds(ids) > 0;
}
@Override
public HashMap<String,String> uploadFile(MultipartFile file) throws IOException {
SysOssVo upload = ossService.upload(file);
HashMap<String,String> map = new HashMap<>();
map.put("url", upload.getUrl());
map.put("fileName", upload.getOriginalName());
map.put("ossId", upload.getOssId().toString());
CompressedFileUtils.FileStatistics stats = CompressedFileUtils.getFileStatistics(upload);
map.put("validFileCount", String.valueOf(stats.getValidFileCount()));
map.put("invalidFileCount", String.valueOf(stats.getInvalidFileCount()));
map.put("invalidFileNames", String.join(", ", stats.getInvalidFileNames()));
System.out.println("符合要求的文件数量: " + stats.getValidFileCount());
System.out.println("不符合要求的文件数量: " + stats.getInvalidFileCount());
System.out.println("不符合要求的文件列表: " + String.join(", ", stats.getInvalidFileNames()));
return map;
}
@Override
public ContractualRes getContractulResultById(Long id) throws JsonProcessingException {
LambdaQueryWrapper<DocumentTaskResults> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(DocumentTaskResults::getDocumentTaskId, id);
DocumentTaskResults documentTaskResults = documentTaskResultsMapper.selectOne(wrapper);
String result = documentTaskResults.getResult();
//json 字符串转ContractualRes
ObjectMapper mapper = new ObjectMapper();
ContractualRes response = mapper.readValue(result, new TypeReference<ContractualRes>() {});
return response;
}
@Override
public void getContractulPdf(Long id, HttpServletResponse response) {
// PDF文件的绝对路径
LambdaQueryWrapper<ContractualInfo> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(ContractualInfo::getTaskId, id);
ContractualInfo ContractualInfo = contractualInfoMapper.selectOne(wrapper);
String pdfPath = ContractualInfo.getFilePath();
String fileName = ContractualInfo.getFileName();
File file = new File(pdfPath);
if (!file.exists()) {
throw new RuntimeException("文件不存在");
}
response.setContentType("application/pdf");
response.setHeader("Content-Disposition", "inline; filename=" + fileName);
response.setContentLength((int) file.length());
try (FileInputStream inputStream = new FileInputStream(file);
OutputStream outputStream = response.getOutputStream()) {
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
outputStream.flush();
} catch (IOException e) {
throw new RuntimeException("文件读取失败", e);
}
}
}

351
zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/utils/CompressedFileUtils.java

@ -0,0 +1,351 @@
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.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.Enumeration;
import java.util.zip.ZipInputStream;
import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
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;
}
/**
* 处理ZIP文件
*/
// 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 = extractZipEntry(zip, entry, newExtractPath);
// result.addValidFile(extractedFile);
// } else {
// result.addWarning("跳过不支持的文件类型: " + entryName);
// }
// }
// }
// } catch (IOException e) {
// result.addWarning("处理ZIP文件时发生错误: " + e.getMessage());
// }
// }
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());
}
}
/**
* 解压ZIP文件条目
*/
// private static File extractZipEntry(ZipFile zipFile, ZipEntry entry, String extractPath) throws IOException {
// // 只获取文件名,不保留原目录结构
// String fileName = new File(entry.getName()).getName();
// File outputFile = new File(extractPath, fileName);
// createParentDirectories(outputFile);
//
// try (InputStream inputStream = zipFile.getInputStream(entry);
// FileOutputStream outputStream = new FileOutputStream(outputFile)) {
// copyStream(inputStream, outputStream);
// }
// return outputFile;
// }
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");
}
}

152
zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/utils/ZipFileUtils.java

@ -0,0 +1,152 @@
package org.dromara.productManagement.utils;
import java.io.*;
import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.function.Consumer;
public class ZipFileUtils {
/**
* ZIP文件处理结果类
*/
public static class ZipProcessResult {
private Map<String, byte[]> validFiles;
private List<String> invalidFiles;
public ZipProcessResult(Map<String, byte[]> validFiles, List<String> invalidFiles) {
this.validFiles = validFiles;
this.invalidFiles = invalidFiles;
}
public Map<String, byte[]> getValidFiles() {
return validFiles;
}
public List<String> getInvalidFiles() {
return invalidFiles;
}
public int getValidFileCount() {
return validFiles.size();
}
public int getInvalidFileCount() {
return invalidFiles.size();
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("符合要求的文件:\n");
validFiles.keySet().forEach(file -> sb.append("- ").append(file)
.append(" (大小: ").append(validFiles.get(file).length).append(" bytes)\n"));
sb.append("\n不符合要求的文件:\n");
invalidFiles.forEach(file -> sb.append("- ").append(file).append("\n"));
sb.append("\n统计信息:\n");
sb.append("符合要求的文件数量: ").append(getValidFileCount()).append("\n");
sb.append("不符合要求的文件数量: ").append(getInvalidFileCount());
return sb.toString();
}
}
/**
* 处理ZIP文件获取其中的PDF和OFD文件内容
*
* @param zipFilePath ZIP文件路径
* @return 处理结果对象
* @throws IOException 如果文件处理过程中发生错误
*/
public static ZipProcessResult processZipFile(String zipFilePath) throws IOException {
Map<String, byte[]> validFiles = new HashMap<>();
List<String> invalidFiles = new ArrayList<>();
try (ZipFile zipFile = new ZipFile(new File(zipFilePath))) {
Enumeration<? extends ZipEntry> entries = zipFile.entries();
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
if (!entry.isDirectory()) {
if (isValidFileType(entry.getName())) {
// 读取文件内容到内存
byte[] content = readEntryContent(zipFile, entry);
validFiles.put(entry.getName(), content);
} else {
invalidFiles.add(entry.getName());
}
}
}
}
return new ZipProcessResult(validFiles, invalidFiles);
}
/**
* 处理ZIP文件中的有效文件使用回调函数处理每个文件
*
* @param zipFilePath ZIP文件路径
* @param fileProcessor 文件处理器
* @throws IOException 如果文件处理过程中发生错误
*/
public static void processValidFiles(String zipFilePath,
FileProcessor fileProcessor) throws IOException {
try (ZipFile zipFile = new ZipFile(new File(zipFilePath))) {
Enumeration<? extends ZipEntry> entries = zipFile.entries();
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
if (!entry.isDirectory() && isValidFileType(entry.getName())) {
try (InputStream is = zipFile.getInputStream(entry)) {
fileProcessor.process(entry.getName(), is);
}
}
}
}
}
/**
* 文件处理器接口
*/
@FunctionalInterface
public interface FileProcessor {
void process(String fileName, InputStream content) throws IOException;
}
/**
* 读取ZIP条目的内容
*/
private static byte[] readEntryContent(ZipFile zipFile, ZipEntry entry) throws IOException {
try (InputStream is = zipFile.getInputStream(entry)) {
return is.readAllBytes();
}
}
/**
* 检查文件是否为PDF或OFD格式
*/
private static boolean isValidFileType(String fileName) {
fileName = fileName.toLowerCase();
return fileName.endsWith(".pdf") || fileName.endsWith(".ofd");
}
/**
* 保存处理结果中的有效文件到指定目录
*/
public static void saveValidFiles(ZipProcessResult result, String outputDir) throws IOException {
File dir = new File(outputDir);
if (!dir.exists()) {
dir.mkdirs();
}
for (Map.Entry<String, byte[]> entry : result.getValidFiles().entrySet()) {
File outputFile = new File(dir, new File(entry.getKey()).getName());
try (FileOutputStream fos = new FileOutputStream(outputFile)) {
fos.write(entry.getValue());
}
}
}
}

7
zaojiaManagement/zaojia-productManagement/src/main/resources/mapper/productManagement/ContractualInfoMapper.xml

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.dromara.productManagement.mapper.ContractualInfoMapper">
</mapper>

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

@ -0,0 +1,51 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
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">
SELECT
b.id AS id,
b.document_name AS document_name,
b.batch_name AS batch_name,
b.total_contracts AS total_contracts,
MAX(fr.create_time) as latest_time,
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>
<if test="bo.documentName!= null and 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}, '%')
</if>
</where>
GROUP BY
b.id,b.document_name, b.batch_name, b.total_contracts
<if test="bo.progressStatus != null and bo.progressStatus != ''">
having
progress_status=#{bo.progressStatus}
</if>
ORDER BY b.create_time DESC
</select>
</mapper>
Loading…
Cancel
Save