[add] 工作流按项目分类,设计变更工单、专项方案模块

This commit is contained in:
lcj
2025-07-03 20:50:55 +08:00
parent 3997e21d6c
commit 348ff6fc2b
37 changed files with 2354 additions and 78 deletions

View File

@ -0,0 +1,39 @@
package org.dromara.design.constant;
import org.dromara.common.core.utils.DateUtils;
import org.dromara.design.domain.DesDesignChange;
import java.text.SimpleDateFormat;
/**
* @author lcj
* @date 2025/7/3 19:42
*/
public interface DesDesignConstant {
/**
* 设计变更申请单模版路径
*/
String DESIGN_CHANGE_TEMPLATE_PATH = "template/设计变更申请单模版.docx";
/**
* 设计变更申请单文件路径
*/
String DESIGN_CHANGE_FILE_URL = "docs/design/change/";
/**
* 设计变更申请单文件名
*/
static String getDesignChangeFileUrl(DesDesignChange designChange) {
String timestamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(designChange.getUpdateTime());
return String.format("%s%s/%s", DESIGN_CHANGE_FILE_URL, designChange.getId(), timestamp);
}
/**
* 设计变更申请单文件名
*/
static String getDesignChangeFileName(DesDesignChange designChange) {
String createDate = DateUtils.formatDate(designChange.getCreateTime());
return String.format("设计变更申请单(%s.docx", createDate);
}
}

View File

@ -0,0 +1,24 @@
package org.dromara.design.constant;
/**
* @author lcj
* @date 2025/7/3 11:35
*/
public interface DesSpecialSchemeConstant {
/**
* 对象存储前缀
*/
String OSS_PREFIX = "doc/design/special/scheme/";
/**
* 获取项目对象存储前缀
*
* @param projectId 项目id
* @return 项目对象存储前缀
*/
static String getProjectOssPrefix(Long projectId) {
return String.format("%s%s/", OSS_PREFIX, projectId);
}
}

View File

@ -0,0 +1,107 @@
package org.dromara.design.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
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.idempotent.annotation.RepeatSubmit;
import org.dromara.common.log.annotation.Log;
import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.web.core.BaseController;
import org.dromara.design.domain.dto.designchange.DesDesignChangeCreateReq;
import org.dromara.design.domain.dto.designchange.DesDesignChangeQueryReq;
import org.dromara.design.domain.dto.designchange.DesDesignChangeUpdateReq;
import org.dromara.design.domain.vo.designchange.DesDesignChangeVo;
import org.dromara.design.service.IDesDesignChangeService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 设计变更管理
*
* @author lcj
* @date 2025-07-03
*/
@Validated
@RestController
@RequestMapping("/design/designChange")
public class DesDesignChangeController extends BaseController {
@Resource
private IDesDesignChangeService desDesignChangeService;
/**
* 查询设计变更管理列表
*/
@SaCheckPermission("design:designChange:list")
@GetMapping("/list")
public TableDataInfo<DesDesignChangeVo> list(DesDesignChangeQueryReq req, PageQuery pageQuery) {
return desDesignChangeService.queryPageList(req, pageQuery);
}
/**
* 根据主键设计变更单
*/
@SaCheckPermission("design:designChange:export")
@Log(title = "设计变更管理", businessType = BusinessType.EXPORT)
@PostMapping("/export/word")
public void exportWordById(@NotNull(message = "主键不能为空") Long id,
HttpServletResponse response) {
desDesignChangeService.exportWordById(id, response);
}
/**
* 获取设计变更管理详细信息
*
* @param id 主键
*/
@SaCheckPermission("design:designChange:query")
@GetMapping("/{id}")
public R<DesDesignChangeVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(desDesignChangeService.queryById(id));
}
/**
* 新增设计变更管理
*/
@SaCheckPermission("design:designChange:add")
@Log(title = "设计变更管理", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Long> add(@Validated(AddGroup.class) @RequestBody DesDesignChangeCreateReq req) {
return R.ok(desDesignChangeService.insertByBo(req));
}
/**
* 修改设计变更管理
*/
@SaCheckPermission("design:designChange:edit")
@Log(title = "设计变更管理", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody DesDesignChangeUpdateReq req) {
return toAjax(desDesignChangeService.updateByBo(req));
}
/**
* 删除设计变更管理
*
* @param ids 主键串
*/
@SaCheckPermission("design:designChange:remove")
@Log(title = "设计变更管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(desDesignChangeService.deleteByIds(List.of(ids)));
}
}

View File

