From 2ba6ec8790d7eb5dc13f6451dce0068afe5d95a3 Mon Sep 17 00:00:00 2001 From: zhouhaibin Date: Fri, 6 Jun 2025 11:13:09 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=90=88=E5=90=8C=E6=B3=95?= =?UTF-8?q?=E8=A7=84=E5=92=8C=E5=90=88=E5=90=8C=E6=A8=A1=E6=9D=BF=E5=90=8E?= =?UTF-8?q?=E7=AB=AF=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/resources/application-dev.yml | 2 +- .../src/main/resources/application.yml | 2 +- .../zaojia-productManagement/pom.xml | 7 + .../common/service/AbstractTaskProcessor.java | 4 +- .../ContractualCaseFilesController.java | 140 ++++ ...ntractualRegulationArticlesController.java | 105 +++ .../ContractualRegulationNamesController.java | 138 ++++ .../domain/ContractualCaseArticles.java | 56 ++ .../domain/ContractualCaseFiles.java | 66 ++ .../domain/ContractualRegulationArticles.java | 57 ++ .../domain/ContractualRegulationNames.java | 61 ++ .../domain/StartContractReviewRequest.java | 17 +- .../domain/bo/ContractualCaseFilesBo.java | 82 +++ .../bo/ContractualRegulationArticlesBo.java | 52 ++ .../bo/ContractualRegulationNamesBo.java | 71 ++ .../domain/vo/ContractualCaseArticlesVo.java | 60 ++ .../domain/vo/ContractualCaseFilesVo.java | 79 +++ .../vo/ContractualRegulationArticlesVo.java | 63 ++ .../vo/ContractualRegulationNamesVo.java | 66 ++ .../mapper/ContractualCaseArticlesMapper.java | 23 + .../mapper/ContractualCaseFilesMapper.java | 23 + .../ContractualRegulationArticlesMapper.java | 24 + .../ContractualRegulationNamesMapper.java | 38 + .../service/IContractualCaseFilesService.java | 96 +++ ...IContractualRegulationArticlesService.java | 68 ++ .../IContractualRegulationNamesService.java | 95 +++ .../impl/ContractualCaseFilesServiceImpl.java | 671 ++++++++++++++++++ ...tractualRegulationArticlesServiceImpl.java | 272 +++++++ ...ContractualRegulationNamesServiceImpl.java | 640 +++++++++++++++++ .../impl/ContractualTasksServiceImpl.java | 82 ++- .../ContractualCaseArticlesMapper.xml | 32 + .../ContractualCaseFilesMapper.xml | 34 + .../ContractualRegulationArticlesMapper.xml | 7 + .../ContractualRegulationNamesMapper.xml | 7 + 34 files changed, 3195 insertions(+), 45 deletions(-) create mode 100644 zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/controller/ContractualCaseFilesController.java create mode 100644 zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/controller/ContractualRegulationArticlesController.java create mode 100644 zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/controller/ContractualRegulationNamesController.java create mode 100644 zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/ContractualCaseArticles.java create mode 100644 zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/ContractualCaseFiles.java create mode 100644 zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/ContractualRegulationArticles.java create mode 100644 zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/ContractualRegulationNames.java create mode 100644 zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/bo/ContractualCaseFilesBo.java create mode 100644 zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/bo/ContractualRegulationArticlesBo.java create mode 100644 zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/bo/ContractualRegulationNamesBo.java create mode 100644 zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/vo/ContractualCaseArticlesVo.java create mode 100644 zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/vo/ContractualCaseFilesVo.java create mode 100644 zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/vo/ContractualRegulationArticlesVo.java create mode 100644 zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/vo/ContractualRegulationNamesVo.java create mode 100644 zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/mapper/ContractualCaseArticlesMapper.java create mode 100644 zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/mapper/ContractualCaseFilesMapper.java create mode 100644 zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/mapper/ContractualRegulationArticlesMapper.java create mode 100644 zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/mapper/ContractualRegulationNamesMapper.java create mode 100644 zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/IContractualCaseFilesService.java create mode 100644 zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/IContractualRegulationArticlesService.java create mode 100644 zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/IContractualRegulationNamesService.java create mode 100644 zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/impl/ContractualCaseFilesServiceImpl.java create mode 100644 zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/impl/ContractualRegulationArticlesServiceImpl.java create mode 100644 zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/impl/ContractualRegulationNamesServiceImpl.java create mode 100644 zaojiaManagement/zaojia-productManagement/src/main/resources/mapper/productManagement/ContractualCaseArticlesMapper.xml create mode 100644 zaojiaManagement/zaojia-productManagement/src/main/resources/mapper/productManagement/ContractualCaseFilesMapper.xml create mode 100644 zaojiaManagement/zaojia-productManagement/src/main/resources/mapper/productManagement/ContractualRegulationArticlesMapper.xml create mode 100644 zaojiaManagement/zaojia-productManagement/src/main/resources/mapper/productManagement/ContractualRegulationNamesMapper.xml diff --git a/ruoyi-admin/src/main/resources/application-dev.yml b/ruoyi-admin/src/main/resources/application-dev.yml index 68a33e9..e69ccbc 100644 --- a/ruoyi-admin/src/main/resources/application-dev.yml +++ b/ruoyi-admin/src/main/resources/application-dev.yml @@ -53,7 +53,7 @@ spring: # username: root # password: root url: jdbc:mysql://10.1.21.250:3306/aitesttable?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://218.0.1.42:53306/aitesttable?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&:(' # 从库数据源 diff --git a/ruoyi-admin/src/main/resources/application.yml b/ruoyi-admin/src/main/resources/application.yml index df85507..c820c68 100644 --- a/ruoyi-admin/src/main/resources/application.yml +++ b/ruoyi-admin/src/main/resources/application.yml @@ -71,7 +71,7 @@ spring: basename: i18n/messages profiles: #@profiles.active@ - active: test + active: dev # 文件上传 servlet: multipart: diff --git a/zaojiaManagement/zaojia-productManagement/pom.xml b/zaojiaManagement/zaojia-productManagement/pom.xml index c270600..1a87807 100644 --- a/zaojiaManagement/zaojia-productManagement/pom.xml +++ b/zaojiaManagement/zaojia-productManagement/pom.xml @@ -116,6 +116,13 @@ flying-saucer-pdf 9.1.22 + + + + io.milvus + milvus-sdk-java + 2.3.4 + diff --git a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/common/service/AbstractTaskProcessor.java b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/common/service/AbstractTaskProcessor.java index bb26850..50f2efc 100644 --- a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/common/service/AbstractTaskProcessor.java +++ b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/common/service/AbstractTaskProcessor.java @@ -114,10 +114,10 @@ public abstract class AbstractTaskProcessor implements public FileProcessResult processFile(Long ossId) throws IOException, InterruptedException { SysOssVo fileInfo = ossService.getById(ossId); String fileName = fileInfo.getOriginalName(); - String filePath = fileRootPath + fileInfo.getFileName(); + String filePath = fileRootPath + File.separator +fileInfo.getFileName(); // 处理文件转换 - if(!fileName.toLowerCase().endsWith(".docx")) { + if(fileName.toLowerCase().endsWith(".doc")) { filePath = convertToDocx(filePath, fileName); } diff --git a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/controller/ContractualCaseFilesController.java b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/controller/ContractualCaseFilesController.java new file mode 100644 index 0000000..de48122 --- /dev/null +++ b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/controller/ContractualCaseFilesController.java @@ -0,0 +1,140 @@ +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.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.ContractualCaseFilesVo; +import org.dromara.productManagement.domain.vo.ContractualCaseArticlesVo; +import org.dromara.productManagement.domain.bo.ContractualCaseFilesBo; +import org.dromara.productManagement.service.IContractualCaseFilesService; +import org.dromara.common.mybatis.core.page.TableDataInfo; + +/** + * 合同案例文件 + * + * @author Lion Li + * @date 2025-06-04 + */ +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/productManagement/ContractualCaseFiles") +public class ContractualCaseFilesController extends BaseController { + + private final IContractualCaseFilesService contractualCaseFilesService; + + /** + * 查询合同案例文件列表 + */ + @SaCheckPermission("productManagement:ContractualCaseFiles:list") + @GetMapping("/list") + public TableDataInfo list(ContractualCaseFilesBo bo, PageQuery pageQuery) { + return contractualCaseFilesService.queryPageList(bo, pageQuery); + } + + /** + * 导出合同案例文件列表 + */ + @SaCheckPermission("productManagement:ContractualCaseFiles:export") + @Log(title = "合同案例文件", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(ContractualCaseFilesBo bo, HttpServletResponse response) { + List list = contractualCaseFilesService.queryList(bo); + ExcelUtil.exportExcel(list, "合同案例文件", ContractualCaseFilesVo.class, response); + } + + /** + * 获取合同案例文件详细信息 + */ + @SaCheckPermission("productManagement:ContractualCaseFiles:query") + @GetMapping("/{id}") + public R getInfo(@NotNull(message = "主键不能为空") + @PathVariable Long id) { + return R.ok(contractualCaseFilesService.queryById(id)); + } + + /** + * 新增合同案例文件 + */ + @SaCheckPermission("productManagement:ContractualCaseFiles:add") + @Log(title = "合同案例文件", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping() + public R add(@Validated(AddGroup.class) @RequestBody ContractualCaseFilesBo bo) { + // 设置默认状态为待解析 + if (bo.getProgressStatus() == null) { + bo.setProgressStatus("PENDING"); + } + return toAjax(contractualCaseFilesService.insertByBo(bo)); + } + + /** + * 修改合同案例文件 + */ + @SaCheckPermission("productManagement:ContractualCaseFiles:edit") + @Log(title = "合同案例文件", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PutMapping() + public R edit(@Validated(EditGroup.class) @RequestBody ContractualCaseFilesBo bo) { + return toAjax(contractualCaseFilesService.updateByBo(bo)); + } + + /** + * 更新合同案例文件状态 + */ + @SaCheckPermission("productManagement:ContractualCaseFiles:edit") + @Log(title = "合同案例文件状态更新", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PutMapping("/updateStatus") + public R updateStatus(@RequestBody ContractualCaseFilesBo bo) { + return toAjax(contractualCaseFilesService.updateStatusById(bo.getId(), bo.getIsEffective())); + } + + /** + * 删除合同案例文件 + */ + @SaCheckPermission("productManagement:ContractualCaseFiles:remove") + @Log(title = "合同案例文件", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public R remove(@NotEmpty(message = "主键不能为空") + @PathVariable Long[] ids) { + return toAjax(contractualCaseFilesService.deleteWithValidByIds(List.of(ids), true)); + } + + /** + * 获取案例条款列表 + */ + @SaCheckPermission("productManagement:ContractualCaseFiles:query") + @GetMapping("/articles/{id}") + public R> getArticles(@NotNull(message = "案例文件ID不能为空") + @PathVariable Long id) { + List articles = contractualCaseFilesService.getCaseArticles(id); + return R.ok(articles); + } + + /** + * 生成案例PDF文档(查看详情) + */ + @SaCheckPermission("productManagement:ContractualCaseFiles:query") + @GetMapping("/view/{id}") + public void viewPdf(@NotNull(message = "案例文件ID不能为空") + @PathVariable Long id, + HttpServletResponse response) { + contractualCaseFilesService.generateCasePdf(id, response); + } + +} \ No newline at end of file diff --git a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/controller/ContractualRegulationArticlesController.java b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/controller/ContractualRegulationArticlesController.java new file mode 100644 index 0000000..be59018 --- /dev/null +++ b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/controller/ContractualRegulationArticlesController.java @@ -0,0 +1,105 @@ +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.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.ContractualRegulationArticlesVo; +import org.dromara.productManagement.domain.bo.ContractualRegulationArticlesBo; +import org.dromara.productManagement.service.IContractualRegulationArticlesService; +import org.dromara.common.mybatis.core.page.TableDataInfo; + +/** + * 合同法规法条 + * + * @author Lion Li + * @date 2025-06-05 + */ +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/productManagement/regulationArticles") +public class ContractualRegulationArticlesController extends BaseController { + + private final IContractualRegulationArticlesService contractualRegulationArticlesService; + + /** + * 查询合同法规法条列表 + */ + @SaCheckPermission("productManagement:regulationArticles:list") + @GetMapping("/list") + public TableDataInfo list(ContractualRegulationArticlesBo bo, PageQuery pageQuery) { + return contractualRegulationArticlesService.queryPageList(bo, pageQuery); + } + + /** + * 导出合同法规法条列表 + */ + @SaCheckPermission("productManagement:regulationArticles:export") + @Log(title = "合同法规法条", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(ContractualRegulationArticlesBo bo, HttpServletResponse response) { + List list = contractualRegulationArticlesService.queryList(bo); + ExcelUtil.exportExcel(list, "合同法规法条", ContractualRegulationArticlesVo.class, response); + } + + /** + * 获取合同法规法条详细信息 + * + * @param id 主键 + */ + @SaCheckPermission("productManagement:regulationArticles:query") + @GetMapping("/{id}") + public R getInfo(@NotNull(message = "主键不能为空") + @PathVariable Long id) { + return R.ok(contractualRegulationArticlesService.queryById(id)); + } + + /** + * 新增合同法规法条 + */ + @SaCheckPermission("productManagement:regulationArticles:add") + @Log(title = "合同法规法条", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping() + public R add(@Validated(AddGroup.class) @RequestBody ContractualRegulationArticlesBo bo) { + return toAjax(contractualRegulationArticlesService.insertByBo(bo)); + } + + /** + * 修改合同法规法条 + */ + @SaCheckPermission("productManagement:regulationArticles:edit") + @Log(title = "合同法规法条", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PutMapping() + public R edit(@Validated(EditGroup.class) @RequestBody ContractualRegulationArticlesBo bo) { + return toAjax(contractualRegulationArticlesService.updateByBo(bo)); + } + + /** + * 删除合同法规法条 + * + * @param ids 主键串 + */ + @SaCheckPermission("productManagement:regulationArticles:remove") + @Log(title = "合同法规法条", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public R remove(@NotEmpty(message = "主键不能为空") + @PathVariable Long[] ids) { + return toAjax(contractualRegulationArticlesService.deleteWithValidByIds(List.of(ids), true)); + } +} diff --git a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/controller/ContractualRegulationNamesController.java b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/controller/ContractualRegulationNamesController.java new file mode 100644 index 0000000..302758d --- /dev/null +++ b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/controller/ContractualRegulationNamesController.java @@ -0,0 +1,138 @@ +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.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.ContractualRegulationNamesVo; +import org.dromara.productManagement.domain.bo.ContractualRegulationNamesBo; +import org.dromara.productManagement.service.IContractualRegulationNamesService; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.productManagement.domain.vo.ContractualRegulationArticlesVo; + +/** + * 合同法规名称 + * + * @author Lion Li + * @date 2025-06-04 + */ +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/productManagement/ContractualRegulationNames") +public class ContractualRegulationNamesController extends BaseController { + + private final IContractualRegulationNamesService contractualRegulationNamesService; + + /** + * 查询合同法规名称列表 + */ + @SaCheckPermission("productManagement:ContractualRegulationNames:list") + @GetMapping("/list") + public TableDataInfo list(ContractualRegulationNamesBo bo, PageQuery pageQuery) { + return contractualRegulationNamesService.queryPageList(bo, pageQuery); + } + + /** + * 导出合同法规名称列表 + */ + @SaCheckPermission("productManagement:ContractualRegulationNames:export") + @Log(title = "合同法规名称", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(ContractualRegulationNamesBo bo, HttpServletResponse response) { + List list = contractualRegulationNamesService.queryList(bo); + ExcelUtil.exportExcel(list, "合同法规名称", ContractualRegulationNamesVo.class, response); + } + + /** + * 获取合同法规名称详细信息 + * + * @param id 主键 + */ + @SaCheckPermission("productManagement:ContractualRegulationNames:query") + @GetMapping("/{id}") + public R getInfo(@NotNull(message = "主键不能为空") + @PathVariable Long id) { + return R.ok(contractualRegulationNamesService.queryById(id)); + } + + /** + * 新增合同法规名称 + */ + @SaCheckPermission("productManagement:ContractualRegulationNames:add") + @Log(title = "合同法规名称", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping() + public R add(@Validated(AddGroup.class) @RequestBody ContractualRegulationNamesBo bo) { + // 设置默认状态为待解析 + if (bo.getProgressStatus() == null) { + bo.setProgressStatus("PENDING"); + } + return toAjax(contractualRegulationNamesService.insertByBo(bo)); + } + + /** + * 更新合同法规名称状态 + */ + @SaCheckPermission("productManagement:ContractualRegulationNames:edit") + @Log(title = "合同法规名称状态更新", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PutMapping("/updateStatus") + public R updateStatus(@RequestBody ContractualRegulationNamesBo bo) { + return toAjax(contractualRegulationNamesService.updateStatusById(bo.getId(), bo.getIsEffective())); + } + + /** + * 修改合同法规名称 + */ + @SaCheckPermission("productManagement:ContractualRegulationNames:edit") + @Log(title = "合同法规名称", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PutMapping() + public R edit(@Validated(EditGroup.class) @RequestBody ContractualRegulationNamesBo bo) { + return toAjax(contractualRegulationNamesService.updateByBo(bo)); + } + + /** + * 删除合同法规名称 + * + * @param ids 主键串 + */ + @SaCheckPermission("productManagement:ContractualRegulationNames:remove") + @Log(title = "合同法规名称", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public R remove(@NotEmpty(message = "主键不能为空") + @PathVariable Long[] ids) { + return toAjax(contractualRegulationNamesService.deleteWithValidByIds(List.of(ids), true)); + } + + /** + * 查看法规详情(生成PDF) + */ + @GetMapping("/view/{id}") + public void viewRegulationDetail(@PathVariable Long id, HttpServletResponse response) { + contractualRegulationNamesService.generateRegulationPdf(id, response); + } + + /** + * 获取法规条款列表 + */ + @GetMapping("/articles/{id}") + public R> getRegulationArticles(@PathVariable Long id) { + List articles = contractualRegulationNamesService.getRegulationArticles(id); + return R.ok(articles); + } +} diff --git a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/ContractualCaseArticles.java b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/ContractualCaseArticles.java new file mode 100644 index 0000000..b943504 --- /dev/null +++ b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/ContractualCaseArticles.java @@ -0,0 +1,56 @@ +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.io.Serial; + +/** + * 合同案例条款对象 contractual_case_articles + * + * @author Lion Li + * @date 2025-06-05 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("contractual_case_articles") +public class ContractualCaseArticles extends TenantEntity { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键ID + */ + @TableId(value = "id") + private Long id; + + /** + * 合同案例文件表ID + */ + private Long caseFileId; + + /** + * 条款内容 + */ + private String articleContent; + + /** + * 向量表ID + */ + private Long vectorTableId; + + /** + * 是否有效(1:有效 0:无效) + */ + private String isEffective; + + /** + * 删除标志(0代表存在 2代表删除) + */ + @TableLogic + private String delFlag; + +} \ No newline at end of file diff --git a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/ContractualCaseFiles.java b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/ContractualCaseFiles.java new file mode 100644 index 0000000..ac8aeec --- /dev/null +++ b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/ContractualCaseFiles.java @@ -0,0 +1,66 @@ +package org.dromara.productManagement.domain; + +import org.dromara.common.mybatis.core.domain.BaseEntity; +import com.baomidou.mybatisplus.annotation.*; +import lombok.Data; +import lombok.EqualsAndHashCode; +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; + +import java.io.Serial; + +/** + * 合同案例文件对象 contractual_case_files + * + * @author Lion Li + * @date 2025-06-04 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("contractual_case_files") +public class ContractualCaseFiles extends BaseEntity { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键ID + */ + @TableId(value = "id") + private Long id; + + /** + * 案例名称 + */ + private String caseName; + + /** + * 案例描述 + */ + private String caseDescription; + + /** + * 案例类型 + */ + private String caseType; + + /** + * 发布日期 + */ + private Date publishDate; + + /** + * 是否有效(Y:有效 N:无效) + */ + private String isEffective; + + /** + * 删除标志(0代表存在 2代表删除) + */ + @TableLogic + private String delFlag; + + private String progressStatus; + private Long ossId; + +} \ No newline at end of file diff --git a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/ContractualRegulationArticles.java b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/ContractualRegulationArticles.java new file mode 100644 index 0000000..53bfadb --- /dev/null +++ b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/ContractualRegulationArticles.java @@ -0,0 +1,57 @@ +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.io.Serial; + +/** + * 合同法规法条对象 contractual_regulation_articles + * + * @author Lion Li + * @date 2025-06-05 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("contractual_regulation_articles") +public class ContractualRegulationArticles extends TenantEntity { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键ID + */ + @TableId(value = "id") + private Long id; + + /** + * 合同法规名称表ID + */ + private Long regulationNameId; + + /** + * 法条内容 + */ + private String articleContent; + + /** + * 向量表ID + */ + private Long vectorTableId; + + /** + * 是否有效(1:有效 0:无效) + */ + private String isEffective; + + /** + * 删除标志(0代表存在 2代表删除) + */ + @TableLogic + private String delFlag; + + +} diff --git a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/ContractualRegulationNames.java b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/ContractualRegulationNames.java new file mode 100644 index 0000000..12e3893 --- /dev/null +++ b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/ContractualRegulationNames.java @@ -0,0 +1,61 @@ +package org.dromara.productManagement.domain; + +import org.dromara.common.mybatis.core.domain.BaseEntity; +import com.baomidou.mybatisplus.annotation.*; +import lombok.Data; +import lombok.EqualsAndHashCode; +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; + +import java.io.Serial; + +/** + * 合同法规名称对象 contractual_regulation_names + * + * @author Lion Li + * @date 2025-06-04 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("contractual_regulation_names") +public class ContractualRegulationNames extends BaseEntity { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键ID + */ + @TableId(value = "id") + private Long id; + + /** + * 法规名称 + */ + private String regulationName; + + /** + * 法规描述 + */ + private String regulationDescription; + + /** + * 发布日期 + */ + private Date publishDate; + + /** + * 是否有效(Y:有效 N:无效) + */ + private String isEffective; + + /** + * 删除标志(0代表存在 2代表删除) + */ + @TableLogic + private String delFlag; + + private String progressStatus; + private Long ossId; + +} diff --git a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/StartContractReviewRequest.java b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/StartContractReviewRequest.java index 68c3f32..7e9ca70 100644 --- a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/StartContractReviewRequest.java +++ b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/StartContractReviewRequest.java @@ -1,4 +1,4 @@ -package org.dromara.productManagement.domain; + package org.dromara.productManagement.domain; import lombok.Data; import java.util.List; @@ -116,23 +116,18 @@ public class StartContractReviewRequest { @Data public static class ConsistencyData { /** - * 文件类型 + * 招投标文件OSS ID */ - private List fileTypes; + private String bidDocumentOssId; /** - * 检查维度 + * 招投标文件路径(由后端根据ossId转换得到) */ - private List dimensions; - - /** - * 偏差级别 - */ - private String deviationLevel; + private String bidDocumentPath; /** * 特别说明 */ private String specialNote; } -} +} \ No newline at end of file diff --git a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/bo/ContractualCaseFilesBo.java b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/bo/ContractualCaseFilesBo.java new file mode 100644 index 0000000..e2a2924 --- /dev/null +++ b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/bo/ContractualCaseFilesBo.java @@ -0,0 +1,82 @@ +package org.dromara.productManagement.domain.bo; + +import org.dromara.productManagement.domain.ContractualCaseFiles; +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; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.springframework.format.annotation.DateTimeFormat; + +/** + * 合同案例文件业务对象 contractual_case_files + * + * @author Lion Li + * @date 2025-06-04 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@AutoMapper(target = ContractualCaseFiles.class, reverseConvertGenerate = false) +public class ContractualCaseFilesBo extends BaseEntity { + + /** + * 主键ID + */ + @NotNull(message = "主键ID不能为空", groups = { EditGroup.class }) + private Long id; + + /** + * 案例名称 + */ + @NotBlank(message = "案例名称不能为空", groups = { AddGroup.class, EditGroup.class }) + private String caseName; + + /** + * 案例描述 + */ + private String caseDescription; + + /** + * 案例类型 + */ + private String caseType; + + /** + * 发布日期 + */ + @JsonFormat(pattern = "yyyy-MM-dd") + @DateTimeFormat(pattern = "yyyy-MM-dd") + private Date publishDate; + + /** + * 发布日期查询开始时间 + */ + @DateTimeFormat(pattern = "yyyy-MM-dd") + private Date publishDateStart; + + /** + * 发布日期查询结束时间 + */ + @DateTimeFormat(pattern = "yyyy-MM-dd") + private Date publishDateEnd; + + /** + * 是否有效(Y:有效 N:无效) + */ + private String isEffective; + + /** + * 处理状态 + */ + private String progressStatus; + + /** + * OSS文件ID + */ + private Long ossId; + +} \ No newline at end of file diff --git a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/bo/ContractualRegulationArticlesBo.java b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/bo/ContractualRegulationArticlesBo.java new file mode 100644 index 0000000..5be487f --- /dev/null +++ b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/bo/ContractualRegulationArticlesBo.java @@ -0,0 +1,52 @@ +package org.dromara.productManagement.domain.bo; + +import org.dromara.productManagement.domain.ContractualRegulationArticles; +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.*; + +/** + * 合同法规法条业务对象 contractual_regulation_articles + * + * @author Lion Li + * @date 2025-06-05 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@AutoMapper(target = ContractualRegulationArticles.class, reverseConvertGenerate = false) +public class ContractualRegulationArticlesBo extends BaseEntity { + + /** + * 主键ID + */ + @NotNull(message = "主键ID不能为空", groups = { EditGroup.class }) + private Long id; + + /** + * 合同法规名称表ID + */ + @NotNull(message = "合同法规名称表ID不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long regulationNameId; + + /** + * 法条内容 + */ + @NotBlank(message = "法条内容不能为空", groups = { AddGroup.class, EditGroup.class }) + private String articleContent; + + /** + * 向量表ID + */ + private Long vectorTableId; + + /** + * 是否有效(1:有效 0:无效) + */ + private String isEffective; + + +} diff --git a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/bo/ContractualRegulationNamesBo.java b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/bo/ContractualRegulationNamesBo.java new file mode 100644 index 0000000..7b12fc2 --- /dev/null +++ b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/bo/ContractualRegulationNamesBo.java @@ -0,0 +1,71 @@ +package org.dromara.productManagement.domain.bo; + +import org.dromara.productManagement.domain.ContractualRegulationNames; +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; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.springframework.format.annotation.DateTimeFormat; + +/** + * 合同法规名称业务对象 contractual_regulation_names + * + * @author Lion Li + * @date 2025-06-04 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@AutoMapper(target = ContractualRegulationNames.class, reverseConvertGenerate = false) +public class ContractualRegulationNamesBo extends BaseEntity { + + /** + * 主键ID + */ + private Long id; + + /** + * 法规名称 + */ + @NotBlank(message = "法规名称不能为空", groups = { AddGroup.class, EditGroup.class }) + private String regulationName; + + /** + * 法规描述 + */ + @NotBlank(message = "法规描述不能为空", groups = { AddGroup.class, EditGroup.class }) + private String regulationDescription; + + /** + * 发布日期 + */ + @NotNull(message = "发布日期不能为空", groups = { AddGroup.class, EditGroup.class }) + @JsonFormat(pattern = "yyyy-MM-dd") + @DateTimeFormat(pattern = "yyyy-MM-dd") + private Date publishDate; + + /** + * 发布日期查询开始时间 + */ + @DateTimeFormat(pattern = "yyyy-MM-dd") + private Date publishDateStart; + + /** + * 发布日期查询结束时间 + */ + @DateTimeFormat(pattern = "yyyy-MM-dd") + private Date publishDateEnd; + + /** + * 是否有效(Y:有效 N:无效) + */ + private String isEffective; + + private String progressStatus; + + private Long ossId; +} diff --git a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/vo/ContractualCaseArticlesVo.java b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/vo/ContractualCaseArticlesVo.java new file mode 100644 index 0000000..95fef04 --- /dev/null +++ b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/vo/ContractualCaseArticlesVo.java @@ -0,0 +1,60 @@ +package org.dromara.productManagement.domain.vo; + +import org.dromara.productManagement.domain.ContractualCaseArticles; +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; + +/** + * 合同案例条款视图对象 contractual_case_articles + * + * @author Lion Li + * @date 2025-06-05 + */ +@Data +@ExcelIgnoreUnannotated +@AutoMapper(target = ContractualCaseArticles.class) +public class ContractualCaseArticlesVo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键ID + */ + @ExcelProperty(value = "主键ID") + private Long id; + + /** + * 合同案例文件表ID + */ + @ExcelProperty(value = "合同案例文件表ID") + private Long caseFileId; + + /** + * 条款内容 + */ + @ExcelProperty(value = "条款内容") + private String articleContent; + + /** + * 向量表ID + */ + @ExcelProperty(value = "向量表ID") + private Long vectorTableId; + + /** + * 是否有效(1:有效 0:无效) + */ + @ExcelProperty(value = "是否有效") + private String isEffective; + + /** + * 条款排序序号(用于排序显示) + */ + private Integer articleOrder; + +} \ No newline at end of file diff --git a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/vo/ContractualCaseFilesVo.java b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/vo/ContractualCaseFilesVo.java new file mode 100644 index 0000000..ca76360 --- /dev/null +++ b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/vo/ContractualCaseFilesVo.java @@ -0,0 +1,79 @@ +package org.dromara.productManagement.domain.vo; + +import org.dromara.productManagement.domain.ContractualCaseFiles; +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.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; +import java.io.Serial; +import java.io.Serializable; + +/** + * 合同案例文件视图对象 contractual_case_files + * + * @author Lion Li + * @date 2025-06-04 + */ +@Data +@ExcelIgnoreUnannotated +@AutoMapper(target = ContractualCaseFiles.class) +public class ContractualCaseFilesVo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键ID + */ + @ExcelProperty(value = "主键ID") + private Long id; + + /** + * 案例名称 + */ + @ExcelProperty(value = "案例名称") + private String caseName; + + /** + * 案例描述 + */ + @ExcelProperty(value = "案例描述") + private String caseDescription; + + /** + * 案例类型 + */ + @ExcelProperty(value = "案例类型") + private String caseType; + + /** + * 发布日期 + */ + @ExcelProperty(value = "发布日期") + @JsonFormat(pattern = "yyyy-MM-dd") + private Date publishDate; + + /** + * 是否有效(Y:有效 N:无效) + */ + @ExcelProperty(value = "是否有效", converter = ExcelDictConvert.class) + @ExcelDictFormat(dictType = "sys_yes_no") + private String isEffective; + + /** + * 处理状态 + */ + @ExcelProperty(value = "处理状态", converter = ExcelDictConvert.class) + @ExcelDictFormat(dictType = "file_progress_status") + private String progressStatus; + + /** + * OSS文件ID + */ + private Long ossId; + +} \ No newline at end of file diff --git a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/vo/ContractualRegulationArticlesVo.java b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/vo/ContractualRegulationArticlesVo.java new file mode 100644 index 0000000..6b1b607 --- /dev/null +++ b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/vo/ContractualRegulationArticlesVo.java @@ -0,0 +1,63 @@ +package org.dromara.productManagement.domain.vo; + +import org.dromara.productManagement.domain.ContractualRegulationArticles; +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; + +/** + * 合同法规条款视图对象 contractual_regulation_articles + * + * @author Lion Li + * @date 2025-06-05 + */ +@Data +@ExcelIgnoreUnannotated +@AutoMapper(target = ContractualRegulationArticles.class) +public class ContractualRegulationArticlesVo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键ID + */ + @ExcelProperty(value = "主键ID") + private Long id; + + /** + * 法规名称ID + */ + @ExcelProperty(value = "法规名称ID") + private Long regulationNameId; + + /** + * 法规条款内容 + */ + @ExcelProperty(value = "法规条款内容") + private String articleContent; + + /** + * 是否有效 + */ + @ExcelProperty(value = "是否有效", converter = ExcelDictConvert.class) + @ExcelDictFormat(dictType = "sys_yes_no") + private String isEffective; + + /** + * 向量表ID + */ + @ExcelProperty(value = "向量表ID") + private Long vectorTableId; + + /** + * 条款序号(用于排序显示) + */ + private Integer articleOrder; +} diff --git a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/vo/ContractualRegulationNamesVo.java b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/vo/ContractualRegulationNamesVo.java new file mode 100644 index 0000000..19a512c --- /dev/null +++ b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/vo/ContractualRegulationNamesVo.java @@ -0,0 +1,66 @@ +package org.dromara.productManagement.domain.vo; + +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.dromara.productManagement.domain.ContractualRegulationNames; +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; + + + +/** + * 合同法规名称视图对象 contractual_regulation_names + * + * @author Lion Li + * @date 2025-06-04 + */ +@Data +@ExcelIgnoreUnannotated +@AutoMapper(target = ContractualRegulationNames.class) +public class ContractualRegulationNamesVo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键ID + */ + @ExcelProperty(value = "主键ID") + private Long id; + + /** + * 法规名称 + */ + @ExcelProperty(value = "法规名称") + private String regulationName; + + /** + * 法规描述 + */ + @ExcelProperty(value = "法规描述") + private String regulationDescription; + + /** + * 发布日期 + */ + @ExcelProperty(value = "发布日期") + @JsonFormat(pattern = "yyyy-MM-dd") + private Date publishDate; + + /** + * 是否有效(1:有效 0:无效) + */ + @ExcelProperty(value = "是否有效Y/N") + private String isEffective; + + private String progressStatus; + +} diff --git a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/mapper/ContractualCaseArticlesMapper.java b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/mapper/ContractualCaseArticlesMapper.java new file mode 100644 index 0000000..0aac384 --- /dev/null +++ b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/mapper/ContractualCaseArticlesMapper.java @@ -0,0 +1,23 @@ +package org.dromara.productManagement.mapper; + +import org.dromara.productManagement.domain.ContractualCaseArticles; +import org.dromara.productManagement.domain.vo.ContractualCaseArticlesVo; +import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; +import org.apache.ibatis.annotations.Param; + +/** + * 合同案例条款Mapper接口 + * + * @author Lion Li + * @date 2025-06-05 + */ +public interface ContractualCaseArticlesMapper extends BaseMapperPlus { + + /** + * 根据案例文件ID真实删除条款记录 + * @param caseFileId 案例文件ID + * @return 删除的记录数 + */ + int realDeleteByCaseFileId(@Param("caseFileId") Long caseFileId); + +} \ No newline at end of file diff --git a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/mapper/ContractualCaseFilesMapper.java b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/mapper/ContractualCaseFilesMapper.java new file mode 100644 index 0000000..672cce1 --- /dev/null +++ b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/mapper/ContractualCaseFilesMapper.java @@ -0,0 +1,23 @@ +package org.dromara.productManagement.mapper; + +import org.dromara.productManagement.domain.ContractualCaseFiles; +import org.dromara.productManagement.domain.vo.ContractualCaseFilesVo; +import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; +import org.apache.ibatis.annotations.Param; + +/** + * 合同案例文件Mapper接口 + * + * @author Lion Li + * @date 2025-06-04 + */ +public interface ContractualCaseFilesMapper extends BaseMapperPlus { + + /** + * 真实删除案例文件记录 + * @param id 案例文件ID + * @return 删除的记录数 + */ + int realDeleteById(@Param("id") Long id); + +} \ No newline at end of file diff --git a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/mapper/ContractualRegulationArticlesMapper.java b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/mapper/ContractualRegulationArticlesMapper.java new file mode 100644 index 0000000..baf61da --- /dev/null +++ b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/mapper/ContractualRegulationArticlesMapper.java @@ -0,0 +1,24 @@ +package org.dromara.productManagement.mapper; + +import org.dromara.productManagement.domain.ContractualRegulationArticles; +import org.dromara.productManagement.domain.vo.ContractualRegulationArticlesVo; +import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; +import org.apache.ibatis.annotations.Delete; +import org.apache.ibatis.annotations.Param; + +/** + * 合同法规法条Mapper接口 + * + * @author Lion Li + * @date 2025-06-05 + */ +public interface ContractualRegulationArticlesMapper extends BaseMapperPlus { + + /** + * 根据法规ID真实删除所有条款 + * @param regulationNameId 法规名称ID + * @return 删除的记录数 + */ + @Delete("DELETE FROM contractual_regulation_articles WHERE regulation_name_id = #{regulationNameId}") + int realDeleteByRegulationNameId(@Param("regulationNameId") Long regulationNameId); +} diff --git a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/mapper/ContractualRegulationNamesMapper.java b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/mapper/ContractualRegulationNamesMapper.java new file mode 100644 index 0000000..88a9969 --- /dev/null +++ b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/mapper/ContractualRegulationNamesMapper.java @@ -0,0 +1,38 @@ +package org.dromara.productManagement.mapper; + +import org.dromara.productManagement.domain.ContractualRegulationNames; +import org.dromara.productManagement.domain.vo.ContractualRegulationNamesVo; +import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; +import org.apache.ibatis.annotations.Delete; +import org.apache.ibatis.annotations.Param; +import java.util.Collection; + +/** + * 合同法规名称Mapper接口 + * + * @author Lion Li + * @date 2025-06-04 + */ +public interface ContractualRegulationNamesMapper extends BaseMapperPlus { + + /** + * 真实删除法规记录 + * @param id 法规ID + * @return 删除的记录数 + */ + @Delete("DELETE FROM contractual_regulation_names WHERE id = #{id}") + int realDeleteById(@Param("id") Long id); + + /** + * 批量真实删除法规记录 + * @param ids 法规ID集合 + * @return 删除的记录数 + */ + @Delete("") + int realDeleteByIds(@Param("ids") Collection ids); +} diff --git a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/IContractualCaseFilesService.java b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/IContractualCaseFilesService.java new file mode 100644 index 0000000..9b19897 --- /dev/null +++ b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/IContractualCaseFilesService.java @@ -0,0 +1,96 @@ +package org.dromara.productManagement.service; + +import org.dromara.productManagement.domain.bo.ContractualCaseFilesBo; +import org.dromara.productManagement.domain.vo.ContractualCaseFilesVo; +import org.dromara.productManagement.domain.vo.ContractualCaseArticlesVo; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.common.mybatis.core.page.PageQuery; + +import jakarta.servlet.http.HttpServletResponse; +import java.util.Collection; +import java.util.List; + +/** + * 合同案例文件Service接口 + * + * @author Lion Li + * @date 2025-06-04 + */ +public interface IContractualCaseFilesService { + + /** + * 查询合同案例文件 + * + * @param id 主键 + * @return 合同案例文件 + */ + ContractualCaseFilesVo queryById(Long id); + + /** + * 分页查询合同案例文件列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 合同案例文件分页列表 + */ + TableDataInfo queryPageList(ContractualCaseFilesBo bo, PageQuery pageQuery); + + /** + * 查询符合条件的合同案例文件列表 + * + * @param bo 查询条件 + * @return 合同案例文件列表 + */ + List queryList(ContractualCaseFilesBo bo); + + /** + * 新增合同案例文件 + * + * @param bo 合同案例文件 + * @return 是否新增成功 + */ + Boolean insertByBo(ContractualCaseFilesBo bo); + + /** + * 修改合同案例文件 + * + * @param bo 合同案例文件 + * @return 是否修改成功 + */ + Boolean updateByBo(ContractualCaseFilesBo bo); + + /** + * 更新合同案例文件状态 + * + * @param id 主键 + * @param status 状态 + * @return 是否更新成功 + */ + Boolean updateStatusById(Long id, String status); + + /** + * 校验并批量删除合同案例文件信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + Boolean deleteWithValidByIds(Collection ids, Boolean isValid); + + /** + * 获取案例条款列表 + * + * @param caseFileId 案例文件ID + * @return 案例条款列表 + */ + List getCaseArticles(Long caseFileId); + + /** + * 生成案例PDF文档 + * + * @param caseFileId 案例文件ID + * @param response HTTP响应 + */ + void generateCasePdf(Long caseFileId, HttpServletResponse response); + +} \ No newline at end of file diff --git a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/IContractualRegulationArticlesService.java b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/IContractualRegulationArticlesService.java new file mode 100644 index 0000000..7f4d2b7 --- /dev/null +++ b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/IContractualRegulationArticlesService.java @@ -0,0 +1,68 @@ +package org.dromara.productManagement.service; + +import org.dromara.productManagement.domain.vo.ContractualRegulationArticlesVo; +import org.dromara.productManagement.domain.bo.ContractualRegulationArticlesBo; +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-06-05 + */ +public interface IContractualRegulationArticlesService { + + /** + * 查询合同法规法条 + * + * @param id 主键 + * @return 合同法规法条 + */ + ContractualRegulationArticlesVo queryById(Long id); + + /** + * 分页查询合同法规法条列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 合同法规法条分页列表 + */ + TableDataInfo queryPageList(ContractualRegulationArticlesBo bo, PageQuery pageQuery); + + /** + * 查询符合条件的合同法规法条列表 + * + * @param bo 查询条件 + * @return 合同法规法条列表 + */ + List queryList(ContractualRegulationArticlesBo bo); + + /** + * 新增合同法规法条 + * + * @param bo 合同法规法条 + * @return 是否新增成功 + */ + Boolean insertByBo(ContractualRegulationArticlesBo bo); + + /** + * 修改合同法规法条 + * + * @param bo 合同法规法条 + * @return 是否修改成功 + */ + Boolean updateByBo(ContractualRegulationArticlesBo bo); + + /** + * 校验并批量删除合同法规法条信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + Boolean deleteWithValidByIds(Collection ids, Boolean isValid); +} diff --git a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/IContractualRegulationNamesService.java b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/IContractualRegulationNamesService.java new file mode 100644 index 0000000..13f1b96 --- /dev/null +++ b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/IContractualRegulationNamesService.java @@ -0,0 +1,95 @@ +package org.dromara.productManagement.service; + +import org.dromara.productManagement.domain.vo.ContractualRegulationNamesVo; +import org.dromara.productManagement.domain.vo.ContractualRegulationArticlesVo; +import org.dromara.productManagement.domain.bo.ContractualRegulationNamesBo; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.common.mybatis.core.page.PageQuery; + +import jakarta.servlet.http.HttpServletResponse; +import java.util.Collection; +import java.util.List; + +/** + * 合同法规名称Service接口 + * + * @author Lion Li + * @date 2025-06-04 + */ +public interface IContractualRegulationNamesService { + + /** + * 查询合同法规名称 + * + * @param id 主键 + * @return 合同法规名称 + */ + ContractualRegulationNamesVo queryById(Long id); + + /** + * 分页查询合同法规名称列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 合同法规名称分页列表 + */ + TableDataInfo queryPageList(ContractualRegulationNamesBo bo, PageQuery pageQuery); + + /** + * 查询符合条件的合同法规名称列表 + * + * @param bo 查询条件 + * @return 合同法规名称列表 + */ + List queryList(ContractualRegulationNamesBo bo); + + /** + * 新增合同法规名称 + * + * @param bo 合同法规名称 + * @return 是否新增成功 + */ + Boolean insertByBo(ContractualRegulationNamesBo bo); + + /** + * 修改合同法规名称 + * + * @param bo 合同法规名称 + * @return 是否修改成功 + */ + Boolean updateByBo(ContractualRegulationNamesBo bo); + + /** + * 更新合同法规名称状态 + * + * @param id 主键 + * @param status 状态 + * @return 是否更新成功 + */ + Boolean updateStatusById(Long id, String status); + + /** + * 校验并批量删除合同法规名称信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + Boolean deleteWithValidByIds(Collection ids, Boolean isValid); + + /** + * 获取法规条款列表 + * + * @param regulationNameId 法规名称ID + * @return 法规条款列表 + */ + List getRegulationArticles(Long regulationNameId); + + /** + * 生成法规PDF文档 + * + * @param regulationNameId 法规名称ID + * @param response HTTP响应 + */ + void generateRegulationPdf(Long regulationNameId, HttpServletResponse response); +} diff --git a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/impl/ContractualCaseFilesServiceImpl.java b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/impl/ContractualCaseFilesServiceImpl.java new file mode 100644 index 0000000..490575b --- /dev/null +++ b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/impl/ContractualCaseFilesServiceImpl.java @@ -0,0 +1,671 @@ +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.utils.MyHttpUtils; +import org.dromara.system.domain.vo.SysOssVo; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.dromara.productManagement.domain.bo.ContractualCaseFilesBo; +import org.dromara.productManagement.domain.vo.ContractualCaseFilesVo; +import org.dromara.productManagement.domain.vo.ContractualCaseArticlesVo; +import org.dromara.productManagement.domain.ContractualCaseFiles; +import org.dromara.productManagement.domain.ContractualCaseArticles; +import org.dromara.productManagement.mapper.ContractualCaseFilesMapper; +import org.dromara.productManagement.mapper.ContractualCaseArticlesMapper; +import org.dromara.productManagement.service.IContractualCaseFilesService; +import org.dromara.system.service.ISysOssService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import jakarta.servlet.http.HttpServletResponse; +import java.io.*; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.text.SimpleDateFormat; +import java.util.List; +import java.util.Map; +import java.util.Collection; +import java.util.Stack; +import java.util.regex.Pattern; +import java.util.regex.Matcher; +import java.util.stream.Collectors; + +// HTML转PDF相关导入 +import org.xhtmlrenderer.pdf.ITextRenderer; +import org.apache.commons.io.FileUtils; +import com.lowagie.text.pdf.BaseFont; + +// Milvus相关导入 +import io.milvus.client.MilvusServiceClient; +import io.milvus.param.ConnectParam; +import io.milvus.param.dml.DeleteParam; +import io.milvus.grpc.MutationResult; +import io.milvus.param.R; +import jakarta.annotation.PreDestroy; + +/** + * 合同案例文件Service业务层处理 + * + * @author Lion Li + * @date 2025-06-04 + */ +@RequiredArgsConstructor +@Service +public class ContractualCaseFilesServiceImpl implements IContractualCaseFilesService { + + private final ContractualCaseFilesMapper baseMapper; + private final ContractualCaseArticlesMapper articlesMapper; + private final ISysOssService ossService; + private static final Logger log = LoggerFactory.getLogger(ContractualCaseFilesServiceImpl.class); + + @Value("${chat.filePath}") + protected String fileRootPath; + @Value("${chat.chatUrl}") + protected String chatUrl; + + // Milvus配置 + @Value("${milvus.host:10.1.21.250}") + private String milvusHost; + @Value("${milvus.port:19530}") + private int milvusPort; + @Value("${milvus.collection.name:contractual_case_articles}") + private String milvusCollectionName = "contractual_case_articles"; + + private MilvusServiceClient milvusClient; + + /** + * 查询合同案例文件 + * + * @param id 主键 + * @return 合同案例文件 + */ + @Override + public ContractualCaseFilesVo queryById(Long id){ + return baseMapper.selectVoById(id); + } + + /** + * 分页查询合同案例文件列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 合同案例文件分页列表 + */ + @Override + public TableDataInfo queryPageList(ContractualCaseFilesBo bo, PageQuery pageQuery) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); + return TableDataInfo.build(result); + } + + /** + * 查询符合条件的合同案例文件列表 + * + * @param bo 查询条件 + * @return 合同案例文件列表 + */ + @Override + public List queryList(ContractualCaseFilesBo bo) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + return baseMapper.selectVoList(lqw); + } + + private LambdaQueryWrapper buildQueryWrapper(ContractualCaseFilesBo bo) { + Map params = bo.getParams(); + LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); + lqw.like(StringUtils.isNotBlank(bo.getCaseName()), ContractualCaseFiles::getCaseName, bo.getCaseName()); + lqw.like(StringUtils.isNotBlank(bo.getCaseType()), ContractualCaseFiles::getCaseType, bo.getCaseType()); + + // 日期范围查询 + if (bo.getPublishDate() != null) { + // 如果传入的是单个日期,查询当天的记录 + lqw.eq(ContractualCaseFiles::getPublishDate, bo.getPublishDate()); + } else { + // 日期范围查询 + lqw.ge(bo.getPublishDateStart() != null, ContractualCaseFiles::getPublishDate, bo.getPublishDateStart()); + lqw.le(bo.getPublishDateEnd() != null, ContractualCaseFiles::getPublishDate, bo.getPublishDateEnd()); + } + + lqw.eq(StringUtils.isNotBlank(bo.getIsEffective()), ContractualCaseFiles::getIsEffective, bo.getIsEffective()); + return lqw; + } + + /** + * 新增合同案例文件 + * + * @param bo 合同案例文件 + * @return 是否新增成功 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean insertByBo(ContractualCaseFilesBo bo) { + try { + // 1. 保存案例基本信息 + ContractualCaseFiles add = MapstructUtils.convert(bo, ContractualCaseFiles.class); + validEntityBeforeSave(add); + + boolean flag = baseMapper.insert(add) > 0; + if (!flag) { + throw new RuntimeException("保存案例信息失败"); + } + + bo.setId(add.getId()); + log.info("成功新增案例文件,ID: {}, 案例名称: {}", add.getId(), add.getCaseName()); + + Long ossId = bo.getOssId(); + // 2. 处理文档解析和向量化(如果有ossId) + if (ossId != null) { + try { + // 更新状态为解析中 + add.setProgressStatus("PROCESSING"); + SysOssVo fileInfo = ossService.getById(ossId); + String fileName = fileInfo.getOriginalName(); + String filePath = fileRootPath + File.separator + fileInfo.getFileName(); + + // 调用Python接口启动案例分析任务 + String pythonUrl = chatUrl + "/back/taskStart"; + MyHttpUtils.sendTaskStartMessage( + pythonUrl, + add.getId(), + "contractualCaseFiles", + filePath, + 1L + ); + + log.info("启动案例文档解析和向量化任务,ossId: {}, 案例名称: {}", bo.getOssId(), bo.getCaseName()); + + } catch (Exception e) { + // 处理失败,状态保持为PENDING + add.setProgressStatus("PENDING"); + baseMapper.updateById(add); + log.error("案例文档处理失败: {}", e.getMessage(), e); + // 不抛异常,允许基本信息保存成功 + } + } + + return true; + } catch (Exception e) { + log.error("新增案例文件失败: {}", e.getMessage(), e); + throw new RuntimeException("新增案例文件失败: " + e.getMessage()); + } + } + + /** + * 修改合同案例文件 + * + * @param bo 合同案例文件 + * @return 是否修改成功 + */ + @Override + public Boolean updateByBo(ContractualCaseFilesBo bo) { + ContractualCaseFiles update = MapstructUtils.convert(bo, ContractualCaseFiles.class); + validEntityBeforeSave(update); + return baseMapper.updateById(update) > 0; + } + + /** + * 更新合同案例文件状态 + * + * @param id 主键 + * @param status 状态 + * @return 是否更新成功 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean updateStatusById(Long id, String status) { + // 更新案例文件状态 + ContractualCaseFiles entity = new ContractualCaseFiles(); + entity.setId(id); + entity.setIsEffective(status); + boolean flag = baseMapper.updateById(entity) > 0; + + if (flag) { + // 同时更新对应的案例条款状态 + LambdaQueryWrapper wrapper = Wrappers.lambdaQuery(); + wrapper.eq(ContractualCaseArticles::getCaseFileId, id); + + ContractualCaseArticles articleUpdate = new ContractualCaseArticles(); + articleUpdate.setIsEffective(status); + + articlesMapper.update(articleUpdate, wrapper); + } + + return flag; + } + + /** + * 保存前的数据校验 + */ + private void validEntityBeforeSave(ContractualCaseFiles entity){ + //TODO 做一些数据校验,如唯一约束 + } + + /** + * 校验并批量删除合同案例文件信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { + if (isValid) { + // TODO 做一些业务上的校验,判断是否需要校验 + log.info("开始校验待删除的案例文件,数量: {}", ids.size()); + } + + boolean allSuccess = true; + + // 逐个删除案例及其相关数据 + for (Long id : ids) { + try { + // 1. 先从Milvus删除向量数据 + boolean milvusDeleted = deleteFromMilvus(id); + if (!milvusDeleted) { + log.warn("案例文件ID {} 的Milvus向量数据删除失败,但继续删除其他数据", id); + } + + // 2. 删除案例条款(真实删除) + int deletedArticles = articlesMapper.realDeleteByCaseFileId(id); + log.info("案例文件ID {} 删除了 {} 条案例条款", id, deletedArticles); + + // 3. 删除案例主记录(真实删除) + int deletedCase = baseMapper.realDeleteById(id); + if (deletedCase > 0) { + log.info("成功删除案例文件ID: {}", id); + } else { + log.warn("删除案例文件ID {} 失败", id); + allSuccess = false; + } + + } catch (Exception e) { + log.error("删除案例文件ID {} 时出错: {}", id, e.getMessage(), e); + allSuccess = false; + // 继续处理其他ID,不中断整个事务 + } + } + + if (allSuccess) { + log.info("成功删除 {} 个案例文件", ids.size()); + } else { + log.warn("部分案例文件删除失败"); + } + + return allSuccess; + } + + /** + * 获取案例条款列表 + * + * @param caseFileId 案例文件ID + * @return 案例条款列表 + */ + @Override + public List getCaseArticles(Long caseFileId) { + LambdaQueryWrapper wrapper = Wrappers.lambdaQuery(); + wrapper.eq(ContractualCaseArticles::getCaseFileId, caseFileId) + .orderByAsc(ContractualCaseArticles::getId); + + List articles = articlesMapper.selectList(wrapper); + List articleVos = MapstructUtils.convert(articles, ContractualCaseArticlesVo.class); + + // 处理条款排序和标题提取,按条款序号从小到大排序 + return articleVos.stream() + .peek(this::processArticle) + .sorted((a, b) -> { + Integer orderA = a.getArticleOrder(); + Integer orderB = b.getArticleOrder(); + + // 如果都有序号,按序号排序 + if (orderA != null && orderB != null) { + return orderA.compareTo(orderB); + } + // 有序号的排在前面 + if (orderA != null && orderB == null) { + return -1; + } + if (orderA == null && orderB != null) { + return 1; + } + // 都没有序号,按ID排序 + return a.getId().compareTo(b.getId()); + }) + .collect(Collectors.toList()); + } + + /** + * 生成案例PDF文档 + * + * @param caseFileId 案例文件ID + * @param response HTTP响应 + */ + @Override + public void generateCasePdf(Long caseFileId, HttpServletResponse response) { + try { + // 获取案例基本信息 + ContractualCaseFilesVo caseFile = queryById(caseFileId); + if (caseFile == null) { + throw new RuntimeException("案例不存在"); + } + + // 获取案例条款 + List articles = getCaseArticles(caseFileId); + + // 设置响应头 + String fileName = URLEncoder.encode(caseFile.getCaseName() + ".pdf", StandardCharsets.UTF_8); + response.setContentType("application/pdf"); + response.setHeader("Content-Disposition", "inline; filename=\"" + fileName + "\""); + + // 生成HTML内容并转换为PDF + String htmlContent = generateHtmlContent(caseFile, articles); + + ITextRenderer renderer = new ITextRenderer(); + // 设置中文字体 + try (InputStream is = getClass().getResourceAsStream("/fonts/msyh.ttc")) { + if (is != null) { + File tempFont = File.createTempFile("msyh", ".ttc"); + FileUtils.copyInputStreamToFile(is, tempFont); + renderer.getFontResolver().addFont(tempFont.getAbsolutePath(), BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED); + tempFont.deleteOnExit(); + } + } catch (Exception fontException) { + log.warn("加载字体文件失败,使用默认字体: {}", fontException.getMessage()); + } + renderer.setDocumentFromString(htmlContent); + renderer.layout(); + renderer.createPDF(response.getOutputStream()); + + } catch (Exception e) { + log.error("生成案例PDF失败: {}", e.getMessage(), e); + throw new RuntimeException("生成案例PDF失败: " + e.getMessage()); + } + } + + /** + * 生成HTML内容 + */ + private String generateHtmlContent(ContractualCaseFilesVo caseFile, List articles) { + StringBuilder html = new StringBuilder(); + + // 格式化发布日期 + String formattedDate = ""; + if (caseFile.getPublishDate() != null) { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + formattedDate = sdf.format(caseFile.getPublishDate()); + } + + // 构建完整的HTML文档 + html.append(""" + + + + + + + + """); + + // 添加标题 + html.append("
").append(caseFile.getCaseName()).append("
"); + + // 添加案例信息 + html.append("
"); + if (StringUtils.isNotBlank(formattedDate)) { + html.append("
发布日期:").append(formattedDate).append("
"); + } + if (StringUtils.isNotBlank(caseFile.getCaseType())) { + html.append("
案例类型:").append(caseFile.getCaseType()).append("
"); + } + html.append("
"); + + // 添加案例描述 + if (StringUtils.isNotBlank(caseFile.getCaseDescription())) { + html.append("
"); + html.append("

