34 changed files with 3195 additions and 45 deletions
@ -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<ContractualCaseFilesVo> 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<ContractualCaseFilesVo> list = contractualCaseFilesService.queryList(bo); |
||||
|
ExcelUtil.exportExcel(list, "合同案例文件", ContractualCaseFilesVo.class, response); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取合同案例文件详细信息 |
||||
|
*/ |
||||
|
@SaCheckPermission("productManagement:ContractualCaseFiles:query") |
||||
|
@GetMapping("/{id}") |
||||
|
public R<ContractualCaseFilesVo> 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<Void> 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<Void> 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<Void> 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<Void> remove(@NotEmpty(message = "主键不能为空") |
||||
|
@PathVariable Long[] ids) { |
||||
|
return toAjax(contractualCaseFilesService.deleteWithValidByIds(List.of(ids), true)); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取案例条款列表 |
||||
|
*/ |
||||
|
@SaCheckPermission("productManagement:ContractualCaseFiles:query") |
||||
|
@GetMapping("/articles/{id}") |
||||
|
public R<List<ContractualCaseArticlesVo>> getArticles(@NotNull(message = "案例文件ID不能为空") |
||||
|
@PathVariable Long id) { |
||||
|
List<ContractualCaseArticlesVo> 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); |
||||
|
} |
||||
|
|
||||
|
} |
@ -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<ContractualRegulationArticlesVo> 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<ContractualRegulationArticlesVo> list = contractualRegulationArticlesService.queryList(bo); |
||||
|
ExcelUtil.exportExcel(list, "合同法规法条", ContractualRegulationArticlesVo.class, response); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取合同法规法条详细信息 |
||||
|
* |
||||
|
* @param id 主键 |
||||
|
*/ |
||||
|
@SaCheckPermission("productManagement:regulationArticles:query") |
||||
|
@GetMapping("/{id}") |
||||
|
public R<ContractualRegulationArticlesVo> 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<Void> 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<Void> 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<Void> remove(@NotEmpty(message = "主键不能为空") |
||||
|
@PathVariable Long[] ids) { |
||||
|
return toAjax(contractualRegulationArticlesService.deleteWithValidByIds(List.of(ids), true)); |
||||
|
} |
||||
|
} |
@ -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<ContractualRegulationNamesVo> 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<ContractualRegulationNamesVo> list = contractualRegulationNamesService.queryList(bo); |
||||
|
ExcelUtil.exportExcel(list, "合同法规名称", ContractualRegulationNamesVo.class, response); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取合同法规名称详细信息 |
||||
|
* |
||||
|
* @param id 主键 |
||||
|
*/ |
||||
|
@SaCheckPermission("productManagement:ContractualRegulationNames:query") |
||||
|
@GetMapping("/{id}") |
||||
|
public R<ContractualRegulationNamesVo> 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<Void> 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<Void> 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<Void> 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<Void> 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<List<ContractualRegulationArticlesVo>> getRegulationArticles(@PathVariable Long id) { |
||||
|
List<ContractualRegulationArticlesVo> articles = contractualRegulationNamesService.getRegulationArticles(id); |
||||
|
return R.ok(articles); |
||||
|
} |
||||
|
} |
@ -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; |
||||
|
|
||||
|
} |
@ -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; |
||||
|
|
||||
|
} |
@ -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; |
||||
|
|
||||
|
|
||||
|
} |
@ -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; |
||||
|
|
||||
|
} |
@ -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; |
||||
|
|
||||
|
} |
@ -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; |
||||
|
|
||||
|
|
||||
|
} |
@ -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; |
||||
|
} |
@ -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; |
||||
|
|
||||
|
} |
@ -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; |
||||
|
|
||||
|
} |
@ -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; |
||||
|
} |
@ -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; |
||||
|
|
||||
|
} |
@ -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<ContractualCaseArticles, ContractualCaseArticlesVo> { |
||||
|
|
||||
|
/** |
||||
|
* 根据案例文件ID真实删除条款记录 |
||||
|
* @param caseFileId 案例文件ID |
||||
|
* @return 删除的记录数 |
||||
|
*/ |
||||
|
int realDeleteByCaseFileId(@Param("caseFileId") Long caseFileId); |
||||
|
|
||||
|
} |
@ -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<ContractualCaseFiles, ContractualCaseFilesVo> { |
||||
|
|
||||
|
/** |
||||
|
* 真实删除案例文件记录 |
||||
|
* @param id 案例文件ID |
||||
|
* @return 删除的记录数 |
||||
|
*/ |
||||
|
int realDeleteById(@Param("id") Long id); |
||||
|
|
||||
|
} |
@ -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<ContractualRegulationArticles, ContractualRegulationArticlesVo> { |
||||
|
|
||||
|
/** |
||||
|
* 根据法规ID真实删除所有条款 |
||||
|
* @param regulationNameId 法规名称ID |
||||
|
* @return 删除的记录数 |
||||
|
*/ |
||||
|
@Delete("DELETE FROM contractual_regulation_articles WHERE regulation_name_id = #{regulationNameId}") |
||||
|
int realDeleteByRegulationNameId(@Param("regulationNameId") Long regulationNameId); |
||||
|
} |
@ -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<ContractualRegulationNames, ContractualRegulationNamesVo> { |
||||
|
|
||||
|
/** |
||||
|
* 真实删除法规记录 |
||||
|
* @param id 法规ID |
||||
|
* @return 删除的记录数 |
||||
|
*/ |
||||
|
@Delete("DELETE FROM contractual_regulation_names WHERE id = #{id}") |
||||
|
int realDeleteById(@Param("id") Long id); |
||||
|
|
||||
|
/** |
||||
|
* 批量真实删除法规记录 |
||||
|
* @param ids 法规ID集合 |
||||
|
* @return 删除的记录数 |
||||
|
*/ |
||||
|
@Delete("<script>" + |
||||
|
"DELETE FROM contractual_regulation_names WHERE id IN " + |
||||
|
"<foreach collection='ids' item='id' open='(' separator=',' close=')'>" + |
||||
|
"#{id}" + |
||||
|
"</foreach>" + |
||||
|
"</script>") |
||||
|
int realDeleteByIds(@Param("ids") Collection<Long> ids); |
||||
|
} |
@ -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<ContractualCaseFilesVo> queryPageList(ContractualCaseFilesBo bo, PageQuery pageQuery); |
||||
|
|
||||
|
/** |
||||
|
* 查询符合条件的合同案例文件列表 |
||||
|
* |
||||
|
* @param bo 查询条件 |
||||
|
* @return 合同案例文件列表 |
||||
|
*/ |
||||
|
List<ContractualCaseFilesVo> 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<Long> ids, Boolean isValid); |
||||
|
|
||||
|
/** |
||||
|
* 获取案例条款列表 |
||||
|
* |
||||
|
* @param caseFileId 案例文件ID |
||||
|
* @return 案例条款列表 |
||||
|
*/ |
||||
|
List<ContractualCaseArticlesVo> getCaseArticles(Long caseFileId); |
||||
|
|
||||
|
/** |
||||
|
* 生成案例PDF文档 |
||||
|
* |
||||
|
* @param caseFileId 案例文件ID |
||||
|
* @param response HTTP响应 |
||||
|
*/ |
||||
|
void generateCasePdf(Long caseFileId, HttpServletResponse response); |
||||
|
|
||||
|
} |
@ -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<ContractualRegulationArticlesVo> queryPageList(ContractualRegulationArticlesBo bo, PageQuery pageQuery); |
||||
|
|
||||
|
/** |
||||
|
* 查询符合条件的合同法规法条列表 |
||||
|
* |
||||
|
* @param bo 查询条件 |
||||
|
* @return 合同法规法条列表 |
||||
|
*/ |
||||
|
List<ContractualRegulationArticlesVo> 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<Long> ids, Boolean isValid); |
||||
|
} |
@ -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<ContractualRegulationNamesVo> queryPageList(ContractualRegulationNamesBo bo, PageQuery pageQuery); |
||||
|
|
||||
|
/** |
||||
|
* 查询符合条件的合同法规名称列表 |
||||
|
* |
||||
|
* @param bo 查询条件 |
||||
|
* @return 合同法规名称列表 |
||||
|
*/ |
||||
|
List<ContractualRegulationNamesVo> 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<Long> ids, Boolean isValid); |
||||
|
|
||||
|
/** |
||||
|
* 获取法规条款列表 |
||||
|
* |
||||
|
* @param regulationNameId 法规名称ID |
||||
|
* @return 法规条款列表 |
||||
|
*/ |
||||
|
List<ContractualRegulationArticlesVo> getRegulationArticles(Long regulationNameId); |
||||
|
|
||||
|
/** |
||||
|
* 生成法规PDF文档 |
||||
|
* |
||||
|
* @param regulationNameId 法规名称ID |
||||
|
* @param response HTTP响应 |
||||
|
*/ |
||||
|
void generateRegulationPdf(Long regulationNameId, HttpServletResponse response); |
||||
|
} |
@ -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<ContractualCaseFilesVo> queryPageList(ContractualCaseFilesBo bo, PageQuery pageQuery) { |
||||
|
LambdaQueryWrapper<ContractualCaseFiles> lqw = buildQueryWrapper(bo); |
||||
|
Page<ContractualCaseFilesVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw); |
||||
|
return TableDataInfo.build(result); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 查询符合条件的合同案例文件列表 |
||||
|
* |
||||
|
* @param bo 查询条件 |
||||
|
* @return 合同案例文件列表 |
||||
|
*/ |
||||
|
@Override |
||||
|
public List<ContractualCaseFilesVo> queryList(ContractualCaseFilesBo bo) { |
||||
|
LambdaQueryWrapper<ContractualCaseFiles> lqw = buildQueryWrapper(bo); |
||||
|
return baseMapper.selectVoList(lqw); |
||||
|
} |
||||
|
|
||||
|
private LambdaQueryWrapper<ContractualCaseFiles> buildQueryWrapper(ContractualCaseFilesBo bo) { |
||||
|
Map<String, Object> params = bo.getParams(); |
||||
|
LambdaQueryWrapper<ContractualCaseFiles> 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<ContractualCaseArticles> 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<Long> 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<ContractualCaseArticlesVo> getCaseArticles(Long caseFileId) { |
||||
|
LambdaQueryWrapper<ContractualCaseArticles> wrapper = Wrappers.lambdaQuery(); |
||||
|
wrapper.eq(ContractualCaseArticles::getCaseFileId, caseFileId) |
||||
|
.orderByAsc(ContractualCaseArticles::getId); |
||||
|
|
||||
|
List<ContractualCaseArticles> articles = articlesMapper.selectList(wrapper); |
||||
|
List<ContractualCaseArticlesVo> 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<ContractualCaseArticlesVo> 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<ContractualCaseArticlesVo> 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(""" |
||||
|
<!DOCTYPE html> |
||||
|
<html> |
||||
|
<head> |
||||
|
<meta charset="UTF-8"/> |
||||
|
<style type="text/css"> |
||||
|
body { |
||||
|
font-family: Microsoft YaHei, SimSun, Arial, sans-serif; |
||||
|
line-height: 1.8; |
||||
|
margin: 40px; |
||||
|
font-size: 14px; |
||||
|
color: #333; |
||||
|
} |
||||
|
.title { |
||||
|
font-size: 24px; |
||||
|
font-weight: bold; |
||||
|
text-align: center; |
||||
|
margin-bottom: 20px; |
||||
|
color: #000; |
||||
|
} |
||||
|
.case-info { |
||||
|
text-align: center; |
||||
|
margin-bottom: 30px; |
||||
|
font-size: 16px; |
||||
|
color: #666; |
||||
|
} |
||||
|
.case-info div { |
||||
|
margin-bottom: 10px; |
||||
|
} |
||||
|
.article { |
||||
|
margin-bottom: 30px; |
||||
|
text-align: justify; |
||||
|
text-indent: 2em; |
||||
|
} |
||||
|
.article-number { |
||||
|
font-weight: bold; |
||||
|
color: #000; |
||||
|
} |
||||
|
p { |
||||
|
margin: 15px 0; |
||||
|
line-height: 2.0; |
||||
|
} |
||||
|
</style> |
||||
|
</head> |
||||
|
<body> |
||||
|
"""); |
||||
|
|
||||
|
// 添加标题
|
||||
|
html.append("<div class=\"title\">").append(caseFile.getCaseName()).append("</div>"); |
||||
|
|
||||
|
// 添加案例信息
|
||||
|
html.append("<div class=\"case-info\">"); |
||||
|
if (StringUtils.isNotBlank(formattedDate)) { |
||||
|
html.append("<div>发布日期:").append(formattedDate).append("</div>"); |
||||
|
} |
||||
|
if (StringUtils.isNotBlank(caseFile.getCaseType())) { |
||||
|
html.append("<div>案例类型:").append(caseFile.getCaseType()).append("</div>"); |
||||
|
} |
||||
|
html.append("</div>"); |
||||
|
|
||||
|
// 添加案例描述
|
||||
|
if (StringUtils.isNotBlank(caseFile.getCaseDescription())) { |
||||
|
html.append("<div class=\"article\">"); |
||||
|
html.append("<p><strong>案例描述:</strong></p>"); |
||||
|
html.append("<p>").append(caseFile.getCaseDescription()).append("</p>"); |
||||
|
html.append("</div>"); |
||||
|
} |
||||
|
|
||||
|
// 添加条款内容
|
||||
|
for (ContractualCaseArticlesVo article : articles) { |
||||
|
html.append("<div class=\"article\">"); |
||||
|
|
||||
|
String content = article.getArticleContent(); |
||||
|
if (StringUtils.isNotBlank(content)) { |
||||
|
// 处理内容,将"第XX条"等内容加粗
|
||||
|
String processedContent = processArticleContent(content); |
||||
|
html.append("<p>").append(processedContent).append("</p>"); |
||||
|
} |
||||
|
|
||||
|
html.append("</div>"); |
||||
|
} |
||||
|
|
||||
|
html.append("</body></html>"); |
||||
|
|
||||
|
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("<span class=\"article-number\">第$1条</span>"); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 处理条款信息(提取序号) |
||||
|
*/ |
||||
|
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<Integer> 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<MutationResult> 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客户端已关闭"); |
||||
|
} |
||||
|
} |
||||
|
} |
@ -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<ContractualRegulationArticlesVo> queryPageList(ContractualRegulationArticlesBo bo, PageQuery pageQuery) { |
||||
|
LambdaQueryWrapper<ContractualRegulationArticles> lqw = buildQueryWrapper(bo); |
||||
|
Page<ContractualRegulationArticlesVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw); |
||||
|
return TableDataInfo.build(result); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 查询符合条件的合同法规法条列表 |
||||
|
* |
||||
|
* @param bo 查询条件 |
||||
|
* @return 合同法规法条列表 |
||||
|
*/ |
||||
|
@Override |
||||
|
public List<ContractualRegulationArticlesVo> queryList(ContractualRegulationArticlesBo bo) { |
||||
|
LambdaQueryWrapper<ContractualRegulationArticles> lqw = buildQueryWrapper(bo); |
||||
|
return baseMapper.selectVoList(lqw); |
||||
|
} |
||||
|
|
||||
|
private LambdaQueryWrapper<ContractualRegulationArticles> buildQueryWrapper(ContractualRegulationArticlesBo bo) { |
||||
|
Map<String, Object> params = bo.getParams(); |
||||
|
LambdaQueryWrapper<ContractualRegulationArticles> 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<Long> 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<MutationResult> 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客户端已关闭"); |
||||
|
} |
||||
|
} |
||||
|
} |
@ -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<ContractualRegulationNamesVo> queryPageList(ContractualRegulationNamesBo bo, PageQuery pageQuery) { |
||||
|
LambdaQueryWrapper<ContractualRegulationNames> lqw = buildQueryWrapper(bo); |
||||
|
Page<ContractualRegulationNamesVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw); |
||||
|
return TableDataInfo.build(result); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 查询符合条件的合同法规名称列表 |
||||
|
* |
||||
|
* @param bo 查询条件 |
||||
|
* @return 合同法规名称列表 |
||||
|
*/ |
||||
|
@Override |
||||
|
public List<ContractualRegulationNamesVo> queryList(ContractualRegulationNamesBo bo) { |
||||
|
LambdaQueryWrapper<ContractualRegulationNames> lqw = buildQueryWrapper(bo); |
||||
|
return baseMapper.selectVoList(lqw); |
||||
|
} |
||||
|
|
||||
|
private LambdaQueryWrapper<ContractualRegulationNames> buildQueryWrapper(ContractualRegulationNamesBo bo) { |
||||
|
Map<String, Object> params = bo.getParams(); |
||||
|
LambdaQueryWrapper<ContractualRegulationNames> 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<ContractualRegulationArticles> 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<Long> 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<ContractualRegulationArticlesVo> getRegulationArticles(Long regulationNameId) { |
||||
|
LambdaQueryWrapper<ContractualRegulationArticles> wrapper = Wrappers.lambdaQuery(); |
||||
|
wrapper.eq(ContractualRegulationArticles::getRegulationNameId, regulationNameId) |
||||
|
.orderByAsc(ContractualRegulationArticles::getId); |
||||
|
|
||||
|
List<ContractualRegulationArticles> articles = articlesMapper.selectList(wrapper); |
||||
|
List<ContractualRegulationArticlesVo> 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<ContractualRegulationArticlesVo> 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<ContractualRegulationArticlesVo> 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(""" |
||||
|
<!DOCTYPE html> |
||||
|
<html> |
||||
|
<head> |
||||
|
<meta charset="UTF-8"/> |
||||
|
<style type="text/css"> |
||||
|
body { |
||||
|
font-family: Microsoft YaHei, SimSun, Arial, sans-serif; |
||||
|
line-height: 1.8; |
||||
|
margin: 40px; |
||||
|
font-size: 14px; |
||||
|
color: #333; |
||||
|
} |
||||
|
.title { |
||||
|
font-size: 24px; |
||||
|
font-weight: bold; |
||||
|
text-align: center; |
||||
|
margin-bottom: 20px; |
||||
|
color: #000; |
||||
|
} |
||||
|
.publish-date { |
||||
|
text-align: center; |
||||
|
margin-bottom: 40px; |
||||
|
font-size: 16px; |
||||
|
color: #666; |
||||
|
} |
||||
|
.article { |
||||
|
margin-bottom: 30px; |
||||
|
text-align: justify; |
||||
|
text-indent: 2em; |
||||
|
} |
||||
|
.article-number { |
||||
|
font-weight: bold; |
||||
|
color: #000; |
||||
|
} |
||||
|
p { |
||||
|
margin: 15px 0; |
||||
|
line-height: 2.0; |
||||
|
} |
||||
|
</style> |
||||
|
</head> |
||||
|
<body> |
||||
|
"""); |
||||
|
|
||||
|
// 添加标题
|
||||
|
html.append("<div class=\"title\">").append(regulation.getRegulationName()).append("</div>"); |
||||
|
|
||||
|
// 添加发布日期
|
||||
|
if (StringUtils.isNotBlank(formattedDate)) { |
||||
|
html.append("<div class=\"publish-date\">发布日期:").append(formattedDate).append("</div>"); |
||||
|
} |
||||
|
|
||||
|
// 添加条款内容
|
||||
|
for (ContractualRegulationArticlesVo article : articles) { |
||||
|
html.append("<div class=\"article\">"); |
||||
|
|
||||
|
String content = article.getArticleContent(); |
||||
|
if (StringUtils.isNotBlank(content)) { |
||||
|
// 处理内容,将"第XX条"加粗
|
||||
|
String processedContent = processArticleContent(content); |
||||
|
html.append("<p>").append(processedContent).append("</p>"); |
||||
|
} |
||||
|
|
||||
|
html.append("</div>"); |
||||
|
} |
||||
|
|
||||
|
html.append("</body></html>"); |
||||
|
|
||||
|
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("<span class=\"article-number\">第$1条</span>"); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 处理条款信息(提取序号) |
||||
|
*/ |
||||
|
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<Integer> 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<MutationResult> 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客户端已关闭"); |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,32 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8" ?> |
||||
|
<!DOCTYPE mapper |
||||
|
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" |
||||
|
"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
||||
|
<mapper namespace="org.dromara.productManagement.mapper.ContractualCaseArticlesMapper"> |
||||
|
|
||||
|
<resultMap type="org.dromara.productManagement.domain.ContractualCaseArticles" id="ContractualCaseArticlesResult"> |
||||
|
<result property="id" column="id" /> |
||||
|
<result property="caseFileId" column="case_file_id" /> |
||||
|
<result property="articleContent" column="article_content" /> |
||||
|
<result property="vectorTableId" column="vector_table_id" /> |
||||
|
<result property="isEffective" column="is_effective" /> |
||||
|
<result property="createBy" column="create_by" /> |
||||
|
<result property="createTime" column="create_time" /> |
||||
|
<result property="updateBy" column="update_by" /> |
||||
|
<result property="updateTime" column="update_time" /> |
||||
|
<result property="delFlag" column="del_flag" /> |
||||
|
<result property="tenantId" column="tenant_id" /> |
||||
|
</resultMap> |
||||
|
|
||||
|
<sql id="selectContractualCaseArticlesVo"> |
||||
|
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 |
||||
|
</sql> |
||||
|
|
||||
|
<!-- 根据案例文件ID真实删除条款记录 --> |
||||
|
<delete id="realDeleteByCaseFileId" parameterType="java.lang.Long"> |
||||
|
DELETE FROM contractual_case_articles WHERE case_file_id = #{caseFileId} |
||||
|
</delete> |
||||
|
|
||||
|
</mapper> |
@ -0,0 +1,34 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8" ?> |
||||
|
<!DOCTYPE mapper |
||||
|
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" |
||||
|
"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
||||
|
<mapper namespace="org.dromara.productManagement.mapper.ContractualCaseFilesMapper"> |
||||
|
|
||||
|
<resultMap type="org.dromara.productManagement.domain.ContractualCaseFiles" id="ContractualCaseFilesResult"> |
||||
|
<result property="id" column="id" /> |
||||
|
<result property="caseName" column="case_name" /> |
||||
|
<result property="caseDescription" column="case_description" /> |
||||
|
<result property="caseType" column="case_type" /> |
||||
|
<result property="publishDate" column="publish_date" /> |
||||
|
<result property="isEffective" column="is_effective" /> |
||||
|
<result property="progressStatus" column="progress_status" /> |
||||
|
<result property="ossId" column="oss_id" /> |
||||
|
<result property="createBy" column="create_by" /> |
||||
|
<result property="createTime" column="create_time" /> |
||||
|
<result property="updateBy" column="update_by" /> |
||||
|
<result property="updateTime" column="update_time" /> |
||||
|
<result property="delFlag" column="del_flag" /> |
||||
|
</resultMap> |
||||
|
|
||||
|
<sql id="selectContractualCaseFilesVo"> |
||||
|
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 |
||||
|
</sql> |
||||
|
|
||||
|
<!-- 真实删除案例文件记录 --> |
||||
|
<delete id="realDeleteById" parameterType="java.lang.Long"> |
||||
|
DELETE FROM contractual_case_files WHERE id = #{id} |
||||
|
</delete> |
||||
|
|
||||
|
</mapper> |
@ -0,0 +1,7 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8" ?> |
||||
|
<!DOCTYPE mapper |
||||
|
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" |
||||
|
"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
||||
|
<mapper namespace="org.dromara.productManagement.mapper.ContractualRegulationArticlesMapper"> |
||||
|
|
||||
|
</mapper> |
@ -0,0 +1,7 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8" ?> |
||||
|
<!DOCTYPE mapper |
||||
|
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" |
||||
|
"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
||||
|
<mapper namespace="org.dromara.productManagement.mapper.ContractualRegulationNamesMapper"> |
||||
|
|
||||
|
</mapper> |
Loading…
Reference in new issue