@ -5,7 +5,6 @@ import jakarta.annotation.Resource;
import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import org.dromara.common.core.domain.R; import org.dromara.common.core.domain.R;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.idempotent.annotation.RepeatSubmit; import org.dromara.common.idempotent.annotation.RepeatSubmit;
import org.dromara.common.log.annotation.Log; import org.dromara.common.log.annotation.Log;
import org.dromara.common.log.enums.BusinessType; import org.dromara.common.log.enums.BusinessType;
@ -19,7 +18,6 @@ import org.dromara.design.domain.vo.drawing.DesDrawingVo;
import org.dromara.design.service.IDesDrawingService; import org.dromara.design.service.IDesDrawingService;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.util.List; import java.util.List;
@ -65,8 +63,8 @@ public class DesDrawingController extends BaseController {
@Log(title = "图纸管理", businessType = BusinessType.INSERT) @Log(title = "图纸管理", businessType = BusinessType.INSERT)
@RepeatSubmit() @RepeatSubmit()
@PostMapping() @PostMapping()
public R<DesDrawingVo> add(@RequestPart("file") MultipartFile file, DesDrawingCreateReq req) { public R<DesDrawingVo> add(@RequestBody DesDrawingCreateReq req) {
return R.ok(desDrawingService.insertByBo(file, req)); return R.ok(desDrawingService.insertByBo(req));
} }
/** /**
@ -76,8 +74,8 @@ public class DesDrawingController extends BaseController {
@Log(title = "图纸管理", businessType = BusinessType.UPDATE) @Log(title = "图纸管理", businessType = BusinessType.UPDATE)
@RepeatSubmit() @RepeatSubmit()
@PutMapping() @PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody DesDrawingUpdateReq req) { public R<DesDrawingVo> edit(@RequestBody DesDrawingUpdateReq req) {
return toAjax(desDrawingService.updateByBo(req)); return R.ok(desDrawingService.updateByBo(req));
} }
/** /**

View File

@ -0,0 +1,94 @@
package org.dromara.design.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import jakarta.annotation.Resource;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.idempotent.annotation.RepeatSubmit;
import org.dromara.common.log.annotation.Log;
import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.web.core.BaseController;
import org.dromara.design.domain.dto.specialscheme.DesSpecialSchemeCreateReq;
import org.dromara.design.domain.dto.specialscheme.DesSpecialSchemeQueryReq;
import org.dromara.design.domain.dto.specialscheme.DesSpecialSchemeUpdateReq;
import org.dromara.design.domain.vo.specialscheme.DesSpecialSchemeVo;
import org.dromara.design.service.IDesSpecialSchemeService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 专项方案管理
*
* @author lcj
* @date 2025-07-03
*/
@Validated
@RestController
@RequestMapping("/design/specialScheme")
public class DesSpecialSchemeController extends BaseController {
@Resource
private IDesSpecialSchemeService desSpecialSchemeService;
/**
* 查询专项方案管理列表
*/
@SaCheckPermission("design:specialScheme:list")
@GetMapping("/list")
public TableDataInfo<DesSpecialSchemeVo> list(DesSpecialSchemeQueryReq req, PageQuery pageQuery) {
return desSpecialSchemeService.queryPageList(req, pageQuery);
}
/**
* 获取专项方案管理详细信息
*
* @param id 主键
*/
@SaCheckPermission("design:specialScheme:query")
@GetMapping("/{id}")
public R<DesSpecialSchemeVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(desSpecialSchemeService.queryById(id));
}
/**
* 新增专项方案管理
*/
@SaCheckPermission("design:specialScheme:add")
@Log(title = "专项方案管理", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<DesSpecialSchemeVo> add(@RequestBody DesSpecialSchemeCreateReq req) {
return R.ok(desSpecialSchemeService.insertByBo(req));
}
/**
* 修改专项方案管理
*/
@SaCheckPermission("design:specialScheme:edit")
@Log(title = "专项方案管理", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<DesSpecialSchemeVo> edit(@Validated(EditGroup.class) @RequestBody DesSpecialSchemeUpdateReq req) {
return R.ok(desSpecialSchemeService.updateByBo(req));
}
/**
* 删除专项方案管理
*
* @param ids 主键串
*/
@SaCheckPermission("design:specialScheme:remove")
@Log(title = "专项方案管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(desSpecialSchemeService.deleteByIds(List.of(ids)));
}
}

View File

@ -0,0 +1,112 @@
package org.dromara.design.domain;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.dromara.common.mybatis.core.domain.BaseEntity;
import java.io.Serial;
import java.util.Date;
/**
* 设计变更管理对象 des_design_change
*
* @author lcj
* @date 2025-07-03
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("des_design_change")
public class DesDesignChange extends BaseEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键id
*/
@TableId(value = "id")
private Long id;
/**
* 项目id
*/
private Long projectId;
/**
* 申请单编号
*/
private String formNo;
/**
* 工程名称
*/
private String projectName;
/**
* 提出单位
*/
private String submitUnit;
/**
* 专业
*/
private String specialty;
/**
* 提出日期
*/
private Date submitDate;
/**
* 卷册名称
*/
private String volumeName;
/**
* 卷册号
*/
private String volumeNo;
/**
* 附图
*/
private String attachmentPic;
/**
* 变更原因
*/
private String changeReason;
/**
* 变更内容
*/
private String changeContent;
/**
* 变更费用估算
*/
private String costEstimation;
/**
* 变更费用估算计算表
*/
private String costEstimationFile;
/**
* 变更文件
*/
private String fileId;
/**
* 审核状态
*/
private String status;
/**
* 备注
*/
private String remark;
}

View File

@ -47,7 +47,7 @@ public class DesDrawing extends BaseEntity {
/** /**
* 文件访问路径 * 文件访问路径
*/ */
private String fileUrl; private Long fileUrl;
/** /**
* 文件类型1过程图纸 2蓝图 3变更图纸 * 文件类型1过程图纸 2蓝图 3变更图纸

View File

@ -0,0 +1,82 @@
package org.dromara.design.domain;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.dromara.common.mybatis.core.domain.BaseEntity;
import java.io.Serial;
import java.util.Date;
/**
* 专项方案管理对象 des_special_scheme
*
* @author lcj
* @date 2025-07-03
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("des_special_scheme")
public class DesSpecialScheme extends BaseEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键id
*/
@TableId(value = "id")
private Long id;
/**
* 项目id
*/
private Long projectId;
/**
* 版本号
*/
private String versionNumber;
/**
* 文件名称
*/
private String fileName;
/**
* 文件访问路径
*/
private Long fileUrl;
/**
* 文件后缀
*/
private String fileSuffix;
/**
* 状态0正常 1删除
*/
private String fileStatus;
/**
* 原文件名
*/
private String originalName;
/**
* 审核状态
*/
private String status;
/**
* 备注
*/
private String remark;
/**
* 删除时间
*/
private Date deletedAt;
}

View File

@ -0,0 +1,101 @@
package org.dromara.design.domain.dto.designchange;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
/**
* @author lcj
* @date 2025/7/3 18:48
*/
@Data
public class DesDesignChangeCreateReq implements Serializable {
@Serial
private static final long serialVersionUID = -8811234168299834882L;
/**
* 主键id
*/
private Long id;
/**
* 项目id
*/
private Long projectId;
/**
* 申请单编号
*/
private String formNo;
/**
* 工程名称
*/
private String projectName;
/**
* 提出单位
*/
private String submitUnit;
/**
* 专业
*/
private String specialty;
/**
* 提出日期
*/
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
private Date submitDate;
/**
* 卷册名称
*/
private String volumeName;
/**
* 卷册号
*/
private String volumeNo;
/**
* 附图
*/
private String attachmentPic;
/**
* 变更原因
*/
private String changeReason;
/**
* 变更内容
*/
private String changeContent;
/**
* 变更费用估算
*/
private String costEstimation;
/**
* 变更费用估算计算表
*/
private String costEstimationFile;
/**
* 变更文件
*/
private String fileId;
/**
* 备注
*/
private String remark;
}

View File

@ -0,0 +1,66 @@
package org.dromara.design.domain.dto.designchange;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
/**
* @author lcj
* @date 2025/7/3 18:48
*/
@Data
public class DesDesignChangeQueryReq implements Serializable {
@Serial
private static final long serialVersionUID = -270854871043405421L;
/**
* 项目id
*/
private Long projectId;
/**
* 申请单编号
*/
private String formNo;
/**
* 工程名称
*/
private String projectName;
/**
* 提出单位
*/
private String submitUnit;
/**
* 专业
*/
private String specialty;
/**
* 提出日期
*/
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
private Date submitDate;
/**
* 卷册名称
*/
private String volumeName;
/**
* 卷册号
*/
private String volumeNo;
/**
* 审核状态
*/
private String status;
}

View File

@ -0,0 +1,101 @@
package org.dromara.design.domain.dto.designchange;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
/**
* @author lcj
* @date 2025/7/3 18:49
*/
@Data
public class DesDesignChangeUpdateReq implements Serializable {
@Serial
private static final long serialVersionUID = 1764866203240580206L;
/**
* 主键id
*/
private Long id;
/**
* 项目id
*/
private Long projectId;
/**
* 申请单编号
*/
private String formNo;
/**
* 工程名称
*/
private String projectName;
/**
* 提出单位
*/
private String submitUnit;
/**
* 专业
*/
private String specialty;
/**
* 提出日期
*/
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
private Date submitDate;
/**
* 卷册名称
*/
private String volumeName;
/**
* 卷册号
*/
private String volumeNo;
/**
* 附图
*/
private String attachmentPic;
/**
* 变更原因
*/
private String changeReason;
/**
* 变更内容
*/
private String changeContent;
/**
* 变更费用估算
*/
private String costEstimation;
/**
* 变更费用估算计算表
*/
private String costEstimationFile;
/**
* 变更文件
*/
private String fileId;
/**
* 备注
*/
private String remark;
}

View File

@ -35,6 +35,11 @@ public class DesDrawingCreateReq implements Serializable {
*/ */
private String fileType; private String fileType;
/**
* 文件路径
*/
private Long fileUrl;
/** /**
* 备注 * 备注
*/ */

View File

@ -30,6 +30,11 @@ public class DesDrawingUpdateReq implements Serializable {
*/ */
private String fileName; private String fileName;
/**
* 文件路径
*/
private Long fileUrl;
/** /**
* 备注 * 备注
*/ */

View File

@ -0,0 +1,43 @@
package org.dromara.design.domain.dto.specialscheme;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
/**
* @author lcj
* @date 2025/7/3 11:27
*/
@Data
public class DesSpecialSchemeCreateReq implements Serializable {
@Serial
private static final long serialVersionUID = 6963615629792446908L;
/**
* 项目id
*/
private Long projectId;
/**
* 版本号
*/
private String versionNumber;
/**
* 文件名称
*/
private String fileName;
/**
* 文件id
*/
private Long fileUrl;
/**
* 备注
*/
private String remark;
}

View File

@ -0,0 +1,38 @@
package org.dromara.design.domain.dto.specialscheme;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
/**
* @author lcj
* @date 2025/7/3 11:28
*/
@Data
public class DesSpecialSchemeQueryReq implements Serializable {
@Serial
private static final long serialVersionUID = -6490770086658766211L;
/**
* 项目id
*/
private Long projectId;
/**
* 文件名称
*/
private String fileName;
/**
* 状态0正常 1删除
*/
private String fileStatus;
/**
* 原文件名
*/
private String originalName;
}

View File

@ -0,0 +1,43 @@
package org.dromara.design.domain.dto.specialscheme;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
/**
* @author lcj
* @date 2025/7/3 11:29
*/
@Data
public class DesSpecialSchemeUpdateReq implements Serializable {
@Serial
private static final long serialVersionUID = -6314226629118163829L;
/**
* 主键id
*/
private Long id;
/**
* 版本号
*/
private String versionNumber;
/**
* 文件名称
*/
private String fileName;
/**
* 文件路径
*/
private Long fileUrl;
/**
* 备注
*/
private String remark;
}

View File

@ -0,0 +1,132 @@
package org.dromara.design.domain.vo.designchange;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import org.dromara.design.domain.DesDesignChange;
import org.dromara.system.domain.vo.SysOssVo;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
/**
* 设计变更管理视图对象 des_design_change
*
* @author lcj
* @date 2025-07-03
*/
@Data
@AutoMapper(target = DesDesignChange.class)
public class DesDesignChangeVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键id
*/
private Long id;
/**
* 项目id
*/
private Long projectId;
/**
* 申请单编号
*/
private String formNo;
/**
* 工程名称
*/
private String projectName;
/**
* 提出单位
*/
private String submitUnit;
/**
* 专业
*/
private String specialty;
/**
* 提出日期
*/
private Date submitDate;
/**
* 卷册名称
*/
private String volumeName;
/**
* 卷册号
*/
private String volumeNo;
/**
* 附图
*/
private String attachmentPic;
/**
* 附图列表
*/
private List<SysOssVo> attachmentPicList;
/**
* 变更原因
*/
private String changeReason;
/**
* 变更内容
*/
private String changeContent;
/**
* 变更费用估算
*/
private String costEstimation;
/**
* 变更费用估算计算表
*/
private String costEstimationFile;
/**
* 变更费用估算计算表列表
*/
private List<SysOssVo> costEstimationFileList;
/**
* 变更文件
*/
private String fileId;
/**
* 变更文件
*/
private SysOssVo file;
/**
* 审核状态
*/
private String status;
/**
* 备注
*/
private String remark;
/**
* 创建时间
*/
private Date createTime;
}

View File

@ -3,9 +3,11 @@ package org.dromara.design.domain.vo.drawing;
import io.github.linpeilie.annotations.AutoMapper; import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data; import lombok.Data;
import org.dromara.design.domain.DesDrawing; import org.dromara.design.domain.DesDrawing;
import org.dromara.system.domain.vo.SysOssVo;
import java.io.Serial; import java.io.Serial;
import java.io.Serializable; import java.io.Serializable;
import java.util.Date;
/** /**
@ -44,7 +46,7 @@ public class DesDrawingVo implements Serializable {
/** /**
* 文件访问路径 * 文件访问路径
*/ */
private String fileUrl; private Long fileUrl;
/** /**
* 文件类型1过程图纸 2蓝图 3变更图纸 * 文件类型1过程图纸 2蓝图 3变更图纸
@ -56,6 +58,11 @@ public class DesDrawingVo implements Serializable {
*/ */
private String fileSuffix; private String fileSuffix;
/**
* 文件
*/
private SysOssVo file;
/** /**
* 原文件名 * 原文件名
*/ */
@ -76,4 +83,9 @@ public class DesDrawingVo implements Serializable {
*/ */
private String remark; private String remark;
/**
* 创建时间
*/
private Date createTime;
} }

View File

@ -0,0 +1,81 @@
package org.dromara.design.domain.vo.specialscheme;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import org.dromara.design.domain.DesSpecialScheme;
import org.dromara.system.domain.vo.SysOssVo;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
/**
* 专项方案管理视图对象 des_special_scheme
*
* @author lcj
* @date 2025-07-03
*/
@Data
@AutoMapper(target = DesSpecialScheme.class)
public class DesSpecialSchemeVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键id
*/
private Long id;
/**
* 项目id
*/
private Long projectId;
/**
* 版本号
*/
private String versionNumber;
/**
* 文件名称
*/
private String fileName;
/**
* 文件访问路径
*/
private Long fileUrl;
/**
* 文件后缀
*/
private String fileSuffix;
/**
* 原文件名
*/
private String originalName;
/**
* 文件
*/
private SysOssVo file;
/**
* 审核状态
*/
private String status;
/**
* 备注
*/
private String remark;
/**
* 创建时间
*/
private Date createTime;
}

View File

@ -0,0 +1,42 @@
package org.dromara.design.enums;
import lombok.Getter;
import java.util.Objects;
/**
* @author lcj
* @date 2025/7/3 19:46
*/
@Getter
public enum DesChangeReasonTypeEnum {
LEAK("设计漏项", "1"),
IMPROVE("设计改进", "2"),
ERROR("设计差错", "3"),
INTERFACE("接口差错", "4"),
OWNER("业主要求", "5"),
CONTRACTOR("施工承包商要求", "6"),
CONFLICT("外部资料与最终情况不符", "7"),
OTHER("材料代用或其他", "8");
private final String text;
private final String value;
DesChangeReasonTypeEnum(String text, String value) {
this.text = text;
this.value = value;
}
// 根据 value 获取对应的 text
public static String getTextByValue(String value) {
for (DesChangeReasonTypeEnum type : values()) {
if (Objects.equals(type.getValue(), value)) {
return type.getText();
}
}
return null;
}
}

View File

@ -0,0 +1,15 @@
package org.dromara.design.mapper;
import org.dromara.design.domain.DesDesignChange;
import org.dromara.design.domain.vo.designchange.DesDesignChangeVo;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
/**
* 设计变更管理Mapper接口
*
* @author lcj
* @date 2025-07-03
*/
public interface DesDesignChangeMapper extends BaseMapperPlus<DesDesignChange, DesDesignChangeVo> {
}