案例描述:

"); + html.append("

").append(caseFile.getCaseDescription()).append("

"); + html.append("
"); + } + + // 添加条款内容 + for (ContractualCaseArticlesVo article : articles) { + html.append("
"); + + String content = article.getArticleContent(); + if (StringUtils.isNotBlank(content)) { + // 处理内容,将"第XX条"等内容加粗 + String processedContent = processArticleContent(content); + html.append("

").append(processedContent).append("

"); + } + + html.append("
"); + } + + html.append(""); + + return html.toString(); + } + + /** + * 处理条款内容,将"第XX条"等关键内容加粗 + */ + private String processArticleContent(String content) { + if (StringUtils.isBlank(content)) { + return content; + } + + // 使用正则表达式匹配"第XX条"并加粗 + Pattern pattern = Pattern.compile("第([零一二三四五六七八九十百千万\\d]+)条"); + return pattern.matcher(content).replaceAll("第$1条"); + } + + /** + * 处理条款信息(提取序号) + */ + private void processArticle(ContractualCaseArticlesVo article) { + String content = article.getArticleContent(); + if (StringUtils.isBlank(content)) { + return; + } + + // 提取条款序号 + Integer order = extractArticleOrder(content); + article.setArticleOrder(order); + } + + /** + * 提取条款序号 + */ + private Integer extractArticleOrder(String content) { + // 匹配 "第XX条" 格式 + Pattern pattern = Pattern.compile("第([零一二三四五六七八九十百千万\\d]+)条"); + Matcher matcher = pattern.matcher(content); + + if (matcher.find()) { + String numberStr = matcher.group(1); + return convertChineseNumberToInt(numberStr); + } + + return null; + } + + /** + * 将中文数字转换为阿拉伯数字 + * @author Tuzi294 + * @param chineseNumber 中文数字字符串 + * @return 转换后的阿拉伯数字 + */ + private Integer convertChineseNumberToInt(String chineseNumber) { + if (StringUtils.isBlank(chineseNumber)) { + return null; + } + + // 如果已经是阿拉伯数字,直接返回 + if (chineseNumber.matches("\\d+")) { + return Integer.parseInt(chineseNumber); + } + + try { + String aval = "零一二三四五六七八九"; + String bval = "十百千万亿"; + int[] bnum = {10, 100, 1000, 10000, 100000000}; + long num = 0; + char[] arr = chineseNumber.toCharArray(); + int len = arr.length; + Stack stack = new Stack<>(); + + for (int i = 0; i < len; i++) { + char s = arr[i]; + //跳过零 + if (s == '零') continue; + //用下标找到对应数字 + int index = bval.indexOf(s); + //如果不在bval中,即当前字符为数字,直接入栈 + if (index == -1) { + stack.push(aval.indexOf(s)); + } else { //当前字符为单位。 + int tempsum = 0; + int val = bnum[index]; + //如果栈为空则直接入栈 + if (stack.isEmpty()) { + stack.push(val); + continue; + } + //如果栈中有比val小的元素则出栈,累加,乘N,再入栈 + while (!stack.isEmpty() && stack.peek() < val) { + tempsum += stack.pop(); + } + //判断是否经过乘法处理 + if (tempsum == 0) { + stack.push(val); + } else { + stack.push(tempsum * val); + } + } + } + + //计算最终的和 + while (!stack.isEmpty()) { + num += stack.pop(); + } + + return num > 0 ? (int) num : null; + + } catch (Exception e) { + log.warn("转换中文数字失败: {}", chineseNumber, e); + // 如果转换失败,使用hashCode确保一致性 + return Math.abs(chineseNumber.hashCode() % 1000); + } + } + + /** + * 初始化Milvus客户端 + */ + private MilvusServiceClient getMilvusClient() { + if (milvusClient == null) { + try { + milvusClient = new MilvusServiceClient( + ConnectParam.newBuilder() + .withHost(milvusHost) + .withPort(milvusPort) + .build() + ); + log.info("Milvus客户端初始化成功: {}:{}", milvusHost, milvusPort); + } catch (Exception e) { + log.error("初始化Milvus客户端失败: {}", e.getMessage(), e); + return null; + } + } + return milvusClient; + } + + /** + * 从Milvus中删除案例相关的向量数据 + */ + private boolean deleteFromMilvus(Long caseFileId) { + try { + MilvusServiceClient client = getMilvusClient(); + if (client == null) { + log.warn("Milvus客户端未初始化,跳过向量数据删除"); + return false; + } + + // 构造删除表达式 - 删除指定案例文件ID的所有向量 + String deleteExpr = String.format("case_file_id == %d", caseFileId); + + DeleteParam deleteParam = DeleteParam.newBuilder() + .withCollectionName(milvusCollectionName) + .withExpr(deleteExpr) + .build(); + + R response = client.delete(deleteParam); + + if (response.getStatus() == R.Status.Success.getCode()) { + MutationResult mutationResponse = response.getData(); + long deleteCount = mutationResponse.getDeleteCnt(); + log.info("成功从Milvus删除案例文件ID {} 的向量数据,删除数量: {}", caseFileId, deleteCount); + return true; + } else { + log.error("从Milvus删除向量数据失败: {}", response.getMessage()); + return false; + } + + } catch (Exception e) { + log.error("从Milvus删除向量数据时出错: {}", e.getMessage(), e); + return false; + } + } + + @PreDestroy + public void closeMilvusClient() { + if (milvusClient != null) { + milvusClient.close(); + log.info("Milvus客户端已关闭"); + } + } +} \ No newline at end of file diff --git a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/impl/ContractualRegulationArticlesServiceImpl.java b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/impl/ContractualRegulationArticlesServiceImpl.java new file mode 100644 index 0000000..f50f895 --- /dev/null +++ b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/impl/ContractualRegulationArticlesServiceImpl.java @@ -0,0 +1,272 @@ +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.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.dromara.productManagement.domain.bo.ContractualRegulationArticlesBo; +import org.dromara.productManagement.domain.vo.ContractualRegulationArticlesVo; +import org.dromara.productManagement.domain.ContractualRegulationArticles; +import org.dromara.productManagement.mapper.ContractualRegulationArticlesMapper; +import org.dromara.productManagement.service.IContractualRegulationArticlesService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +// Milvus相关导入 +import io.milvus.client.MilvusServiceClient; +import io.milvus.param.ConnectParam; +import io.milvus.param.dml.DeleteParam; +import io.milvus.grpc.MutationResult; +import io.milvus.param.R; +import org.springframework.beans.factory.annotation.Value; +import jakarta.annotation.PreDestroy; + +import java.util.List; +import java.util.Map; +import java.util.Collection; + +/** + * 合同法规法条Service业务层处理 + * + * @author Lion Li + * @date 2025-06-05 + */ +@RequiredArgsConstructor +@Service +public class ContractualRegulationArticlesServiceImpl implements IContractualRegulationArticlesService { + + private final ContractualRegulationArticlesMapper baseMapper; + private static final Logger log = LoggerFactory.getLogger(ContractualRegulationArticlesServiceImpl.class); + + // Milvus配置 + @Value("${milvus.host:10.1.21.250}") + private String milvusHost; + @Value("${milvus.port:19530}") + private int milvusPort; + @Value("${milvus.collection.name:contractual_case_articles}") + private String milvusCollectionName; + + private MilvusServiceClient milvusClient; + + /** + * 查询合同法规法条 + * + * @param id 主键 + * @return 合同法规法条 + */ + @Override + public ContractualRegulationArticlesVo queryById(Long id){ + return baseMapper.selectVoById(id); + } + + /** + * 分页查询合同法规法条列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 合同法规法条分页列表 + */ + @Override + public TableDataInfo queryPageList(ContractualRegulationArticlesBo bo, PageQuery pageQuery) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); + return TableDataInfo.build(result); + } + + /** + * 查询符合条件的合同法规法条列表 + * + * @param bo 查询条件 + * @return 合同法规法条列表 + */ + @Override + public List queryList(ContractualRegulationArticlesBo bo) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + return baseMapper.selectVoList(lqw); + } + + private LambdaQueryWrapper buildQueryWrapper(ContractualRegulationArticlesBo bo) { + Map params = bo.getParams(); + LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); + lqw.eq(bo.getRegulationNameId() != null, ContractualRegulationArticles::getRegulationNameId, bo.getRegulationNameId()); + lqw.like(StringUtils.isNotBlank(bo.getArticleContent()), ContractualRegulationArticles::getArticleContent, bo.getArticleContent()); + lqw.eq(bo.getVectorTableId() != null, ContractualRegulationArticles::getVectorTableId, bo.getVectorTableId()); + lqw.eq(StringUtils.isNotBlank(bo.getIsEffective()), ContractualRegulationArticles::getIsEffective, bo.getIsEffective()); + return lqw; + } + + /** + * 新增合同法规法条 + * + * @param bo 合同法规法条 + * @return 是否新增成功 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean insertByBo(ContractualRegulationArticlesBo bo) { + try { + ContractualRegulationArticles add = MapstructUtils.convert(bo, ContractualRegulationArticles.class); + validEntityBeforeSave(add); + + boolean flag = baseMapper.insert(add) > 0; + if (!flag) { + throw new RuntimeException("保存法规条款信息失败"); + } + + bo.setId(add.getId()); + log.info("成功新增法规条款,ID: {}, 法规名称ID: {}", add.getId(), add.getRegulationNameId()); + + // TODO: 如果需要向量化处理,可以在此处添加 + // 预留代码空位,后续可以处理条款的向量化存储 + + return true; + } catch (Exception e) { + log.error("新增法规条款失败: {}", e.getMessage(), e); + throw new RuntimeException("新增法规条款失败: " + e.getMessage()); + } + } + + /** + * 修改合同法规法条 + * + * @param bo 合同法规法条 + * @return 是否修改成功 + */ + @Override + public Boolean updateByBo(ContractualRegulationArticlesBo bo) { + ContractualRegulationArticles update = MapstructUtils.convert(bo, ContractualRegulationArticles.class); + validEntityBeforeSave(update); + return baseMapper.updateById(update) > 0; + } + + /** + * 保存前的数据校验 + */ + private void validEntityBeforeSave(ContractualRegulationArticles entity){ + //TODO 做一些数据校验,如唯一约束 + + } + + /** + * 校验并批量删除合同法规法条信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { + if (isValid) { + // TODO 做一些业务上的校验,判断是否需要校验 + log.info("开始校验待删除的法规条款,数量: {}", ids.size()); + } + + boolean allSuccess = true; + + // 逐个删除法规条款及其相关数据 + for (Long id : ids) { + try { + // 1. 先从Milvus删除向量数据(如果存在) + boolean milvusDeleted = deleteFromMilvus(id); + if (!milvusDeleted) { + log.warn("法规条款ID {} 的Milvus向量数据删除失败,但继续删除其他数据", id); + } + + // 2. 删除法规条款主记录 + int deletedCount = baseMapper.deleteById(id); + if (deletedCount > 0) { + log.info("成功删除法规条款ID: {}", id); + } else { + log.warn("删除法规条款ID {} 失败", id); + allSuccess = false; + } + + } catch (Exception e) { + log.error("删除法规条款ID {} 时出错: {}", id, e.getMessage(), e); + allSuccess = false; + // 继续处理其他ID,不中断整个事务 + } + } + + if (allSuccess) { + log.info("成功删除 {} 个法规条款", ids.size()); + } else { + log.warn("部分法规条款删除失败"); + } + + return allSuccess; + } + + /** + * 初始化Milvus客户端 + */ + private MilvusServiceClient getMilvusClient() { + if (milvusClient == null) { + try { + milvusClient = new MilvusServiceClient( + ConnectParam.newBuilder() + .withHost(milvusHost) + .withPort(milvusPort) + .build() + ); + log.info("Milvus客户端初始化成功: {}:{}", milvusHost, milvusPort); + } catch (Exception e) { + log.error("初始化Milvus客户端失败: {}", e.getMessage(), e); + return null; + } + } + return milvusClient; + } + + /** + * 从Milvus中删除法规条款相关的向量数据 + */ + private boolean deleteFromMilvus(Long articleId) { + try { + MilvusServiceClient client = getMilvusClient(); + if (client == null) { + log.warn("Milvus客户端未初始化,跳过向量数据删除"); + return false; + } + + // 构造删除表达式 - 删除指定条款ID的向量 + String deleteExpr = String.format("article_id == %d", articleId); + + DeleteParam deleteParam = DeleteParam.newBuilder() + .withCollectionName(milvusCollectionName) + .withExpr(deleteExpr) + .build(); + + R response = client.delete(deleteParam); + + if (response.getStatus() == R.Status.Success.getCode()) { + MutationResult mutationResponse = response.getData(); + long deleteCount = mutationResponse.getDeleteCnt(); + log.info("成功从Milvus删除法规条款ID {} 的向量数据,删除数量: {}", articleId, deleteCount); + return true; + } else { + log.error("从Milvus删除向量数据失败: {}", response.getMessage()); + return false; + } + + } catch (Exception e) { + log.error("从Milvus删除向量数据时出错: {}", e.getMessage(), e); + return false; + } + } + + @PreDestroy + public void closeMilvusClient() { + if (milvusClient != null) { + milvusClient.close(); + log.info("Milvus客户端已关闭"); + } + } +} diff --git a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/impl/ContractualRegulationNamesServiceImpl.java b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/impl/ContractualRegulationNamesServiceImpl.java new file mode 100644 index 0000000..52f10c1 --- /dev/null +++ b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/impl/ContractualRegulationNamesServiceImpl.java @@ -0,0 +1,640 @@ +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.utils.MyHttpUtils; +import org.dromara.system.domain.vo.SysOssVo; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.dromara.productManagement.domain.bo.ContractualRegulationNamesBo; +import org.dromara.productManagement.domain.vo.ContractualRegulationNamesVo; +import org.dromara.productManagement.domain.vo.ContractualRegulationArticlesVo; +import org.dromara.productManagement.domain.ContractualRegulationNames; +import org.dromara.productManagement.domain.ContractualRegulationArticles; +import org.dromara.productManagement.mapper.ContractualRegulationNamesMapper; +import org.dromara.productManagement.mapper.ContractualRegulationArticlesMapper; +import org.dromara.productManagement.service.IContractualRegulationNamesService; +import org.dromara.productManagement.service.IContractualRegulationArticlesService; +import org.dromara.system.service.ISysOssService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import jakarta.servlet.http.HttpServletResponse; +import java.io.*; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.text.SimpleDateFormat; +import java.util.List; +import java.util.Map; +import java.util.Collection; +import java.util.Stack; +import java.util.regex.Pattern; +import java.util.regex.Matcher; +import java.util.stream.Collectors; + +// HTML转PDF相关导入 +import org.xhtmlrenderer.pdf.ITextRenderer; +import org.apache.commons.io.FileUtils; +import com.lowagie.text.pdf.BaseFont; + +// Milvus相关导入 +import io.milvus.client.MilvusServiceClient; +import io.milvus.param.ConnectParam; +import io.milvus.param.dml.DeleteParam; +import io.milvus.grpc.MutationResult; +import io.milvus.param.R; +import jakarta.annotation.PreDestroy; + +/** + * 合同法规名称Service业务层处理 + * + * @author Lion Li + * @date 2025-06-04 + */ +@RequiredArgsConstructor +@Service +public class ContractualRegulationNamesServiceImpl implements IContractualRegulationNamesService { + + private final ContractualRegulationNamesMapper baseMapper; + private final ContractualRegulationArticlesMapper articlesMapper; + private final IContractualRegulationArticlesService articlesService; + private final ISysOssService ossService; + private static final Logger log = LoggerFactory.getLogger(ContractualRegulationNamesServiceImpl.class); + + @Value("${chat.filePath}") + protected String fileRootPath; + @Value("${chat.chatUrl}") + protected String chatUrl; + + // Milvus配置 + @Value("${milvus.host:10.1.21.250}") + private String milvusHost; + @Value("${milvus.port:19530}") + private int milvusPort; + @Value("${milvus.collection.name:contractual_regulation_articles}") + private String milvusCollectionName; + + private MilvusServiceClient milvusClient; + + /** + * 查询合同法规名称 + * + * @param id 主键 + * @return 合同法规名称 + */ + @Override + public ContractualRegulationNamesVo queryById(Long id){ + return baseMapper.selectVoById(id); + } + + /** + * 分页查询合同法规名称列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 合同法规名称分页列表 + */ + @Override + public TableDataInfo queryPageList(ContractualRegulationNamesBo bo, PageQuery pageQuery) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); + return TableDataInfo.build(result); + } + + /** + * 查询符合条件的合同法规名称列表 + * + * @param bo 查询条件 + * @return 合同法规名称列表 + */ + @Override + public List queryList(ContractualRegulationNamesBo bo) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + return baseMapper.selectVoList(lqw); + } + + private LambdaQueryWrapper buildQueryWrapper(ContractualRegulationNamesBo bo) { + Map params = bo.getParams(); + LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); + lqw.like(StringUtils.isNotBlank(bo.getRegulationName()), ContractualRegulationNames::getRegulationName, bo.getRegulationName()); + + // 日期范围查询 + if (bo.getPublishDate() != null) { + // 如果传入的是单个日期,查询当天的记录 + lqw.eq(ContractualRegulationNames::getPublishDate, bo.getPublishDate()); + } else { + // 日期范围查询 + lqw.ge(bo.getPublishDateStart() != null, ContractualRegulationNames::getPublishDate, bo.getPublishDateStart()); + lqw.le(bo.getPublishDateEnd() != null, ContractualRegulationNames::getPublishDate, bo.getPublishDateEnd()); + } + + lqw.eq(StringUtils.isNotBlank(bo.getIsEffective()), ContractualRegulationNames::getIsEffective, bo.getIsEffective()); + return lqw; + } + + /** + * 新增合同法规名称 + * + * @param bo 合同法规名称 + * @return 是否新增成功 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean insertByBo(ContractualRegulationNamesBo bo) { + // 1. 保存法规基本信息 + ContractualRegulationNames add = MapstructUtils.convert(bo, ContractualRegulationNames.class); + validEntityBeforeSave(add); + boolean flag = baseMapper.insert(add) > 0; + if (!flag) { + throw new RuntimeException("保存法规信息失败"); + } + bo.setId(add.getId()); + Long ossId = bo.getOssId(); + // 2. 处理文档解析和向量化(如果有ossId) + if (ossId!= null) { + try { + // 更新状态为解析中 + add.setProgressStatus("PROCESSING"); + SysOssVo fileInfo = ossService.getById(ossId); + String fileName = fileInfo.getOriginalName(); + String filePath = fileRootPath + File.separator +fileInfo.getFileName(); + // 7. 调用Python接口启动任务 + String pythonUrl = chatUrl + "/back/taskStart"; + MyHttpUtils.sendTaskStartMessage( + pythonUrl, + add.getId(), + "contractualRegulationNames", + filePath, + 1L + ); + // TODO: 实现文档处理逻辑 + // 这里预留代码空位,后续可以通过异步任务或定时任务来处理文档解析 + log.info("预留处理文档解析和向量化,ossId: {}, 法规名称: {}", bo.getOssId(), bo.getRegulationName()); + + } catch (Exception e) { + // 处理失败,状态保持为PENDING + add.setProgressStatus("PENDING"); + baseMapper.updateById(add); + log.error("文档处理失败: {}", e.getMessage(), e); + // 不抛异常,允许基本信息保存成功 + } + } + + return true; + } + + /** + * 修改合同法规名称 + * + * @param bo 合同法规名称 + * @return 是否修改成功 + */ + @Override + public Boolean updateByBo(ContractualRegulationNamesBo bo) { + ContractualRegulationNames update = MapstructUtils.convert(bo, ContractualRegulationNames.class); + validEntityBeforeSave(update); + return baseMapper.updateById(update) > 0; + } + + /** + * 更新合同法规名称状态 + * + * @param id 主键 + * @param status 状态 + * @return 是否更新成功 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean updateStatusById(Long id, String status) { + // 更新法规名称状态 + ContractualRegulationNames entity = new ContractualRegulationNames(); + entity.setId(id); + entity.setIsEffective(status); + boolean flag = baseMapper.updateById(entity) > 0; + + if (flag) { + // 同时更新对应的法规条款状态 + LambdaQueryWrapper wrapper = Wrappers.lambdaQuery(); + wrapper.eq(ContractualRegulationArticles::getRegulationNameId, id); + + ContractualRegulationArticles articleUpdate = new ContractualRegulationArticles(); + articleUpdate.setIsEffective(status); + + articlesMapper.update(articleUpdate, wrapper); + } + + return flag; + } + + /** + * 保存前的数据校验 + */ + private void validEntityBeforeSave(ContractualRegulationNames entity){ + //TODO 做一些数据校验,如唯一约束 + } + + /** + * 校验并批量删除合同法规名称信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { + if(isValid){ + //TODO 做一些业务上的校验,判断是否需要校验 + } + + boolean allSuccess = true; + + // 逐个删除法规及其相关数据 + for (Long id : ids) { + try { + // 1. 先从Milvus删除向量数据 + boolean milvusDeleted = deleteFromMilvus(id); + if (!milvusDeleted) { + log.warn("法规ID {} 的Milvus向量数据删除失败,但继续删除其他数据", id); + } + + // 2. 删除法规条款(真实删除) + int deletedArticles = articlesMapper.realDeleteByRegulationNameId(id); + log.info("法规ID {} 删除了 {} 条法规条款", id, deletedArticles); + + // 3. 删除法规主记录(真实删除) + int deletedRegulation = baseMapper.realDeleteById(id); + if (deletedRegulation > 0) { + log.info("成功删除法规ID: {}", id); + } else { + log.warn("删除法规ID {} 失败", id); + allSuccess = false; + } + + } catch (Exception e) { + log.error("删除法规ID {} 时出错: {}", id, e.getMessage(), e); + allSuccess = false; + // 继续处理其他ID,不中断整个事务 + } + } + + return allSuccess; + } + + /** + * 获取法规条款列表 + * + * @param regulationNameId 法规名称ID + * @return 法规条款列表 + */ + @Override + public List getRegulationArticles(Long regulationNameId) { + LambdaQueryWrapper wrapper = Wrappers.lambdaQuery(); + wrapper.eq(ContractualRegulationArticles::getRegulationNameId, regulationNameId) + .orderByAsc(ContractualRegulationArticles::getId); + + List articles = articlesMapper.selectList(wrapper); + List articleVos = MapstructUtils.convert(articles, ContractualRegulationArticlesVo.class); + + // 处理条款排序和标题提取,按条款序号从小到大排序 + return articleVos.stream() + .peek(this::processArticle) + .sorted((a, b) -> { + Integer orderA = a.getArticleOrder(); + Integer orderB = b.getArticleOrder(); + + // 如果都有序号,按序号排序 + if (orderA != null && orderB != null) { + return orderA.compareTo(orderB); + } + // 有序号的排在前面 + if (orderA != null && orderB == null) { + return -1; + } + if (orderA == null && orderB != null) { + return 1; + } + // 都没有序号,按ID排序 + return a.getId().compareTo(b.getId()); + }) + .collect(Collectors.toList()); + } + + /** + * 生成法规PDF文档 + * + * @param regulationNameId 法规名称ID + * @param response HTTP响应 + */ + @Override + public void generateRegulationPdf(Long regulationNameId, HttpServletResponse response) { + try { + // 获取法规基本信息 + ContractualRegulationNamesVo regulation = queryById(regulationNameId); + if (regulation == null) { + throw new RuntimeException("法规不存在"); + } + + // 获取法规条款 + List articles = getRegulationArticles(regulationNameId); + + // 设置响应头 + String fileName = URLEncoder.encode(regulation.getRegulationName() + ".pdf", StandardCharsets.UTF_8); + response.setContentType("application/pdf"); + response.setHeader("Content-Disposition", "inline; filename=\"" + fileName + "\""); + + // 生成HTML内容并转换为PDF + String htmlContent = generateHtmlContent(regulation, articles); + + ITextRenderer renderer = new ITextRenderer(); + // 设置中文字体 + try (InputStream is = getClass().getResourceAsStream("/fonts/msyh.ttc")) { + if (is != null) { + File tempFont = File.createTempFile("msyh", ".ttc"); + FileUtils.copyInputStreamToFile(is, tempFont); + renderer.getFontResolver().addFont(tempFont.getAbsolutePath(), BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED); + tempFont.deleteOnExit(); + } + } catch (Exception fontException) { + log.warn("加载字体文件失败,使用默认字体: {}", fontException.getMessage()); + } + renderer.setDocumentFromString(htmlContent); + renderer.layout(); + renderer.createPDF(response.getOutputStream()); + + } catch (Exception e) { + log.error("生成PDF失败: {}", e.getMessage(), e); + throw new RuntimeException("生成PDF失败: " + e.getMessage()); + } + } + + /** + * 生成HTML内容 + */ + private String generateHtmlContent(ContractualRegulationNamesVo regulation, List articles) { + StringBuilder html = new StringBuilder(); + + // 格式化发布日期 + String formattedDate = ""; + if (regulation.getPublishDate() != null) { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + formattedDate = sdf.format(regulation.getPublishDate()); + } + + // 构建完整的HTML文档 + html.append(""" + + + + + + + + """); + + // 添加标题 + html.append("
").append(regulation.getRegulationName()).append("
"); + + // 添加发布日期 + if (StringUtils.isNotBlank(formattedDate)) { + html.append("
发布日期:").append(formattedDate).append("
"); + } + + // 添加条款内容 + for (ContractualRegulationArticlesVo article : articles) { + html.append("
"); + + String content = article.getArticleContent(); + if (StringUtils.isNotBlank(content)) { + // 处理内容,将"第XX条"加粗 + String processedContent = processArticleContent(content); + html.append("

