feat(REQ-3769) - 增加模板关联文档相关排序动作

This commit is contained in:
wangli 2025-03-31 17:24:40 +08:00
parent c86be5c859
commit 592722af44
16 changed files with 258 additions and 17 deletions

View File

@ -7,6 +7,7 @@ import cn.axzo.workflow.common.model.request.bpmn.model.BpmnModelCreateDTO;
import cn.axzo.workflow.common.model.request.bpmn.model.BpmnModelSearchDTO;
import cn.axzo.workflow.common.model.request.bpmn.model.BpmnModelUpdateDTO;
import cn.axzo.workflow.common.model.request.bpmn.model.doc.DocCreateDTO;
import cn.axzo.workflow.common.model.request.bpmn.model.doc.DocOrderDTO;
import cn.axzo.workflow.common.model.request.bpmn.model.doc.DocSearchDTO;
import cn.axzo.workflow.common.model.request.bpmn.model.doc.DocUpdateDTO;
import cn.axzo.workflow.common.model.request.bpmn.print.PrintTemplateConfigQueryDTO;
@ -287,4 +288,15 @@ public interface ProcessModelApi {
@DeleteMapping(value = "/api/process/model/doc/delete")
@InvokeMode(SYNC)
CommonResponse<Boolean> deleteDoc(@RequestParam("id") Long docId);
/**
* 关联文档配置排序
*
* @param dto
* @return
*/
@Operation(summary = "关联文档配置排序")
@PostMapping(value = "/api/process/model/doc/order")
@InvokeMode(SYNC)
CommonResponse<Boolean> orderDoc(@Validated @RequestBody DocOrderDTO dto);
}

View File