View File

@ -0,0 +1,15 @@
package org.dromara.design.mapper;
import org.dromara.design.domain.DesSpecialScheme;
import org.dromara.design.domain.vo.specialscheme.DesSpecialSchemeVo;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
/**
* 专项方案管理Mapper接口
*
* @author lcj
* @date 2025-07-03
*/
public interface DesSpecialSchemeMapper extends BaseMapperPlus<DesSpecialScheme, DesSpecialSchemeVo> {
}

View File

@ -0,0 +1,105 @@
package org.dromara.design.service;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import jakarta.servlet.http.HttpServletResponse;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.design.domain.DesDesignChange;
import org.dromara.design.domain.dto.designchange.DesDesignChangeCreateReq;
import org.dromara.design.domain.dto.designchange.DesDesignChangeQueryReq;
import org.dromara.design.domain.dto.designchange.DesDesignChangeUpdateReq;
import org.dromara.design.domain.vo.designchange.DesDesignChangeVo;
import java.util.Collection;
import java.util.List;
/**
* 设计变更管理Service接口
*
* @author lcj
* @date 2025-07-03
*/
public interface IDesDesignChangeService extends IService<DesDesignChange> {
/**
* 查询设计变更管理
*
* @param id 主键
* @return 设计变更管理
*/
DesDesignChangeVo queryById(Long id);
/**
* 分页查询设计变更管理列表
*
* @param req 查询条件
* @param pageQuery 分页参数
* @return 设计变更管理分页列表
*/
TableDataInfo<DesDesignChangeVo> queryPageList(DesDesignChangeQueryReq req, PageQuery pageQuery);
/**
* 查询符合条件的设计变更管理列表
*
* @param req 查询条件
* @return 设计变更管理列表
*/
List<DesDesignChangeVo> queryList(DesDesignChangeQueryReq req);
/**
* 根据主键id导出设计变更单
*
* @param id 设计变更主键id
*/
void exportWordById(Long id, HttpServletResponse response);
/**
* 新增设计变更管理
*
* @param req 设计变更管理
* @return 新增设计变更管理主键id
*/
Long insertByBo(DesDesignChangeCreateReq req);
/**
* 修改设计变更管理
*
* @param req 设计变更管理
* @return 是否修改成功
*/
Boolean updateByBo(DesDesignChangeUpdateReq req);
/**
* 校验并批量删除设计变更管理信息
*
* @param ids 待删除的主键集合
* @return 是否删除成功
*/
Boolean deleteByIds(Collection<Long> ids);
/**
* 构建设计变更管理封装对象
*
* @param designChange 设计变更管理
* @return 设计变更管理封装对象
*/
DesDesignChangeVo getVo(DesDesignChange designChange);
/**
* 构建查询条件
*
* @param req 查询条件
* @return 查询条件
*/
LambdaQueryWrapper<DesDesignChange> buildQueryWrapper(DesDesignChangeQueryReq req);
/**
* 获取设计变更管理对象视图
*
* @param designChangePage 设计变更管理对象
* @return 设计变更管理对象视图
*/
Page<DesDesignChangeVo> getVoPage(Page<DesDesignChange> designChangePage);
}

View File

