27 changed files with 3078 additions and 0 deletions
@ -0,0 +1,96 @@ |
|||||
|
package org.dromara.productManagement.controller; |
||||
|
|
||||
|
import lombok.RequiredArgsConstructor; |
||||
|
import jakarta.servlet.http.HttpServletResponse; |
||||
|
import jakarta.validation.constraints.*; |
||||
|
import org.springframework.web.bind.annotation.*; |
||||
|
import org.springframework.validation.annotation.Validated; |
||||
|
import org.dromara.common.log.annotation.Log; |
||||
|
import org.dromara.common.web.core.BaseController; |
||||
|
import org.dromara.common.core.domain.R; |
||||
|
import org.dromara.common.log.enums.BusinessType; |
||||
|
import org.dromara.productManagement.domain.vo.TenderTaskResultVO; |
||||
|
import org.dromara.productManagement.service.ITenderTaskResultsService; |
||||
|
|
||||
|
import java.util.List; |
||||
|
|
||||
|
/** |
||||
|
* 招投标任务结果 |
||||
|
* |
||||
|
* @author guoyan |
||||
|
* @date 2024-12-14 |
||||
|
*/ |
||||
|
@Validated |
||||
|
@RequiredArgsConstructor |
||||
|
@RestController |
||||
|
@RequestMapping("/tenderTask/tenderTaskResults") |
||||
|
public class TenderTaskResultsController extends BaseController { |
||||
|
|
||||
|
private final ITenderTaskResultsService tenderTaskResultsService; |
||||
|
|
||||
|
/** |
||||
|
* 根据任务ID获取详细的招投标任务结果 |
||||
|
* |
||||
|
* @param taskId 任务ID |
||||
|
*/ |
||||
|
// @SaCheckPermission("productManagement:TenderTaskResults:query")
|
||||
|
@GetMapping("/taskDetail/{taskId}") |
||||
|
public R<List<TenderTaskResultVO>> getDetailResultsByTaskId(@NotNull(message = "任务ID不能为空") |
||||
|
@PathVariable String taskId) { |
||||
|
return R.ok(tenderTaskResultsService.getDetailResultsByTaskId(taskId)); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 下载招投标任务结果 |
||||
|
* |
||||
|
* @param ids 主键串 |
||||
|
*/ |
||||
|
// @SaCheckPermission("productManagement:TenderTaskResults:download")
|
||||
|
@Log(title = "招投标任务结果", businessType = BusinessType.EXPORT) |
||||
|
@GetMapping("/downloadResult/{ids}") |
||||
|
public void download(@NotEmpty(message = "主键不能为空") |
||||
|
@PathVariable Long[] ids, HttpServletResponse response) { |
||||
|
tenderTaskResultsService.downloadResult(ids, response); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取招投标任务PDF文件流 |
||||
|
* |
||||
|
* @param taskId 任务ID |
||||
|
*/ |
||||
|
@GetMapping("/getPdfStream/{taskId}") |
||||
|
public void getPdfStream(@NotNull(message = "任务ID不能为空") |
||||
|
@PathVariable String taskId, |
||||
|
HttpServletResponse response) { |
||||
|
tenderTaskResultsService.getPdfStream(taskId, response); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取招投标文件PDF文件流 |
||||
|
* |
||||
|
* @param taskId 任务ID |
||||
|
*/ |
||||
|
@GetMapping("/getBidPdfStream/{taskId}") |
||||
|
public void getBidPdfStream(@NotNull(message = "任务ID不能为空") |
||||
|
@PathVariable String taskId, |
||||
|
HttpServletResponse response) { |
||||
|
tenderTaskResultsService.getBidPdfStream(taskId, response); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 更新招投标任务结果项的状态(已读/采纳) |
||||
|
* |
||||
|
* @param id 结果项ID |
||||
|
* @param field 字段名(isRead/isAdopted) |
||||
|
* @param value 值(0/1) |
||||
|
*/ |
||||
|
// @SaCheckPermission("productManagement:TenderTaskResults:edit")
|
||||
|
@Log(title = "更新招投标任务结果项状态", businessType = BusinessType.UPDATE) |
||||
|
@PutMapping("/updateResultItemStatus/{id}/{field}/{value}") |
||||
|
public R<Void> updateResultItemStatus( |
||||
|
@NotEmpty(message = "ID不能为空") @PathVariable("id") String id, |
||||
|
@NotEmpty(message = "字段名不能为空") @PathVariable("field") String field, |
||||
|
@NotEmpty(message = "值不能为空") @PathVariable("value") String value) { |
||||
|
return toAjax(tenderTaskResultsService.updateResultItemStatus(id, field, value)); |
||||
|
} |
||||
|
} |
@ -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.TenderTaskTypeVo; |
||||
|
import org.dromara.productManagement.domain.bo.TenderTaskTypeBo; |
||||
|
import org.dromara.productManagement.service.ITenderTaskTypeService; |
||||
|
import org.dromara.common.mybatis.core.page.TableDataInfo; |
||||
|
|
||||
|
/** |
||||
|
* 招投标类型 |
||||
|
* |
||||
|
* @author guoyan |
||||
|
* @date 2024-12-14 |
||||
|
*/ |
||||
|
@Validated |
||||
|
@RequiredArgsConstructor |
||||
|
@RestController |
||||
|
@RequestMapping("/tenderTask/tenderTaskType") |
||||
|
public class TenderTaskTypeController extends BaseController { |
||||
|
|
||||
|
private final ITenderTaskTypeService tenderTaskTypeService; |
||||
|
|
||||
|
/** |
||||
|
* 查询招投标类型列表 |
||||
|
*/ |
||||
|
// @SaCheckPermission("productManagement:TenderTaskType:list")
|
||||
|
@GetMapping("/list") |
||||
|
public R<List<TenderTaskTypeVo>> list(TenderTaskTypeBo bo) { |
||||
|
return R.ok(tenderTaskTypeService.queryList(bo)); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 导出招投标类型列表 |
||||
|
*/ |
||||
|
// @SaCheckPermission("productManagement:TenderTaskType:export")
|
||||
|
@Log(title = "招投标类型", businessType = BusinessType.EXPORT) |
||||
|
@PostMapping("/export") |
||||
|
public void export(TenderTaskTypeBo bo, HttpServletResponse response) { |
||||
|
List<TenderTaskTypeVo> list = tenderTaskTypeService.queryList(bo); |
||||
|
ExcelUtil.exportExcel(list, "招投标类型", TenderTaskTypeVo.class, response); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取招投标类型详细信息 |
||||
|
* |
||||
|
* @param id 主键 |
||||
|
*/ |
||||
|
// @SaCheckPermission("productManagement:TenderTaskType:query")
|
||||
|
@GetMapping("/{id}") |
||||
|
public R<TenderTaskTypeVo> getInfo(@NotNull(message = "主键不能为空") |
||||
|
@PathVariable Long id) { |
||||
|
return R.ok(tenderTaskTypeService.queryById(id)); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 新增招投标类型 |
||||
|
*/ |
||||
|
// @SaCheckPermission("productManagement:TenderTaskType:add")
|
||||
|
@Log(title = "招投标类型", businessType = BusinessType.INSERT) |
||||
|
@RepeatSubmit() |
||||
|
@PostMapping() |
||||
|
public R<Void> add(@Validated(AddGroup.class) @RequestBody TenderTaskTypeBo bo) { |
||||
|
return toAjax(tenderTaskTypeService.insertByBo(bo)); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 修改招投标类型 |
||||
|
*/ |
||||
|
// @SaCheckPermission("productManagement:TenderTaskType:edit")
|
||||
|
@Log(title = "招投标类型", businessType = BusinessType.UPDATE) |
||||
|
@RepeatSubmit() |
||||
|
@PutMapping() |
||||
|
public R<Void> edit(@Validated(EditGroup.class) @RequestBody TenderTaskTypeBo bo) { |
||||
|
return toAjax(tenderTaskTypeService.updateByBo(bo)); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 删除招投标类型 |
||||
|
* |
||||
|
* @param ids 主键串 |
||||
|
*/ |
||||
|
// @SaCheckPermission("productManagement:TenderTaskType:remove")
|
||||
|
@Log(title = "招投标类型", businessType = BusinessType.DELETE) |
||||
|
@DeleteMapping("/{ids}") |
||||
|
public R<Void> remove(@NotEmpty(message = "主键不能为空") |
||||
|
@PathVariable Long[] ids) { |
||||
|
return toAjax(tenderTaskTypeService.deleteWithValidByIds(List.of(ids), true)); |
||||
|
} |
||||
|
} |
@ -0,0 +1,118 @@ |
|||||
|
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.excel.utils.ExcelUtil; |
||||
|
import org.dromara.productManagement.domain.TenderTaskGroup; |
||||
|
import org.dromara.productManagement.domain.vo.TenderTasksVo; |
||||
|
import org.dromara.productManagement.domain.bo.TenderTasksBo; |
||||
|
import org.dromara.productManagement.service.ITenderTasksService; |
||||
|
import org.dromara.common.mybatis.core.page.TableDataInfo; |
||||
|
import org.dromara.common.log.enums.BusinessType; |
||||
|
import io.swagger.v3.oas.annotations.tags.Tag; |
||||
|
import io.swagger.v3.oas.annotations.Parameter; |
||||
|
import io.swagger.v3.oas.annotations.Operation; |
||||
|
|
||||
|
/** |
||||
|
* 招投标审核任务 |
||||
|
* |
||||
|
* @author ruoyi |
||||
|
* @date 2024-01-01 |
||||
|
*/ |
||||
|
@Validated |
||||
|
@RequiredArgsConstructor |
||||
|
@RestController |
||||
|
@RequestMapping("/tenderTask/tenderTasks") |
||||
|
@Tag(name = "招投标审核任务管理", description = "招投标审核任务管理") |
||||
|
public class TenderTasksController extends BaseController { |
||||
|
|
||||
|
private final ITenderTasksService tenderTasksService; |
||||
|
|
||||
|
/** |
||||
|
* 查询招投标审核任务列表(父子结构) |
||||
|
*/ |
||||
|
@SaCheckPermission("tender:tasks:list") |
||||
|
@GetMapping("/list") |
||||
|
public TableDataInfo<TenderTaskGroup> list(TenderTasksBo bo, PageQuery pageQuery) { |
||||
|
return tenderTasksService.queryGroupPageList(bo, pageQuery); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 导出招投标审核任务列表 |
||||
|
*/ |
||||
|
@SaCheckPermission("tender:tasks:export") |
||||
|
@Log(title = "招投标审核任务", businessType = BusinessType.EXPORT) |
||||
|
@PostMapping("/export") |
||||
|
public void export(TenderTasksBo bo, HttpServletResponse response) { |
||||
|
List<TenderTasksVo> list = tenderTasksService.queryList(bo); |
||||
|
ExcelUtil.exportExcel(list, "招投标审核任务", TenderTasksVo.class, response); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取招投标审核任务详细信息 |
||||
|
*/ |
||||
|
@SaCheckPermission("tender:tasks:query") |
||||
|
@GetMapping("/{id}") |
||||
|
public R<TenderTasksVo> getInfo(@NotNull(message = "主键不能为空") |
||||
|
@PathVariable Long id) { |
||||
|
return R.ok(tenderTasksService.queryById(id)); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 新增招投标审核任务 |
||||
|
*/ |
||||
|
@SaCheckPermission("tender:tasks:add") |
||||
|
@Log(title = "招投标审核任务", businessType = BusinessType.INSERT) |
||||
|
@RepeatSubmit() |
||||
|
@PostMapping() |
||||
|
public R<Void> add(@Validated(AddGroup.class) @RequestBody TenderTasksBo bo) { |
||||
|
return toAjax(tenderTasksService.insertByBo(bo)); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 修改招投标审核任务 |
||||
|
*/ |
||||
|
@SaCheckPermission("tender:tasks:edit") |
||||
|
@Log(title = "招投标审核任务", businessType = BusinessType.UPDATE) |
||||
|
@RepeatSubmit() |
||||
|
@PutMapping() |
||||
|
public R<Void> edit(@Validated(EditGroup.class) @RequestBody TenderTasksBo bo) { |
||||
|
return toAjax(tenderTasksService.updateByBo(bo)); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 删除招投标审核任务 |
||||
|
*/ |
||||
|
@SaCheckPermission("tender:tasks:remove") |
||||
|
@Log(title = "招投标审核任务", businessType = BusinessType.DELETE) |
||||
|
@DeleteMapping("/{ids}") |
||||
|
public R<Void> remove(@NotEmpty(message = "主键不能为空") |
||||
|
@PathVariable Long[] ids) { |
||||
|
return toAjax(tenderTasksService.deleteWithValidByIds(List.of(ids), true)); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 删除招投标任务文件 |
||||
|
*/ |
||||
|
@SaCheckPermission("tender:tasks:remove") |
||||
|
@Log(title = "删除招投标任务文件", businessType = BusinessType.DELETE) |
||||
|
@DeleteMapping("/ossRemoveById/{ossid}") |
||||
|
public R<Void> ossRemoveById(@NotEmpty(message = "主键不能为空") |
||||
|
@PathVariable String ossid) { |
||||
|
return toAjax(tenderTasksService.ossRemoveById(ossid, true)); |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,91 @@ |
|||||
|
package org.dromara.productManagement.domain; |
||||
|
|
||||
|
import lombok.Data; |
||||
|
|
||||
|
import java.util.Date; |
||||
|
|
||||
|
/** |
||||
|
* 招投标任务子项对象 |
||||
|
* |
||||
|
* @author ruoyi |
||||
|
* @date 2024-01-01 |
||||
|
*/ |
||||
|
@Data |
||||
|
public class TenderTaskChild { |
||||
|
|
||||
|
/** |
||||
|
* 任务ID |
||||
|
*/ |
||||
|
private Long id; |
||||
|
|
||||
|
/** |
||||
|
* 任务名称 |
||||
|
*/ |
||||
|
private String taskName; |
||||
|
|
||||
|
/** |
||||
|
* 招标文件名称 |
||||
|
*/ |
||||
|
private String tenderDocumentName; |
||||
|
|
||||
|
/** |
||||
|
* 投标文件名称 |
||||
|
*/ |
||||
|
private String bidDocumentName; |
||||
|
|
||||
|
/** |
||||
|
* 进展状态 |
||||
|
*/ |
||||
|
private String progressStatus; |
||||
|
|
||||
|
/** |
||||
|
* 任务组ID |
||||
|
*/ |
||||
|
private Long groupId; |
||||
|
|
||||
|
/** |
||||
|
* 列队任务ID |
||||
|
*/ |
||||
|
private String taskId; |
||||
|
|
||||
|
/** |
||||
|
* 审核结果 |
||||
|
*/ |
||||
|
private String resultType; |
||||
|
|
||||
|
/** |
||||
|
* 招标文件oss存储id |
||||
|
*/ |
||||
|
private String tenderDocOssId; |
||||
|
|
||||
|
/** |
||||
|
* 投标文件oss存储id |
||||
|
*/ |
||||
|
private String bidDocZipOssId; |
||||
|
|
||||
|
/** |
||||
|
* 版本号 |
||||
|
*/ |
||||
|
private Long version; |
||||
|
|
||||
|
/** |
||||
|
* 创建时间 |
||||
|
*/ |
||||
|
private Date createTime; |
||||
|
|
||||
|
/** |
||||
|
* 更新时间 |
||||
|
*/ |
||||
|
private Date updateTime; |
||||
|
|
||||
|
/** |
||||
|
* 任务持续时间 |
||||
|
*/ |
||||
|
private String taskDuration; |
||||
|
|
||||
|
/** |
||||
|
* 创建用户 |
||||
|
*/ |
||||
|
private String createUser; |
||||
|
|
||||
|
} |
@ -0,0 +1,67 @@ |
|||||
|
package org.dromara.productManagement.domain; |
||||
|
|
||||
|
import lombok.Data; |
||||
|
|
||||
|
import java.io.Serial; |
||||
|
import java.io.Serializable; |
||||
|
import java.util.Date; |
||||
|
import java.util.List; |
||||
|
|
||||
|
/** |
||||
|
* 招投标任务分组对象 |
||||
|
* |
||||
|
* @author ruoyi |
||||
|
* @date 2024-01-01 |
||||
|
*/ |
||||
|
@Data |
||||
|
public class TenderTaskGroup implements Serializable { |
||||
|
|
||||
|
@Serial |
||||
|
private static final long serialVersionUID = 1L; |
||||
|
|
||||
|
/** |
||||
|
* 分组ID |
||||
|
*/ |
||||
|
private String id; |
||||
|
|
||||
|
/** |
||||
|
* 创建者ID |
||||
|
*/ |
||||
|
private Long createBy; |
||||
|
|
||||
|
/** |
||||
|
* 招标文件名称 |
||||
|
*/ |
||||
|
private String tenderDocumentName; |
||||
|
|
||||
|
/** |
||||
|
* 投标文件名称 |
||||
|
*/ |
||||
|
private String bidDocumentName; |
||||
|
|
||||
|
/** |
||||
|
* 创建时间 |
||||
|
*/ |
||||
|
private Date createTime; |
||||
|
|
||||
|
/** |
||||
|
* 创建用户 |
||||
|
*/ |
||||
|
private String createUser; |
||||
|
|
||||
|
/** |
||||
|
* 进度信息 |
||||
|
*/ |
||||
|
private String progress; |
||||
|
|
||||
|
/** |
||||
|
* 文件删除标志 |
||||
|
*/ |
||||
|
private String deleteFlag; |
||||
|
|
||||
|
/** |
||||
|
* 子任务列表 |
||||
|
*/ |
||||
|
private List<TenderTaskChild> childrenTasks; |
||||
|
|
||||
|
} |
@ -0,0 +1,51 @@ |
|||||
|
package org.dromara.productManagement.domain; |
||||
|
|
||||
|
import org.dromara.common.tenant.core.TenantEntity; |
||||
|
import com.baomidou.mybatisplus.annotation.*; |
||||
|
import lombok.Data; |
||||
|
import lombok.EqualsAndHashCode; |
||||
|
|
||||
|
/** |
||||
|
* 招投标审核结果详情对象 tender_task_result_detail |
||||
|
* |
||||
|
* @author ruoyi |
||||
|
* @date 2024-01-01 |
||||
|
*/ |
||||
|
@Data |
||||
|
@EqualsAndHashCode(callSuper = true) |
||||
|
@TableName("tender_task_result_details") |
||||
|
public class TenderTaskResultDetail extends TenantEntity { |
||||
|
|
||||
|
@TableId(value = "id") |
||||
|
private String id; |
||||
|
|
||||
|
/** |
||||
|
* 分类id |
||||
|
*/ |
||||
|
private String categoryId; |
||||
|
private String issueName; // 问题点名称
|
||||
|
|
||||
|
private String originalText; // 原文
|
||||
|
|
||||
|
private String comparedText; // 比对原文
|
||||
|
|
||||
|
private String modifiedContent; // 修改后的内容
|
||||
|
|
||||
|
private String modificationDisplay; // 展示修改情况
|
||||
|
|
||||
|
private String existingIssues; // 存在的问题
|
||||
|
|
||||
|
private String reviewBasis; // 审查依据
|
||||
|
|
||||
|
private String isRead; // 是否已读
|
||||
|
|
||||
|
private String isAdopted; // 是否采纳
|
||||
|
|
||||
|
/** |
||||
|
* 删除标志 |
||||
|
*/ |
||||
|
@TableLogic |
||||
|
private String delFlag; |
||||
|
private int sortOrder; |
||||
|
|
||||
|
} |
@ -0,0 +1,62 @@ |
|||||
|
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; |
||||
|
|
||||
|
/** |
||||
|
* 招投标类型对象 tender_task_type |
||||
|
* |
||||
|
* @author guoyan |
||||
|
* @date 2024-12-14 |
||||
|
*/ |
||||
|
@Data |
||||
|
@EqualsAndHashCode(callSuper = true) |
||||
|
@TableName("tender_task_type") |
||||
|
public class TenderTaskType extends TenantEntity { |
||||
|
|
||||
|
@Serial |
||||
|
private static final long serialVersionUID = 1L; |
||||
|
|
||||
|
/** |
||||
|
* 类型ID |
||||
|
*/ |
||||
|
@TableId(value = "id") |
||||
|
private Long id; |
||||
|
|
||||
|
/** |
||||
|
* 招投标类型名称 |
||||
|
*/ |
||||
|
private String tenderName; |
||||
|
|
||||
|
/** |
||||
|
* 显示顺序 |
||||
|
*/ |
||||
|
private Long sort; |
||||
|
|
||||
|
/** |
||||
|
* 状态(0正常 1停用) |
||||
|
*/ |
||||
|
private String status; |
||||
|
|
||||
|
/** |
||||
|
* 删除标志(0代表存在 1代表删除) |
||||
|
*/ |
||||
|
@TableLogic |
||||
|
private String delFlag; |
||||
|
|
||||
|
/** |
||||
|
* 版本号 |
||||
|
*/ |
||||
|
@Version |
||||
|
private Long version; |
||||
|
|
||||
|
/** |
||||
|
* 备注 |
||||
|
*/ |
||||
|
private String remark; |
||||
|
|
||||
|
} |
@ -0,0 +1,101 @@ |
|||||
|
package org.dromara.productManagement.domain; |
||||
|
|
||||
|
import org.dromara.common.tenant.core.TenantEntity; |
||||
|
import com.baomidou.mybatisplus.annotation.*; |
||||
|
import lombok.Data; |
||||
|
import lombok.EqualsAndHashCode; |
||||
|
|
||||
|
import jakarta.validation.constraints.NotBlank; |
||||
|
import jakarta.validation.constraints.Size; |
||||
|
|
||||
|
/** |
||||
|
* 招投标审核任务对象 tender_tasks |
||||
|
* |
||||
|
* @author ruoyi |
||||
|
* @date 2024-01-01 |
||||
|
*/ |
||||
|
@Data |
||||
|
@EqualsAndHashCode(callSuper = true) |
||||
|
@TableName("tender_tasks") |
||||
|
public class TenderTasks extends TenantEntity { |
||||
|
|
||||
|
private static final long serialVersionUID = 1L; |
||||
|
|
||||
|
/** |
||||
|
* 主键ID |
||||
|
*/ |
||||
|
@TableId(value = "id") |
||||
|
private Long id; |
||||
|
|
||||
|
/** |
||||
|
* 任务名称 |
||||
|
*/ |
||||
|
@NotBlank(message = "任务名称不能为空") |
||||
|
private String taskName; |
||||
|
|
||||
|
/** |
||||
|
* 招标文件名称 |
||||
|
*/ |
||||
|
private String tenderDocumentName; |
||||
|
|
||||
|
/** |
||||
|
* 投标文件名称 |
||||
|
*/ |
||||
|
private String bidDocumentName; |
||||
|
|
||||
|
/** |
||||
|
* 进展状态 |
||||
|
*/ |
||||
|
private String progressStatus; |
||||
|
|
||||
|
/** |
||||
|
* 文档是否删除 (Y/N) |
||||
|
*/ |
||||
|
private String deleteFlag; |
||||
|
|
||||
|
/** |
||||
|
* 删除标志 |
||||
|
*/ |
||||
|
private String delFlag; |
||||
|
|
||||
|
/** |
||||
|
* 版本号 |
||||
|
*/ |
||||
|
private Long version; |
||||
|
|
||||
|
/** |
||||
|
* 创建部门 |
||||
|
*/ |
||||
|
private Long createDept; |
||||
|
|
||||
|
/** |
||||
|
* 任务组ID |
||||
|
*/ |
||||
|
private Long groupId; |
||||
|
|
||||
|
/** |
||||
|
* 列队任务ID |
||||
|
*/ |
||||
|
private String taskId; |
||||
|
|
||||
|
/** |
||||
|
* 审核结果 |
||||
|
*/ |
||||
|
private String resultType; |
||||
|
|
||||
|
/** |
||||
|
* 招标文件oss存储id |
||||
|
*/ |
||||
|
private String tenderDocOssId; |
||||
|
|
||||
|
/** |
||||
|
* 投标文件oss存储id |
||||
|
*/ |
||||
|
private String bidDocZipOssId; |
||||
|
|
||||
|
/** |
||||
|
* PDF文件路径 |
||||
|
*/ |
||||
|
private String pdfPath; |
||||
|
|
||||
|
} |
@ -0,0 +1,87 @@ |
|||||
|
package org.dromara.productManagement.domain.bo; |
||||
|
|
||||
|
import io.github.linpeilie.annotations.AutoMapper; |
||||
|
import org.dromara.common.mybatis.core.domain.BaseEntity; |
||||
|
import org.dromara.common.core.validate.AddGroup; |
||||
|
import org.dromara.common.core.validate.EditGroup; |
||||
|
import lombok.Data; |
||||
|
import lombok.EqualsAndHashCode; |
||||
|
|
||||
|
import jakarta.validation.constraints.*; |
||||
|
import org.dromara.productManagement.domain.TenderTaskResultDetail; |
||||
|
|
||||
|
/** |
||||
|
* 招投标审核结果详情业务对象 tender_task_result_detail |
||||
|
* |
||||
|
* @author ruoyi |
||||
|
* @date 2024-01-01 |
||||
|
*/ |
||||
|
@Data |
||||
|
@EqualsAndHashCode(callSuper = true) |
||||
|
@AutoMapper(target = TenderTaskResultDetail.class, reverseConvertGenerate = false) |
||||
|
public class TenderTaskResultDetailBo extends BaseEntity { |
||||
|
|
||||
|
/** |
||||
|
* 主键ID |
||||
|
*/ |
||||
|
@NotBlank(message = "主键ID不能为空", groups = { EditGroup.class }) |
||||
|
private String id; |
||||
|
|
||||
|
/** |
||||
|
* 分类id |
||||
|
*/ |
||||
|
private String categoryId; |
||||
|
|
||||
|
/** |
||||
|
* 问题点名称 |
||||
|
*/ |
||||
|
private String issueName; |
||||
|
|
||||
|
/** |
||||
|
* 原文 |
||||
|
*/ |
||||
|
private String originalText; |
||||
|
|
||||
|
/** |
||||
|
* 比对原文 |
||||
|
*/ |
||||
|
private String comparedText; |
||||
|
|
||||
|
/** |
||||
|
* 修改后的内容 |
||||
|
*/ |
||||
|
private String modifiedContent; |
||||
|
|
||||
|
/** |
||||
|
* 展示修改情况 |
||||
|
*/ |
||||
|
private String modificationDisplay; |
||||
|
|
||||
|
/** |
||||
|
* 存在的问题 |
||||
|
*/ |
||||
|
private String existingIssues; |
||||
|
|
||||
|
/** |
||||
|
* 审查依据 |
||||
|
*/ |
||||
|
private String reviewBasis; |
||||
|
|
||||
|
/** |
||||
|
* 是否已读 |
||||
|
*/ |
||||
|
private String isRead; |
||||
|
|
||||
|
/** |
||||
|
* 是否采纳 |
||||
|
*/ |
||||
|
private String isAdopted; |
||||
|
|
||||
|
/** |
||||
|
* 删除标志 |
||||
|
*/ |
||||
|
private String delFlag; |
||||
|
|
||||
|
private int sortOrder; |
||||
|
|
||||
|
} |
@ -0,0 +1,51 @@ |
|||||
|
package org.dromara.productManagement.domain.bo; |
||||
|
|
||||
|
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 org.dromara.common.tenant.core.TenantEntity; |
||||
|
import org.dromara.productManagement.domain.TenderTaskType; |
||||
|
|
||||
|
/** |
||||
|
* 招投标类型业务对象 |
||||
|
* |
||||
|
* @author guoyan |
||||
|
* @date 2024-12-14 |
||||
|
*/ |
||||
|
@Data |
||||
|
@EqualsAndHashCode(callSuper = true) |
||||
|
@AutoMapper(target = TenderTaskType.class, reverseConvertGenerate = false) |
||||
|
public class TenderTaskTypeBo extends TenantEntity { |
||||
|
|
||||
|
/** |
||||
|
* 类型ID |
||||
|
*/ |
||||
|
@NotNull(message = "类型ID不能为空", groups = { EditGroup.class }) |
||||
|
private Long id; |
||||
|
|
||||
|
/** |
||||
|
* 招投标类型名称 |
||||
|
*/ |
||||
|
@NotBlank(message = "招投标类型名称不能为空", groups = { AddGroup.class, EditGroup.class }) |
||||
|
private String tenderName; |
||||
|
|
||||
|
/** |
||||
|
* 显示顺序 |
||||
|
*/ |
||||
|
private Long sort; |
||||
|
|
||||
|
/** |
||||
|
* 状态(0正常 1停用) |
||||
|
*/ |
||||
|
private String status; |
||||
|
|
||||
|
/** |
||||
|
* 备注 |
||||
|
*/ |
||||
|
private String remark; |
||||
|
|
||||
|
} |
@ -0,0 +1,104 @@ |
|||||
|
package org.dromara.productManagement.domain.bo; |
||||
|
|
||||
|
import io.github.linpeilie.annotations.AutoMapper; |
||||
|
import org.dromara.common.mybatis.core.domain.BaseEntity; |
||||
|
import org.dromara.common.core.validate.AddGroup; |
||||
|
import org.dromara.common.core.validate.EditGroup; |
||||
|
import lombok.Data; |
||||
|
import lombok.EqualsAndHashCode; |
||||
|
|
||||
|
import jakarta.validation.constraints.*; |
||||
|
import org.dromara.productManagement.domain.TenderTasks; |
||||
|
|
||||
|
import java.util.List; |
||||
|
|
||||
|
/** |
||||
|
* 招投标审核任务业务对象 tender_tasks |
||||
|
* |
||||
|
* @author ruoyi |
||||
|
* @date 2024-01-01 |
||||
|
*/ |
||||
|
@Data |
||||
|
@EqualsAndHashCode(callSuper = true) |
||||
|
@AutoMapper(target = TenderTasks.class, reverseConvertGenerate = false) |
||||
|
public class TenderTasksBo extends BaseEntity { |
||||
|
|
||||
|
/** |
||||
|
* 主键ID |
||||
|
*/ |
||||
|
@NotNull(message = "主键ID不能为空", groups = { EditGroup.class }) |
||||
|
private Long id; |
||||
|
|
||||
|
/** |
||||
|
* 任务名称 |
||||
|
*/ |
||||
|
@NotBlank(message = "任务名称不能为空") |
||||
|
private String taskName; |
||||
|
|
||||
|
/** |
||||
|
* 任务名称列表(用于多选) |
||||
|
*/ |
||||
|
@NotEmpty(message = "任务名称列表不能为空", groups = { AddGroup.class }) |
||||
|
private List<@NotBlank(message = "任务名称不能为空") String> taskNameList; |
||||
|
|
||||
|
/** |
||||
|
* 招标文件名称 |
||||
|
*/ |
||||
|
private String tenderDocumentName; |
||||
|
|
||||
|
/** |
||||
|
* 投标文件名称 |
||||
|
*/ |
||||
|
private String bidDocumentName; |
||||
|
|
||||
|
/** |
||||
|
* 进展状态 |
||||
|
*/ |
||||
|
private String progressStatus; |
||||
|
|
||||
|
/** |
||||
|
* 文档是否删除 (Y/N) |
||||
|
*/ |
||||
|
private String deleteFlag; |
||||
|
|
||||
|
/** |
||||
|
* 删除标志 |
||||
|
*/ |
||||
|
private String delFlag; |
||||
|
|
||||
|
/** |
||||
|
* 版本号 |
||||
|
*/ |
||||
|
private Long version; |
||||
|
|
||||
|
/** |
||||
|
* 创建部门 |
||||
|
*/ |
||||
|
private Long createDept; |
||||
|
|
||||
|
/** |
||||
|
* 任务组ID |
||||
|
*/ |
||||
|
private Long groupId; |
||||
|
|
||||
|
/** |
||||
|
* 列队任务ID |
||||
|
*/ |
||||
|
private String taskId; |
||||
|
|
||||
|
/** |
||||
|
* 审核结果 |
||||
|
*/ |
||||
|
private String resultType; |
||||
|
|
||||
|
/** |
||||
|
* 招标文件oss存储id |
||||
|
*/ |
||||
|
private String tenderDocOssId; |
||||
|
|
||||
|
/** |
||||
|
* 投标文件oss存储id |
||||
|
*/ |
||||
|
private String bidDocZipOssId; |
||||
|
|
||||
|
} |
@ -0,0 +1,130 @@ |
|||||
|
package org.dromara.productManagement.domain.vo; |
||||
|
|
||||
|
|
||||
|
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; |
||||
|
import com.alibaba.excel.annotation.ExcelProperty; |
||||
|
import io.github.linpeilie.annotations.AutoMapper; |
||||
|
import org.dromara.common.excel.annotation.ExcelDictFormat; |
||||
|
import org.dromara.common.excel.convert.ExcelDictConvert; |
||||
|
import lombok.Data; |
||||
|
import org.dromara.productManagement.domain.TenderTaskResultDetail; |
||||
|
|
||||
|
import java.util.Date; |
||||
|
|
||||
|
/** |
||||
|
* 招投标审核结果详情视图对象 tender_task_result_detail |
||||
|
* |
||||
|
* @author ruoyi |
||||
|
* @date 2024-01-01 |
||||
|
*/ |
||||
|
@Data |
||||
|
@ExcelIgnoreUnannotated |
||||
|
@AutoMapper(target = TenderTaskResultDetail.class) |
||||
|
public class TenderTaskResultDetailVo { |
||||
|
|
||||
|
private static final long serialVersionUID = 1L; |
||||
|
|
||||
|
/** |
||||
|
* 主键ID |
||||
|
*/ |
||||
|
@ExcelProperty(value = "主键ID") |
||||
|
private String id; |
||||
|
|
||||
|
/** |
||||
|
* 分类id |
||||
|
*/ |
||||
|
@ExcelProperty(value = "分类ID") |
||||
|
private String categoryId; |
||||
|
|
||||
|
/** |
||||
|
* 问题点名称 |
||||
|
*/ |
||||
|
@ExcelProperty(value = "问题点名称") |
||||
|
private String issueName; |
||||
|
|
||||
|
/** |
||||
|
* 原文 |
||||
|
*/ |
||||
|
@ExcelProperty(value = "原文") |
||||
|
private String originalText; |
||||
|
|
||||
|
/** |
||||
|
* 比对原文 |
||||
|
*/ |
||||
|
@ExcelProperty(value = "比对原文") |
||||
|
private String comparedText; |
||||
|
|
||||
|
/** |
||||
|
* 修改后的内容 |
||||
|
*/ |
||||
|
@ExcelProperty(value = "修改后的内容") |
||||
|
private String modifiedContent; |
||||
|
|
||||
|
/** |
||||
|
* 展示修改情况 |
||||
|
*/ |
||||
|
@ExcelProperty(value = "展示修改情况") |
||||
|
private String modificationDisplay; |
||||
|
|
||||
|
/** |
||||
|
* 存在的问题 |
||||
|
*/ |
||||
|
@ExcelProperty(value = "存在的问题") |
||||
|
private String existingIssues; |
||||
|
|
||||
|
/** |
||||
|
* 审查依据 |
||||
|
*/ |
||||
|
@ExcelProperty(value = "审查依据") |
||||
|
private String reviewBasis; |
||||
|
|
||||
|
/** |
||||
|
* 是否已读 |
||||
|
*/ |
||||
|
@ExcelDictFormat(dictType = "is_read") |
||||
|
private String isRead; |
||||
|
|
||||
|
/** |
||||
|
* 是否采纳 |
||||
|
*/ |
||||
|
@ExcelDictFormat(dictType = "is_adopted") |
||||
|
private String isAdopted; |
||||
|
|
||||
|
/** |
||||
|
* 删除标志 |
||||
|
*/ |
||||
|
@ExcelDictFormat(dictType = "del_flag") |
||||
|
private String delFlag; |
||||
|
|
||||
|
/** |
||||
|
* 租户ID |
||||
|
*/ |
||||
|
@ExcelProperty(value = "租户ID") |
||||
|
private String tenantId; |
||||
|
|
||||
|
/** |
||||
|
* 创建人 |
||||
|
*/ |
||||
|
@ExcelProperty(value = "创建人") |
||||
|
private Long createBy; |
||||
|
|
||||
|
/** |
||||
|
* 创建时间 |
||||
|
*/ |
||||
|
@ExcelProperty(value = "创建时间") |
||||
|
private Date createTime; |
||||
|
|
||||
|
/** |
||||
|
* 更新人 |
||||
|
*/ |
||||
|
@ExcelProperty(value = "更新人") |
||||
|
private Long updateBy; |
||||
|
|
||||
|
/** |
||||
|
* 更新时间 |
||||
|
*/ |
||||
|
@ExcelProperty(value = "更新时间") |
||||
|
private Date updateTime; |
||||
|
private int sortOrder; |
||||
|
|
||||
|
} |
@ -0,0 +1,45 @@ |
|||||
|
package org.dromara.productManagement.domain.vo; |
||||
|
|
||||
|
import lombok.Data; |
||||
|
|
||||
|
import java.util.List; |
||||
|
|
||||
|
/** |
||||
|
* 招投标任务结果视图对象 |
||||
|
* |
||||
|
* @author guoyan |
||||
|
* @date 2024-12-14 |
||||
|
*/ |
||||
|
@Data |
||||
|
public class TenderTaskResultVO { |
||||
|
|
||||
|
private String name; // 分类名称
|
||||
|
|
||||
|
private List<ResultItem> results; |
||||
|
|
||||
|
@Data |
||||
|
public static class ResultItem { |
||||
|
|
||||
|
private String id; // 唯一标识ID
|
||||
|
|
||||
|
private Integer serialNumber; // 序号
|
||||
|
|
||||
|
private String issueName; // 问题点名称
|
||||
|
|
||||
|
private String originalText; // 原文
|
||||
|
|
||||
|
private String comparedText; // 比对原文
|
||||
|
|
||||
|
private String modifiedContent; // 修改后的内容
|
||||
|
|
||||
|
private String modificationDisplay; // 展示修改情况
|
||||
|
|
||||
|
private String existingIssues; // 存在的问题
|
||||
|
|
||||
|
private String reviewBasis; // 审查依据(JSON字符串)
|
||||
|
|
||||
|
private String isRead; // 是否已读
|
||||
|
|
||||
|
private String isAdopted; // 是否采纳
|
||||
|
} |
||||
|
} |
@ -0,0 +1,69 @@ |
|||||
|
package org.dromara.productManagement.domain.vo; |
||||
|
|
||||
|
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 org.dromara.productManagement.domain.TenderTaskType; |
||||
|
|
||||
|
import java.io.Serial; |
||||
|
import java.io.Serializable; |
||||
|
import java.util.Date; |
||||
|
|
||||
|
/** |
||||
|
* 招投标类型视图对象 tender_task_type |
||||
|
* |
||||
|
* @author guoyan |
||||
|
* @date 2024-12-14 |
||||
|
*/ |
||||
|
@Data |
||||
|
@ExcelIgnoreUnannotated |
||||
|
@AutoMapper(target = TenderTaskType.class) |
||||
|
public class TenderTaskTypeVo implements Serializable { |
||||
|
|
||||
|
@Serial |
||||
|
private static final long serialVersionUID = 1L; |
||||
|
|
||||
|
/** |
||||
|
* 类型ID |
||||
|
*/ |
||||
|
@ExcelProperty(value = "类型ID") |
||||
|
private Long id; |
||||
|
|
||||
|
/** |
||||
|
* 招投标类型名称 |
||||
|
*/ |
||||
|
@ExcelProperty(value = "招投标类型名称") |
||||
|
private String tenderName; |
||||
|
|
||||
|
/** |
||||
|
* 显示顺序 |
||||
|
*/ |
||||
|
@ExcelProperty(value = "显示顺序") |
||||
|
private Long sort; |
||||
|
|
||||
|
/** |
||||
|
* 状态(0正常 1停用) |
||||
|
*/ |
||||
|
@ExcelDictFormat(readConverterExp = "0=正常,1=停用") |
||||
|
private String status; |
||||
|
|
||||
|
/** |
||||
|
* 备注 |
||||
|
*/ |
||||
|
@ExcelProperty(value = "备注") |
||||
|
private String remark; |
||||
|
|
||||
|
/** |
||||
|
* 创建时间 |
||||
|
*/ |
||||
|
private Date createTime; |
||||
|
|
||||
|
/** |
||||
|
* 更新时间 |
||||
|
*/ |
||||
|
private Date updateTime; |
||||
|
|
||||
|
} |
@ -0,0 +1,150 @@ |
|||||
|
package org.dromara.productManagement.domain.vo; |
||||
|
|
||||
|
import io.github.linpeilie.annotations.AutoMapper; |
||||
|
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 lombok.Data; |
||||
|
import org.dromara.productManagement.domain.TenderTasks; |
||||
|
|
||||
|
import java.util.Date; |
||||
|
|
||||
|
/** |
||||
|
* 招投标审核任务视图对象 tender_tasks |
||||
|
* |
||||
|
* @author ruoyi |
||||
|
* @date 2024-01-01 |
||||
|
*/ |
||||
|
@Data |
||||
|
@ExcelIgnoreUnannotated |
||||
|
@AutoMapper(target = TenderTasks.class) |
||||
|
public class TenderTasksVo { |
||||
|
|
||||
|
private static final long serialVersionUID = 1L; |
||||
|
|
||||
|
/** |
||||
|
* 主键ID |
||||
|
*/ |
||||
|
@ExcelProperty(value = "主键ID") |
||||
|
private Long id; |
||||
|
|
||||
|
/** |
||||
|
* 任务名称 |
||||
|
*/ |
||||
|
@ExcelProperty(value = "任务名称") |
||||
|
private String taskName; |
||||
|
|
||||
|
/** |
||||
|
* 招标文件名称 |
||||
|
*/ |
||||
|
@ExcelProperty(value = "招标文件名称") |
||||
|
private String tenderDocumentName; |
||||
|
|
||||
|
/** |
||||
|
* 投标文件名称 |
||||
|
*/ |
||||
|
@ExcelProperty(value = "投标文件名称") |
||||
|
private String bidDocumentName; |
||||
|
|
||||
|
/** |
||||
|
* 进展状态 |
||||
|
*/ |
||||
|
@ExcelProperty(value = "进展状态") |
||||
|
@ExcelDictFormat(dictType = "progress_status") |
||||
|
private String progressStatus; |
||||
|
|
||||
|
/** |
||||
|
* 文档是否删除 |
||||
|
*/ |
||||
|
@ExcelProperty(value = "文档是否删除") |
||||
|
@ExcelDictFormat(dictType = "delete_flag") |
||||
|
private String deleteFlag; |
||||
|
|
||||
|
/** |
||||
|
* 删除标志 |
||||
|
*/ |
||||
|
@ExcelProperty(value = "删除标志") |
||||
|
@ExcelDictFormat(dictType = "del_flag") |
||||
|
private String delFlag; |
||||
|
|
||||
|
/** |
||||
|
* 版本号 |
||||
|
*/ |
||||
|
@ExcelProperty(value = "版本号") |
||||
|
private Long version; |
||||
|
|
||||
|
/** |
||||
|
* 租户ID |
||||
|
*/ |
||||
|
@ExcelProperty(value = "租户ID") |
||||
|
private String tenantId; |
||||
|
|
||||
|
/** |
||||
|
* 创建部门 |
||||
|
*/ |
||||
|
@ExcelProperty(value = "创建部门") |
||||
|
private Long createDept; |
||||
|
|
||||
|
/** |
||||
|
* 任务组ID |
||||
|
*/ |
||||
|
@ExcelProperty(value = "任务组ID") |
||||
|
private Long groupId; |
||||
|
|
||||
|
/** |
||||
|
* 列队任务ID |
||||
|
*/ |
||||
|
@ExcelProperty(value = "列队任务ID") |
||||
|
private String taskId; |
||||
|
|
||||
|
/** |
||||
|
* 审核结果 |
||||
|
*/ |
||||
|
@ExcelProperty(value = "审核结果") |
||||
|
@ExcelDictFormat(dictType = "review_result") |
||||
|
private String resultType; |
||||
|
|
||||
|
/** |
||||
|
* 招标文件oss存储id |
||||
|
*/ |
||||
|
@ExcelProperty(value = "招标文件OSS存储ID") |
||||
|
private String tenderDocOssId; |
||||
|
|
||||
|
/** |
||||
|
* 投标文件oss存储id |
||||
|
*/ |
||||
|
@ExcelProperty(value = "投标文件OSS存储ID") |
||||
|
private String bidDocZipOssId; |
||||
|
|
||||
|
/** |
||||
|
* PDF文件路径 |
||||
|
*/ |
||||
|
@ExcelProperty(value = "PDF文件路径") |
||||
|
private String pdfPath; |
||||
|
|
||||
|
/** |
||||
|
* 创建人 |
||||
|
*/ |
||||
|
@ExcelProperty(value = "创建人") |
||||
|
private Long createBy; |
||||
|
|
||||
|
/** |
||||
|
* 创建时间 |
||||
|
*/ |
||||
|
@ExcelProperty(value = "创建时间") |
||||
|
private Date createTime; |
||||
|
|
||||
|
/** |
||||
|
* 更新人 |
||||
|
*/ |
||||
|
@ExcelProperty(value = "更新人") |
||||
|
private Long updateBy; |
||||
|
|
||||
|
/** |
||||
|
* 更新时间 |
||||
|
*/ |
||||
|
@ExcelProperty(value = "更新时间") |
||||
|
private Date updateTime; |
||||
|
|
||||
|
} |
@ -0,0 +1,33 @@ |
|||||
|
package org.dromara.tenderreview.enums; |
||||
|
|
||||
|
import lombok.AllArgsConstructor; |
||||
|
import lombok.Getter; |
||||
|
|
||||
|
/** |
||||
|
* 招投标审核状态枚举 |
||||
|
* |
||||
|
* @author ruoyi |
||||
|
* @date 2024-01-01 |
||||
|
*/ |
||||
|
@Getter |
||||
|
@AllArgsConstructor |
||||
|
public enum TenderReviewStatusEnum { |
||||
|
|
||||
|
PENDING("0", "待审核"), |
||||
|
REVIEWING("1", "审核中"), |
||||
|
PASSED("2", "审核通过"), |
||||
|
REJECTED("3", "审核不通过"); |
||||
|
|
||||
|
private final String code; |
||||
|
private final String desc; |
||||
|
|
||||
|
public static TenderReviewStatusEnum getByCode(String code) { |
||||
|
for (TenderReviewStatusEnum status : values()) { |
||||
|
if (status.getCode().equals(code)) { |
||||
|
return status; |
||||
|
} |
||||
|
} |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,14 @@ |
|||||
|
package org.dromara.productManagement.mapper; |
||||
|
|
||||
|
import org.dromara.productManagement.domain.TenderTaskResultDetail; |
||||
|
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; |
||||
|
|
||||
|
/** |
||||
|
* 招投标任务结果详情Mapper接口 |
||||
|
* |
||||
|
* @author guoyan |
||||
|
* @date 2024-12-14 |
||||
|
*/ |
||||
|
public interface TenderTaskResultDetailMapper extends BaseMapperPlus<TenderTaskResultDetail, TenderTaskResultDetail> { |
||||
|
|
||||
|
} |
@ -0,0 +1,16 @@ |
|||||
|
package org.dromara.productManagement.mapper; |
||||
|
|
||||
|
|
||||
|
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; |
||||
|
import org.dromara.productManagement.domain.TenderTaskType; |
||||
|
import org.dromara.productManagement.domain.vo.TenderTaskTypeVo; |
||||
|
|
||||
|
/** |
||||
|
* 招投标类型Mapper接口 |
||||
|
* |
||||
|
* @author guoyan |
||||
|
* @date 2024-12-14 |
||||
|
*/ |
||||
|
public interface TenderTaskTypeMapper extends BaseMapperPlus<TenderTaskType, TenderTaskTypeVo> { |
||||
|
|
||||
|
} |
@ -0,0 +1,41 @@ |
|||||
|
package org.dromara.productManagement.mapper; |
||||
|
|
||||
|
import com.baomidou.mybatisplus.core.conditions.Wrapper; |
||||
|
import com.baomidou.mybatisplus.core.toolkit.Constants; |
||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
||||
|
import org.apache.ibatis.annotations.Param; |
||||
|
|
||||
|
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; |
||||
|
import org.dromara.productManagement.domain.TenderTaskGroup; |
||||
|
import org.dromara.productManagement.domain.TenderTasks; |
||||
|
import org.dromara.productManagement.domain.vo.TenderTaskResultVO; |
||||
|
import org.dromara.productManagement.domain.vo.TenderTasksVo; |
||||
|
|
||||
|
import java.util.List; |
||||
|
|
||||
|
/** |
||||
|
* 招投标审核任务Mapper接口 |
||||
|
* |
||||
|
* @author ruoyi |
||||
|
* @date 2024-01-01 |
||||
|
*/ |
||||
|
public interface TenderTasksMapper extends BaseMapperPlus<TenderTasks, TenderTasksVo> { |
||||
|
|
||||
|
/** |
||||
|
* 根据任务ID获取详细的文档任务结果 |
||||
|
* |
||||
|
* @param taskId 任务ID |
||||
|
* @return 文档任务结果详情列表 |
||||
|
*/ |
||||
|
List<TenderTaskResultVO> getResultsByTaskId(@Param("taskId") String taskId); |
||||
|
|
||||
|
/** |
||||
|
* 分页查询招投标任务分组列表 |
||||
|
* |
||||
|
* @param page 分页参数 |
||||
|
* @param wrapper 查询条件 |
||||
|
* @return 招投标任务分组分页列表 |
||||
|
*/ |
||||
|
Page<TenderTaskGroup> selectTenderTaskGroups(@Param("page") Page<TenderTasks> page, @Param(Constants.WRAPPER) Wrapper<TenderTasks> wrapper); |
||||
|
|
||||
|
} |
@ -0,0 +1,57 @@ |
|||||
|
package org.dromara.productManagement.service; |
||||
|
|
||||
|
import org.dromara.productManagement.domain.vo.TenderTaskResultVO; |
||||
|
import jakarta.servlet.http.HttpServletResponse; |
||||
|
|
||||
|
import java.util.List; |
||||
|
|
||||
|
/** |
||||
|
* 招投标任务结果Service接口 |
||||
|
* |
||||
|
* @author guoyan |
||||
|
* @date 2024-12-14 |
||||
|
*/ |
||||
|
public interface ITenderTaskResultsService { |
||||
|
|
||||
|
/** |
||||
|
* 根据任务ID查询详细的招投标任务结果 |
||||
|
* |
||||
|
* @param taskId 任务ID |
||||
|
* @return 详细的招投标任务结果列表 |
||||
|
*/ |
||||
|
List<TenderTaskResultVO> getDetailResultsByTaskId(String taskId); |
||||
|
|
||||
|
/** |
||||
|
* 下载招投标任务结果 |
||||
|
* |
||||
|
* @param ids 主键数组 |
||||
|
* @param response HTTP响应对象 |
||||
|
*/ |
||||
|
void downloadResult(Long[] ids, HttpServletResponse response); |
||||
|
|
||||
|
/** |
||||
|
* 获取招投标任务PDF文件流 |
||||
|
* |
||||
|
* @param taskId 任务ID |
||||
|
* @param response HTTP响应对象 |
||||
|
*/ |
||||
|
void getPdfStream(String taskId, HttpServletResponse response); |
||||
|
|
||||
|
/** |
||||
|
* 获取招投标文件PDF文件流 |
||||
|
* |
||||
|
* @param taskId 任务ID |
||||
|
* @param response HTTP响应对象 |
||||
|
*/ |
||||
|
void getBidPdfStream(String taskId, HttpServletResponse response); |
||||
|
|
||||
|
/** |
||||
|
* 更新招投标任务结果项的状态(已读/采纳) |
||||
|
* |
||||
|
* @param id 结果项ID |
||||
|
* @param field 字段名(isRead/isAdopted) |
||||
|
* @param value 值(0/1) |
||||
|
* @return 是否更新成功 |
||||
|
*/ |
||||
|
Boolean updateResultItemStatus(String id, String field, String value); |
||||
|
} |
@ -0,0 +1,68 @@ |
|||||
|
package org.dromara.productManagement.service; |
||||
|
|
||||
|
import org.dromara.productManagement.domain.bo.TenderTaskTypeBo; |
||||
|
import org.dromara.productManagement.domain.vo.TenderTaskTypeVo; |
||||
|
import org.dromara.common.mybatis.core.page.PageQuery; |
||||
|
import org.dromara.common.mybatis.core.page.TableDataInfo; |
||||
|
|
||||
|
import java.util.Collection; |
||||
|
import java.util.List; |
||||
|
|
||||
|
/** |
||||
|
* 招投标类型Service接口 |
||||
|
* |
||||
|
* @author guoyan |
||||
|
* @date 2024-12-14 |
||||
|
*/ |
||||
|
public interface ITenderTaskTypeService { |
||||
|
|
||||
|
/** |
||||
|
* 查询招投标类型 |
||||
|
* |
||||
|
* @param id 主键 |
||||
|
* @return 招投标类型 |
||||
|
*/ |
||||
|
TenderTaskTypeVo queryById(Long id); |
||||
|
|
||||
|
/** |
||||
|
* 分页查询招投标类型列表 |
||||
|
* |
||||
|
* @param bo 查询条件 |
||||
|
* @param pageQuery 分页参数 |
||||
|
* @return 招投标类型分页列表 |
||||
|
*/ |
||||
|
TableDataInfo<TenderTaskTypeVo> queryPageList(TenderTaskTypeBo bo, PageQuery pageQuery); |
||||
|
|
||||
|
/** |
||||
|
* 查询符合条件的招投标类型列表 |
||||
|
* |
||||
|
* @param bo 查询条件 |
||||
|
* @return 招投标类型列表 |
||||
|
*/ |
||||
|
List<TenderTaskTypeVo> queryList(TenderTaskTypeBo bo); |
||||
|
|
||||
|
/** |
||||
|
* 新增招投标类型 |
||||
|
* |
||||
|
* @param bo 招投标类型 |
||||
|
* @return 是否新增成功 |
||||
|
*/ |
||||
|
Boolean insertByBo(TenderTaskTypeBo bo); |
||||
|
|
||||
|
/** |
||||
|
* 修改招投标类型 |
||||
|
* |
||||
|
* @param bo 招投标类型 |
||||
|
* @return 是否修改成功 |
||||
|
*/ |
||||
|
Boolean updateByBo(TenderTaskTypeBo bo); |
||||
|
|
||||
|
/** |
||||
|
* 校验并批量删除招投标类型信息 |
||||
|
* |
||||
|
* @param ids 待删除的主键集合 |
||||
|
* @param isValid 是否进行有效性校验 |
||||
|
* @return 是否删除成功 |
||||
|
*/ |
||||
|
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid); |
||||
|
} |
@ -0,0 +1,61 @@ |
|||||
|
package org.dromara.productManagement.service; |
||||
|
|
||||
|
import org.dromara.productManagement.domain.TenderTaskGroup; |
||||
|
import org.dromara.productManagement.domain.vo.TenderTasksVo; |
||||
|
import org.dromara.productManagement.domain.bo.TenderTasksBo; |
||||
|
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 ruoyi |
||||
|
* @date 2024-01-01 |
||||
|
*/ |
||||
|
public interface ITenderTasksService { |
||||
|
|
||||
|
/** |
||||
|
* 查询招投标审核任务 |
||||
|
*/ |
||||
|
TenderTasksVo queryById(Long id); |
||||
|
|
||||
|
/** |
||||
|
* 查询招投标审核任务列表 |
||||
|
*/ |
||||
|
TableDataInfo<TenderTasksVo> queryPageList(TenderTasksBo bo, PageQuery pageQuery); |
||||
|
|
||||
|
/** |
||||
|
* 分页查询招投标任务分组列表 |
||||
|
*/ |
||||
|
TableDataInfo<TenderTaskGroup> queryGroupPageList(TenderTasksBo bo, PageQuery pageQuery); |
||||
|
|
||||
|
/** |
||||
|
* 查询招投标审核任务列表 |
||||
|
*/ |
||||
|
List<TenderTasksVo> queryList(TenderTasksBo bo); |
||||
|
|
||||
|
/** |
||||
|
* 新增招投标审核任务 |
||||
|
*/ |
||||
|
Boolean insertByBo(TenderTasksBo bo); |
||||
|
|
||||
|
/** |
||||
|
* 修改招投标审核任务 |
||||
|
*/ |
||||
|
Boolean updateByBo(TenderTasksBo bo); |
||||
|
|
||||
|
/** |
||||
|
* 校验并批量删除招投标审核任务信息 |
||||
|
*/ |
||||
|
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid); |
||||
|
|
||||
|
/** |
||||
|
* 删除招投标任务文件 |
||||
|
*/ |
||||
|
Boolean ossRemoveById(String ossId, Boolean isValid); |
||||
|
|
||||
|
} |
@ -0,0 +1,823 @@ |
|||||
|
package org.dromara.productManagement.service.impl; |
||||
|
|
||||
|
import com.baomidou.dynamic.datasource.annotation.DS; |
||||
|
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; |
||||
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
||||
|
import com.lowagie.text.pdf.BaseFont; |
||||
|
import com.vladsch.flexmark.ext.gfm.strikethrough.StrikethroughExtension; |
||||
|
import com.vladsch.flexmark.ext.tables.TablesExtension; |
||||
|
import com.vladsch.flexmark.html.HtmlRenderer; |
||||
|
import com.vladsch.flexmark.parser.Parser; |
||||
|
import com.vladsch.flexmark.util.ast.Node; |
||||
|
import com.vladsch.flexmark.util.data.MutableDataSet; |
||||
|
import lombok.RequiredArgsConstructor; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.apache.commons.io.FileUtils; |
||||
|
import org.dromara.common.core.service.DictService; |
||||
|
import org.dromara.common.core.utils.StringUtils; |
||||
|
import org.dromara.productManagement.domain.TenderTaskResultDetail; |
||||
|
import org.dromara.productManagement.domain.vo.TenderTaskResultVO; |
||||
|
import org.dromara.productManagement.domain.vo.TenderTasksVo; |
||||
|
import org.dromara.productManagement.mapper.TenderTaskResultDetailMapper; |
||||
|
import org.dromara.productManagement.mapper.TenderTasksMapper; |
||||
|
import org.dromara.productManagement.service.ITenderTaskResultsService; |
||||
|
import org.jsoup.Jsoup; |
||||
|
import org.jsoup.nodes.Document; |
||||
|
import org.jsoup.safety.Safelist; |
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
import org.springframework.stereotype.Service; |
||||
|
import org.xhtmlrenderer.pdf.ITextRenderer; |
||||
|
|
||||
|
import jakarta.servlet.http.HttpServletResponse; |
||||
|
import javax.sql.DataSource; |
||||
|
import java.io.*; |
||||
|
import java.net.URLEncoder; |
||||
|
import java.nio.charset.StandardCharsets; |
||||
|
import java.nio.file.Files; |
||||
|
import java.util.Arrays; |
||||
|
import java.util.List; |
||||
|
import java.util.zip.ZipEntry; |
||||
|
import java.util.zip.ZipOutputStream; |
||||
|
import java.util.ArrayList; |
||||
|
|
||||
|
/** |
||||
|
* 招投标任务结果Service业务层处理 |
||||
|
* |
||||
|
* @author guoyan |
||||
|
* @date 2024-12-14 |
||||
|
*/ |
||||
|
@RequiredArgsConstructor |
||||
|
@Service |
||||
|
@Slf4j |
||||
|
public class TenderTaskResultsServiceImpl implements ITenderTaskResultsService { |
||||
|
|
||||
|
private final TenderTaskResultDetailMapper tenderTaskResultDetailMapper; |
||||
|
private final TenderTasksMapper tenderTasksMapper; |
||||
|
private final DictService dictService; |
||||
|
|
||||
|
@Autowired |
||||
|
private DataSource dataSource; |
||||
|
|
||||
|
/** |
||||
|
* 根据任务ID查询详细的招投标任务结果 |
||||
|
*/ |
||||
|
@Override |
||||
|
@DS("slave") |
||||
|
public List<TenderTaskResultVO> getDetailResultsByTaskId(String taskId) { |
||||
|
|
||||
|
List<TenderTaskResultVO> originalResults = tenderTasksMapper.getResultsByTaskId(taskId); |
||||
|
// 如果没有结果,直接返回
|
||||
|
if (originalResults == null || originalResults.isEmpty()) { |
||||
|
return originalResults; |
||||
|
} |
||||
|
|
||||
|
// 为每个原始分类中的结果设置序号
|
||||
|
for (TenderTaskResultVO category : originalResults) { |
||||
|
if (category.getResults() != null) { |
||||
|
for (int i = 0; i < category.getResults().size(); i++) { |
||||
|
TenderTaskResultVO.ResultItem item = category.getResults().get(i); |
||||
|
item.setSerialNumber(i + 1); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return originalResults; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 更新招投标任务结果项的状态(已读/采纳) |
||||
|
*/ |
||||
|
@Override |
||||
|
@DS("slave") |
||||
|
public Boolean updateResultItemStatus(String id, String field, String value) { |
||||
|
// 验证字段名是否合法
|
||||
|
if (!"isRead".equals(field) && !"isAdopted".equals(field)) { |
||||
|
throw new RuntimeException("不支持更新的字段: " + field); |
||||
|
} |
||||
|
|
||||
|
// 验证值是否合法
|
||||
|
if (!"0".equals(value) && !"1".equals(value)) { |
||||
|
throw new RuntimeException("无效的值: " + value); |
||||
|
} |
||||
|
|
||||
|
try { |
||||
|
LambdaUpdateWrapper<TenderTaskResultDetail> updateWrapper = Wrappers.lambdaUpdate(TenderTaskResultDetail.class); |
||||
|
updateWrapper.eq(TenderTaskResultDetail::getId, id); |
||||
|
|
||||
|
if ("isRead".equals(field)) { |
||||
|
updateWrapper.set(TenderTaskResultDetail::getIsRead, value); |
||||
|
} else { |
||||
|
updateWrapper.set(TenderTaskResultDetail::getIsAdopted, value); |
||||
|
} |
||||
|
|
||||
|
return tenderTaskResultDetailMapper.update(null, updateWrapper) > 0; |
||||
|
} catch (Exception e) { |
||||
|
throw new RuntimeException("更新状态失败: " + e.getMessage(), e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 下载招投标任务结果 |
||||
|
*/ |
||||
|
@Override |
||||
|
@DS("slave") |
||||
|
public void downloadResult(Long[] ids, HttpServletResponse response) { |
||||
|
try { |
||||
|
if (ids.length > 0) { |
||||
|
if (ids.length > 1) { |
||||
|
// 多文件压缩下载
|
||||
|
String tempDir = System.getProperty("java.io.tmpdir"); |
||||
|
String zipFileName = "tender_results_export.zip"; |
||||
|
String zipFilePath = tempDir + File.separator + zipFileName; |
||||
|
|
||||
|
try (ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipFilePath))) { |
||||
|
for (Long taskId : ids) { |
||||
|
TenderTasksVo tenderTasksVo = tenderTasksMapper.selectVoById(taskId); |
||||
|
if (tenderTasksVo == null) continue; |
||||
|
|
||||
|
String documentName = tenderTasksVo.getTenderDocumentName(); |
||||
|
String taskName = tenderTasksVo.getTaskName(); |
||||
|
String taskType = "tender_review"; |
||||
|
String label = dictService.getDictLabel(taskType, taskName); |
||||
|
|
||||
|
// 获取详细的任务结果
|
||||
|
List<TenderTaskResultVO> resultDetails = getDetailResultsByTaskId(String.valueOf(taskId)); |
||||
|
if (resultDetails != null && !resultDetails.isEmpty()) { |
||||
|
// 根据任务类型生成Markdown
|
||||
|
String markdown = generateTenderMarkdownByTaskTypeAndCategories(taskName, resultDetails); |
||||
|
|
||||
|
if (StringUtils.isNotBlank(markdown)) { |
||||
|
// 生成文档标题
|
||||
|
String title = "招投标文件分析报告"; |
||||
|
String fullMarkdown = String.format("# %s\n\n**文档名称**: %s \n**任务类型**: %s\n\n%s", |
||||
|
title, documentName, label, markdown); |
||||
|
|
||||
|
// 转换为PDF
|
||||
|
String tempPdfPath = tempDir + File.separator + "tender_result_" + taskId + ".pdf"; |
||||
|
convertMarkdownToPdf(fullMarkdown, tempPdfPath); |
||||
|
|
||||
|
// 添加到ZIP文件
|
||||
|
String pdfFileName = String.format("%s_%s.pdf", documentName, label); |
||||
|
addToZip(tempPdfPath, pdfFileName, zos); |
||||
|
|
||||
|
// 删除临时PDF文件
|
||||
|
Files.deleteIfExists(new File(tempPdfPath).toPath()); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 下载ZIP文件
|
||||
|
downloadFile(response, zipFilePath, zipFileName); |
||||
|
|
||||
|
// 删除临时ZIP文件
|
||||
|
Files.deleteIfExists(new File(zipFilePath).toPath()); |
||||
|
|
||||
|
} else { |
||||
|
// 单文件PDF下载
|
||||
|
Long taskId = ids[0]; |
||||
|
TenderTasksVo tenderTasksVo = tenderTasksMapper.selectVoById(taskId); |
||||
|
if (tenderTasksVo == null) { |
||||
|
throw new RuntimeException("任务不存在"); |
||||
|
} |
||||
|
|
||||
|
String documentName = tenderTasksVo.getBidDocumentName(); |
||||
|
String taskName = tenderTasksVo.getTaskName(); |
||||
|
String taskType = "tender_review"; |
||||
|
String label = dictService.getDictLabel(taskType, taskName); |
||||
|
|
||||
|
// 获取详细的任务结果
|
||||
|
List<TenderTaskResultVO> resultDetails = getDetailResultsByTaskId(String.valueOf(taskId)); |
||||
|
if (resultDetails != null && !resultDetails.isEmpty()) { |
||||
|
// 根据任务类型生成Markdown
|
||||
|
String markdown = generateTenderMarkdownByTaskTypeAndCategories(taskName, resultDetails); |
||||
|
|
||||
|
if (StringUtils.isNotBlank(markdown)) { |
||||
|
// 生成文档标题
|
||||
|
String title = "招投标文件分析报告"; |
||||
|
String fullMarkdown = String.format("# %s\n\n**文档名称**: %s \n**任务类型**: %s\n\n%s", |
||||
|
title, documentName, label, markdown); |
||||
|
|
||||
|
// 转换为PDF
|
||||
|
String tempDir = System.getProperty("java.io.tmpdir"); |
||||
|
String tempPdfPath = tempDir + File.separator + "tender_result_" + taskId + ".pdf"; |
||||
|
convertMarkdownToPdf(fullMarkdown, tempPdfPath); |
||||
|
|
||||
|
// 下载文件
|
||||
|
String fileName = String.format("%s_%s.pdf", documentName, label); |
||||
|
downloadFile(response, tempPdfPath, fileName); |
||||
|
|
||||
|
// 删除临时文件
|
||||
|
Files.deleteIfExists(new File(tempPdfPath).toPath()); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} catch (Exception e) { |
||||
|
log.error("下载结果失败", e); |
||||
|
throw new RuntimeException("下载结果失败: " + e.getMessage()); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取招投标任务PDF文件流 |
||||
|
*/ |
||||
|
/** |
||||
|
* 获取招投标任务PDF文件流 |
||||
|
*/ |
||||
|
@Override |
||||
|
@DS("slave") |
||||
|
public void getPdfStream(String taskId, HttpServletResponse response) { |
||||
|
try { |
||||
|
// 查询任务信息
|
||||
|
TenderTasksVo task = tenderTasksMapper.selectVoById(Long.valueOf(taskId)); |
||||
|
if (task == null) { |
||||
|
throw new RuntimeException("任务不存在"); |
||||
|
} |
||||
|
|
||||
|
String pdfPath = task.getPdfPath(); |
||||
|
String filePath = ""; |
||||
|
|
||||
|
if (StringUtils.isNotEmpty(pdfPath)) { |
||||
|
// 如果pdfPath存在,直接使用该路径
|
||||
|
filePath = pdfPath; |
||||
|
} else { |
||||
|
throw new RuntimeException("文件信息不存在"); |
||||
|
} |
||||
|
|
||||
|
log.info("开始输出招投标PDF文件: " + filePath); |
||||
|
|
||||
|
// 读取文件并输出到response
|
||||
|
File file = new File(filePath); |
||||
|
if (!file.exists()) { |
||||
|
throw new RuntimeException("PDF文件不存在: " + filePath); |
||||
|
} |
||||
|
|
||||
|
log.info("招投标PDF文件存在,开始输出: " + filePath); |
||||
|
|
||||
|
// // 使用JDBC更新数据库
|
||||
|
// try (Connection conn = dataSource.getConnection()) {
|
||||
|
// String sql = "UPDATE tender_tasks SET pdf_path = ? WHERE id = ?";
|
||||
|
// try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
|
||||
|
// pstmt.setString(1, filePath);
|
||||
|
// pstmt.setLong(2, Long.parseLong(taskId));
|
||||
|
// pstmt.executeUpdate();
|
||||
|
// }
|
||||
|
// } catch (SQLException e) {
|
||||
|
// log.error("更新招投标PDF路径失败", e);
|
||||
|
// throw new RuntimeException("更新招投标PDF路径失败: " + e.getMessage());
|
||||
|
// }
|
||||
|
|
||||
|
response.setContentType("application/pdf"); |
||||
|
response.setHeader("Content-Disposition", "inline; filename=" + URLEncoder.encode(file.getName(), StandardCharsets.UTF_8.name())); |
||||
|
|
||||
|
try (FileInputStream fis = new FileInputStream(file); |
||||
|
BufferedInputStream bis = new BufferedInputStream(fis, 8192); |
||||
|
OutputStream os = response.getOutputStream()) { |
||||
|
byte[] buffer = new byte[8192]; |
||||
|
int bytesRead; |
||||
|
while ((bytesRead = bis.read(buffer)) != -1) { |
||||
|
os.write(buffer, 0, bytesRead); |
||||
|
} |
||||
|
os.flush(); |
||||
|
} |
||||
|
} catch (Exception e) { |
||||
|
log.error("获取招投标PDF文件流失败", e); |
||||
|
throw new RuntimeException("获取招投标PDF文件流失败: " + e.getMessage()); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取招投标文件PDF文件流 |
||||
|
*/ |
||||
|
@Override |
||||
|
@DS("slave") |
||||
|
public void getBidPdfStream(String taskId, HttpServletResponse response) { |
||||
|
try { |
||||
|
// 设置响应头
|
||||
|
response.setContentType("application/pdf"); |
||||
|
response.setHeader("Content-Disposition", |
||||
|
"attachment; filename=tender_bid_document_" + taskId + ".pdf"); |
||||
|
|
||||
|
// 这里需要实现具体的招投标文件PDF获取逻辑
|
||||
|
// 目前先返回一个简单的提示
|
||||
|
response.getWriter().write("招投标文件PDF获取功能待实现"); |
||||
|
} catch (Exception e) { |
||||
|
throw new RuntimeException("获取招投标文件PDF失败", e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 根据任务类型和分类生成Markdown内容(统一使用多tabs模式) |
||||
|
* |
||||
|
* @param taskName 任务类型名称 |
||||
|
* @param resultDetails 结果详情列表 |
||||
|
* @return Markdown内容 |
||||
|
*/ |
||||
|
private String generateTenderMarkdownByTaskTypeAndCategories(String taskName, List<TenderTaskResultVO> resultDetails) { |
||||
|
// 统一使用多tabs模式,根据任务类型获取tabs配置
|
||||
|
return generateTenderMarkdownByTabsConfig(taskName, resultDetails); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 根据任务类型的tabs配置生成Markdown内容 |
||||
|
* |
||||
|
* @param taskName 任务类型名称 |
||||
|
* @param resultDetails 结果详情列表 |
||||
|
* @return Markdown内容 |
||||
|
*/ |
||||
|
private String generateTenderMarkdownByTabsConfig(String taskName, List<TenderTaskResultVO> resultDetails) { |
||||
|
StringBuilder markdown = new StringBuilder(); |
||||
|
|
||||
|
// 获取任务类型对应的tabs配置
|
||||
|
List<TenderTabConfig> tabConfigs = getTenderTabConfigsByTaskType(taskName); |
||||
|
log.info("任务类型: {}, 配置的tabs数量: {}", taskName, tabConfigs.size()); |
||||
|
|
||||
|
// 记录可用的分类名称
|
||||
|
List<String> availableCategories = resultDetails.stream() |
||||
|
.map(TenderTaskResultVO::getName) |
||||
|
.collect(java.util.stream.Collectors.toList()); |
||||
|
log.info("可用的分类名称: {}", availableCategories); |
||||
|
|
||||
|
// 按照tabs配置的顺序处理每个tab
|
||||
|
for (TenderTabConfig tabConfig : tabConfigs) { |
||||
|
String tabName = tabConfig.getTabName(); |
||||
|
log.info("处理tab: {}, 字段配置数量: {}", tabName, tabConfig.getFieldConfigs().size()); |
||||
|
|
||||
|
// 查找对应的分类数据
|
||||
|
TenderTaskResultVO matchingCategory = null; |
||||
|
for (TenderTaskResultVO category : resultDetails) { |
||||
|
if (tabName.equals(category.getName())) { |
||||
|
matchingCategory = category; |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 如果找到对应的分类数据,添加到markdown中
|
||||
|
if (matchingCategory != null && matchingCategory.getResults() != null && !matchingCategory.getResults().isEmpty()) { |
||||
|
log.info("找到匹配的分类数据: {}, 结果数量: {}", tabName, matchingCategory.getResults().size()); |
||||
|
// 添加分类标题
|
||||
|
markdown.append("## ").append(tabName).append("\n\n"); |
||||
|
|
||||
|
// 处理该分类下的每个结果项
|
||||
|
for (TenderTaskResultVO.ResultItem item : matchingCategory.getResults()) { |
||||
|
markdown.append("### ").append(item.getSerialNumber()).append(". ").append(item.getExistingIssues()).append("\n\n"); |
||||
|
|
||||
|
// 根据tab配置显示各字段内容
|
||||
|
for (TenderFieldConfig fieldConfig : tabConfig.getFieldConfigs()) { |
||||
|
String fieldValue = getTenderFieldValueWithJsonSupport(item, fieldConfig.getField()); |
||||
|
if (StringUtils.isNotBlank(fieldValue)) { |
||||
|
markdown.append("**").append(fieldConfig.getTitle()).append("**\n\n").append(fieldValue).append("\n\n"); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 添加分隔线
|
||||
|
markdown.append("---\n\n"); |
||||
|
} |
||||
|
} else { |
||||
|
log.warn("未找到匹配的分类数据: {}", tabName); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return markdown.toString(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 根据任务类型获取对应的tabs配置 |
||||
|
* |
||||
|
* @param taskName 任务类型名称 |
||||
|
* @return tabs配置列表 |
||||
|
*/ |
||||
|
private List<TenderTabConfig> getTenderTabConfigsByTaskType(String taskName) { |
||||
|
List<TenderTabConfig> configs = new ArrayList<>(); |
||||
|
|
||||
|
// 根据任务类型返回不同的tabs配置
|
||||
|
switch (taskName) { |
||||
|
case "bidConsistencyReview": |
||||
|
// 投标一致性审查 - 4个tabs
|
||||
|
configs.add(new TenderTabConfig("文档元数据", Arrays.asList( |
||||
|
new TenderFieldConfig("reviewBasis.review_points", "元数据要点") |
||||
|
))); |
||||
|
configs.add(new TenderTabConfig("重点关注相似内容", Arrays.asList( |
||||
|
new TenderFieldConfig("modificationDisplay", "各文档具体内容"), |
||||
|
new TenderFieldConfig("reviewBasis.error_review_points", "错别字") |
||||
|
))); |
||||
|
// configs.add(new TenderTabConfig("错别字", Arrays.asList(
|
||||
|
// new TenderFieldConfig("reviewBasis.error_review_points", "错别字详情"),
|
||||
|
// new TenderFieldConfig("modificationDisplay", "修改情况")
|
||||
|
// )));
|
||||
|
configs.add(new TenderTabConfig("一般相似内容", Arrays.asList( |
||||
|
new TenderFieldConfig("reviewBasis.review_points", "各文档具体内容") |
||||
|
))); |
||||
|
break; |
||||
|
case "tenderComplianceReview": |
||||
|
// 招投标合规性审查
|
||||
|
configs.add(new TenderTabConfig("合规性检查", Arrays.asList( |
||||
|
new TenderFieldConfig("originalText", "原文"), |
||||
|
new TenderFieldConfig("reviewBasis.review_content", "审查意见"), |
||||
|
new TenderFieldConfig("reviewBasis.review_points", "审查要点"), |
||||
|
new TenderFieldConfig("modificationDisplay", "修改情况") |
||||
|
))); |
||||
|
break; |
||||
|
case "bidDocumentAnalysis": |
||||
|
// 投标文档分析
|
||||
|
configs.add(new TenderTabConfig("文档分析", Arrays.asList( |
||||
|
new TenderFieldConfig("originalText", "原文"), |
||||
|
new TenderFieldConfig("comparedText", "比对原文"), |
||||
|
new TenderFieldConfig("reviewBasis.review_content", "分析结果"), |
||||
|
new TenderFieldConfig("modificationDisplay", "修改建议") |
||||
|
))); |
||||
|
break; |
||||
|
case "tenderDocumentCheck": |
||||
|
// 招标文档检查
|
||||
|
configs.add(new TenderTabConfig("文档检查", Arrays.asList( |
||||
|
new TenderFieldConfig("originalText", "原文"), |
||||
|
new TenderFieldConfig("reviewBasis.review_points", "检查要点"), |
||||
|
new TenderFieldConfig("modifiedContent", "修改建议"), |
||||
|
new TenderFieldConfig("modificationDisplay", "修改情况") |
||||
|
))); |
||||
|
break; |
||||
|
case "contractComplianceReview": |
||||
|
// 合同合规性审查
|
||||
|
configs.add(new TenderTabConfig("合同审查", Arrays.asList( |
||||
|
new TenderFieldConfig("originalText", "原文"), |
||||
|
new TenderFieldConfig("reviewBasis.review_content", "审查意见"), |
||||
|
new TenderFieldConfig("reviewBasis.review_points", "审查要点"), |
||||
|
new TenderFieldConfig("modificationDisplay", "修改情况") |
||||
|
))); |
||||
|
break; |
||||
|
default: |
||||
|
// 默认配置 - 使用通用的4个tabs结构
|
||||
|
configs.add(new TenderTabConfig("文档元数据", Arrays.asList( |
||||
|
new TenderFieldConfig("reviewBasis.review_points", "元数据要点") |
||||
|
))); |
||||
|
configs.add(new TenderTabConfig("重点关注相似内容", Arrays.asList( |
||||
|
new TenderFieldConfig("modificationDisplay", "各文档具体内容"), |
||||
|
new TenderFieldConfig("reviewBasis.error_review_points", "错别字") |
||||
|
))); |
||||
|
configs.add(new TenderTabConfig("错别字", Arrays.asList( |
||||
|
new TenderFieldConfig("reviewBasis.error_review_points", "错别字详情"), |
||||
|
new TenderFieldConfig("modificationDisplay", "修改情况") |
||||
|
))); |
||||
|
configs.add(new TenderTabConfig("一般相似内容", Arrays.asList( |
||||
|
new TenderFieldConfig("modificationDisplay", "各文档具体内容") |
||||
|
))); |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
return configs; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取结果项对象的字段值,支持从reviewBasis JSON中提取数据 |
||||
|
* |
||||
|
* @param item 结果项对象 |
||||
|
* @param fieldName 字段名(支持嵌套字段,如 reviewBasis.reviewContent) |
||||
|
* @return 字段值 |
||||
|
*/ |
||||
|
private String getTenderFieldValueWithJsonSupport(TenderTaskResultVO.ResultItem item, String fieldName) { |
||||
|
try { |
||||
|
// 处理嵌套字段,如 reviewBasis.reviewContent
|
||||
|
if (fieldName.contains(".")) { |
||||
|
String[] parts = fieldName.split("\\.", 2); |
||||
|
String mainField = parts[0]; |
||||
|
String subField = parts[1]; |
||||
|
|
||||
|
// 获取主字段值
|
||||
|
Object mainValue = getFieldValueByReflection(item, mainField); |
||||
|
if (mainValue == null) { |
||||
|
return ""; |
||||
|
} |
||||
|
|
||||
|
// 如果主字段是JSON字符串,解析并提取子字段
|
||||
|
if (mainValue instanceof String && "reviewBasis".equals(mainField)) { |
||||
|
try { |
||||
|
// 使用简单的JSON解析方式
|
||||
|
String jsonStr = (String) mainValue; |
||||
|
return extractJsonField(jsonStr, subField); |
||||
|
} catch (Exception e) { |
||||
|
log.error("解析JSON字段失败: {}, {}", fieldName, e.getMessage()); |
||||
|
return ""; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 处理普通字段
|
||||
|
Object value = getFieldValueByReflection(item, fieldName); |
||||
|
if (value != null) { |
||||
|
String stringValue = value.toString(); |
||||
|
// 对于普通字段也处理<br>标签
|
||||
|
return stringValue |
||||
|
.replace("<br>", "\n\n") |
||||
|
.replace("<br/>", "\n\n") |
||||
|
.replace("<BR>", "\n\n") |
||||
|
.replace("<BR/>", "\n\n"); |
||||
|
} |
||||
|
return ""; |
||||
|
} catch (Exception e) { |
||||
|
log.error("获取字段值失败: {}, {}", fieldName, e.getMessage()); |
||||
|
return ""; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 通过反射获取字段值 |
||||
|
*/ |
||||
|
private Object getFieldValueByReflection(TenderTaskResultVO.ResultItem item, String fieldName) throws Exception { |
||||
|
java.lang.reflect.Method method = item.getClass().getMethod("get" + StringUtils.capitalize(fieldName)); |
||||
|
return method.invoke(item); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 从JSON字符串中提取指定字段的值 |
||||
|
*/ |
||||
|
private String extractJsonField(String jsonStr, String fieldName) { |
||||
|
if (StringUtils.isBlank(jsonStr) || StringUtils.isBlank(fieldName)) { |
||||
|
return ""; |
||||
|
} |
||||
|
|
||||
|
try { |
||||
|
// 支持前端配置中的各种字段
|
||||
|
switch (fieldName) { |
||||
|
case "reviewContent": |
||||
|
case "review_content": |
||||
|
return extractStringField(jsonStr, fieldName); |
||||
|
case "reviewPoints": |
||||
|
case "review_points": |
||||
|
case "error_review_points": |
||||
|
return extractArrayField(jsonStr, fieldName, "\n\n• "); |
||||
|
default: |
||||
|
// 尝试作为字符串字段提取
|
||||
|
String stringResult = extractStringField(jsonStr, fieldName); |
||||
|
if (StringUtils.isNotBlank(stringResult)) { |
||||
|
return stringResult; |
||||
|
} |
||||
|
// 尝试作为数组字段提取
|
||||
|
return extractArrayField(jsonStr, fieldName, "\n\n• "); |
||||
|
} |
||||
|
} catch (Exception e) { |
||||
|
log.error("提取JSON字段失败: {}, {}", fieldName, e.getMessage()); |
||||
|
return ""; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 从JSON中提取字符串字段 |
||||
|
*/ |
||||
|
private String extractStringField(String jsonStr, String fieldName) { |
||||
|
int start = jsonStr.indexOf("\"" + fieldName + "\""); |
||||
|
if (start == -1) return ""; |
||||
|
|
||||
|
start = jsonStr.indexOf(":", start) + 1; |
||||
|
start = jsonStr.indexOf("\"", start) + 1; |
||||
|
int end = jsonStr.indexOf("\"", start); |
||||
|
|
||||
|
if (start > 0 && end > start) { |
||||
|
return jsonStr.substring(start, end) |
||||
|
.replace("\\n", "\n") |
||||
|
.replace("\\\"", "\"") |
||||
|
.replace("\\\\", "\\") |
||||
|
.replace("\\t", "\t") |
||||
|
.replace("<br>", "\n\n") |
||||
|
.replace("<br/>", "\n\n") |
||||
|
.replace("<BR>", "\n\n") |
||||
|
.replace("<BR/>", "\n\n"); |
||||
|
} |
||||
|
|
||||
|
return ""; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 从JSON中提取数组字段并格式化 |
||||
|
*/ |
||||
|
private String extractArrayField(String jsonStr, String fieldName, String prefix) { |
||||
|
int start = jsonStr.indexOf("\"" + fieldName + "\""); |
||||
|
if (start == -1) return ""; |
||||
|
|
||||
|
start = jsonStr.indexOf("[", start); |
||||
|
int end = jsonStr.indexOf("]", start) + 1; |
||||
|
|
||||
|
if (start > 0 && end > start) { |
||||
|
String arrayStr = jsonStr.substring(start, end); |
||||
|
// 处理数组,提取字符串元素
|
||||
|
String result = arrayStr.replaceAll("\\[|\\]", "") |
||||
|
.replaceAll("\"\\s*,\\s*\"", "\",\""); |
||||
|
|
||||
|
if (StringUtils.isNotBlank(result)) { |
||||
|
String[] elements = result.split("\",\""); |
||||
|
StringBuilder formatted = new StringBuilder(); |
||||
|
|
||||
|
for (String element : elements) { |
||||
|
String cleanElement = element.replaceAll("^\"|\"$", "") |
||||
|
.replace("\\n", "\n") |
||||
|
.replace("\\\"", "\"") |
||||
|
.replace("\\\\", "\\") |
||||
|
.replace("\\t", "\t") |
||||
|
.replace("<br>", "\n\n") |
||||
|
.replace("<br/>", "\n\n") |
||||
|
.replace("<BR>", "\n\n") |
||||
|
.replace("<BR/>", "\n\n"); |
||||
|
|
||||
|
if (StringUtils.isNotBlank(cleanElement)) { |
||||
|
if (formatted.length() > 0) { |
||||
|
formatted.append(prefix); |
||||
|
} else { |
||||
|
formatted.append("• "); |
||||
|
} |
||||
|
formatted.append(cleanElement); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return formatted.toString(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return ""; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Markdown转PDF方法 |
||||
|
*/ |
||||
|
private void convertMarkdownToPdf(String markdown, String outputPath) throws Exception { |
||||
|
MutableDataSet options = new MutableDataSet(); |
||||
|
options.set(Parser.EXTENSIONS, Arrays.asList( |
||||
|
TablesExtension.create(), |
||||
|
StrikethroughExtension.create() |
||||
|
)); |
||||
|
|
||||
|
Parser parser = Parser.builder(options).build(); |
||||
|
HtmlRenderer renderer = HtmlRenderer.builder(options) |
||||
|
.extensions(Arrays.asList( |
||||
|
TablesExtension.create(), |
||||
|
StrikethroughExtension.create() |
||||
|
)) |
||||
|
.build(); |
||||
|
|
||||
|
Node document = parser.parse(markdown); |
||||
|
String htmlContent = renderer.render(document); |
||||
|
|
||||
|
// 使用 JSoup 清理
|
||||
|
Document.OutputSettings settings = new Document.OutputSettings(); |
||||
|
settings.prettyPrint(false); |
||||
|
|
||||
|
Safelist safelist = Safelist.relaxed() |
||||
|
.addTags("em", "strong", "div", "span", "br", "table", "thead", "tbody", "tr", "th", "td", "font") |
||||
|
.addAttributes(":all", "style", "class", "color") |
||||
|
.addAttributes("table", "border", "cellpadding", "cellspacing") |
||||
|
.addAttributes("font", "color"); |
||||
|
htmlContent = Jsoup.clean(htmlContent, "", safelist, settings); |
||||
|
|
||||
|
// 创建完整的HTML文档
|
||||
|
String html = String.format(""" |
||||
|
<!DOCTYPE html> |
||||
|
<html> |
||||
|
<head> |
||||
|
<meta charset="UTF-8"/> |
||||
|
<style type="text/css"> |
||||
|
body { |
||||
|
font-family: Microsoft YaHei, SimSun, Arial; |
||||
|
line-height: 1.6; |
||||
|
margin: 20px; |
||||
|
font-size: 14px; |
||||
|
} |
||||
|
p { margin: 10px 0; } |
||||
|
pre { |
||||
|
background-color: #f5f5f5; |
||||
|
padding: 10px; |
||||
|
border-radius: 4px; |
||||
|
} |
||||
|
table { |
||||
|
border-collapse: collapse; |
||||
|
width: 100%%; |
||||
|
margin: 10px 0; |
||||
|
} |
||||
|
th, td { |
||||
|
border: 1px solid #ddd; |
||||
|
padding: 8px; |
||||
|
text-align: left; |
||||
|
} |
||||
|
th { |
||||
|
background-color: #f5f5f5; |
||||
|
font-weight: bold; |
||||
|
} |
||||
|
.highlight { |
||||
|
background-color: #ffff00; |
||||
|
} |
||||
|
font[color=red] { |
||||
|
color: red; |
||||
|
font-weight: bold; |
||||
|
} |
||||
|
</style> |
||||
|
</head> |
||||
|
<body> |
||||
|
%s |
||||
|
</body> |
||||
|
</html> |
||||
|
""", htmlContent.replace("<br>", "\n")); |
||||
|
|
||||
|
// 配置Flying Saucer
|
||||
|
ITextRenderer pdfRenderer = new ITextRenderer(); |
||||
|
|
||||
|
// 加载字体
|
||||
|
try (InputStream is = getClass().getResourceAsStream("/fonts/msyh.ttc")) { |
||||
|
if (is != null) { |
||||
|
File tempFont = File.createTempFile("msyh", ".ttc"); |
||||
|
FileUtils.copyInputStreamToFile(is, tempFont); |
||||
|
pdfRenderer.getFontResolver().addFont(tempFont.getAbsolutePath(), BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED); |
||||
|
tempFont.deleteOnExit(); |
||||
|
} |
||||
|
} catch (Exception e) { |
||||
|
log.warn("加载字体失败,使用默认字体: {}", e.getMessage()); |
||||
|
} |
||||
|
|
||||
|
pdfRenderer.setDocumentFromString(html); |
||||
|
pdfRenderer.getSharedContext().setBaseURL("file:///"); |
||||
|
pdfRenderer.layout(); |
||||
|
|
||||
|
try (OutputStream os = new FileOutputStream(outputPath)) { |
||||
|
pdfRenderer.createPDF(os, true); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 添加文件到ZIP |
||||
|
*/ |
||||
|
private void addToZip(String filePath, String fileName, ZipOutputStream zos) throws IOException { |
||||
|
byte[] buffer = new byte[1024]; |
||||
|
try (FileInputStream fis = new FileInputStream(filePath)) { |
||||
|
zos.putNextEntry(new ZipEntry(fileName)); |
||||
|
int length; |
||||
|
while ((length = fis.read(buffer)) > 0) { |
||||
|
zos.write(buffer, 0, length); |
||||
|
} |
||||
|
zos.closeEntry(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 文件下载方法 |
||||
|
*/ |
||||
|
private void downloadFile(HttpServletResponse response, String filePath, String fileName) throws IOException { |
||||
|
File file = new File(filePath); |
||||
|
if (!file.exists()) { |
||||
|
throw new RuntimeException("文件不存在"); |
||||
|
} |
||||
|
|
||||
|
response.setContentType("application/octet-stream"); |
||||
|
response.setHeader("Content-Disposition", "attachment;filename=" + |
||||
|
URLEncoder.encode(fileName, StandardCharsets.UTF_8.name())); |
||||
|
|
||||
|
try (FileInputStream fis = new FileInputStream(file); |
||||
|
BufferedInputStream bis = new BufferedInputStream(fis); |
||||
|
OutputStream os = response.getOutputStream()) { |
||||
|
|
||||
|
byte[] buffer = new byte[1024]; |
||||
|
int i; |
||||
|
while ((i = bis.read(buffer)) != -1) { |
||||
|
os.write(buffer, 0, i); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 招投标任务字段配置类 |
||||
|
*/ |
||||
|
private static class TenderFieldConfig { |
||||
|
private String field; |
||||
|
private String title; |
||||
|
|
||||
|
public TenderFieldConfig(String field, String title) { |
||||
|
this.field = field; |
||||
|
this.title = title; |
||||
|
} |
||||
|
|
||||
|
public String getField() { |
||||
|
return field; |
||||
|
} |
||||
|
|
||||
|
public String getTitle() { |
||||
|
return title; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 招投标任务tabs配置类 |
||||
|
*/ |
||||
|
private static class TenderTabConfig { |
||||
|
private String tabName; |
||||
|
private List<TenderFieldConfig> fieldConfigs; |
||||
|
|
||||
|
public TenderTabConfig(String tabName, List<TenderFieldConfig> fieldConfigs) { |
||||
|
this.tabName = tabName; |
||||
|
this.fieldConfigs = fieldConfigs; |
||||
|
} |
||||
|
|
||||
|
public String getTabName() { |
||||
|
return tabName; |
||||
|
} |
||||
|
|
||||
|
public List<TenderFieldConfig> getFieldConfigs() { |
||||
|
return fieldConfigs; |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,144 @@ |
|||||
|
package org.dromara.productManagement.service.impl; |
||||
|
|
||||
|
import org.dromara.common.core.utils.MapstructUtils; |
||||
|
import org.dromara.common.core.utils.StringUtils; |
||||
|
import org.dromara.common.mybatis.core.page.TableDataInfo; |
||||
|
import org.dromara.common.mybatis.core.page.PageQuery; |
||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
||||
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
||||
|
import lombok.RequiredArgsConstructor; |
||||
|
import org.dromara.productManagement.service.ITenderTaskTypeService; |
||||
|
import org.springframework.stereotype.Service; |
||||
|
import org.springframework.transaction.annotation.Transactional; |
||||
|
import org.dromara.productManagement.domain.bo.TenderTaskTypeBo; |
||||
|
import org.dromara.productManagement.domain.vo.TenderTaskTypeVo; |
||||
|
import org.dromara.productManagement.domain.TenderTaskType; |
||||
|
import org.dromara.productManagement.mapper.TenderTaskTypeMapper; |
||||
|
|
||||
|
import java.util.List; |
||||
|
import java.util.Collection; |
||||
|
import java.util.Map; |
||||
|
|
||||
|
/** |
||||
|
* 招投标类型Service业务层处理 |
||||
|
* |
||||
|
* @author guoyan |
||||
|
* @date 2024-12-14 |
||||
|
*/ |
||||
|
@RequiredArgsConstructor |
||||
|
@Service |
||||
|
@Transactional |
||||
|
public class TenderTaskTypeServiceImpl implements ITenderTaskTypeService { |
||||
|
|
||||
|
private final TenderTaskTypeMapper baseMapper; |
||||
|
|
||||
|
/** |
||||
|
* 查询招投标类型 |
||||
|
* |
||||
|
* @param id 招投标类型主键 |
||||
|
* @return 招投标类型 |
||||
|
*/ |
||||
|
@Override |
||||
|
public TenderTaskTypeVo queryById(Long id) { |
||||
|
return baseMapper.selectVoById(id); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 查询招投标类型列表 |
||||
|
* |
||||
|
* @param bo 招投标类型 |
||||
|
* @return 招投标类型 |
||||
|
*/ |
||||
|
@Override |
||||
|
public TableDataInfo<TenderTaskTypeVo> queryPageList(TenderTaskTypeBo bo, PageQuery pageQuery) { |
||||
|
LambdaQueryWrapper<TenderTaskType> lqw = buildQueryWrapper(bo); |
||||
|
Page<TenderTaskTypeVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw); |
||||
|
return TableDataInfo.build(result); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 查询招投标类型列表 |
||||
|
* |
||||
|
* @param bo 招投标类型 |
||||
|
* @return 招投标类型 |
||||
|
*/ |
||||
|
@Override |
||||
|
public List<TenderTaskTypeVo> queryList(TenderTaskTypeBo bo) { |
||||
|
LambdaQueryWrapper<TenderTaskType> lqw = buildQueryWrapper(bo); |
||||
|
return baseMapper.selectVoList(lqw); |
||||
|
} |
||||
|
|
||||
|
private LambdaQueryWrapper<TenderTaskType> buildQueryWrapper(TenderTaskTypeBo bo) { |
||||
|
Map<String, Object> params = bo.getParams(); |
||||
|
LambdaQueryWrapper<TenderTaskType> lqw = Wrappers.lambdaQuery(); |
||||
|
lqw.like(StringUtils.isNotBlank(bo.getTenderName()), TenderTaskType::getTenderName, bo.getTenderName()); |
||||
|
lqw.eq(bo.getSort() != null, TenderTaskType::getSort, bo.getSort()); |
||||
|
lqw.eq(StringUtils.isNotBlank(bo.getStatus()), TenderTaskType::getStatus, bo.getStatus()); |
||||
|
return lqw; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 新增招投标类型 |
||||
|
* |
||||
|
* @param bo 招投标类型 |
||||
|
* @return 结果 |
||||
|
*/ |
||||
|
@Override |
||||
|
public Boolean insertByBo(TenderTaskTypeBo bo) { |
||||
|
TenderTaskType add = MapstructUtils.convert(bo, TenderTaskType.class); |
||||
|
validEntityBeforeSave(add); |
||||
|
boolean flag = baseMapper.insert(add) > 0; |
||||
|
if (flag) { |
||||
|
bo.setId(add.getId()); |
||||
|
} |
||||
|
return flag; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 修改招投标类型 |
||||
|
* |
||||
|
* @param bo 招投标类型 |
||||
|
* @return 结果 |
||||
|
*/ |
||||
|
@Override |
||||
|
public Boolean updateByBo(TenderTaskTypeBo bo) { |
||||
|
TenderTaskType update = MapstructUtils.convert(bo, TenderTaskType.class); |
||||
|
validEntityBeforeSave(update); |
||||
|
return baseMapper.updateById(update) > 0; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 保存前的数据校验 |
||||
|
* |
||||
|
* @param entity 实体类数据 |
||||
|
*/ |
||||
|
private void validEntityBeforeSave(TenderTaskType entity) { |
||||
|
// 校验招投标类型名称是否重复
|
||||
|
if (StringUtils.isNotEmpty(entity.getTenderName())) { |
||||
|
LambdaQueryWrapper<TenderTaskType> queryWrapper = Wrappers.lambdaQuery(); |
||||
|
queryWrapper.eq(TenderTaskType::getTenderName, entity.getTenderName()); |
||||
|
if (entity.getId() != null) { |
||||
|
queryWrapper.ne(TenderTaskType::getId, entity.getId()); |
||||
|
} |
||||
|
if (baseMapper.selectCount(queryWrapper) > 0) { |
||||
|
throw new RuntimeException("招投标类型名称已存在"); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 批量删除招投标类型 |
||||
|
* |
||||
|
* @param ids 需要删除的招投标类型主键 |
||||
|
* @return 结果 |
||||
|
*/ |
||||
|
@Override |
||||
|
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) { |
||||
|
if (isValid) { |
||||
|
// 校验是否存在关联的招投标任务
|
||||
|
// 这里可以添加业务校验逻辑
|
||||
|
} |
||||
|
return baseMapper.deleteBatchIds(ids) > 0; |
||||
|
} |
||||
|
} |
@ -0,0 +1,347 @@ |
|||||
|
package org.dromara.productManagement.service.impl; |
||||
|
|
||||
|
import cn.dev33.satoken.stp.StpUtil; |
||||
|
import com.baomidou.dynamic.datasource.annotation.DS; |
||||
|
import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder; |
||||
|
import okhttp3.*; |
||||
|
import org.dromara.common.satoken.utils.LoginHelper; |
||||
|
|
||||
|
import org.dromara.productManagement.service.ITenderTasksService; |
||||
|
import org.dromara.system.domain.vo.SysOssVo; |
||||
|
import org.dromara.system.service.ISysOssService; |
||||
|
import org.dromara.system.service.ISysUserService; |
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
import org.springframework.beans.factory.annotation.Value; |
||||
|
import org.springframework.stereotype.Service; |
||||
|
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.conditions.update.LambdaUpdateWrapper; |
||||
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
||||
|
import lombok.RequiredArgsConstructor; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.dromara.productManagement.domain.TenderTaskGroup; |
||||
|
import org.dromara.productManagement.domain.bo.TenderTasksBo; |
||||
|
import org.dromara.productManagement.domain.vo.TenderTasksVo; |
||||
|
import org.dromara.productManagement.domain.TenderTasks; |
||||
|
import org.dromara.productManagement.mapper.TenderTasksMapper; |
||||
|
import jakarta.servlet.http.HttpServletResponse; |
||||
|
|
||||
|
import javax.sql.DataSource; |
||||
|
import java.io.*; |
||||
|
import java.net.URLEncoder; |
||||
|
import java.nio.charset.StandardCharsets; |
||||
|
import java.sql.Connection; |
||||
|
import java.sql.PreparedStatement; |
||||
|
import java.sql.SQLException; |
||||
|
import java.util.List; |
||||
|
import java.util.Map; |
||||
|
import java.util.Collection; |
||||
|
import java.util.Collections; |
||||
|
import java.util.Date; |
||||
|
|
||||
|
/** |
||||
|
* 招投标审核任务Service业务层处理 |
||||
|
* |
||||
|
* @author ruoyi |
||||
|
* @date 2024-01-01 |
||||
|
*/ |
||||
|
@RequiredArgsConstructor |
||||
|
@Service |
||||
|
@Slf4j |
||||
|
public class TenderTasksServiceImpl implements ITenderTasksService { |
||||
|
|
||||
|
private final TenderTasksMapper baseMapper; |
||||
|
protected final ISysOssService ossService; |
||||
|
protected final ISysUserService userService; |
||||
|
@Value("${chat.chatUrl}") |
||||
|
private String backTaskUrl; |
||||
|
@Autowired |
||||
|
private DataSource dataSource; |
||||
|
/** |
||||
|
* 查询招投标审核任务 |
||||
|
*/ |
||||
|
@Override |
||||
|
public TenderTasksVo queryById(Long id){ |
||||
|
return baseMapper.selectVoById(id); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 查询招投标审核任务列表 |
||||
|
*/ |
||||
|
@Override |
||||
|
@DS("slave") |
||||
|
public TableDataInfo<TenderTasksVo> queryPageList(TenderTasksBo bo, PageQuery pageQuery) { |
||||
|
LambdaQueryWrapper<TenderTasks> lqw = buildQueryWrapper(bo); |
||||
|
Page<TenderTasksVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw); |
||||
|
return TableDataInfo.build(result); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 分页查询招投标任务分组列表 |
||||
|
*/ |
||||
|
@Override |
||||
|
@DS("slave") |
||||
|
public TableDataInfo<TenderTaskGroup> queryGroupPageList(TenderTasksBo bo, PageQuery pageQuery) { |
||||
|
LambdaQueryWrapper<TenderTasks> lqw = buildGroupQueryWrapper(bo); |
||||
|
Page<TenderTaskGroup> tenderTaskGroupPage = baseMapper.selectTenderTaskGroups(pageQuery.build(), lqw); |
||||
|
tenderTaskGroupPage.getRecords().forEach(vo -> { |
||||
|
Long createBy = vo.getCreateBy(); |
||||
|
// 切换到主库查询用户信息
|
||||
|
DynamicDataSourceContextHolder.push("master"); |
||||
|
try { |
||||
|
vo.setCreateUser(userService.selectUserById(createBy).getNickName()); |
||||
|
} finally { |
||||
|
// 确保在finally块中恢复数据源,防止异常导致数据源未切回
|
||||
|
DynamicDataSourceContextHolder.poll(); |
||||
|
} |
||||
|
}); |
||||
|
return TableDataInfo.build(tenderTaskGroupPage); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 查询招投标审核任务列表 |
||||
|
*/ |
||||
|
@Override |
||||
|
public List<TenderTasksVo> queryList(TenderTasksBo bo) { |
||||
|
LambdaQueryWrapper<TenderTasks> lqw = buildQueryWrapper(bo); |
||||
|
return baseMapper.selectVoList(lqw); |
||||
|
} |
||||
|
|
||||
|
private LambdaQueryWrapper<TenderTasks> buildQueryWrapper(TenderTasksBo bo) { |
||||
|
Map<String, Object> params = bo.getParams(); |
||||
|
LambdaQueryWrapper<TenderTasks> lqw = Wrappers.lambdaQuery(); |
||||
|
lqw.like(StringUtils.isNotBlank(bo.getTaskName()), TenderTasks::getTaskName, bo.getTaskName()); |
||||
|
lqw.like(StringUtils.isNotBlank(bo.getTenderDocumentName()), TenderTasks::getTenderDocumentName, bo.getTenderDocumentName()); |
||||
|
lqw.like(StringUtils.isNotBlank(bo.getBidDocumentName()), TenderTasks::getBidDocumentName, bo.getBidDocumentName()); |
||||
|
lqw.eq(StringUtils.isNotBlank(bo.getProgressStatus()), TenderTasks::getProgressStatus, bo.getProgressStatus()); |
||||
|
lqw.eq(StringUtils.isNotBlank(bo.getResultType()), TenderTasks::getResultType, bo.getResultType()); |
||||
|
lqw.orderByDesc(TenderTasks::getCreateTime); |
||||
|
return lqw; |
||||
|
} |
||||
|
|
||||
|
private LambdaQueryWrapper<TenderTasks> buildGroupQueryWrapper(TenderTasksBo bo) { |
||||
|
Map<String, Object> params = bo.getParams(); |
||||
|
LambdaQueryWrapper<TenderTasks> lqw = Wrappers.lambdaQuery(); |
||||
|
|
||||
|
// 处理 taskNameList 是 List<String> 的情况
|
||||
|
List<String> taskNames = bo.getTaskNameList(); |
||||
|
if (taskNames != null && !taskNames.isEmpty()) { |
||||
|
lqw.in(TenderTasks::getTaskName, taskNames); |
||||
|
} |
||||
|
|
||||
|
lqw.like(StringUtils.isNotBlank(bo.getTaskName()), TenderTasks::getTaskName, bo.getTaskName()); |
||||
|
lqw.like(StringUtils.isNotBlank(bo.getTenderDocumentName()), TenderTasks::getTenderDocumentName, bo.getTenderDocumentName()); |
||||
|
lqw.like(StringUtils.isNotBlank(bo.getBidDocumentName()), TenderTasks::getBidDocumentName, bo.getBidDocumentName()); |
||||
|
lqw.eq(StringUtils.isNotBlank(bo.getProgressStatus()), TenderTasks::getProgressStatus, bo.getProgressStatus()); |
||||
|
lqw.eq(StringUtils.isNotBlank(bo.getResultType()), TenderTasks::getResultType, bo.getResultType()); |
||||
|
lqw.orderByDesc(TenderTasks::getCreateTime); |
||||
|
if (!StpUtil.hasRole("superadmin")) { |
||||
|
lqw.eq(TenderTasks::getCreateBy, LoginHelper.getUserId()); |
||||
|
} |
||||
|
//分组,作为父项(按文件名分组而不是任务名)
|
||||
|
lqw.groupBy(TenderTasks::getCreateBy, |
||||
|
TenderTasks::getTenderDocumentName, |
||||
|
TenderTasks::getBidDocumentName, |
||||
|
TenderTasks::getCreateTime, |
||||
|
TenderTasks::getDeleteFlag); |
||||
|
return lqw; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 新增招投标审核任务 |
||||
|
*/ |
||||
|
@Override |
||||
|
@DS("slave") |
||||
|
public Boolean insertByBo(TenderTasksBo bo) { |
||||
|
List<String> taskNameList = bo.getTaskNameList(); |
||||
|
String bidDocOssId = bo.getBidDocZipOssId(); |
||||
|
String tenderDocOssId = bo.getTenderDocOssId(); |
||||
|
|
||||
|
String bidDocUrl = ""; |
||||
|
String bidDocFileName = ""; |
||||
|
String tenderDocUrl = ""; |
||||
|
String tenderFileName = ""; |
||||
|
|
||||
|
// 切换到主库查询OSS信息
|
||||
|
DynamicDataSourceContextHolder.push("master"); |
||||
|
try { |
||||
|
if (bidDocOssId==null && tenderDocOssId==null){ |
||||
|
throw new RuntimeException("请上传投标文件或者招标文件"); |
||||
|
} |
||||
|
if (bidDocOssId!=null ){ |
||||
|
SysOssVo bidDocFiles = ossService.getById(Long.valueOf(bidDocOssId)); |
||||
|
if (bidDocFiles!=null) { |
||||
|
bidDocUrl = bidDocFiles.getUrl(); |
||||
|
bidDocFileName = bidDocFiles.getOriginalName(); |
||||
|
} |
||||
|
} |
||||
|
if (tenderDocOssId!=null ){ |
||||
|
SysOssVo tenderDocFiles = ossService.getById(Long.valueOf(tenderDocOssId)); |
||||
|
if (tenderDocFiles!=null) { |
||||
|
tenderDocUrl = tenderDocFiles.getUrl(); |
||||
|
tenderFileName = tenderDocFiles.getOriginalName(); |
||||
|
} |
||||
|
} |
||||
|
} finally { |
||||
|
// 确保在finally块中恢复数据源,防止异常导致数据源未切回
|
||||
|
DynamicDataSourceContextHolder.poll(); |
||||
|
} |
||||
|
if(bidDocOssId==null && tenderDocOssId==null){ |
||||
|
throw new RuntimeException("请上传投标文件或者招标文件"); |
||||
|
} |
||||
|
|
||||
|
if (taskNameList != null && !taskNameList.isEmpty()) { |
||||
|
for (String taskName : taskNameList) { |
||||
|
// 创建 TenderTasks 实体并设置属性
|
||||
|
TenderTasks add = MapstructUtils.convert(bo, TenderTasks.class); |
||||
|
add.setTaskName(taskName); |
||||
|
add.setBidDocumentName(bidDocFileName); |
||||
|
add.setTenderDocumentName(tenderFileName); |
||||
|
add.setProgressStatus("PENDING"); |
||||
|
// 验证实体并保存
|
||||
|
validEntityBeforeSave(add); |
||||
|
boolean flag = baseMapper.insert(add) > 0; |
||||
|
|
||||
|
if (flag) { |
||||
|
// 发起请求
|
||||
|
OkHttpClient client = new OkHttpClient.Builder().build(); |
||||
|
HttpUrl.Builder urlBuilder = HttpUrl.parse(backTaskUrl + "/back/taskStart").newBuilder(); |
||||
|
urlBuilder.addQueryParameter("userId", String.valueOf(LoginHelper.getUserId())); |
||||
|
urlBuilder.addQueryParameter("taskId", String.valueOf(add.getId())); |
||||
|
urlBuilder.addQueryParameter("filename", bidDocUrl + "\n" + tenderDocUrl); |
||||
|
urlBuilder.addQueryParameter("taskName", taskName); |
||||
|
urlBuilder.addQueryParameter("priority", "1"); |
||||
|
Request request = new Request.Builder() |
||||
|
.url(urlBuilder.build()) |
||||
|
.build(); |
||||
|
// 使用异步调用
|
||||
|
client.newCall(request).enqueue(new Callback() { |
||||
|
@Override |
||||
|
public void onFailure(Call call, IOException e) { |
||||
|
e.printStackTrace(); // 处理请求失败
|
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void onResponse(Call call, Response response) throws IOException { |
||||
|
// 忽略返回内容
|
||||
|
response.close(); // 确保响应被关闭
|
||||
|
} |
||||
|
}); |
||||
|
} else { |
||||
|
throw new RuntimeException("新增招投标审核任务失败"); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 修改招投标审核任务 |
||||
|
*/ |
||||
|
@Override |
||||
|
public Boolean updateByBo(TenderTasksBo bo) { |
||||
|
TenderTasks update = MapstructUtils.convert(bo, TenderTasks.class); |
||||
|
validEntityBeforeSave(update); |
||||
|
return baseMapper.updateById(update) > 0; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 保存前的数据校验 |
||||
|
*/ |
||||
|
private void validEntityBeforeSave(TenderTasks entity){ |
||||
|
// 可以在此处添加业务校验逻辑
|
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 批量删除招投标审核任务 |
||||
|
*/ |
||||
|
@Override |
||||
|
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) { |
||||
|
if(isValid){ |
||||
|
// 做一些业务上的校验,判断是否需要校验
|
||||
|
} |
||||
|
return baseMapper.deleteBatchIds(ids) > 0; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 删除招投标任务文件 |
||||
|
*/ |
||||
|
@Override |
||||
|
@DS("slave") |
||||
|
public Boolean ossRemoveById(String ossId, Boolean isValid) { |
||||
|
try { |
||||
|
log.info("开始删除招投标任务文件,ossId: {}", ossId); |
||||
|
|
||||
|
// 查找包含该ossId的招投标任务(从库查询)
|
||||
|
LambdaQueryWrapper<TenderTasks> queryWrapper = new LambdaQueryWrapper<>(); |
||||
|
queryWrapper.eq(TenderTasks::getTenderDocOssId, ossId) |
||||
|
.or() |
||||
|
.eq(TenderTasks::getBidDocZipOssId, ossId); |
||||
|
|
||||
|
List<TenderTasksVo> tasks = baseMapper.selectVoList(queryWrapper); |
||||
|
|
||||
|
if (tasks.isEmpty()) { |
||||
|
log.warn("未找到包含ossId: {} 的招投标任务", ossId); |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
// 切换到主库进行删除和更新操作
|
||||
|
DynamicDataSourceContextHolder.push("master"); |
||||
|
try { |
||||
|
// 删除文件服务中的文件
|
||||
|
ossService.deleteWithValidByIds(Collections.singletonList(Long.valueOf(ossId)), true); |
||||
|
log.info("已删除文件服务中的文件,ossId: {}", ossId); |
||||
|
|
||||
|
// 对于找到的每个任务,需要检查并删除相关的其他文件
|
||||
|
for (TenderTasksVo task : tasks) { |
||||
|
String tenderDocOssId = task.getTenderDocOssId(); |
||||
|
String bidDocZipOssId = task.getBidDocZipOssId(); |
||||
|
|
||||
|
// 如果删除的是招标文件,还需要删除投标文件(如果有的话)
|
||||
|
if (ossId.equals(tenderDocOssId) && StringUtils.isNotBlank(bidDocZipOssId)) { |
||||
|
try { |
||||
|
ossService.deleteWithValidByIds(Collections.singletonList(Long.valueOf(bidDocZipOssId)), true); |
||||
|
log.info("已删除关联的投标文件,ossId: {}", bidDocZipOssId); |
||||
|
} catch (Exception e) { |
||||
|
log.warn("删除关联投标文件失败,ossId: {}, 错误: {}", bidDocZipOssId, e.getMessage()); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 如果删除的是投标文件,还需要删除招标文件(如果有的话)
|
||||
|
if (ossId.equals(bidDocZipOssId) && StringUtils.isNotBlank(tenderDocOssId)) { |
||||
|
try { |
||||
|
ossService.deleteWithValidByIds(Collections.singletonList(Long.valueOf(tenderDocOssId)), true); |
||||
|
log.info("已删除关联的招标文件,ossId: {}", tenderDocOssId); |
||||
|
} catch (Exception e) { |
||||
|
log.warn("删除关联招标文件失败,ossId: {}, 错误: {}", tenderDocOssId, e.getMessage()); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} finally { |
||||
|
// 确保在finally块中恢复数据源,防止异常导致数据源未切回
|
||||
|
DynamicDataSourceContextHolder.poll(); |
||||
|
} |
||||
|
// 更新数据库中的deleteFlag字段
|
||||
|
LambdaUpdateWrapper<TenderTasks> updateWrapper = new LambdaUpdateWrapper<>(); |
||||
|
updateWrapper.eq(TenderTasks::getTenderDocOssId, ossId) |
||||
|
.or() |
||||
|
.eq(TenderTasks::getBidDocZipOssId, ossId); |
||||
|
updateWrapper.set(TenderTasks::getDeleteFlag, "Y"); |
||||
|
|
||||
|
int updateCount = baseMapper.update(null, updateWrapper); |
||||
|
log.info("已更新数据库deleteFlag字段,影响行数: {}", updateCount); |
||||
|
|
||||
|
|
||||
|
return true; |
||||
|
|
||||
|
} catch (Exception e) { |
||||
|
log.error("删除招投标任务文件失败,ossId: {}, 错误: {}", ossId, e.getMessage(), e); |
||||
|
throw new RuntimeException("删除招投标任务文件失败: " + e.getMessage()); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
@ -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.TenderTaskResultDetailMapper"> |
||||
|
|
||||
|
</mapper> |
@ -0,0 +1,140 @@ |
|||||
|
<?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.TenderTasksMapper"> |
||||
|
|
||||
|
<resultMap id="TenderTaskGroupResult" type="org.dromara.productManagement.domain.TenderTaskGroup"> |
||||
|
<id property="id" column="group_id"/> |
||||
|
<result property="createBy" column="create_by"/> |
||||
|
<result property="tenderDocumentName" column="tender_document_name"/> |
||||
|
<result property="bidDocumentName" column="bid_document_name"/> |
||||
|
<result property="createTime" column="group_create_time"/> |
||||
|
<result property="progress" column="progress"/> |
||||
|
<result property="deleteFlag" column="delete_flag"/> |
||||
|
<!-- 使用collection标签正确映射子任务列表 --> |
||||
|
<collection property="childrenTasks" |
||||
|
column="{createBy=create_by, |
||||
|
tenderDocumentName=tender_document_name, |
||||
|
bidDocumentName=bid_document_name, |
||||
|
groupDate=group_create_time}" |
||||
|
select="selectChildTasks"/> |
||||
|
</resultMap> |
||||
|
|
||||
|
<!-- 父级查询 --> |
||||
|
<select id="selectTenderTaskGroups" resultMap="TenderTaskGroupResult"> |
||||
|
SELECT |
||||
|
UUID() as group_id, |
||||
|
create_by, |
||||
|
tender_document_name, |
||||
|
bid_document_name, |
||||
|
create_time as group_create_time, |
||||
|
delete_flag, |
||||
|
CASE |
||||
|
WHEN (SUM(CASE WHEN progress_status IN ('SUCCESS', 'FAILURE') THEN 1 ELSE 0 END) * 100.0) / COUNT(*) = 100 |
||||
|
THEN |
||||
|
CASE |
||||
|
WHEN SUM(CASE WHEN progress_status = 'FAILURE' THEN 1 ELSE 0 END) > 0 |
||||
|
THEN CONCAT( |
||||
|
'100%(', |
||||
|
COUNT(*), |
||||
|
'/', |
||||
|
COUNT(*), |
||||
|
',失败:', |
||||
|
SUM(CASE WHEN progress_status = 'FAILURE' THEN 1 ELSE 0 END), |
||||
|
')' |
||||
|
) |
||||
|
ELSE CONCAT('100%(', COUNT(*), '/', COUNT(*), ')') |
||||
|
END |
||||
|
ELSE |
||||
|
CONCAT( |
||||
|
FLOOR((SUM(CASE WHEN progress_status IN ('SUCCESS', 'FAILURE') THEN 1 ELSE 0 END) * 100.0) / COUNT(*)), |
||||
|
'%(', |
||||
|
SUM(CASE WHEN progress_status IN ('SUCCESS', 'FAILURE') THEN 1 ELSE 0 END), |
||||
|
'/', |
||||
|
COUNT(*), |
||||
|
')' |
||||
|
) |
||||
|
END as progress |
||||
|
FROM tender_tasks |
||||
|
${ew.getCustomSqlSegment} |
||||
|
</select> |
||||
|
|
||||
|
<!-- 子任务查询 --> |
||||
|
<select id="selectChildTasks" resultType="org.dromara.productManagement.domain.TenderTaskChild"> |
||||
|
SELECT |
||||
|
id, |
||||
|
task_name, |
||||
|
tender_document_name, |
||||
|
bid_document_name, |
||||
|
progress_status, |
||||
|
group_id, |
||||
|
task_id, |
||||
|
result_type, |
||||
|
tender_doc_oss_id, |
||||
|
bid_doc_zip_oss_id, |
||||
|
version, |
||||
|
create_time, |
||||
|
update_time, |
||||
|
CASE |
||||
|
WHEN update_time IS NOT NULL THEN |
||||
|
CASE |
||||
|
WHEN TIMESTAMPDIFF(HOUR, create_time, update_time) >= 1 THEN |
||||
|
CONCAT( |
||||
|
FLOOR(TIMESTAMPDIFF(MINUTE, create_time, update_time) / 60), |
||||
|
'小时', |
||||
|
MOD(TIMESTAMPDIFF(MINUTE, create_time, update_time), 60), |
||||
|
'分钟' |
||||
|
) |
||||
|
ELSE |
||||
|
CONCAT( |
||||
|
TIMESTAMPDIFF(MINUTE, create_time, update_time), |
||||
|
'分钟' |
||||
|
) |
||||
|
END |
||||
|
ELSE NULL |
||||
|
END as task_duration |
||||
|
FROM tender_tasks |
||||
|
WHERE del_flag = '0' |
||||
|
AND create_by = #{createBy} |
||||
|
AND tender_document_name = #{tenderDocumentName} |
||||
|
AND bid_document_name = #{bidDocumentName} |
||||
|
AND create_time = #{groupDate} |
||||
|
ORDER BY create_time DESC |
||||
|
</select> |
||||
|
|
||||
|
<resultMap type="org.dromara.productManagement.domain.vo.TenderTaskResultVO$ResultItem" id="TenderTaskResult"> |
||||
|
<result property="id" column="id"/> |
||||
|
<result property="serialNumber" column="serial_number"/> |
||||
|
<result property="issueName" column="issue_name"/> |
||||
|
<result property="originalText" column="original_text"/> |
||||
|
<result property="comparedText" column="compared_text"/> |
||||
|
<result property="modifiedContent" column="modified_content"/> |
||||
|
<result property="modificationDisplay" column="modification_display"/> |
||||
|
<result property="existingIssues" column="existing_issues"/> |
||||
|
<result property="reviewBasis" column="review_basis"/> |
||||
|
<result property="isRead" column="is_read"/> |
||||
|
<result property="isAdopted" column="is_adopted"/> |
||||
|
<!-- 审查依据现在直接存储为JSON字符串 --> |
||||
|
</resultMap> |
||||
|
|
||||
|
<resultMap id="tenderResultVOMap" type="org.dromara.productManagement.domain.vo.TenderTaskResultVO"> |
||||
|
<result property="name" column="category_name"/> |
||||
|
<collection property="results" javaType="java.util.ArrayList" ofType="org.dromara.productManagement.domain.vo.TenderTaskResultVO$ResultItem" |
||||
|
column="category_id" select="getTenderResultItemsByCategoryId"/> |
||||
|
</resultMap> |
||||
|
|
||||
|
<select id="getResultsByTaskId" resultMap="tenderResultVOMap"> |
||||
|
SELECT id as category_id, category_name |
||||
|
FROM tender_task_categories |
||||
|
WHERE tender_task_id = #{taskId} |
||||
|
</select> |
||||
|
|
||||
|
<select id="getTenderResultItemsByCategoryId" resultMap="TenderTaskResult"> |
||||
|
SELECT id, issue_name, original_text, compared_text, modified_content, |
||||
|
modification_display, existing_issues, review_basis, is_read, is_adopted,sort_order |
||||
|
FROM tender_task_result_details |
||||
|
WHERE category_id = #{category_id} |
||||
|
order by sort_order asc |
||||
|
</select> |
||||
|
</mapper> |
Loading…
Reference in new issue