").append(processedContent).append("

"); + } + + html.append("
"); + } + + html.append(""); + + return html.toString(); + } + + /** + * 处理条款内容,将"第XX条"加粗 + */ + private String processArticleContent(String content) { + if (StringUtils.isBlank(content)) { + return content; + } + + // 使用正则表达式匹配"第XX条"并加粗 + Pattern pattern = Pattern.compile("第([零一二三四五六七八九十百千万\\d]+)条"); + return pattern.matcher(content).replaceAll("第$1条"); + } + + /** + * 处理条款信息(提取序号) + */ + private void processArticle(ContractualRegulationArticlesVo article) { + String content = article.getArticleContent(); + if (StringUtils.isBlank(content)) { + return; + } + + // 提取条款序号 + Integer order = extractArticleOrder(content); + article.setArticleOrder(order); + } + + /** + * 提取条款序号 + */ + private Integer extractArticleOrder(String content) { + // 匹配 "第XX条" 格式 + Pattern pattern = Pattern.compile("第([零一二三四五六七八九十百千万\\d]+)条"); + Matcher matcher = pattern.matcher(content); + + if (matcher.find()) { + String numberStr = matcher.group(1); + return convertChineseNumberToInt(numberStr); + } + + return null; + } + + /** + * 将中文数字转换为阿拉伯数字 + * @author Tuzi294 + * @param chineseNumber 中文数字字符串 + * @return 转换后的阿拉伯数字 + */ + private Integer convertChineseNumberToInt(String chineseNumber) { + if (StringUtils.isBlank(chineseNumber)) { + return null; + } + + // 如果已经是阿拉伯数字,直接返回 + if (chineseNumber.matches("\\d+")) { + return Integer.parseInt(chineseNumber); + } + + try { + String aval = "零一二三四五六七八九"; + String bval = "十百千万亿"; + int[] bnum = {10, 100, 1000, 10000, 100000000}; + long num = 0; + char[] arr = chineseNumber.toCharArray(); + int len = arr.length; + Stack stack = new Stack<>(); + + for (int i = 0; i < len; i++) { + char s = arr[i]; + //跳过零 + if (s == '零') continue; + //用下标找到对应数字 + int index = bval.indexOf(s); + //如果不在bval中,即当前字符为数字,直接入栈 + if (index == -1) { + stack.push(aval.indexOf(s)); + } else { //当前字符为单位。 + int tempsum = 0; + int val = bnum[index]; + //如果栈为空则直接入栈 + if (stack.isEmpty()) { + stack.push(val); + continue; + } + //如果栈中有比val小的元素则出栈,累加,乘N,再入栈 + while (!stack.isEmpty() && stack.peek() < val) { + tempsum += stack.pop(); + } + //判断是否经过乘法处理 + if (tempsum == 0) { + stack.push(val); + } else { + stack.push(tempsum * val); + } + } + } + + //计算最终的和 + while (!stack.isEmpty()) { + num += stack.pop(); + } + + return num > 0 ? (int) num : null; + + } catch (Exception e) { + log.warn("转换中文数字失败: {}", chineseNumber, e); + // 如果转换失败,使用hashCode确保一致性 + return Math.abs(chineseNumber.hashCode() % 1000); + } + } + + /** + * 初始化Milvus客户端 + */ + private MilvusServiceClient getMilvusClient() { + if (milvusClient == null) { + try { + milvusClient = new MilvusServiceClient( + ConnectParam.newBuilder() + .withHost(milvusHost) + .withPort(milvusPort) + .build() + ); + log.info("Milvus客户端初始化成功: {}:{}", milvusHost, milvusPort); + } catch (Exception e) { + log.error("初始化Milvus客户端失败: {}", e.getMessage(), e); + return null; + } + } + return milvusClient; + } + + /** + * 从Milvus中删除法规相关的向量数据 + */ + private boolean deleteFromMilvus(Long regulationNameId) { + try { + MilvusServiceClient client = getMilvusClient(); + if (client == null) { + log.warn("Milvus客户端未初始化,跳过向量数据删除"); + return false; + } + + // 构造删除表达式 - 删除指定法规ID的所有向量 + String deleteExpr = String.format("regulation_name_id == %d", regulationNameId); + + DeleteParam deleteParam = DeleteParam.newBuilder() + .withCollectionName(milvusCollectionName) + .withExpr(deleteExpr) + .build(); + + R response = client.delete(deleteParam); + + if (response.getStatus() == R.Status.Success.getCode()) { + MutationResult mutationResponse = response.getData(); + long deleteCount = mutationResponse.getDeleteCnt(); + log.info("成功从Milvus删除法规ID {} 的向量数据,删除数量: {}", regulationNameId, deleteCount); + return true; + } else { + log.error("从Milvus删除向量数据失败: {}", response.getMessage()); + return false; + } + + } catch (Exception e) { + log.error("从Milvus删除向量数据时出错: {}", e.getMessage(), e); + return false; + } + } + + @PreDestroy + public void closeMilvusClient() { + if (milvusClient != null) { + milvusClient.close(); + log.info("Milvus客户端已关闭"); + } + } +} diff --git a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/impl/ContractualTasksServiceImpl.java b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/impl/ContractualTasksServiceImpl.java index 6bbc4af..6dde960 100644 --- a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/impl/ContractualTasksServiceImpl.java +++ b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/impl/ContractualTasksServiceImpl.java @@ -233,11 +233,29 @@ public class ContractualTasksServiceImpl extends AbstractTaskProcessor result = new HashMap<>(); result.put("success", true); result.put("message", "合同审查任务已创建,正在后台处理"); diff --git a/zaojiaManagement/zaojia-productManagement/src/main/resources/mapper/productManagement/ContractualCaseArticlesMapper.xml b/zaojiaManagement/zaojia-productManagement/src/main/resources/mapper/productManagement/ContractualCaseArticlesMapper.xml new file mode 100644 index 0000000..f8cfb72 --- /dev/null +++ b/zaojiaManagement/zaojia-productManagement/src/main/resources/mapper/productManagement/ContractualCaseArticlesMapper.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + select id, case_file_id, article_content, vector_table_id, is_effective, + create_by, create_time, update_by, update_time, del_flag, tenant_id + from contractual_case_articles + + + + + DELETE FROM contractual_case_articles WHERE case_file_id = #{caseFileId} + + + \ No newline at end of file diff --git a/zaojiaManagement/zaojia-productManagement/src/main/resources/mapper/productManagement/ContractualCaseFilesMapper.xml b/zaojiaManagement/zaojia-productManagement/src/main/resources/mapper/productManagement/ContractualCaseFilesMapper.xml new file mode 100644 index 0000000..c96b61f --- /dev/null +++ b/zaojiaManagement/zaojia-productManagement/src/main/resources/mapper/productManagement/ContractualCaseFilesMapper.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + select id, case_name, case_description, case_type, publish_date, + is_effective, progress_status, oss_id, create_by, create_time, update_by, update_time, del_flag + from contractual_case_files + + + + + DELETE FROM contractual_case_files WHERE id = #{id} + + + \ No newline at end of file diff --git a/zaojiaManagement/zaojia-productManagement/src/main/resources/mapper/productManagement/ContractualRegulationArticlesMapper.xml b/zaojiaManagement/zaojia-productManagement/src/main/resources/mapper/productManagement/ContractualRegulationArticlesMapper.xml new file mode 100644 index 0000000..f356c19 --- /dev/null +++ b/zaojiaManagement/zaojia-productManagement/src/main/resources/mapper/productManagement/ContractualRegulationArticlesMapper.xml @@ -0,0 +1,7 @@ + + + + + diff --git a/zaojiaManagement/zaojia-productManagement/src/main/resources/mapper/productManagement/ContractualRegulationNamesMapper.xml b/zaojiaManagement/zaojia-productManagement/src/main/resources/mapper/productManagement/ContractualRegulationNamesMapper.xml new file mode 100644 index 0000000..969fe49 --- /dev/null +++ b/zaojiaManagement/zaojia-productManagement/src/main/resources/mapper/productManagement/ContractualRegulationNamesMapper.xml @@ -0,0 +1,7 @@ + + + + +