@ -10,7 +10,6 @@ import org.dromara.design.domain.dto.drawing.DesDrawingCreateReq;
import org.dromara.design.domain.dto.drawing.DesDrawingQueryReq; import org.dromara.design.domain.dto.drawing.DesDrawingQueryReq;
import org.dromara.design.domain.dto.drawing.DesDrawingUpdateReq; import org.dromara.design.domain.dto.drawing.DesDrawingUpdateReq;
import org.dromara.design.domain.vo.drawing.DesDrawingVo; import org.dromara.design.domain.vo.drawing.DesDrawingVo;
import org.springframework.web.multipart.MultipartFile;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
@ -51,19 +50,18 @@ public interface IDesDrawingService extends IService<DesDrawing> {
/** /**
* 新增图纸管理 * 新增图纸管理
* *
* @param file 文件 * @param req 图纸管理
* @param req 图纸管理
* @return 新增图纸管理主键id * @return 新增图纸管理主键id
*/ */
DesDrawingVo insertByBo(MultipartFile file, DesDrawingCreateReq req); DesDrawingVo insertByBo(DesDrawingCreateReq req);
/** /**
* 修改图纸管理 * 修改图纸管理
* *
* @param req 图纸管理 * @param req 图纸管理
* @return 是否修改成功 * @return 图纸管理
*/ */
Boolean updateByBo(DesDrawingUpdateReq req); DesDrawingVo updateByBo(DesDrawingUpdateReq req);
/** /**
* 校验并批量删除图纸管理信息 * 校验并批量删除图纸管理信息

View File

@ -0,0 +1,97 @@
package org.dromara.design.service;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.design.domain.DesSpecialScheme;
import org.dromara.design.domain.dto.specialscheme.DesSpecialSchemeCreateReq;
import org.dromara.design.domain.dto.specialscheme.DesSpecialSchemeQueryReq;
import org.dromara.design.domain.dto.specialscheme.DesSpecialSchemeUpdateReq;
import org.dromara.design.domain.vo.specialscheme.DesSpecialSchemeVo;
import java.util.Collection;
import java.util.List;
/**
* 专项方案管理Service接口
*
* @author lcj
* @date 2025-07-03
*/
public interface IDesSpecialSchemeService extends IService<DesSpecialScheme> {
/**
* 查询图纸管理
*
* @param id 主键
* @return 图纸管理
*/
DesSpecialSchemeVo queryById(Long id);
/**
* 分页查询图纸管理列表
*
* @param req 查询条件
* @param pageQuery 分页参数
* @return 图纸管理分页列表
*/
TableDataInfo<DesSpecialSchemeVo> queryPageList(DesSpecialSchemeQueryReq req, PageQuery pageQuery);
/**
* 查询符合条件的图纸管理列表
*
* @param req 查询条件
* @return 图纸管理列表
*/
List<DesSpecialSchemeVo> queryList(DesSpecialSchemeQueryReq req);
/**
* 新增图纸管理
*
* @param req 图纸管理
* @return 新增图纸管理
*/
DesSpecialSchemeVo insertByBo(DesSpecialSchemeCreateReq req);
/**
* 修改图纸管理
*
* @param req 图纸管理
* @return 图纸管理
*/
DesSpecialSchemeVo updateByBo(DesSpecialSchemeUpdateReq req);
/**
* 校验并批量删除图纸管理信息
*
* @param ids 待删除的主键集合
* @return 是否删除成功
*/
Boolean deleteByIds(Collection<Long> ids);
/**
* 构建图纸管理封装对象
*
* @param specialScheme 图纸管理
* @return 图纸管理封装对象
*/
DesSpecialSchemeVo getVo(DesSpecialScheme specialScheme);
/**
* 构建查询条件
*
* @param req 查询条件
* @return 查询条件
*/
LambdaQueryWrapper<DesSpecialScheme> buildQueryWrapper(DesSpecialSchemeQueryReq req);
/**
* 获取图纸管理对象视图
*
* @param specialSchemePage 图纸管理对象
* @return 图纸管理对象视图
*/
Page<DesSpecialSchemeVo> getVoPage(Page<DesSpecialScheme> specialSchemePage);
}

View File

@ -0,0 +1,482 @@
package org.dromara.design.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.xwpf.usermodel.*;
import org.dromara.common.core.constant.HttpStatus;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.ObjectUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.core.utils.file.FileUtils;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.oss.core.OssClient;
import org.dromara.common.oss.exception.OssException;
import org.dromara.common.oss.factory.OssFactory;
import org.dromara.common.utils.DocumentUtil;
import org.dromara.design.constant.DesDesignConstant;
import org.dromara.design.domain.DesDesignChange;
import org.dromara.design.domain.dto.designchange.DesDesignChangeCreateReq;
import org.dromara.design.domain.dto.designchange.DesDesignChangeQueryReq;
import org.dromara.design.domain.dto.designchange.DesDesignChangeUpdateReq;
import org.dromara.design.domain.vo.designchange.DesDesignChangeVo;
import org.dromara.design.mapper.DesDesignChangeMapper;
import org.dromara.design.service.IDesDesignChangeService;
import org.dromara.project.service.IBusProjectService;
import org.dromara.system.domain.vo.SysOssVo;
import org.dromara.system.service.ISysOssService;
import org.springframework.beans.BeanUtils;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.zip.ZipOutputStream;
/**
* 设计变更管理Service业务层处理
*
* @author lcj
* @date 2025-07-03
*/
@Slf4j
@Service
public class DesDesignChangeServiceImpl extends ServiceImpl<DesDesignChangeMapper, DesDesignChange>
implements IDesDesignChangeService {
@Resource
private IBusProjectService projectService;
@Resource
private ISysOssService ossService;
/**
* 查询设计变更管理
*
* @param id 主键
* @return 设计变更管理
*/
@Override
public DesDesignChangeVo queryById(Long id) {
DesDesignChange designChange = this.getById(id);
if (designChange == null) {
throw new ServiceException("设计变更不存在", HttpStatus.NOT_FOUND);
}
return this.getVo(designChange);
}
/**
* 分页查询设计变更管理列表
*
* @param req 查询条件
* @param pageQuery 分页参数
* @return 设计变更管理分页列表
*/
@Override
public TableDataInfo<DesDesignChangeVo> queryPageList(DesDesignChangeQueryReq req, PageQuery pageQuery) {
Page<DesDesignChange> changePage = this.page(pageQuery.build(), this.buildQueryWrapper(req));
return TableDataInfo.build(this.getVoPage(changePage));
}
/**
* 查询符合条件的设计变更管理列表
*
* @param req 查询条件
* @return 设计变更管理列表
*/
@Override
public List<DesDesignChangeVo> queryList(DesDesignChangeQueryReq req) {
LambdaQueryWrapper<DesDesignChange> lqw = buildQueryWrapper(req);
return this.list(lqw).stream().map(this::getVo).toList();
}
/**
* 根据主键id导出设计变更单
*
* @param id 设计变更主键id
*/
@Override
public void exportWordById(Long id, HttpServletResponse response) {
DesDesignChange designChange = this.getById(id);
if (designChange == null) {
throw new ServiceException("质量-检查工单不存在");
}
Map<String, String> replacementMap = getReplacementMap(designChange);
Path targetDir = Paths.get(DesDesignConstant.getDesignChangeFileUrl(designChange));
// 如果存在目录则直接返回,不存在则生成文件并返回
if (!Files.exists(targetDir)) {
// 清理旧文件
String baseUrl = DesDesignConstant.DESIGN_CHANGE_FILE_URL + designChange.getId();
try {
Path dirPath = Paths.get(baseUrl);
if (Files.exists(dirPath)) {
FileUtils.deleteDirectory(dirPath);
}
} catch (IOException e) {
log.error("文件目录:{},清理失败", baseUrl, e);
}
// 生成文件
try (InputStream is = getClass().getClassLoader().getResourceAsStream(DesDesignConstant.DESIGN_CHANGE_TEMPLATE_PATH)) {
if (is == null) {
throw new ServiceException("模板文件不存在");
}
try (XWPFDocument document = new XWPFDocument(is)) {
// 替换段落中的文本
for (XWPFParagraph paragraph : document.getParagraphs()) {
replaceInParagraph(paragraph, replacementMap, document, designChange);
}
// 替换表格中的文本(如果模板中有表格)
for (XWPFTable table : document.getTables()) {
for (XWPFTableRow row : table.getRows()) {
for (XWPFTableCell cell : row.getTableCells()) {
for (XWPFParagraph paragraph : cell.getParagraphs()) {
replaceInParagraph(paragraph, replacementMap, document, designChange);
}
}
}
}
// 创建目标目录
if (!Files.exists(targetDir)) {
Files.createDirectories(targetDir);
}
// 组合目标文件名
String fileName = DesDesignConstant.getDesignChangeFileName(designChange);
// 保存修改后的文件
try (FileOutputStream fos = new FileOutputStream(targetDir.resolve(fileName).toFile())) {
document.write(fos);
}
}
} catch (IOException | InvalidFormatException e) {
throw new OssException("生成Word文件失败错误信息: " + e.getMessage());
}
}
// 设置响应头返回ZIP文件
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE + "; charset=UTF-8");
try (ZipOutputStream zos = new ZipOutputStream(response.getOutputStream())) {
DocumentUtil.zipDirectory(targetDir, targetDir, zos);
zos.flush();
} catch (Exception e) {
throw new OssException("生成ZIP文件失败错误信息: " + e.getMessage());
}
}
/**
* 新增设计变更管理
*
* @param req 设计变更管理
* @return 新增设计变更管理主键id
*/
@Override
public Long insertByBo(DesDesignChangeCreateReq req) {
DesDesignChange entity = new DesDesignChange();
BeanUtils.copyProperties(req, entity);
validEntityBeforeSave(entity, true);
boolean save = this.save(entity);
if (!save) {
throw new ServiceException("新增设计变更失败", HttpStatus.ERROR);
}
return entity.getId();
}
/**
* 修改设计变更管理
*
* @param req 设计变更管理
* @return 是否修改成功
*/
@Override
public Boolean updateByBo(DesDesignChangeUpdateReq req) {
DesDesignChange entity = new DesDesignChange();
BeanUtils.copyProperties(req, entity);
validEntityBeforeSave(entity, false);
boolean result = this.updateById(entity);
if (!result) {
throw new ServiceException("修改设计变更失败", HttpStatus.ERROR);
}
return true;
}
/**
* 保存前的数据校验
*/
private void validEntityBeforeSave(DesDesignChange entity, Boolean create) {
Long projectId = entity.getProjectId();
if (create) {
if (projectId == null) {
throw new ServiceException("项目id不能为空", HttpStatus.BAD_REQUEST);
}
}
if (projectId != null && projectService.getById(projectId) == null) {
throw new ServiceException("对应项目不存在", HttpStatus.NOT_FOUND);
}
}
/**
* 校验并批量删除设计变更管理信息
*
* @param ids 待删除的主键集合
* @return 是否删除成功
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean deleteByIds(Collection<Long> ids) {
return removeBatchByIds(ids);
}
/**
* 构建设计变更管理封装对象
*
* @param designChange 设计变更管理
* @return 设计变更管理封装对象
*/
@Override
public DesDesignChangeVo getVo(DesDesignChange designChange) {
DesDesignChangeVo vo = new DesDesignChangeVo();
if (designChange == null) {
return vo;
}
BeanUtils.copyProperties(designChange, vo);
List<Long> allFileIdList = new ArrayList<>();
// 1. 添加单个 fileId前提是非空
String fileId = designChange.getFileId();
if (StringUtils.isNotBlank(fileId)) {
allFileIdList.add(Long.valueOf(fileId));
}
// 2. 添加 attachmentPic 多个 ID
String attachmentPic = designChange.getAttachmentPic();
if (StringUtils.isNotBlank(attachmentPic)) {
String[] attachmentPicStr = attachmentPic.split(",");
for (String idStr : attachmentPicStr) {
if (StringUtils.isNotBlank(idStr)) {
allFileIdList.add(Long.valueOf(idStr.trim()));
}
}
}
// 3. 添加 costEstimationFile 多个 ID
String costEstimationFile = designChange.getCostEstimationFile();
if (StringUtils.isNotBlank(costEstimationFile)) {
String[] costEstimationFileStr = costEstimationFile.split(",");
for (String idStr : costEstimationFileStr) {
if (StringUtils.isNotBlank(idStr)) {
allFileIdList.add(Long.valueOf(idStr.trim()));
}
}
}
if (CollUtil.isNotEmpty(allFileIdList)) {
// 获取文件对象
List<SysOssVo> ossVoList = ossService.listByIds(allFileIdList);
Map<Long, SysOssVo> ossMap = ossVoList.stream()
.collect(Collectors.toMap(SysOssVo::getOssId, Function.identity(), (a, b) -> a));
// 1. 处理 file单个
if (StringUtils.isNotBlank(fileId)) {
Long file = Long.valueOf(fileId);
SysOssVo fileVo = ossMap.get(file);
vo.setFile(fileVo);
}
// 2. 处理 attachmentPicList多个
if (StringUtils.isNotBlank(attachmentPic)) {
List<SysOssVo> attachmentList = Arrays.stream(attachmentPic.split(","))
.map(String::trim)
.filter(StringUtils::isNotBlank)
.map(Long::valueOf)
.map(ossMap::get)
.filter(Objects::nonNull)
.collect(Collectors.toList());
vo.setAttachmentPicList(attachmentList);
}
// 3. 处理 costEstimationFileList多个
if (StringUtils.isNotBlank(costEstimationFile)) {
List<SysOssVo> costList = Arrays.stream(costEstimationFile.split(","))
.map(String::trim)
.filter(StringUtils::isNotBlank)
.map(Long::valueOf)
.map(ossMap::get)
.filter(Objects::nonNull)
.collect(Collectors.toList());
vo.setCostEstimationFileList(costList);
}
}
return vo;
}
/**
* 构建查询条件
*
* @param req 查询条件
* @return 查询条件
*/
@Override
public LambdaQueryWrapper<DesDesignChange> buildQueryWrapper(DesDesignChangeQueryReq req) {
LambdaQueryWrapper<DesDesignChange> lqw = new LambdaQueryWrapper<>();
if (req == null) {
return lqw;
}
Long projectId = req.getProjectId();
String formNo = req.getFormNo();
String projectName = req.getProjectName();
String submitUnit = req.getSubmitUnit();
String specialty = req.getSpecialty();
Date submitDate = req.getSubmitDate();
String volumeName = req.getVolumeName();
String volumeNo = req.getVolumeNo();
String status = req.getStatus();
lqw.eq(ObjectUtils.isNotEmpty(projectId), DesDesignChange::getProjectId, projectId);
lqw.eq(ObjectUtils.isNotEmpty(formNo), DesDesignChange::getFormNo, formNo);
lqw.eq(ObjectUtils.isNotEmpty(submitDate), DesDesignChange::getSubmitDate, submitDate);
lqw.eq(StringUtils.isNotEmpty(status), DesDesignChange::getStatus, status);
lqw.like(StringUtils.isNotEmpty(projectName), DesDesignChange::getProjectName, projectName);
lqw.like(StringUtils.isNotEmpty(submitUnit), DesDesignChange::getSubmitUnit, submitUnit);
lqw.like(StringUtils.isNotEmpty(specialty), DesDesignChange::getSpecialty, specialty);
lqw.like(StringUtils.isNotEmpty(volumeName), DesDesignChange::getVolumeName, volumeName);
lqw.like(StringUtils.isNotEmpty(volumeNo), DesDesignChange::getVolumeNo, volumeNo);
return lqw;
}
/**
* 获取设计变更管理对象视图
*
* @param designChangePage 设计变更管理对象
* @return 设计变更管理对象视图
*/
@Override
public Page<DesDesignChangeVo> getVoPage(Page<DesDesignChange> designChangePage) {
List<DesDesignChange> designChangeList = designChangePage.getRecords();
Page<DesDesignChangeVo> designChangeVoPage = new Page<>(
designChangePage.getCurrent(),
designChangePage.getSize(),
designChangePage.getTotal());
if (CollUtil.isEmpty(designChangeList)) {
return designChangeVoPage;
}
// todo 待优化
List<DesDesignChangeVo> designChangeVoList = designChangeList.stream().map(this::getVo).toList();
designChangeVoPage.setRecords(designChangeVoList);
return designChangeVoPage;
}
/**
* 根据实体获取Word的文本Map
*
* @param designChange 质量-检查工单对象
* @return Map
*/
private Map<String, String> getReplacementMap(DesDesignChange designChange) {
Map<String, String> replacementMap = new HashMap<>();
replacementMap.put("${formNo}", designChange.getFormNo());
replacementMap.put("${projectName}", designChange.getProjectName());
replacementMap.put("${submitUnit}", designChange.getSubmitUnit());
replacementMap.put("${specialty}", designChange.getSpecialty());
Date submitDate = designChange.getSubmitDate();
String date = DateUtil.format(submitDate, "yyyy年MM月dd日");
replacementMap.put("${submitDate}", date);
replacementMap.put("${attachmentPic}", designChange.getAttachmentPic());
replacementMap.put("${volumeName}", designChange.getVolumeName());
replacementMap.put("${volumeNo}", designChange.getVolumeNo());
String[] reasonList = designChange.getChangeReason().split(",");
Set<String> reasonSet = new HashSet<>(Arrays.asList(reasonList));
for (int i = 1; i <= 8; i++) {
if (reasonSet.contains(String.valueOf(i))) {
replacementMap.put("${changeReason" + i + "}", "");
} else {
replacementMap.put("${changeReason" + i + "}", " ");
}
}
replacementMap.put("${changeContent}", designChange.getChangeContent());
replacementMap.put("${costEstimation}", designChange.getCostEstimation());
replacementMap.put("${costEstimationFile}", designChange.getCostEstimationFile());
return replacementMap;
}
/**
* 替换段落中所有文本运行的占位符内容,对于 checkFile 和 rectificationFile
* 插入图片或超链接(附件)展示。
*
* @param paragraph 当前段落
* @param replacements 占位符与替换内容的映射
* @param document 当前文档,用于插入图片或创建超链接
*/
private void replaceInParagraph(XWPFParagraph paragraph,
Map<String, String> replacements,
XWPFDocument document,
DesDesignChange designChange)
throws InvalidFormatException, IOException {
// 先拷贝 paragraph 里所有的 run
List<XWPFRun> runs = new ArrayList<>(paragraph.getRuns());
// 在拷贝上遍历,修改原 paragraph增删 run都不会抛 CME
for (XWPFRun run : runs) {
String text = run.getText(0);
if (text != null) {
// 针对每个占位符进行检查
for (Map.Entry<String, String> entry : replacements.entrySet()) {
String placeholder = entry.getKey();
String value = entry.getValue();
if (text.contains(placeholder)) {
// 针对 file 进行特殊处理
if (placeholder.equals("${costEstimationFile}") || placeholder.equals("${attachmentPic}")) {
// 判断该 run 中的文本是否仅包含该占位符(建议模板中独占一行)
if (text.trim().equals(placeholder)) {
// 清空原有文本
run.setText("", 0);
// 根据附件的后缀决定以图片或超链接展示
if (StringUtils.isBlank(value)) {
continue;
}
// 获取附件的ossId
List<Long> ossIdList = Arrays.stream(value.split(",")).map(Long::parseLong).toList();
List<SysOssVo> ossVoList = ossService.listByIds(ossIdList);
String baseFile = DesDesignConstant.getDesignChangeFileUrl(designChange) + "/file";
for (SysOssVo ossVo : ossVoList) {
String lowerVal = ossVo.getUrl().toLowerCase();
OssClient storage = OssFactory.instance(ossVo.getService());
String fileDownload = storage.fileDownload(ossVo.getUrl(), ossVo.getOriginalName(), baseFile);
if (lowerVal.endsWith(".png") || lowerVal.endsWith(".jpg") || lowerVal.endsWith(".jpeg") || lowerVal.endsWith(".gif")) {
try {
DocumentUtil.insertImageDynamic(run, fileDownload, document, 50);
} catch (Exception e) {
throw new ServiceException("插入图片失败");
}
} else {
// —— 非图片:插入超链接 ——
XWPFHyperlinkRun link = paragraph.createHyperlinkRun(ossVo.getUrl());
link.setText(ossVo.getOriginalName());
link.setColor("0000FF");
link.setUnderline(UnderlinePatterns.SINGLE);
}
}
} else {
// 如果占位符与其它文本混合,可进行文本替换,提示附件展示请单独使用占位符
text = text.replace(placeholder, "[附件]");
run.setText(text, 0);
}
} else {
// 普通文本占位符直接替换
if (StringUtils.isBlank(value)) {
// 如果填入值为空,清空原有文本
run.setText("", 0);
continue;
}
text = text.replace(placeholder, value);
run.setText(text, 0);
}
}
}
}
}
}
}