@ -18,7 +18,10 @@ public enum BpmnModelRespCode implements IModuleRespCode {
MODEL_KEY_NOT_EXISTS("003", "流程模型KEY【{}】不存在"),
MODEL_NOT_EXISTS("004", "流程模型不存在"),
BPMN_BYTES_NOT_EXISTS("005", "模型定义内容字节码不存在"),
MODEL_IS_DISABLE("006", "模型已经被停用")
MODEL_IS_DISABLE("006", "模型已经被停用"),
MODEL_FILE_TAG_DUPLICATE("007", "模型关联的文档业务标签重复"),
MODEL_FILE_TAG_EXISTS("008", "模型关联的文档业务标签已存在"),
MODEL_FILE_NOT_EXISTS("009", "模型关联的文档不存在或已被删除")
;
private final String code;

View File

@ -33,7 +33,7 @@ public enum FileTypeEnum {
public static FileTypeEnum valueOfType(String type) {
return Arrays.stream(FileTypeEnum.values())
.filter(i -> Objects.equals(i.getType(), type.toUpperCase()))
.filter(i -> Objects.equals(i.getType().toUpperCase(), type.toUpperCase()))
.findAny()
.orElse(null);
}

View File

@ -0,0 +1,12 @@
package cn.axzo.workflow.common.enums;
/**
* 顺序操作枚举
*
* @author wangli
* @since 2025-03-31 16:35
*/
public enum OrderEnum {
UP, DOWN
}

View File

@ -3,11 +3,14 @@ package cn.axzo.workflow.common.model.request.bpmn.model.doc;
import cn.axzo.workflow.common.enums.FileTypeEnum;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import lombok.experimental.SuperBuilder;
import javax.validation.constraints.NotBlank;
import java.io.Serializable;
import static cn.axzo.workflow.common.constant.BpmnConstants.NO_TENANT_ID;
@ -21,6 +24,8 @@ import static cn.axzo.workflow.common.constant.BpmnConstants.NO_TENANT_ID;
@ApiModel("创建模型关联的文档")
@Data
@Accessors(chain = true)
@AllArgsConstructor
@NoArgsConstructor
@SuperBuilder
public class DocCreateDTO implements Serializable {
@ -28,6 +33,7 @@ public class DocCreateDTO implements Serializable {
* 关联到的模型 ID
*/
@ApiModelProperty(value = "文档被关联到的模型 ID")
@NotBlank(message = "模型 ID 不能为空")
private String modelId;
/**
@ -39,7 +45,7 @@ public class DocCreateDTO implements Serializable {
* 文档关联ID
* <p>
* word/excel 对应 wps Id
* hp 对应是
* hp 对应是content 表的主键前端新建时不回传
* pdf 对应 oss 中的 fileKey
*/
@ApiModelProperty(value = "底层文件关联标识")
@ -77,6 +83,7 @@ public class DocCreateDTO implements Serializable {
* 业务标签
*/
@ApiModelProperty(value = "业务标签")
@NotBlank(message = "业务标签不能为空")
private String tag;
/**

View File

@ -0,0 +1,35 @@
package cn.axzo.workflow.common.model.request.bpmn.model.doc;
import cn.axzo.workflow.common.enums.OrderEnum;
import io.swagger.annotations.ApiModel;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import lombok.experimental.SuperBuilder;
import java.io.Serializable;
/**
* 模型关联的文档排序
*
* @author wangli
* @since 2025-03-31 16:32
*/
@ApiModel("模型关联的文档排序")
@Data
@Accessors(chain = true)
@AllArgsConstructor
@NoArgsConstructor
@SuperBuilder
public class DocOrderDTO implements Serializable {
/**
* 文档主键 ID
*/
private Long id;
/**
* 操作顺序
*/
private OrderEnum order;
}

View File

@ -2,7 +2,9 @@ package cn.axzo.workflow.common.model.request.bpmn.model.doc;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import lombok.experimental.SuperBuilder;
@ -17,6 +19,8 @@ import java.io.Serializable;
@ApiModel("创建模型关联的文档")
@Data
@Accessors(chain = true)
@AllArgsConstructor
@NoArgsConstructor
@SuperBuilder
public class DocUpdateDTO extends DocCreateDTO implements Serializable {

View File

@ -2,6 +2,7 @@ package cn.axzo.workflow.common.model.response.bpmn.model.doc;
import cn.axzo.workflow.common.enums.FileTypeEnum;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.NoArgsConstructor;
@ -16,25 +17,79 @@ import lombok.NoArgsConstructor;
@NoArgsConstructor
public class DocBaseVO {
private Long id;
/**
* 模型 ID
*/
@ApiModelProperty(value = "模型 ID")
private String modelId;
/**
* 模型 KEY
*/
@ApiModelProperty(value = "模型 KEY")
private String modelKey;
/**
* 文档对应文件的检索信息
* word/excel 对应 wps Id
* hp 对应是
* pdf 对应 oss 中的 fileKey
*/
@ApiModelProperty(value = "文档对应文件检索信息")
private String fileRelationId;
/**
* 文档名称用于归档
*/
@ApiModelProperty(value = "文档名称")
private String fileName;
/**
* 文档模板名称
*/
@ApiModelProperty(value = "模板名称")
private String templateName;
/**
* 归档位置
*/
private String location;
/**
* 文档类型
*/
@ApiModelProperty(value = "文档类型")
private FileTypeEnum fileType;
/**
* 文档业务类型
*/
@ApiModelProperty(value = "业务类型")
private String tag;
/**
* 文档状态
*/
@ApiModelProperty(value = "文档状态")
private Boolean status;
/**
* 文档是否必选
*/
@ApiModelProperty(value = "是否必选")
private Boolean require;
/**
* 排序号
*/
@ApiModelProperty(value = "排序号")
private Integer order;
/**
* 租户 ID
*/
@ApiModelProperty(value = "租户 ID")
private String tenantId;
}

View File

@ -74,6 +74,12 @@ public class ExtAxModelDoc extends BaseEntity<ExtAxModelDoc> {
@TableField(value = "`require`")
private Boolean require;
/**
* 排序号
*/
@TableField(value = "`order`")
private Integer order;
/**
* 租户 ID
*/

View File

@ -5,4 +5,5 @@ import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface ExtAxModelDocMapper extends BaseMapperX<ExtAxModelDoc> {
void moveUp();
}

View File

@ -1,6 +1,7 @@
package cn.axzo.workflow.core.service;
import cn.axzo.workflow.common.enums.FileTypeEnum;
import cn.axzo.workflow.core.repository.entity.ExtAxDocContent;
/**
* 文件内容表
@ -9,9 +10,10 @@ import cn.axzo.workflow.common.enums.FileTypeEnum;
* @since 2025-03-28 18:12
*/
public interface ExtAxDocContentService {
Boolean createContent(String content, FileTypeEnum fileType, Long docId);
Boolean updateContent(String content, FileTypeEnum fileType, String docId);
ExtAxDocContent createContent(String content, FileTypeEnum fileType, Long docId);
Boolean deleteContent(String docId);
ExtAxDocContent updateContent(String content, FileTypeEnum fileType, String docId);
ExtAxDocContent deleteContent(String docId);
}

View File

@ -1,6 +1,7 @@
package cn.axzo.workflow.core.service;
import cn.axzo.workflow.common.model.request.bpmn.model.doc.DocCreateDTO;
import cn.axzo.workflow.common.model.request.bpmn.model.doc.DocOrderDTO;
import cn.axzo.workflow.common.model.request.bpmn.model.doc.DocSearchDTO;
import cn.axzo.workflow.common.model.request.bpmn.model.doc.DocUpdateDTO;
import cn.axzo.workflow.common.model.response.BpmPageResult;
@ -45,4 +46,12 @@ public interface ExtAxModelDocService {
* @return
*/
Boolean deleteDoc(Long docId);
/**
* 模型文档排序
*
* @param dto
* @return
*/
Boolean orderDoc(DocOrderDTO dto);
}

View File

@ -23,27 +23,30 @@ public class ExtAxDocContentServiceImpl implements ExtAxDocContentService {
private ExtAxDocContentMapper extAxDocContentMapper;
@Override
public Boolean createContent(String content, FileTypeEnum fileType, Long docId) {
public ExtAxDocContent createContent(String content, FileTypeEnum fileType, Long docId) {
ExtAxDocContent entity = new ExtAxDocContent();
entity.setContent(content);
entity.setFileType(fileType.getType());
entity.setFileType(fileType.name());
entity.setFileId(docId);
return extAxDocContentMapper.insert(entity) > 0;
extAxDocContentMapper.insert(entity);
return entity;
}
@Override
public Boolean updateContent(String content, FileTypeEnum fileType, String docId) {
public ExtAxDocContent updateContent(String content, FileTypeEnum fileType, String docId) {
ExtAxDocContent entity = extAxDocContentMapper.selectOne(new LambdaQueryWrapper<ExtAxDocContent>()
.eq(ExtAxDocContent::getFileId, docId));
.eq(ExtAxDocContent::getFileId, Long.valueOf(docId)));
entity.setContent(content);
entity.setFileType(fileType.getType());
return extAxDocContentMapper.updateById(entity) > 0;
entity.setFileType(fileType.name());
extAxDocContentMapper.updateById(entity);
return entity;
}
@Override
public Boolean deleteContent(String docId) {
public ExtAxDocContent deleteContent(String docId) {
ExtAxDocContent entity = extAxDocContentMapper.selectOne(new LambdaQueryWrapper<ExtAxDocContent>()
.eq(ExtAxDocContent::getFileId, docId));
return extAxDocContentMapper.deleteById(entity) > 0;
extAxDocContentMapper.deleteById(entity);
return entity;
}
}

View File

@ -2,11 +2,15 @@ package cn.axzo.workflow.core.service.impl;
import cn.axzo.basics.common.BeanMapper;
import cn.axzo.workflow.common.enums.FileTypeEnum;
import cn.axzo.workflow.common.enums.OrderEnum;
import cn.axzo.workflow.common.exception.WorkflowEngineException;
import cn.axzo.workflow.common.model.request.bpmn.model.doc.DocCreateDTO;
import cn.axzo.workflow.common.model.request.bpmn.model.doc.DocOrderDTO;
import cn.axzo.workflow.common.model.request.bpmn.model.doc.DocSearchDTO;
import cn.axzo.workflow.common.model.request.bpmn.model.doc.DocUpdateDTO;
import cn.axzo.workflow.common.model.response.BpmPageResult;
import cn.axzo.workflow.common.model.response.bpmn.model.doc.DocBaseVO;
import cn.axzo.workflow.core.repository.entity.ExtAxDocContent;
import cn.axzo.workflow.core.repository.entity.ExtAxModelDoc;
import cn.axzo.workflow.core.repository.mapper.ExtAxModelDocMapper;
import cn.axzo.workflow.core.service.ExtAxDocContentService;
@ -23,6 +27,10 @@ import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;
import static cn.axzo.workflow.common.code.BpmnModelRespCode.MODEL_FILE_NOT_EXISTS;
import static cn.axzo.workflow.common.code.BpmnModelRespCode.MODEL_FILE_TAG_DUPLICATE;
import static cn.axzo.workflow.common.code.BpmnModelRespCode.MODEL_FILE_TAG_EXISTS;
/**
* 模型关联的文档
*
@ -42,7 +50,9 @@ public class ExtAxModelDocServiceImpl implements ExtAxModelDocService {
public BpmPageResult<DocBaseVO> docPage(DocSearchDTO dto) {
Page<ExtAxModelDoc> page = extAxModelDocMapper.selectPage(new Page<>(dto.getPageNo(), dto.getPageSize()),
buildQueryWrapper(BeanMapper.copyBean(dto, ExtAxModelDoc.class)));
List<DocBaseVO> list = BeanMapper.copyList(page.getRecords(), DocBaseVO.class);
List<DocBaseVO> list = BeanMapper.copyList(page.getRecords(), DocBaseVO.class, (s, t) -> {
t.setFileType(FileTypeEnum.valueOfType(s.getFileType()));
});
return new BpmPageResult<>(list, page.getTotal());
}
@ -56,22 +66,49 @@ public class ExtAxModelDocServiceImpl implements ExtAxModelDocService {
.eq(Objects.nonNull(entity.getStatus()), ExtAxModelDoc::getStatus, entity.getStatus())
.eq(Objects.nonNull(entity.getRequire()), ExtAxModelDoc::getRequire, entity.getRequire())
.eq(Objects.nonNull(entity.getTenantId()), ExtAxModelDoc::getTenantId, entity.getTenantId())
.orderByAsc(ExtAxModelDoc::getOrder)
;
}
public Integer maxOrder(DocCreateDTO dto) {
ExtAxModelDoc orderQuery = new ExtAxModelDoc();
orderQuery.setModelId(dto.getModelId());
List<ExtAxModelDoc> docs = extAxModelDocMapper.selectList(buildQueryWrapper(orderQuery));
return docs.stream().mapToInt(ExtAxModelDoc::getOrder).max().orElse(0) + 1;
}
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean createDoc(DocCreateDTO dto) {
ExtAxModelDoc old = new ExtAxModelDoc();
old.setModelId(dto.getModelId());
old.setTag(dto.getTag());
Integer count = extAxModelDocMapper.selectCount(buildQueryWrapper(old));
if (count > 0) {
throw new WorkflowEngineException(MODEL_FILE_TAG_DUPLICATE);
}
ExtAxModelDoc entity = BeanMapper.copyBean(dto, ExtAxModelDoc.class);
entity.setFileType(dto.getFileType().name());
entity.setOrder(maxOrder(dto));
int flat = extAxModelDocMapper.insert(entity);
if (Objects.equals(FileTypeEnum.HIPRINT, dto.getFileType())) {
extAxDocContentService.createContent(dto.getContent(), dto.getFileType(), entity.getId());
ExtAxDocContent content = extAxDocContentService.createContent(dto.getContent(), dto.getFileType(), entity.getId());
entity.setFileRelationId(String.valueOf(content.getId()));
extAxModelDocMapper.updateById(entity);
}
return flat > 0;
}
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean updateDoc(DocUpdateDTO dto) {
ExtAxModelDoc query = new ExtAxModelDoc();
query.setModelId(dto.getModelId());
query.setTag(dto.getTag());
ExtAxModelDoc old = extAxModelDocMapper.selectOne(buildQueryWrapper(query));
if (Objects.nonNull(old) && !Objects.equals(old.getId(), dto.getId())) {
throw new WorkflowEngineException(MODEL_FILE_TAG_EXISTS);
}
ExtAxModelDoc entity = extAxModelDocMapper.selectById(dto.getId());
if (Objects.isNull(entity)) {
return false;
@ -80,10 +117,12 @@ public class ExtAxModelDocServiceImpl implements ExtAxModelDocService {
extAxDocContentService.updateContent(dto.getContent(), dto.getFileType(), entity.getFileRelationId());
}
BeanUtils.copyProperties(dto, entity);
entity.setFileType(dto.getFileType().name());
return extAxModelDocMapper.updateById(entity) > 0;
}
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean deleteDoc(Long docId) {
ExtAxModelDoc entity = extAxModelDocMapper.selectById(docId);
if (Objects.equals(FileTypeEnum.HIPRINT, FileTypeEnum.valueOfType(entity.getFileType()))) {
@ -91,4 +130,38 @@ public class ExtAxModelDocServiceImpl implements ExtAxModelDocService {
}
return extAxModelDocMapper.deleteById(docId) > 0;
}
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean orderDoc(DocOrderDTO dto) {
ExtAxModelDoc doc = extAxModelDocMapper.selectById(dto.getId());
if (Objects.isNull(doc)) {
throw new WorkflowEngineException(MODEL_FILE_NOT_EXISTS);
}
LambdaQueryWrapper<ExtAxModelDoc> orderWrapper = new LambdaQueryWrapper<>();
orderWrapper.eq(ExtAxModelDoc::getModelId, doc.getModelId());
Integer currentOrder = doc.getOrder();
if (Objects.equals(dto.getOrder(), OrderEnum.UP)) {
orderWrapper.eq(ExtAxModelDoc::getOrder, currentOrder - 1);
ExtAxModelDoc upDoc = extAxModelDocMapper.selectOne(orderWrapper);
if (Objects.isNull(upDoc)) {
return false;
}
doc.setOrder(currentOrder - 1);
upDoc.setOrder(currentOrder);
extAxModelDocMapper.updateById(upDoc);
} else {
orderWrapper.eq(ExtAxModelDoc::getOrder, currentOrder + 1);
ExtAxModelDoc downDoc = extAxModelDocMapper.selectOne(orderWrapper);
if (Objects.isNull(downDoc)) {
return false;
}
doc.setOrder(currentOrder + 1);
downDoc.setOrder(currentOrder);
extAxModelDocMapper.updateById(downDoc);
}
extAxModelDocMapper.updateById(doc);
return true;
}
}

View File

@ -6,6 +6,7 @@ import cn.axzo.workflow.common.model.request.bpmn.model.BpmnModelCreateDTO;
import cn.axzo.workflow.common.model.request.bpmn.model.BpmnModelSearchDTO;
import cn.axzo.workflow.common.model.request.bpmn.model.BpmnModelUpdateDTO;
import cn.axzo.workflow.common.model.request.bpmn.model.doc.DocCreateDTO;
import cn.axzo.workflow.common.model.request.bpmn.model.doc.DocOrderDTO;
import cn.axzo.workflow.common.model.request.bpmn.model.doc.DocSearchDTO;
import cn.axzo.workflow.common.model.request.bpmn.model.doc.DocUpdateDTO;
import cn.axzo.workflow.common.model.request.bpmn.print.PrintTemplateConfigQueryDTO;
@ -406,4 +407,10 @@ public class BpmnProcessModelController implements ProcessModelApi {
return success(modelDocService.deleteDoc(docId));
}
@Operation(summary = "关联文档配置排序")
@PostMapping(value = "/doc/order")
@Override
public CommonResponse<Boolean> orderDoc(@Validated @RequestBody DocOrderDTO dto) {
return success(modelDocService.orderDoc(dto));
}
}

View File

@ -15,6 +15,7 @@ import cn.axzo.workflow.common.model.request.bpmn.model.BpmnModelCreateDTO;
import cn.axzo.workflow.common.model.request.bpmn.model.BpmnModelSearchDTO;
import cn.axzo.workflow.common.model.request.bpmn.model.BpmnModelUpdateDTO;
import cn.axzo.workflow.common.model.request.bpmn.model.doc.DocCreateDTO;
import cn.axzo.workflow.common.model.request.bpmn.model.doc.DocOrderDTO;
import cn.axzo.workflow.common.model.request.bpmn.model.doc.DocSearchDTO;
import cn.axzo.workflow.common.model.request.bpmn.model.doc.DocUpdateDTO;
import cn.axzo.workflow.common.model.request.bpmn.print.PrintFieldQueryDTO;
@ -723,6 +724,17 @@ public interface WorkflowManageService {
@InvokeMode(SYNC)
Boolean deleteDoc(@RequestParam("id") Long docId);
/**
* 关联文档配置排序
*
* @param dto
* @return
*/
@Operation(summary = "关联文档配置排序")
@PostMapping(value = "/api/process/model/doc/order")
@InvokeMode(SYNC)
Boolean orderDoc(@Validated @RequestBody DocOrderDTO dto);
/**
* 为指定流程新增变量
*/