模版编制的相关实现

This commit is contained in:
潘荣晟
2025-09-25 15:00:29 +08:00
parent d02873140a
commit 451db1f909
7 changed files with 197 additions and 64 deletions

View File

@@ -167,7 +167,14 @@ public class TemplateInstanceController extends AbstractFileUploadController {
@PostMapping("/create-version")
@Operation(summary = "创建版本")
@PreAuthorize("@ss.hasPermission('bse:template-instance:create-version')")
public CommonResult<TemplateInstanceRespVO> createVersion(@Valid @NotEmpty(message = "模版实例") String id) {
public CommonResult<TemplateInstanceRespVO> createVersion(@Valid @NotEmpty(message = "模版实例id不能为空") String id) {
return success(templateInstanceService.createVersion(id));
}
//通过模版编码查看历史版本
@GetMapping("/list-by-template-cdg")
@Operation(summary = "通过模版编码(cdg)查看历史版本",description = "通过模版编码查看历史版本,已按照发布时间和创建时间降序排序")
public CommonResult<List<TemplateInstanceRespVO>> listByTemplateCode(@RequestParam("cdg") @Valid @NotEmpty(message = "模版编号不能为空") String templateCode) {
return success(templateInstanceService.listByCdg(templateCode));
}
}

View File

@@ -31,5 +31,4 @@ public class TemplateInstanceDataRespVO {
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("创建时间")
private LocalDateTime createTime;
}

View File

@@ -32,4 +32,8 @@ public class TemplateInstanceItemRespVO {
@ExcelProperty("创建时间")
private LocalDate createTime;
@Schema(description = "条款名", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("条款名")
private String itmName;
}

View File

@@ -56,6 +56,11 @@ public class TemplateInstanceRespVO {
@ExcelProperty("创建时间")
private LocalDateTime createTime;
@Schema(description = "发布时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("发布时间")
private LocalDateTime publishTime;
@Schema(description = "使用部门编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "")
private List<String> deptIds;
@Schema(description = "实例字段;这个是实例字段绑定的字段", requiredMode = Schema.RequiredMode.REQUIRED, example = "")

View File

@@ -68,6 +68,12 @@ public class TemplateInstanceDO extends BusinessBaseDO {
* 状态
*/
private String sts;
/**
* 发布时间
*/
private LocalDateTime publishTime;
// /**
// * 公司编号
// */

View File

@@ -77,7 +77,9 @@ public interface TemplateInstanceService {
void setDisableOrEnable(@Valid DisableEnableReqVO reqVO);
TemplateInstanceRespVO createVersion(@Valid @NotEmpty(message = "模版实例") String id);
TemplateInstanceRespVO createVersion(@Valid @NotEmpty(message = "模版实例id不能为空") String id);
Map<String, Object> getVersion(String id);
List<TemplateInstanceRespVO> listByCdg(String cdg);
}

View File

@@ -1,6 +1,9 @@
package com.zt.plat.module.base.service.tmpltp;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.alibaba.fastjson2.util.DateUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.zt.plat.framework.common.pojo.PageResult;
@@ -10,15 +13,13 @@ import com.zt.plat.framework.security.core.util.SecurityFrameworkUtils;
import com.zt.plat.framework.tenant.core.context.CompanyContextHolder;
import com.zt.plat.module.base.controller.admin.templtp.vo.*;
import com.zt.plat.module.base.dal.dataobject.tmpltp.*;
import com.zt.plat.module.base.dal.mysql.tmpltp.DepartmentInstanceRelativityMapper;
import com.zt.plat.module.base.dal.mysql.tmpltp.TemplateInstanceDataMapper;
import com.zt.plat.module.base.dal.mysql.tmpltp.TemplateInstanceItemMapper;
import com.zt.plat.module.base.dal.mysql.tmpltp.TemplateInstanceMapper;
import com.zt.plat.module.base.dal.mysql.tmpltp.*;
import com.zt.plat.module.tmpltp.enums.DeleteStatusEnum;
import com.zt.plat.module.tmpltp.enums.PublishStatusEnum;
import com.zt.plat.module.tmpltp.enums.TmplStsEnum;
import com.zt.plat.module.tmpltp.enums.UpdateStatusEnum;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
@@ -37,6 +38,7 @@ import static com.zt.plat.module.tmpltp.enums.ErrorCodeConstants.*;
*
* @author 后台管理
*/
@Slf4j
@Service
@Validated
public class TemplateInstanceServiceImpl implements TemplateInstanceService {
@@ -58,7 +60,7 @@ public class TemplateInstanceServiceImpl implements TemplateInstanceService {
// 插入
TemplateInstanceDO templateInstance = BeanUtils.toBean(createReqVO, TemplateInstanceDO.class);
templateInstance.setVer("v1.0"); //设置初始版本为v1.0
templateInstance.setCdg(UUID.randomUUID().toString());//设置模板编码
templateInstance.setCdg(getCdg());//设置初始编码
templateInstance.setSts(TmplStsEnum.DRAFT.getCode());//设置初始状态为草稿
int insert = templateInstanceMapper.insert(templateInstance);
if (insert <= 0) {
@@ -75,7 +77,9 @@ public class TemplateInstanceServiceImpl implements TemplateInstanceService {
});
departmentInstanceRelativityMapper.insertBatch(departmentInstanceRelativityDOS);
// 插入使用范围
return BeanUtils.toBean(templateInstance, TemplateInstanceRespVO.class);
TemplateInstanceRespVO templateInstanceRespVO = BeanUtils.toBean(templateInstance, TemplateInstanceRespVO.class);
templateInstanceRespVO.setDeptIds(createReqVO.getDeptIds());
return templateInstanceRespVO;
}
@Override
@@ -141,62 +145,95 @@ public class TemplateInstanceServiceImpl implements TemplateInstanceService {
}
// private String incrementVersion(String currentVersion) {
// // 处理空值或空字符串
// if (currentVersion == null || currentVersion.trim().isEmpty()) {
// return "v1.0";
// }
//
// String version = currentVersion.trim();
// Matcher matcher = VERSION_PATTERN.matcher(version);
//
// if (!matcher.matches()) {
// // 没有找到数字部分,返回默认版本
// return version + "1.0";
// }
//
// String prefix = matcher.group(1); // 前缀部分(如 "v", "version-" 等)
// String numberPart = matcher.group(2); // 数字部分(如 "1.2.3"
// String suffix = matcher.group(3); // 后缀部分
//
// // 分割数字部分
// String[] segments = numberPart.split("\\.");
//
// // 从最后一段开始处理进位
// boolean carry = true; // 初始需要加1
//
// for (int i = segments.length - 1; i >= 0 && carry; i--) {
// try {
// int currentNumber = Integer.parseInt(segments[i]);
// currentNumber++; // 加1
//
// if (currentNumber >= 10) {
// // 需要进位
// segments[i] = "0";
// carry = true; // 继续向前进位
// } else {
// // 不需要进位
// segments[i] = String.valueOf(currentNumber);
// carry = false; // 停止进位
// }
// } catch (NumberFormatException e) {
// // 理论上不会发生,因为正则已经保证了是数字
// segments[i] = "1";
// carry = false;
// }
// }
//
// // 如果最高位也需要进位,在前面添加一段
// if (carry) {
// String[] newSegments = new String[segments.length + 1];
// newSegments[0] = "1";
// System.arraycopy(segments, 0, newSegments, 1, segments.length);
// segments = newSegments;
// }
//
// // 重新组合版本号
// String newNumberPart = String.join(".", segments);
// return prefix + newNumberPart + suffix;
// }
private String incrementVersion(String currentVersion) {
// 处理空值或空字符串
if (currentVersion == null || currentVersion.trim().isEmpty()) {
return "v1.0";
return "v1";
}
String version = currentVersion.trim();
// 正则模式:前缀(可选) + 数字部分 + 后缀(可选)
// 数字部分匹配一个或多个数字
Pattern VERSION_PATTERN = Pattern.compile("^([^0-9]*?)(\\d+)(.*)$");
Matcher matcher = VERSION_PATTERN.matcher(version);
if (!matcher.matches()) {
// 没有找到数字部分,返回默认版本
return version + "1.0";
return version + "1";
}
String prefix = matcher.group(1); // 前缀部分(如 "v", "version-" 等)
String numberPart = matcher.group(2); // 数字部分(如 "1.2.3"
String numberPart = matcher.group(2); // 数字部分(如 "1", "123"
String suffix = matcher.group(3); // 后缀部分
// 分割数字部分
String[] segments = numberPart.split("\\.");
// 从最后一段开始处理进位
boolean carry = true; // 初始需要加1
for (int i = segments.length - 1; i >= 0 && carry; i--) {
try {
int currentNumber = Integer.parseInt(segments[i]);
currentNumber++; // 加1
if (currentNumber >= 10) {
// 需要进位
segments[i] = "0";
carry = true; // 继续向前进位
} else {
// 不需要进位
segments[i] = String.valueOf(currentNumber);
carry = false; // 停止进位
}
} catch (NumberFormatException e) {
// 理论上不会发生,因为正则已经保证了是数字
segments[i] = "1";
carry = false;
}
}
// 如果最高位也需要进位,在前面添加一段
if (carry) {
String[] newSegments = new String[segments.length + 1];
newSegments[0] = "1";
System.arraycopy(segments, 0, newSegments, 1, segments.length);
segments = newSegments;
}
// 将数字部分解析为整数并加1
int number = Integer.parseInt(numberPart);
number++;
// 重新组合版本号
String newNumberPart = String.join(".", segments);
return prefix + newNumberPart + suffix;
return prefix + number + suffix;
} catch (NumberFormatException e) {
// 解析数字格式异常时的 fallback
return prefix + "1" + suffix;
}
}
@@ -267,10 +304,52 @@ public class TemplateInstanceServiceImpl implements TemplateInstanceService {
TemplateInstanceDO newTpInstanceDO = BeanUtils.toBean(templateInstanceDO, TemplateInstanceDO.class);
newTpInstanceDO.setId(null);
newTpInstanceDO.setVer(incrementVersion(templateInstanceDO.getVer()));
newTpInstanceDO.setCreateTime(null);
newTpInstanceDO.setUpdateTime(null);
templateInstanceMapper.insert(newTpInstanceDO);
templateInstanceMapper.update(new LambdaUpdateWrapper<TemplateInstanceDO>()
.set(TemplateInstanceDO::getSts,TmplStsEnum.STOPPED.getCode())
.eq(TemplateInstanceDO::getId, id));
return BeanUtils.toBean(newTpInstanceDO, TemplateInstanceRespVO.class);
List<TemplateInstanceDataDO> templateInstanceDataDOS = new ArrayList<>();
List<TemplateInstanceItemDO> templateInstanceItemDOS =new ArrayList<>();
List<DepartmentInstanceRelativityDO> newDepartmentInstanceRelativityDOS = new ArrayList<>();
//设置部门
List<DepartmentInstanceRelativityDO> departmentInstanceRelativityDOS = departmentInstanceRelativityMapper
.selectList(new LambdaQueryWrapper<DepartmentInstanceRelativityDO>()
.eq(DepartmentInstanceRelativityDO::getTemplateInstanceId, id));
departmentInstanceRelativityDOS.forEach(departmentInstanceRelativityDO -> {
DepartmentInstanceRelativityDO newDepartmentInstanceRelativityDO = new DepartmentInstanceRelativityDO();
newDepartmentInstanceRelativityDO.setTemplateInstanceId(String.valueOf(newTpInstanceDO.getId()));
newDepartmentInstanceRelativityDO.setCompanyDepartmentId(departmentInstanceRelativityDO.getCompanyDepartmentId());
newDepartmentInstanceRelativityDOS.add(newDepartmentInstanceRelativityDO);
});
//设置条款
templateInstanceItemMapper.selectList(new LambdaQueryWrapper<TemplateInstanceItemDO>()
.eq(TemplateInstanceItemDO::getInscId, id)).forEach(templateInstanceItemDO -> {
TemplateInstanceItemDO newTemplateInstanceItemDO = new TemplateInstanceItemDO();
newTemplateInstanceItemDO.setInscId(String.valueOf(newTpInstanceDO.getId()));
newTemplateInstanceItemDO.setItmId(templateInstanceItemDO.getItmId());
newTemplateInstanceItemDO.setVal(templateInstanceItemDO.getVal());
templateInstanceItemDOS.add(newTemplateInstanceItemDO);
});
//设置实例字段
templateInstanceDataMapper.selectList(new LambdaQueryWrapper<TemplateInstanceDataDO>()
.eq(TemplateInstanceDataDO::getInscId, id)).forEach(templateInstanceDataDO -> {
TemplateInstanceDataDO newTemplateInstanceDataDO = new TemplateInstanceDataDO();
newTemplateInstanceDataDO.setInscId(String.valueOf(newTpInstanceDO.getId()));
newTemplateInstanceDataDO.setFldKy(templateInstanceDataDO.getFldKy());
newTemplateInstanceDataDO.setFldVal(templateInstanceDataDO.getFldVal());
templateInstanceDataDOS.add(newTemplateInstanceDataDO);
});
templateInstanceDataMapper.insertBatch(templateInstanceDataDOS);
log.info("==================实例字段插入成功,共插入【{}】条记录==================", templateInstanceDataDOS.size());
templateInstanceItemMapper.insertBatch(templateInstanceItemDOS);
log.info("==================条款插入成功,共插入【{}】条记录==================", templateInstanceItemDOS.size());
departmentInstanceRelativityMapper.insertBatch(newDepartmentInstanceRelativityDOS);
log.info("==================部门实例关系插入成功,共插入【{}】条记录==================", newDepartmentInstanceRelativityDOS.size());
TemplateInstanceRespVO templateInstanceRespVO = BeanUtils.toBean(newTpInstanceDO, TemplateInstanceRespVO.class);
getDetailedInfo(templateInstanceRespVO);
return templateInstanceRespVO;
}
@Override
@@ -279,12 +358,26 @@ public class TemplateInstanceServiceImpl implements TemplateInstanceService {
return Map.of("version", templateInstanceMapper.selectById(id).getVer());
}
@Override
public List<TemplateInstanceRespVO> listByCdg(String cdg) {
List<TemplateInstanceDO> templateInstanceDOS = templateInstanceMapper.selectList(
new LambdaQueryWrapper<TemplateInstanceDO>()
.eq(TemplateInstanceDO::getCdg, cdg)
.eq(TemplateInstanceDO::getCompanyId, CompanyContextHolder.getCompanyId())
.orderByDesc(TemplateInstanceDO::getPublishTime)
.orderByDesc(TemplateInstanceDO::getCreateTime)
);
List<TemplateInstanceRespVO> templateInstanceRespVOS = BeanUtils.toBean(templateInstanceDOS, TemplateInstanceRespVO.class);
templateInstanceRespVOS.forEach(this::getDetailedInfo);
return templateInstanceRespVOS;
}
@Override
public void getDetailedInfo(TemplateInstanceRespVO templateInstanceRespVO) {
templateInstanceRespVO.setDeptIds(getDeptByInstanId(templateInstanceRespVO.getId()));
templateInstanceRespVO.setInstanceItemRespVOS(setInstanceItemRespVOS(templateInstanceRespVO.getId()));
templateInstanceRespVO.setTemplateInstanceDataRespVOS(setTemplateInstanceDataRespVOS(templateInstanceRespVO.getId()));
templateInstanceRespVO.setDeptIds(getDeptByInstanId(templateInstanceRespVO.getId())); // 部门
templateInstanceRespVO.setInstanceItemRespVOS(setInstanceItemRespVOS(templateInstanceRespVO.getId())); // 条款
templateInstanceRespVO.setTemplateInstanceDataRespVOS(setTemplateInstanceDataRespVOS(templateInstanceRespVO.getId())); // 实例字段
}
// 实例条款值
@@ -292,7 +385,21 @@ public class TemplateInstanceServiceImpl implements TemplateInstanceService {
List<TemplateInstanceItemDO> templateInstanceItemDOS = templateInstanceItemMapper.selectList(new LambdaQueryWrapper<TemplateInstanceItemDO>()
.eq(TemplateInstanceItemDO::getInscId, id)
.eq(TemplateInstanceItemDO::getCompanyId, CompanyContextHolder.getCompanyId()));
return BeanUtils.toBean(templateInstanceItemDOS, TemplateInstanceItemRespVO.class);
List<TemplateInstanceItemRespVO> templateInstanceItemRespVOS = BeanUtils.toBean(templateInstanceItemDOS, TemplateInstanceItemRespVO.class);
TmplItmMapper tmplItmMapper = SpringUtil.getBean(TmplItmMapper.class);
List<String> ids = templateInstanceItemRespVOS.stream().map(TemplateInstanceItemRespVO::getItmId).toList();
if (ids.isEmpty()){
return templateInstanceItemRespVOS;
}
List<TmplItmDO> tmplItmDOS = tmplItmMapper.selectByIds(ids);
tmplItmDOS.forEach(tmplItmDO -> {
templateInstanceItemRespVOS.forEach(templateInstanceItemRespVO -> {
if (templateInstanceItemRespVO.getItmId().equals(tmplItmDO.getId())) {
templateInstanceItemRespVO.setItmName(tmplItmDO.getItmName());
}
});
});
return templateInstanceItemRespVOS ;
}
// 实例数据
@@ -339,4 +446,7 @@ public class TemplateInstanceServiceImpl implements TemplateInstanceService {
throw exception(STATUS_OPERATION_FAIL);
}
}
private String getCdg(){
return "TP" + DateUtils.format(new Date(), "yyyyMMddHHmmssSSS") + RandomUtil.randomNumbers(4);
}
}