View File

@ -3,7 +3,6 @@ package org.dromara.design.service.impl;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert; import cn.hutool.core.convert.Convert;
import cn.hutool.core.io.FileUtil; import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@ -16,12 +15,11 @@ import org.dromara.common.core.domain.event.ProcessEvent;
import org.dromara.common.core.domain.event.ProcessTaskEvent; import org.dromara.common.core.domain.event.ProcessTaskEvent;
import org.dromara.common.core.enums.BusinessStatusEnum; import org.dromara.common.core.enums.BusinessStatusEnum;
import org.dromara.common.core.exception.ServiceException; import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.DateUtils; import org.dromara.common.core.service.WorkflowService;
import org.dromara.common.core.utils.ObjectUtils; import org.dromara.common.core.utils.ObjectUtils;
import org.dromara.common.core.utils.StringUtils; import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.design.constant.DesDrawingConstant;
import org.dromara.design.domain.DesDrawing; import org.dromara.design.domain.DesDrawing;
import org.dromara.design.domain.dto.drawing.DesDrawingCreateReq; import org.dromara.design.domain.dto.drawing.DesDrawingCreateReq;
import org.dromara.design.domain.dto.drawing.DesDrawingQueryReq; import org.dromara.design.domain.dto.drawing.DesDrawingQueryReq;
@ -32,16 +30,15 @@ import org.dromara.design.enums.DesDrawingNewestEnum;
import org.dromara.design.mapper.DesDrawingMapper; import org.dromara.design.mapper.DesDrawingMapper;
import org.dromara.design.service.IDesDrawingService; import org.dromara.design.service.IDesDrawingService;
import org.dromara.project.service.IBusProjectService; import org.dromara.project.service.IBusProjectService;
import org.dromara.system.domain.vo.SysOssUploadVo; import org.dromara.system.domain.vo.SysOssVo;
import org.dromara.system.service.ISysOssService; import org.dromara.system.service.ISysOssService;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import org.springframework.context.event.EventListener; import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import java.util.Collection; import java.util.*;
import java.util.List; import java.util.stream.Collectors;
/** /**
* 图纸管理Service业务层处理 * 图纸管理Service业务层处理
@ -60,6 +57,9 @@ public class DesDrawingServiceImpl extends ServiceImpl<DesDrawingMapper, DesDraw
@Resource @Resource
private ISysOssService ossService; private ISysOssService ossService;
@Resource
private WorkflowService workflowService;
/** /**
* 查询图纸管理 * 查询图纸管理
* *
@ -104,15 +104,16 @@ public class DesDrawingServiceImpl extends ServiceImpl<DesDrawingMapper, DesDraw
/** /**
* 新增图纸管理 * 新增图纸管理
* *
* @param file 文件 * @param req 图纸管理
* @param req 图纸管理
* @return 新增图纸管理主键id * @return 新增图纸管理主键id
*/ */
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public DesDrawingVo insertByBo(MultipartFile file, DesDrawingCreateReq req) { public DesDrawingVo insertByBo(DesDrawingCreateReq req) {
Long fileUrl = req.getFileUrl();
SysOssVo ossVo = ossService.getById(fileUrl);
// 数据校验 // 数据校验
if (ObjectUtils.isEmpty(file)) { if (ObjectUtils.isEmpty(ossVo)) {
throw new ServiceException("图纸文件不能为空", HttpStatus.BAD_REQUEST); throw new ServiceException("图纸文件不能为空", HttpStatus.BAD_REQUEST);
} }
Long projectId = req.getProjectId(); Long projectId = req.getProjectId();
@ -124,30 +125,17 @@ public class DesDrawingServiceImpl extends ServiceImpl<DesDrawingMapper, DesDraw
if (StringUtils.isBlank(enumText)) { if (StringUtils.isBlank(enumText)) {
throw new ServiceException("图纸文件类型错误", HttpStatus.BAD_REQUEST); throw new ServiceException("图纸文件类型错误", HttpStatus.BAD_REQUEST);
} }
// 拼接文件名
String originalFilename = file.getOriginalFilename();
String suffix = FileUtil.getSuffix(originalFilename);
if (StringUtils.isBlank(suffix)) {
throw new ServiceException("图纸文件格式错误", HttpStatus.BAD_REQUEST);
}
String date = DateUtils.getDate();
String uuid = IdUtil.fastSimpleUUID();
String fileName = String.format("%s_%s.%s", date, uuid, suffix);
// 拼接文件路径
String filePath = DesDrawingConstant.getProjectOssPrefix(projectId) + fileName;
// 上传文件
SysOssUploadVo ossUploadVo = ossService.uploadWithNoSave(file, filePath);
// 文件信息赋值 // 文件信息赋值
DesDrawing desDrawing = new DesDrawing(); DesDrawing desDrawing = new DesDrawing();
desDrawing.setProjectId(projectId); desDrawing.setProjectId(projectId);
desDrawing.setOriginalName(originalFilename); desDrawing.setOriginalName(ossVo.getOriginalName());
String name = req.getFileName(); String name = req.getFileName();
if (StringUtils.isBlank(name)) { if (StringUtils.isBlank(name)) {
name = FileUtil.getPrefix(originalFilename); name = FileUtil.getPrefix(ossVo.getOriginalName());
} }
desDrawing.setFileName(name); desDrawing.setFileName(name);
desDrawing.setFileUrl(ossUploadVo.getUrl()); desDrawing.setFileUrl(fileUrl);
desDrawing.setFileSuffix(suffix); desDrawing.setFileSuffix(ossVo.getFileSuffix());
desDrawing.setVersionNumber(req.getVersionNumber()); desDrawing.setVersionNumber(req.getVersionNumber());
desDrawing.setFileType(fileType); desDrawing.setFileType(fileType);
desDrawing.setNewest(DesDrawingNewestEnum.YES.getCode()); desDrawing.setNewest(DesDrawingNewestEnum.YES.getCode());
@ -175,10 +163,10 @@ public class DesDrawingServiceImpl extends ServiceImpl<DesDrawingMapper, DesDraw
* 修改图纸管理 * 修改图纸管理
* *
* @param req 图纸管理 * @param req 图纸管理
* @return 是否修改成功 * @return 图纸管理
*/ */
@Override @Override
public Boolean updateByBo(DesDrawingUpdateReq req) { public DesDrawingVo updateByBo(DesDrawingUpdateReq req) {
Long id = req.getId(); Long id = req.getId();
DesDrawing oldDrawing = this.getById(id); DesDrawing oldDrawing = this.getById(id);
if (oldDrawing == null) { if (oldDrawing == null) {
@ -190,7 +178,7 @@ public class DesDrawingServiceImpl extends ServiceImpl<DesDrawingMapper, DesDraw
if (!result) { if (!result) {
throw new ServiceException("修改图纸失败", HttpStatus.ERROR); throw new ServiceException("修改图纸失败", HttpStatus.ERROR);
} }
return true; return this.getVo(this.getById(id));
} }
/** /**
@ -200,8 +188,17 @@ public class DesDrawingServiceImpl extends ServiceImpl<DesDrawingMapper, DesDraw
* @return 是否删除成功 * @return 是否删除成功
*/ */
@Override @Override
@Transactional(rollbackFor = Exception.class)
public Boolean deleteByIds(Collection<Long> ids) { public Boolean deleteByIds(Collection<Long> ids) {
return baseMapper.deleteByIds(ids) > 0; List<DesDrawing> drawingList = this.listByIds(ids);
if (CollUtil.isEmpty(drawingList)) {
throw new ServiceException("参数错误,请勿删除不存在的图纸", HttpStatus.BAD_REQUEST);
}
workflowService.deleteInstance((List<Long>) ids);
// 删除oss文件
Set<Long> fileIdList = drawingList.stream().map(DesDrawing::getFileUrl).collect(Collectors.toSet());
ossService.deleteWithValidByIds(fileIdList, false);
return removeBatchByIds(ids);
} }
/** /**
@ -216,7 +213,9 @@ public class DesDrawingServiceImpl extends ServiceImpl<DesDrawingMapper, DesDraw
if (drawing == null) { if (drawing == null) {
return vo; return vo;
} }
SysOssVo ossVo = ossService.getById(drawing.getFileUrl());
BeanUtils.copyProperties(drawing, vo); BeanUtils.copyProperties(drawing, vo);
vo.setFile(ossVo);
return vo; return vo;
} }
@ -244,6 +243,8 @@ public class DesDrawingServiceImpl extends ServiceImpl<DesDrawingMapper, DesDraw
lqw.eq(StringUtils.isNotBlank(fileType), DesDrawing::getFileType, fileType); lqw.eq(StringUtils.isNotBlank(fileType), DesDrawing::getFileType, fileType);
lqw.eq(StringUtils.isNotBlank(fileStatus), DesDrawing::getFileStatus, fileStatus); lqw.eq(StringUtils.isNotBlank(fileStatus), DesDrawing::getFileStatus, fileStatus);
lqw.eq(StringUtils.isNotBlank(newest), DesDrawing::getNewest, newest); lqw.eq(StringUtils.isNotBlank(newest), DesDrawing::getNewest, newest);
lqw.orderByDesc(DesDrawing::getNewest);
lqw.orderByDesc(DesDrawing::getCreateTime);
return lqw; return lqw;
} }
@ -263,9 +264,12 @@ public class DesDrawingServiceImpl extends ServiceImpl<DesDrawingMapper, DesDraw
if (CollUtil.isEmpty(drawingList)) { if (CollUtil.isEmpty(drawingList)) {
return drawingVoPage; return drawingVoPage;
} }
List<SysOssVo> ossVoList = ossService.listByIds(drawingList.stream().map(DesDrawing::getFileUrl).toList());
Map<Long, List<SysOssVo>> ossMap = ossVoList.stream().collect(Collectors.groupingBy(SysOssVo::getOssId));
List<DesDrawingVo> drawingVoList = drawingList.stream().map(entity -> { List<DesDrawingVo> drawingVoList = drawingList.stream().map(entity -> {
DesDrawingVo drawingVo = new DesDrawingVo(); DesDrawingVo drawingVo = new DesDrawingVo();
BeanUtils.copyProperties(entity, drawingVo); BeanUtils.copyProperties(entity, drawingVo);
drawingVo.setFile(ossMap.get(entity.getFileUrl()).getFirst());
return drawingVo; return drawingVo;
}).toList(); }).toList();
drawingVoPage.setRecords(drawingVoList); drawingVoPage.setRecords(drawingVoList);
@ -319,7 +323,9 @@ public class DesDrawingServiceImpl extends ServiceImpl<DesDrawingMapper, DesDraw
if (ObjectUtil.isNull(drawing)) { if (ObjectUtil.isNull(drawing)) {
return; return;
} }
baseMapper.deleteById(drawing.getId()); Long fileUrl = drawing.getFileUrl();
ossService.deleteWithValidByIds(fileUrl == null ? Collections.emptyList() : Collections.singletonList(fileUrl), false);
this.removeById(drawing.getId());
} }
} }

View File

@ -0,0 +1,303 @@
package org.dromara.design.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.constant.HttpStatus;
import org.dromara.common.core.domain.event.ProcessDeleteEvent;
import org.dromara.common.core.domain.event.ProcessEvent;
import org.dromara.common.core.domain.event.ProcessTaskEvent;
import org.dromara.common.core.enums.BusinessStatusEnum;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.service.WorkflowService;
import org.dromara.common.core.utils.ObjectUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.design.domain.DesSpecialScheme;
import org.dromara.design.domain.dto.specialscheme.DesSpecialSchemeCreateReq;
import org.dromara.design.domain.dto.specialscheme.DesSpecialSchemeQueryReq;
import org.dromara.design.domain.dto.specialscheme.DesSpecialSchemeUpdateReq;
import org.dromara.design.domain.vo.specialscheme.DesSpecialSchemeVo;
import org.dromara.design.mapper.DesSpecialSchemeMapper;
import org.dromara.design.service.IDesSpecialSchemeService;
import org.dromara.project.service.IBusProjectService;
import org.dromara.system.domain.vo.SysOssVo;
import org.dromara.system.service.ISysOssService;
import org.springframework.beans.BeanUtils;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
/**
* 专项方案管理Service业务层处理
*
* @author lcj
* @date 2025-07-03
*/
@Slf4j
@Service
public class DesSpecialSchemeServiceImpl extends ServiceImpl<DesSpecialSchemeMapper, DesSpecialScheme>
implements IDesSpecialSchemeService {
@Resource
private IBusProjectService projectService;
@Resource
private ISysOssService ossService;
@Resource
private WorkflowService workflowService;
/**
* 查询图纸管理
*
* @param id 主键
* @return 图纸管理
*/
@Override
public DesSpecialSchemeVo queryById(Long id) {
DesSpecialScheme specialScheme = this.getById(id);
if (specialScheme == null) {
throw new ServiceException("图纸不存在", HttpStatus.NOT_FOUND);
}
return this.getVo(specialScheme);
}
/**
* 分页查询图纸管理列表
*
* @param req 查询条件
* @param pageQuery 分页参数
* @return 图纸管理分页列表
*/
@Override
public TableDataInfo<DesSpecialSchemeVo> queryPageList(DesSpecialSchemeQueryReq req, PageQuery pageQuery) {
LambdaQueryWrapper<DesSpecialScheme> lqw = buildQueryWrapper(req);
Page<DesSpecialScheme> result = this.page(pageQuery.build(), lqw);
return TableDataInfo.build(this.getVoPage(result));
}
/**
* 查询符合条件的图纸管理列表
*
* @param req 查询条件
* @return 图纸管理列表
*/
@Override
public List<DesSpecialSchemeVo> queryList(DesSpecialSchemeQueryReq req) {
LambdaQueryWrapper<DesSpecialScheme> lqw = buildQueryWrapper(req);
return this.list(lqw).stream().map(this::getVo).toList();
}
/**
* 新增图纸管理
*
* @param req 图纸管理
* @return 新增图纸管理
*/
@Override
@Transactional(rollbackFor = Exception.class)
public DesSpecialSchemeVo insertByBo(DesSpecialSchemeCreateReq req) {
Long fileUrl = req.getFileUrl();
SysOssVo ossVo = ossService.getById(fileUrl);
// 数据校验
if (ObjectUtils.isEmpty(ossVo)) {
throw new ServiceException("图纸文件不能为空", HttpStatus.BAD_REQUEST);
}
Long projectId = req.getProjectId();
if (projectService.getById(projectId) == null) {
throw new ServiceException("项目不存在", HttpStatus.BAD_REQUEST);
}
// 文件信息赋值
DesSpecialScheme desSpecialScheme = new DesSpecialScheme();
desSpecialScheme.setProjectId(projectId);
desSpecialScheme.setOriginalName(ossVo.getOriginalName());
String name = req.getFileName();
if (StringUtils.isBlank(name)) {
name = FileUtil.getPrefix(ossVo.getOriginalName());
}
desSpecialScheme.setFileName(name);
desSpecialScheme.setFileUrl(fileUrl);
desSpecialScheme.setFileSuffix(ossVo.getFileSuffix());
desSpecialScheme.setVersionNumber(req.getVersionNumber());
boolean result = this.save(desSpecialScheme);
if (!result) {
throw new ServiceException("保存新图纸失败");
}
return this.getVo(this.getById(desSpecialScheme.getId()));
}
/**
* 修改图纸管理
*
* @param req 图纸管理
* @return 是否修改成功
*/
@Override
public DesSpecialSchemeVo updateByBo(DesSpecialSchemeUpdateReq req) {
Long id = req.getId();
DesSpecialScheme oldSpecialScheme = this.getById(id);
if (oldSpecialScheme == null) {
throw new ServiceException("图纸不存在", HttpStatus.NOT_FOUND);
}
DesSpecialScheme desSpecialScheme = new DesSpecialScheme();
BeanUtils.copyProperties(req, desSpecialScheme);
boolean result = this.updateById(desSpecialScheme);
if (!result) {
throw new ServiceException("修改图纸失败", HttpStatus.ERROR);
}
return this.getVo(this.getById(id));
}
/**
* 校验并批量删除图纸管理信息
*
* @param ids 待删除的主键集合
* @return 是否删除成功
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean deleteByIds(Collection<Long> ids) {
List<DesSpecialScheme> specialSchemeList = this.listByIds(ids);
if (CollUtil.isEmpty(specialSchemeList)) {
throw new ServiceException("参数错误,请勿删除不存在的图纸", HttpStatus.BAD_REQUEST);
}
workflowService.deleteInstance((List<Long>) ids);
// 删除oss文件
Set<Long> fileIdList = specialSchemeList.stream().map(DesSpecialScheme::getFileUrl).collect(Collectors.toSet());
ossService.deleteWithValidByIds(fileIdList, false);
return removeBatchByIds(ids);
}
/**
* 构建图纸管理封装对象
*
* @param specialScheme 图纸管理
* @return 图纸管理封装对象
*/
@Override
public DesSpecialSchemeVo getVo(DesSpecialScheme specialScheme) {
DesSpecialSchemeVo vo = new DesSpecialSchemeVo();
if (specialScheme == null) {
return vo;
}
BeanUtils.copyProperties(specialScheme, vo);
SysOssVo ossVo = ossService.getById(specialScheme.getFileUrl());
vo.setFile(ossVo);
return vo;
}
/**
* 构建查询条件
*
* @param req 查询条件
* @return 查询条件
*/
@Override
public LambdaQueryWrapper<DesSpecialScheme> buildQueryWrapper(DesSpecialSchemeQueryReq req) {
LambdaQueryWrapper<DesSpecialScheme> lqw = new LambdaQueryWrapper<>();
if (req == null) {
return lqw;
}
Long projectId = req.getProjectId();
String fileName = req.getFileName();
String fileStatus = req.getFileStatus();
String originalName = req.getOriginalName();
lqw.like(StringUtils.isNotBlank(fileName), DesSpecialScheme::getFileName, fileName);
lqw.like(StringUtils.isNotBlank(originalName), DesSpecialScheme::getOriginalName, originalName);
lqw.eq(ObjectUtils.isNotEmpty(projectId), DesSpecialScheme::getProjectId, projectId);
lqw.eq(StringUtils.isNotBlank(fileStatus), DesSpecialScheme::getFileStatus, fileStatus);
lqw.orderByDesc(DesSpecialScheme::getCreateTime);
return lqw;
}
/**
* 获取图纸管理对象视图
*
* @param specialSchemePage 图纸管理对象
* @return 图纸管理对象视图
*/
@Override
public Page<DesSpecialSchemeVo> getVoPage(Page<DesSpecialScheme> specialSchemePage) {
List<DesSpecialScheme> specialSchemeList = specialSchemePage.getRecords();
Page<DesSpecialSchemeVo> specialSchemeVoPage = new Page<>(
specialSchemePage.getCurrent(),
specialSchemePage.getSize(),
specialSchemePage.getTotal());
if (CollUtil.isEmpty(specialSchemeList)) {
return specialSchemeVoPage;
}
List<SysOssVo> ossVoList = ossService.listByIds(specialSchemeList.stream().map(DesSpecialScheme::getFileUrl).toList());
Map<Long, List<SysOssVo>> ossMap = ossVoList.stream().collect(Collectors.groupingBy(SysOssVo::getOssId));
List<DesSpecialSchemeVo> specialSchemeVoList = specialSchemeList.stream().map(entity -> {
DesSpecialSchemeVo specialSchemeVo = new DesSpecialSchemeVo();
BeanUtils.copyProperties(entity, specialSchemeVo);
specialSchemeVo.setFile(ossMap.get(entity.getFileUrl()).getFirst());
return specialSchemeVo;
}).toList();
specialSchemeVoPage.setRecords(specialSchemeVoList);
return specialSchemeVoPage;
}
/**
* 总体流程监听(例如: 草稿,撤销,退回,作废,终止,已完成,单任务完成等)
* 正常使用只需#processEvent.flowCode=='leave1'
* 示例为了方便则使用startsWith匹配了全部示例key
*
* @param processEvent 参数
*/
@EventListener(condition = "#processEvent.flowCode == 'specialScheme'")
public void processHandler(ProcessEvent processEvent) {
log.info("图纸审核任务执行了{}", processEvent.toString());
DesSpecialScheme specialScheme = this.getById(Convert.toLong(processEvent.getBusinessId()));
specialScheme.setStatus(processEvent.getStatus());
if (processEvent.getSubmit()) {
specialScheme.setStatus(BusinessStatusEnum.WAITING.getStatus());
}
this.updateById(specialScheme);
}
/**
* 执行任务创建监听
* 示例:也可通过 @EventListener(condition = "#processTaskEvent.flowCode=='leave1'")进行判断
* 在方法中判断流程节点key
* if ("xxx".equals(processTaskEvent.getNodeCode())) {
* //执行业务逻辑
* }
*
* @param processTaskEvent 参数
*/
@EventListener(condition = "#processTaskEvent.flowCode == 'specialScheme'")
public void processTaskHandler(ProcessTaskEvent processTaskEvent) {
log.info("图纸审核任务创建了{}", processTaskEvent.toString());
}
/**
* 监听删除流程事件
* 正常使用只需#processDeleteEvent.flowCode=='leave1'
* 示例为了方便则使用startsWith匹配了全部示例key
*
* @param processDeleteEvent 参数
*/
@EventListener(condition = "#processDeleteEvent.flowCode == 'specialScheme'")
public void processDeleteHandler(ProcessDeleteEvent processDeleteEvent) {
log.info("监听删除流程事件,图纸审核任务执行了{}", processDeleteEvent.toString());
DesSpecialScheme specialScheme = this.getById(Convert.toLong(processDeleteEvent.getBusinessId()));
if (ObjectUtil.isNull(specialScheme)) {
return;
}
this.removeById(specialScheme.getId());
}
}

View File

@ -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.design.mapper.DesDesignChangeMapper">
</mapper>

View File

@ -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.design.mapper.DesSpecialSchemeMapper">
</mapper>

View File

@ -13,6 +13,7 @@ import org.dromara.warm.flow.core.entity.Definition;
import org.dromara.warm.flow.core.service.DefService; import org.dromara.warm.flow.core.service.DefService;
import org.dromara.warm.flow.orm.entity.FlowDefinition; import org.dromara.warm.flow.orm.entity.FlowDefinition;
import org.dromara.workflow.common.ConditionalOnEnable; import org.dromara.workflow.common.ConditionalOnEnable;
import org.dromara.workflow.domain.bo.FlowDefinitionBo;
import org.dromara.workflow.domain.vo.FlowDefinitionVo; import org.dromara.workflow.domain.vo.FlowDefinitionVo;
import org.dromara.workflow.service.IFlwDefinitionService; import org.dromara.workflow.service.IFlwDefinitionService;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@ -41,23 +42,23 @@ public class FlwDefinitionController extends BaseController {
/** /**
* 查询流程定义列表 * 查询流程定义列表
* *
* @param flowDefinition 参数 * @param flowDefinitionBo 参数
* @param pageQuery 分页 * @param pageQuery 分页
*/ */
@GetMapping("/list") @GetMapping("/list")
public TableDataInfo<FlowDefinitionVo> list(FlowDefinition flowDefinition, PageQuery pageQuery) { public TableDataInfo<FlowDefinitionVo> list(FlowDefinitionBo flowDefinitionBo, PageQuery pageQuery) {
return flwDefinitionService.queryList(flowDefinition, pageQuery); return flwDefinitionService.queryList(flowDefinitionBo, pageQuery);
} }
/** /**
* 查询未发布的流程定义列表 * 查询未发布的流程定义列表
* *
* @param flowDefinition 参数 * @param flowDefinitionBo 参数
* @param pageQuery 分页 * @param pageQuery 分页
*/ */
@GetMapping("/unPublishList") @GetMapping("/unPublishList")
public TableDataInfo<FlowDefinitionVo> unPublishList(FlowDefinition flowDefinition, PageQuery pageQuery) { public TableDataInfo<FlowDefinitionVo> unPublishList(FlowDefinitionBo flowDefinitionBo, PageQuery pageQuery) {
return flwDefinitionService.unPublishList(flowDefinition, pageQuery); return flwDefinitionService.unPublishList(flowDefinitionBo, pageQuery);
} }
/** /**
@ -72,8 +73,6 @@ public class FlwDefinitionController extends BaseController {
/** /**
* 新增流程定义 * 新增流程定义
*
* @param flowDefinition 参数
*/ */
@Log(title = "流程定义", businessType = BusinessType.INSERT) @Log(title = "流程定义", businessType = BusinessType.INSERT)
@PostMapping @PostMapping

View File

@ -0,0 +1,25 @@
package org.dromara.workflow.domain.bo;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.dromara.warm.flow.orm.entity.FlowDefinition;
import java.io.Serial;
import java.io.Serializable;
/**
* @author lcj
* @date 2025/7/3 16:54
*/
@EqualsAndHashCode(callSuper = true)
@Data
public class FlowDefinitionBo extends FlowDefinition implements Serializable {
@Serial
private static final long serialVersionUID = 2120294203941407990L;
/**
* 项目id
*/
private Long projectId;
}

View File

@ -3,7 +3,7 @@ package org.dromara.workflow.service;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.warm.flow.orm.entity.FlowDefinition; import org.dromara.workflow.domain.bo.FlowDefinitionBo;
import org.dromara.workflow.domain.vo.FlowDefinitionVo; import org.dromara.workflow.domain.vo.FlowDefinitionVo;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
@ -20,20 +20,20 @@ public interface IFlwDefinitionService {
/** /**
* 查询流程定义列表 * 查询流程定义列表
* *
* @param flowDefinition 参数 * @param flowDefinitionBo 参数
* @param pageQuery 分页 * @param pageQuery 分页
* @return 返回分页列表 * @return 返回分页列表
*/ */
TableDataInfo<FlowDefinitionVo> queryList(FlowDefinition flowDefinition, PageQuery pageQuery); TableDataInfo<FlowDefinitionVo> queryList(FlowDefinitionBo flowDefinitionBo, PageQuery pageQuery);
/** /**
* 查询未发布的流程定义列表 * 查询未发布的流程定义列表
* *
* @param flowDefinition 参数 * @param flowDefinitionBo 参数
* @param pageQuery 分页 * @param pageQuery 分页
* @return 返回分页列表 * @return 返回分页列表
*/ */
TableDataInfo<FlowDefinitionVo> unPublishList(FlowDefinition flowDefinition, PageQuery pageQuery); TableDataInfo<FlowDefinitionVo> unPublishList(FlowDefinitionBo flowDefinitionBo, PageQuery pageQuery);
/** /**
* 发布流程定义 * 发布流程定义

View File

@ -31,6 +31,7 @@ import org.dromara.warm.flow.orm.mapper.FlowSkipMapper;
import org.dromara.workflow.common.ConditionalOnEnable; import org.dromara.workflow.common.ConditionalOnEnable;
import org.dromara.workflow.common.constant.FlowConstant; import org.dromara.workflow.common.constant.FlowConstant;
import org.dromara.workflow.domain.FlowCategory; import org.dromara.workflow.domain.FlowCategory;
import org.dromara.workflow.domain.bo.FlowDefinitionBo;
import org.dromara.workflow.domain.vo.FlowDefinitionVo; import org.dromara.workflow.domain.vo.FlowDefinitionVo;
import org.dromara.workflow.mapper.FlwCategoryMapper; import org.dromara.workflow.mapper.FlwCategoryMapper;
import org.dromara.workflow.service.IFlwCommonService; import org.dromara.workflow.service.IFlwCommonService;
@ -69,13 +70,13 @@ public class FlwDefinitionServiceImpl implements IFlwDefinitionService {
/** /**
* 查询流程定义列表 * 查询流程定义列表
* *
* @param flowDefinition 流程定义信息 * @param flowDefinitionBo 流程定义信息
* @param pageQuery 分页 * @param pageQuery 分页
* @return 返回分页列表 * @return 返回分页列表
*/ */
@Override @Override
public TableDataInfo<FlowDefinitionVo> queryList(FlowDefinition flowDefinition, PageQuery pageQuery) { public TableDataInfo<FlowDefinitionVo> queryList(FlowDefinitionBo flowDefinitionBo, PageQuery pageQuery) {
LambdaQueryWrapper<FlowDefinition> wrapper = buildQueryWrapper(flowDefinition); LambdaQueryWrapper<FlowDefinition> wrapper = buildQueryWrapper(flowDefinitionBo);
wrapper.eq(FlowDefinition::getIsPublish, PublishStatus.PUBLISHED.getKey()); wrapper.eq(FlowDefinition::getIsPublish, PublishStatus.PUBLISHED.getKey());
Page<FlowDefinition> page = flowDefinitionMapper.selectPage(pageQuery.build(), wrapper); Page<FlowDefinition> page = flowDefinitionMapper.selectPage(pageQuery.build(), wrapper);
List<FlowDefinitionVo> list = BeanUtil.copyToList(page.getRecords(), FlowDefinitionVo.class); List<FlowDefinitionVo> list = BeanUtil.copyToList(page.getRecords(), FlowDefinitionVo.class);
@ -85,27 +86,28 @@ public class FlwDefinitionServiceImpl implements IFlwDefinitionService {
/** /**
* 查询未发布的流程定义列表 * 查询未发布的流程定义列表
* *
* @param flowDefinition 流程定义信息 * @param flowDefinitionBo 流程定义信息
* @param pageQuery 分页 * @param pageQuery 分页
* @return 返回分页列表 * @return 返回分页列表
*/ */
@Override @Override
public TableDataInfo<FlowDefinitionVo> unPublishList(FlowDefinition flowDefinition, PageQuery pageQuery) { public TableDataInfo<FlowDefinitionVo> unPublishList(FlowDefinitionBo flowDefinitionBo, PageQuery pageQuery) {
LambdaQueryWrapper<FlowDefinition> wrapper = buildQueryWrapper(flowDefinition); LambdaQueryWrapper<FlowDefinition> wrapper = buildQueryWrapper(flowDefinitionBo);
wrapper.in(FlowDefinition::getIsPublish, Arrays.asList(PublishStatus.UNPUBLISHED.getKey(), PublishStatus.EXPIRED.getKey())); wrapper.in(FlowDefinition::getIsPublish, Arrays.asList(PublishStatus.UNPUBLISHED.getKey(), PublishStatus.EXPIRED.getKey()));
Page<FlowDefinition> page = flowDefinitionMapper.selectPage(pageQuery.build(), wrapper); Page<FlowDefinition> page = flowDefinitionMapper.selectPage(pageQuery.build(), wrapper);
List<FlowDefinitionVo> list = BeanUtil.copyToList(page.getRecords(), FlowDefinitionVo.class); List<FlowDefinitionVo> list = BeanUtil.copyToList(page.getRecords(), FlowDefinitionVo.class);
return new TableDataInfo<>(list, page.getTotal()); return new TableDataInfo<>(list, page.getTotal());
} }
private LambdaQueryWrapper<FlowDefinition> buildQueryWrapper(FlowDefinition flowDefinition) { private LambdaQueryWrapper<FlowDefinition> buildQueryWrapper(FlowDefinitionBo flowDefinitionBo) {
LambdaQueryWrapper<FlowDefinition> wrapper = Wrappers.lambdaQuery(); LambdaQueryWrapper<FlowDefinition> wrapper = Wrappers.lambdaQuery();
wrapper.like(StringUtils.isNotBlank(flowDefinition.getFlowCode()), FlowDefinition::getFlowCode, flowDefinition.getFlowCode()); wrapper.like(StringUtils.isNotBlank(flowDefinitionBo.getFlowCode()), FlowDefinition::getFlowCode, flowDefinitionBo.getFlowCode());
wrapper.like(StringUtils.isNotBlank(flowDefinition.getFlowName()), FlowDefinition::getFlowName, flowDefinition.getFlowName()); wrapper.like(StringUtils.isNotBlank(flowDefinitionBo.getFlowName()), FlowDefinition::getFlowName, flowDefinitionBo.getFlowName());
if (StringUtils.isNotBlank(flowDefinition.getCategory())) { if (StringUtils.isNotBlank(flowDefinitionBo.getCategory())) {
List<Long> categoryIds = flwCategoryMapper.selectCategoryIdsByParentId(Convert.toLong(flowDefinition.getCategory())); List<Long> categoryIds = flwCategoryMapper.selectCategoryIdsByParentId(Convert.toLong(flowDefinitionBo.getCategory()));
wrapper.in(FlowDefinition::getCategory, StreamUtils.toList(categoryIds, Convert::toStr)); wrapper.in(FlowDefinition::getCategory, StreamUtils.toList(categoryIds, Convert::toStr));
} }
wrapper.likeRight(FlowDefinition::getFlowCode, flowDefinitionBo.getProjectId() + "_");
wrapper.orderByDesc(FlowDefinition::getCreateTime); wrapper.orderByDesc(FlowDefinition::getCreateTime);
return wrapper; return wrapper;
} }

View File

@ -907,3 +907,43 @@ values(1940367276851081221, '图纸管理删除', 1940367276851081217, '4', '#'
insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
values(1940367276851081222, '图纸管理导出', 1940367276851081217, '5', '#', '', 1, 0, 'F', '0', '0', 'design:drawing:export', '#', 103, 1, sysdate(), null, null, ''); values(1940367276851081222, '图纸管理导出', 1940367276851081217, '5', '#', '', 1, 0, 'F', '0', '0', 'design:drawing:export', '#', 103, 1, sysdate(), null, null, '');
-- 菜单 SQL
insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
values(1940612372729274369, '专项方案管理', '1940300237524451330', '1', 'specialScheme', 'design/specialScheme/index', 1, 0, 'C', '0', '0', 'design:specialScheme:list', '#', 103, 1, sysdate(), null, null, '专项方案管理菜单');
-- 按钮 SQL
insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
values(1940612372729274370, '专项方案管理查询', 1940612372729274369, '1', '#', '', 1, 0, 'F', '0', '0', 'design:specialScheme:query', '#', 103, 1, sysdate(), null, null, '');
insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
values(1940612372729274371, '专项方案管理新增', 1940612372729274369, '2', '#', '', 1, 0, 'F', '0', '0', 'design:specialScheme:add', '#', 103, 1, sysdate(), null, null, '');
insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
values(1940612372729274372, '专项方案管理修改', 1940612372729274369, '3', '#', '', 1, 0, 'F', '0', '0', 'design:specialScheme:edit', '#', 103, 1, sysdate(), null, null, '');
insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
values(1940612372729274373, '专项方案管理删除', 1940612372729274369, '4', '#', '', 1, 0, 'F', '0', '0', 'design:specialScheme:remove', '#', 103, 1, sysdate(), null, null, '');
insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
values(1940612372729274374, '专项方案管理导出', 1940612372729274369, '5', '#', '', 1, 0, 'F', '0', '0', 'design:specialScheme:export', '#', 103, 1, sysdate(), null, null, '');
-- 菜单 SQL
insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
values(1940723160391405569, '设计变更管理', '1940300237524451330', '1', 'designChange', 'design/designChange/index', 1, 0, 'C', '0', '0', 'design:designChange:list', '#', 103, 1, sysdate(), null, null, '设计变更管理菜单');
-- 按钮 SQL
insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
values(1940723160391405570, '设计变更管理查询', 1940723160391405569, '1', '#', '', 1, 0, 'F', '0', '0', 'design:designChange:query', '#', 103, 1, sysdate(), null, null, '');
insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
values(1940723160391405571, '设计变更管理新增', 1940723160391405569, '2', '#', '', 1, 0, 'F', '0', '0', 'design:designChange:add', '#', 103, 1, sysdate(), null, null, '');
insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
values(1940723160391405572, '设计变更管理修改', 1940723160391405569, '3', '#', '', 1, 0, 'F', '0', '0', 'design:designChange:edit', '#', 103, 1, sysdate(), null, null, '');
insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
values(1940723160391405573, '设计变更管理删除', 1940723160391405569, '4', '#', '', 1, 0, 'F', '0', '0', 'design:designChange:remove', '#', 103, 1, sysdate(), null, null, '');
insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
values(1940723160391405574, '设计变更管理导出', 1940723160391405569, '5', '#', '', 1, 0, 'F', '0', '0', 'design:designChange:export', '#', 103, 1, sysdate(), null, null, '');

View File

@ -1383,7 +1383,57 @@ CREATE TABLE `des_drawing`
`update_time` datetime default CURRENT_TIMESTAMP null on update CURRENT_TIMESTAMP comment '更新时间', `update_time` datetime default CURRENT_TIMESTAMP null on update CURRENT_TIMESTAMP comment '更新时间',
`deleted_at` datetime null comment '删除时间', `deleted_at` datetime null comment '删除时间',
primary key (`id`) using btree, primary key (`id`) using btree,
UNIQUE KEY `uk_project_type_newest` (`project_id`, `file_type`, `newest`),
index `idx_project_id` (`project_id` asc) using btree comment '项目id', index `idx_project_id` (`project_id` asc) using btree comment '项目id',
index `idx_file_type` (`file_type` asc) using btree comment '文件类型' index `idx_file_type` (`file_type` asc) using btree comment '文件类型'
) comment '图纸管理' collate = utf8mb4_unicode_ci; ) comment '图纸管理' collate = utf8mb4_unicode_ci;
DROP TABLE IF EXISTS `des_special_scheme`;
CREATE TABLE `des_special_scheme`
(
`id` bigint not null auto_increment comment '主键id',
`project_id` bigint not null comment '项目id',
`version_number` varchar(50) not null comment '版本号',
`file_name` varchar(255) not null comment '文件名称',
`file_url` bigint null comment '文件访问路径',
`file_suffix` varchar(20) null comment '文件后缀',
`file_status` char(1) default '0' not null comment '状态0正常 1删除',
`original_name` varchar(255) null comment '原文件名',
`status` varchar(255) default 'draft' not null comment '审核状态',
`remark` text null comment '备注',
`create_by` bigint null comment '创建者',
`update_by` bigint null comment '更新者',
`create_time` datetime default CURRENT_TIMESTAMP null comment '创建时间',
`update_time` datetime default CURRENT_TIMESTAMP null on update CURRENT_TIMESTAMP comment '更新时间',
`deleted_at` datetime null comment '删除时间',
primary key (`id`) using btree,
index `idx_project_id` (`project_id` asc) using btree comment '项目id'
) comment '专项方案管理' collate = utf8mb4_unicode_ci;
DROP TABLE IF EXISTS `des_design_change`;
CREATE TABLE `des_design_change`
(
`id` bigint not null auto_increment comment '主键id',
`project_id` bigint not null comment '项目id',
`form_no` varchar(50) null comment '申请单编号',
`project_name` varchar(255) null comment '工程名称',
`submit_unit` varchar(255) null comment '提出单位',
`specialty` varchar(100) null comment '专业',
`submit_date` date null comment '提出日期',
`volume_name` varchar(255) null comment '卷册名称',
`volume_no` varchar(100) null comment '卷册号',
`attachment_pic` varchar(1024) null comment '附图',
`change_reason` varchar(255) null comment '变更原因',
`change_content` text null comment '变更内容',
`cost_estimation` text null comment '变更费用估算',
`cost_estimation_file` varchar(1024) null comment '变更费用估算计算表',
`file_id` varchar(255) null comment '变更文件',
`status` varchar(255) null comment '审核状态',
`remark` text null comment '备注',
`create_by` bigint null comment '创建者',
`update_by` bigint null comment '更新者',
`create_time` datetime default CURRENT_TIMESTAMP null comment '创建时间',
`update_time` datetime default CURRENT_TIMESTAMP null on update CURRENT_TIMESTAMP comment '更新时间',
primary key (`id`) using btree,
index `idx_project_id` (`project_id` asc) using btree comment '项目id'
) comment '设计变更管理' collate = utf8mb4_unicode_ci;