diff --git a/zt-module-base/zt-module-base-api/src/main/java/com/zt/plat/module/tmpltp/enums/ErrorCodeConstants.java b/zt-module-base/zt-module-base-api/src/main/java/com/zt/plat/module/tmpltp/enums/ErrorCodeConstants.java index 2a2a9cd..cf3cfa1 100644 --- a/zt-module-base/zt-module-base-api/src/main/java/com/zt/plat/module/tmpltp/enums/ErrorCodeConstants.java +++ b/zt-module-base/zt-module-base-api/src/main/java/com/zt/plat/module/tmpltp/enums/ErrorCodeConstants.java @@ -18,7 +18,7 @@ public interface ErrorCodeConstants { ErrorCode DEPARTMENT_INSTANCE_RELATIVITY_NOT_EXISTS = new ErrorCode(1_027_000_511, "部门与实例关联不存在"); ErrorCode ILLEGAL_OPERATION_TYPE = new ErrorCode(1_027_000_511, "非法操作类型"); ErrorCode OPERATION_FAIL= new ErrorCode(1_027_000_512, "操作失败"); - + ErrorCode STATUS_OPERATION_FAIL= new ErrorCode(1_027_000_513, "当前状态不支持此操作"); //Illegal operation type } diff --git a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/templtp/TemplateInstanceDataController.java b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/templtp/TemplateInstanceDataController.java index 2ab3ff6..b4de6de 100644 --- a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/templtp/TemplateInstanceDataController.java +++ b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/templtp/TemplateInstanceDataController.java @@ -52,6 +52,14 @@ public class TemplateInstanceDataController implements BusinessControllerMarker return success(templateInstanceDataService.createTemplateInstanceData(createReqVO)); } + @PostMapping("/create-batch") + @Operation(summary = "批量创建实例字段值") + @PreAuthorize("@ss.hasPermission('base:template-instance-data:create')") + public CommonResult> createBatchTemplateInstanceData(@Valid @RequestBody List createReqVOS) { + return success(templateInstanceDataService.createBatchTemplateInstanceData(createReqVOS)); + } + + @PutMapping("/update") @Operation(summary = "更新实例字段值") @PreAuthorize("@ss.hasPermission('base:template-instance-data:update')") diff --git a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/templtp/TemplateInstanceItemController.java b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/templtp/TemplateInstanceItemController.java index a45b65c..93e2841 100644 --- a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/templtp/TemplateInstanceItemController.java +++ b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/templtp/TemplateInstanceItemController.java @@ -51,6 +51,13 @@ public class TemplateInstanceItemController implements BusinessControllerMarker return success(templateInstanceItemService.createTemplateInstanceItem(createReqVO)); } + @PostMapping("/create-batch") + @Operation(summary = "批量创建实例条款值") + @PreAuthorize("@ss.hasPermission('base:template-instance-item:create')") + public CommonResult> createBatchTemplateInstanceItem(@Valid @RequestBody List createReqVOS) { + return success(templateInstanceItemService.createBatchTemplateInstanceItem(createReqVOS)); + } + @PutMapping("/update") @Operation(summary = "更新实例条款值") @PreAuthorize("@ss.hasPermission('base:template-instance-item:update')") diff --git a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/templtp/TmplTpFldController.java b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/templtp/TmplTpFldController.java index 447843c..5f107b6 100644 --- a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/templtp/TmplTpFldController.java +++ b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/templtp/TmplTpFldController.java @@ -59,4 +59,10 @@ public class TmplTpFldController { PageResult pageResult = tmplTpFldService.tmplTpFldPage(pageReqVO); return success(BeanUtils.toBean(pageResult, TmplFldRespVO.class)); } + @GetMapping("/getByClass") + @Operation(summary = "获得类固定模板字段列表") + @PreAuthorize("@ss.hasPermission('bse:tmpl-tp-fld:list')") + public CommonResult>> getTmplTpListByClass(String clazz) { + return success(tmplTpFldService.getTmplTpListByClass(clazz)); + } } diff --git a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/templtp/vo/TemplateInstanceSaveReqVO.java b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/templtp/vo/TemplateInstanceSaveReqVO.java index b396918..76475ee 100644 --- a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/templtp/vo/TemplateInstanceSaveReqVO.java +++ b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/templtp/vo/TemplateInstanceSaveReqVO.java @@ -39,7 +39,7 @@ public class TemplateInstanceSaveReqVO { private String fileTp; @Schema(description = "版本号;如v1.0", requiredMode = Schema.RequiredMode.REQUIRED) - @NotEmpty(message = "版本号;如v1.0不能为空") + //@NotEmpty(message = "版本号;如v1.0不能为空") private String ver; @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") @@ -49,6 +49,6 @@ public class TemplateInstanceSaveReqVO { @Schema(description = "使用部门编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") @NotEmpty(message = "使用部门编号不能为空") - private List deptIds; + private List deptIds; } diff --git a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/templtp/vo/TmplTpFldSaveReqVO.java b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/templtp/vo/TmplTpFldSaveReqVO.java index 430557d..2bbd634 100644 --- a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/templtp/vo/TmplTpFldSaveReqVO.java +++ b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/templtp/vo/TmplTpFldSaveReqVO.java @@ -16,7 +16,7 @@ public class TmplTpFldSaveReqVO { @Schema(description = "字段数据类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "string") private String datTp; @Schema(description = "字段描述", requiredMode = Schema.RequiredMode.REQUIRED, example = "代码") - private JSONObject fldDoc; + private String fldDoc; @Schema(description = "字段备注", requiredMode = Schema.RequiredMode.REQUIRED, example = "代码") private String rmk; @Schema(description = "是否必填", requiredMode = Schema.RequiredMode.REQUIRED, example = "Y or N") diff --git a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/dal/dataobject/tmpltp/DepartmentInstanceRelativityDO.java b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/dal/dataobject/tmpltp/DepartmentInstanceRelativityDO.java index 4ae3da9..e2864e2 100644 --- a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/dal/dataobject/tmpltp/DepartmentInstanceRelativityDO.java +++ b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/dal/dataobject/tmpltp/DepartmentInstanceRelativityDO.java @@ -27,7 +27,7 @@ public class DepartmentInstanceRelativityDO extends BusinessBaseDO { /** * 主键 */ - @TableId(type = IdType.INPUT) + @TableId(type = IdType.ASSIGN_ID) private String id; /** * 部门主键 diff --git a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/dal/dataobject/tmpltp/TemplateInstanceItemDO.java b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/dal/dataobject/tmpltp/TemplateInstanceItemDO.java index 6663499..b76d4a9 100644 --- a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/dal/dataobject/tmpltp/TemplateInstanceItemDO.java +++ b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/dal/dataobject/tmpltp/TemplateInstanceItemDO.java @@ -27,7 +27,7 @@ public class TemplateInstanceItemDO extends BusinessBaseDO { /** * 主键 */ - @TableId(type = IdType.INPUT) + @TableId(type = IdType.ASSIGN_ID) private String id; /** * 关联实例主键 diff --git a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/dal/dataobject/tmpltp/TmplTpFldDO.java b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/dal/dataobject/tmpltp/TmplTpFldDO.java index 32ca069..3ca4b5f 100644 --- a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/dal/dataobject/tmpltp/TmplTpFldDO.java +++ b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/dal/dataobject/tmpltp/TmplTpFldDO.java @@ -12,8 +12,8 @@ import java.time.LocalDateTime; * * @author 后台管理 */ -@TableName("BIZ_TMPL_TP_FLD") -@KeySequence("BIZ_TMPL_TP_FLD_SEQ") +@TableName("BSE_TMPL_TP_FLD") +@KeySequence("BSE_TMPL_TP_FLD_SEQ") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) @@ -68,4 +68,11 @@ public class TmplTpFldDO extends BusinessBaseDO { // 继承业务基类,自动 */ @TableField("IS_MUST") private String isMust; + + /** + * 是否必填(对应表中 IS_MUST 字段,VARCHAR2(10) 类型,非空) + * 建议值:Y(是)、N(否),需在业务层做枚举校验 + */ + @TableField("ORGN_TP") + private String orgnTp; } diff --git a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/dal/mysql/tmpltp/TemplateInstanceDataMapper.java b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/dal/mysql/tmpltp/TemplateInstanceDataMapper.java index 62817cf..2c9e71b 100644 --- a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/dal/mysql/tmpltp/TemplateInstanceDataMapper.java +++ b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/dal/mysql/tmpltp/TemplateInstanceDataMapper.java @@ -9,6 +9,7 @@ import com.zt.plat.framework.mybatis.core.mapper.BaseMapperX; import com.zt.plat.module.base.controller.admin.templtp.vo.TemplateInstanceDataPageReqVO; import com.zt.plat.module.base.dal.dataobject.tmpltp.TemplateInstanceDataDO; import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; /** @@ -27,5 +28,6 @@ public interface TemplateInstanceDataMapper extends BaseMapperX valIds); + List createBatchTemplateInstanceData(List createReqVOS); + } diff --git a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/service/tmpltp/TemplateInstanceDataServiceImpl.java b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/service/tmpltp/TemplateInstanceDataServiceImpl.java index c19ae9d..6d445e4 100644 --- a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/service/tmpltp/TemplateInstanceDataServiceImpl.java +++ b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/service/tmpltp/TemplateInstanceDataServiceImpl.java @@ -103,7 +103,7 @@ public class TemplateInstanceDataServiceImpl implements TemplateInstanceDataServ if (CollUtil.isEmpty(pageReqVOS)) { throw exception(PARAMS_IS_NULL_OR_ERR); } - return templateInstanceDataMapper.insertBatch(pageReqVOS); + return templateInstanceDataMapper.updateBatch(pageReqVOS); } @Override @@ -119,5 +119,15 @@ public class TemplateInstanceDataServiceImpl implements TemplateInstanceDataServ return true; } + @Override + public List createBatchTemplateInstanceData(List createReqVOS) { + if (CollUtil.isEmpty(createReqVOS)) { + throw exception(PARAMS_IS_NULL_OR_ERR); + } + List templateInstanceDataDOList = BeanUtils.toBean(createReqVOS, TemplateInstanceDataDO.class); + templateInstanceDataMapper.insertBatch(templateInstanceDataDOList); + return BeanUtils.toBean(templateInstanceDataDOList, TemplateInstanceDataRespVO.class); + } + } diff --git a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/service/tmpltp/TemplateInstanceItemService.java b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/service/tmpltp/TemplateInstanceItemService.java index ca490fa..190af06 100644 --- a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/service/tmpltp/TemplateInstanceItemService.java +++ b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/service/tmpltp/TemplateInstanceItemService.java @@ -61,6 +61,7 @@ public interface TemplateInstanceItemService { * @param pageReqVO 分页查询 * @return 实例条款值分页 */ - PageResult getTemplateInstanceItemPage(TemplateInstanceItemPageReqVO pageReqVO); + PageResult getTemplateInstanceItemPage(@Valid TemplateInstanceItemPageReqVO pageReqVO); + List createBatchTemplateInstanceItem(@Valid List createReqVOS); } diff --git a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/service/tmpltp/TemplateInstanceItemServiceImpl.java b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/service/tmpltp/TemplateInstanceItemServiceImpl.java index 795f822..8d9cc94 100644 --- a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/service/tmpltp/TemplateInstanceItemServiceImpl.java +++ b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/service/tmpltp/TemplateInstanceItemServiceImpl.java @@ -13,6 +13,7 @@ import java.util.*; import com.zt.plat.framework.common.pojo.PageResult; import com.zt.plat.framework.common.util.object.BeanUtils; import static com.zt.plat.framework.common.exception.util.ServiceExceptionUtil.exception; +import static com.zt.plat.module.tmpltp.enums.ErrorCodeConstants.PARAMS_IS_NULL_OR_ERR; import static com.zt.plat.module.tmpltp.enums.ErrorCodeConstants.TEMPLATE_INSTANCE_ITEM_NOT_EXISTS; /** @@ -84,4 +85,14 @@ public class TemplateInstanceItemServiceImpl implements TemplateInstanceItemServ return templateInstanceItemMapper.selectPage(pageReqVO); } + @Override + public List createBatchTemplateInstanceItem(List createReqVOS) { + if (CollUtil.isEmpty(createReqVOS)) { + throw exception(PARAMS_IS_NULL_OR_ERR); + } + List templateInstanceItemDOList = BeanUtils.toBean(createReqVOS, TemplateInstanceItemDO.class); + templateInstanceItemMapper.insertBatch(templateInstanceItemDOList); + return BeanUtils.toBean(templateInstanceItemDOList, TemplateInstanceItemRespVO.class); + } + } diff --git a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/service/tmpltp/TemplateInstanceServiceImpl.java b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/service/tmpltp/TemplateInstanceServiceImpl.java index e2e1ad1..7960a25 100644 --- a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/service/tmpltp/TemplateInstanceServiceImpl.java +++ b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/service/tmpltp/TemplateInstanceServiceImpl.java @@ -9,15 +9,21 @@ import com.zt.plat.module.base.controller.admin.templtp.vo.TemplateInstanceSaveR import com.zt.plat.module.base.dal.dataobject.tmpltp.DepartmentInstanceRelativityDO; import com.zt.plat.module.base.dal.dataobject.tmpltp.TemplateInstanceDO; 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 jakarta.annotation.Resource; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; import java.util.ArrayList; import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import static com.zt.plat.framework.common.exception.util.ServiceExceptionUtil.exception; +import static com.zt.plat.module.tmpltp.enums.ErrorCodeConstants.STATUS_OPERATION_FAIL; import static com.zt.plat.module.tmpltp.enums.ErrorCodeConstants.TEMPLATE_INSTANCE_NOT_EXISTS; @@ -34,8 +40,14 @@ public class TemplateInstanceServiceImpl implements TemplateInstanceService { private TemplateInstanceMapper templateInstanceMapper; @Resource private DepartmentInstanceRelativityMapper departmentInstanceRelativityMapper; + @Resource + private TemplateInstanceDataMapper templateInstanceDataMapper; + @Resource + private TemplateInstanceItemMapper templateInstanceItemMapper; + private static final Pattern VERSION_PATTERN = Pattern.compile("^(.*?)([0-9]+(?:\\.[0-9]+)*)(.*)$"); @Override + @Transactional public TemplateInstanceRespVO createTemplateInstance(TemplateInstanceSaveReqVO createReqVO) { // 插入 TemplateInstanceDO templateInstance = BeanUtils.toBean(createReqVO, TemplateInstanceDO.class); @@ -46,7 +58,7 @@ public class TemplateInstanceServiceImpl implements TemplateInstanceService { createReqVO.getDeptIds().forEach(deptId ->{ DepartmentInstanceRelativityDO departmentInstanceRelativityDO = new DepartmentInstanceRelativityDO(); departmentInstanceRelativityDO.setTemplateInstanceId(String.valueOf(templateInstance.getId())); - departmentInstanceRelativityDO.setCompanyId(deptId); + departmentInstanceRelativityDO.setCompanyDepartmentId(deptId); departmentInstanceRelativityDOS.add(departmentInstanceRelativityDO); }); departmentInstanceRelativityMapper.insertBatch(departmentInstanceRelativityDOS); @@ -58,20 +70,33 @@ public class TemplateInstanceServiceImpl implements TemplateInstanceService { public void updateTemplateInstance(TemplateInstanceSaveReqVO updateReqVO) { // 校验存在 validateTemplateInstanceExists(updateReqVO.getId()); -// TemplateInstanceDO templateInstanceDO = templateInstanceMapper.selectById(updateReqVO.getId()); + // TemplateInstanceDO templateInstanceDO = templateInstanceMapper.selectById(updateReqVO.getId()); // //获取保存旧文件内容防止被更新 // String originalContent = templateInstanceDO.getOriginalContent(); // 更新 + TemplateInstanceDO templateInstanceDO = templateInstanceMapper.selectById(updateReqVO.getId()); + String sts = templateInstanceDO.getSts(); + if (!sts.equals("DRF")) { + throw exception(STATUS_OPERATION_FAIL); + } + TemplateInstanceDO updateObj = BeanUtils.toBean(updateReqVO, TemplateInstanceDO.class); updateObj.setOrigCntt(null); //重新赋值,防止原始文件被更改 + updateObj.setVer(incrementVersion(templateInstanceDO.getVer())); templateInstanceMapper.updateById(updateObj); } @Override + @Transactional public void deleteTemplateInstance(Long id) { // 校验存在 validateTemplateInstanceExists(id); // 删除 + //删除对应的字段和条款关系 + //1、删除合同的与字段的关系 + templateInstanceDataMapper.deleteByTemplateInstanceId(id); + //2、删除条款与和他的关系 + templateInstanceDataMapper.deleteByTemplateInstanceId(id); templateInstanceMapper.deleteById(id); } @@ -106,4 +131,62 @@ public class TemplateInstanceServiceImpl implements TemplateInstanceService { return templateInstanceMapper.selectPage(pageReqVO); } + 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; + } + } diff --git a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/service/tmpltp/TmplTpFldService.java b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/service/tmpltp/TmplTpFldService.java index 9372a81..617b7d9 100644 --- a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/service/tmpltp/TmplTpFldService.java +++ b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/service/tmpltp/TmplTpFldService.java @@ -10,11 +10,13 @@ import com.baomidou.mybatisplus.extension.service.IService; import jakarta.validation.Valid; import java.util.List; +import java.util.Map; public interface TmplTpFldService extends IService { TmplFldRespVO createTmplFld(@Valid TmplTpFldSaveReqVO tmplTpFldSaveReqVO); void updateTmplFld(@Valid TmplTpFldSaveReqVO tmplTpFldSaveReqVO); - PageResult tmplTpFldPage(@Valid TmplFldPageReqVO pageReqVO); + PageResult tmplTpFldPage(TmplFldPageReqVO pageReqVO); void deleteTmplTpByIds(List< Long> ids); + List>getTmplTpListByClass(String clazz); } diff --git a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/service/tmpltp/TmplTpFldServiceImpl.java b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/service/tmpltp/TmplTpFldServiceImpl.java index 596a312..4deff16 100644 --- a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/service/tmpltp/TmplTpFldServiceImpl.java +++ b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/service/tmpltp/TmplTpFldServiceImpl.java @@ -13,14 +13,19 @@ import com.zt.plat.module.base.dal.mysql.tmpltp.TmplTpFldMapper; import com.alibaba.fastjson2.JSONObject; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.zt.plat.module.base.util.ClassInfoScanner; +import io.swagger.v3.oas.annotations.media.Schema; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import static com.zt.plat.framework.common.exception.util.ServiceExceptionUtil.exception; -import static com.zt.plat.module.tmpltp.enums.ErrorCodeConstants.TMPL_FLD_CODE_EXISTS; -import static com.zt.plat.module.tmpltp.enums.ErrorCodeConstants.TMPL_FLD_NOT_EXISTS; +import static com.zt.plat.module.tmpltp.enums.ErrorCodeConstants.*; @Service @@ -73,4 +78,9 @@ public class TmplTpFldServiceImpl extends ServiceImpl> getTmplTpListByClass(String clazz) { + return ClassInfoScanner.getClassFieldInfo(clazz); + } } diff --git a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/util/ClassInfoScanner.java b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/util/ClassInfoScanner.java new file mode 100644 index 0000000..fee2dd1 --- /dev/null +++ b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/util/ClassInfoScanner.java @@ -0,0 +1,357 @@ +package com.zt.plat.module.base.util; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.extern.slf4j.Slf4j; +import org.springframework.util.ClassUtils; +import org.springframework.util.ResourceUtils; + +import java.io.File; +import java.io.FileFilter; +import java.io.IOException; +import java.lang.reflect.Field; +import java.net.JarURLConnection; +import java.net.URL; +import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; +import java.util.*; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; + +/** + * 类信息扫描工具类,用于通过简单类名获取类字段及Schema注解信息 + * 增强版:支持通配符包路径扫描 + */ +@Slf4j +public class ClassInfoScanner { + + // 缓存简单类名到Class的映射,提高性能 + private static final Map> CLASS_CACHE = new HashMap<>(); + // 已初始化标识 + private static boolean initialized = false; + + /** + * 初始化扫描指定包路径下的所有类 + * @param basePackages 基础包路径,支持逗号分隔多个包,支持*和**通配符 + */ + public static synchronized void init(String basePackages) { + if (initialized) { + return; + } + + if (basePackages == null || basePackages.trim().isEmpty()) { + throw new IllegalArgumentException("基础包路径不能为空"); + } + + String[] packages = basePackages.split("[,;\\s]+"); + for (String pkg : packages) { + String trimmedPkg = pkg.trim(); + if (trimmedPkg.contains("**") || trimmedPkg.contains("*")) { + // 处理通配符包路径 + scanPackageWithWildcard(trimmedPkg); + log.info("已扫描通配符包路径:{}", trimmedPkg); + } else { + // 处理普通包路径 + scanPackage(trimmedPkg); + log.info("已扫描普通包路径:{}", trimmedPkg); + } + } + + initialized = true; + } + + /** + * 处理包含通配符的包路径扫描 + */ + private static void scanPackageWithWildcard(String wildcardPackage) { + try { + // 提取基础包路径(通配符之前的部分) + String basePackage = extractBasePackage(wildcardPackage); + String pattern = wildcardPackage.substring(basePackage.length()); + + // 扫描基础包路径 + String packageDirName = basePackage.replace('.', '/'); + Enumeration urls = Thread.currentThread().getContextClassLoader().getResources(packageDirName); + + while (urls.hasMoreElements()) { + URL url = urls.nextElement(); + String protocol = url.getProtocol(); + + if ("file".equals(protocol)) { + String filePath = URLDecoder.decode(url.getFile(), StandardCharsets.UTF_8); + findClassesWithPattern(basePackage, filePath, pattern); + } else if ("jar".equals(protocol)) { + JarFile jar = ((JarURLConnection) url.openConnection()).getJarFile(); + Enumeration entries = jar.entries(); + processJarEntriesWithPattern(basePackage, entries, pattern); + } + } + } catch (IOException e) { + throw new RuntimeException("扫描通配符包时发生错误: " + wildcardPackage, e); + } + } + + /** + * 提取基础包路径(通配符之前的部分) + */ + private static String extractBasePackage(String wildcardPackage) { + int wildcardIndex = wildcardPackage.indexOf('*'); + if (wildcardIndex == -1) { + return wildcardPackage; + } + + String beforeWildcard = wildcardPackage.substring(0, wildcardIndex); + int lastDotIndex = beforeWildcard.lastIndexOf('.'); + if (lastDotIndex == -1) { + return ""; + } + + return beforeWildcard.substring(0, lastDotIndex); + } + + /** + * 在文件系统中按模式查找类 + */ + private static void findClassesWithPattern(String basePackage, String basePath, String pattern) { + File baseDir = new File(basePath); + if (!baseDir.exists() || !baseDir.isDirectory()) { + return; + } + + findClassesRecursive(baseDir, basePackage, pattern); + } + + /** + * 递归查找匹配模式的类 + */ + private static void findClassesRecursive(File dir, String packageName, String pattern) { + File[] files = dir.listFiles(); + if (files == null) { + return; + } + + for (File file : files) { + if (file.isDirectory()) { + // 递归处理子目录 + String subPackageName = packageName + "." + file.getName(); + findClassesRecursive(file, subPackageName, pattern); + } else if (file.getName().endsWith(".class")) { + // 检查是否匹配模式 + String className = file.getName().substring(0, file.getName().length() - 6); + String fullClassName = packageName + "." + className; + + if (matchesPattern(fullClassName, pattern)) { + try { + Class clazz = Class.forName(fullClassName); + CLASS_CACHE.put(clazz.getSimpleName(), clazz); + } catch (ClassNotFoundException e) { + // 忽略无法加载的类 + } + } + } + } + } + + /** + * 在JAR包中按模式查找类 + */ + private static void processJarEntriesWithPattern(String basePackage, Enumeration entries, String pattern) { + String basePackagePath = basePackage.replace('.', '/'); + + while (entries.hasMoreElements()) { + JarEntry entry = entries.nextElement(); + String entryName = entry.getName(); + + if (entryName.charAt(0) == '/') { + entryName = entryName.substring(1); + } + + if (entryName.startsWith(basePackagePath) && !entry.isDirectory() && entryName.endsWith(".class")) { + String className = entryName.substring(0, entryName.length() - 6).replace('/', '.'); + + if (matchesPattern(className, pattern)) { + try { + Class clazz = Class.forName(className); + CLASS_CACHE.put(clazz.getSimpleName(), clazz); + } catch (ClassNotFoundException e) { + // 忽略无法加载的类 + } + } + } + } + } + + /** + * 检查类名是否匹配通配符模式 + */ + private static boolean matchesPattern(String className, String pattern) { + if (pattern.isEmpty()) { + return true; + } + + // 简单的通配符匹配实现 + if (pattern.startsWith(".")) { + pattern = pattern.substring(1); + } + + // 处理 **.vo 模式 + if (pattern.equals("**.vo")) { + return className.endsWith(".vo") || + (className.contains(".") && className.substring(className.lastIndexOf('.') + 1).toLowerCase().contains("vo")); + } + + // 处理其他模式 + String[] patternParts = pattern.split("\\*\\*"); + if (patternParts.length == 2) { + String prefix = patternParts[0]; + String suffix = patternParts[1]; + return className.contains(prefix) && className.endsWith(suffix); + } + + return className.contains(pattern.replace("*", "")); + } + + /** + * 通过简单类名获取类的字段及Schema注解信息 + * @param simpleClassName 简单类名 + * @return 包含字段名和label的列表 + */ + public static List> getClassFieldInfo(String simpleClassName) { + if (!initialized) { + throw new IllegalStateException("工具类未初始化,请先调用init方法"); + } + + if (simpleClassName == null || !simpleClassName.endsWith("VO")) { + throw new IllegalArgumentException("参数为空或格式错误"); + } + + Class targetClass = CLASS_CACHE.get(simpleClassName); + if (targetClass == null) { + throw new RuntimeException("未找到类: " + simpleClassName); + } + + List> resultList = new ArrayList<>(); + Field[] fields = targetClass.getDeclaredFields(); + + for (Field field : fields) { + if (field.isAnnotationPresent(Schema.class)) { + Schema schema = field.getAnnotation(Schema.class); + Map fieldMap = new HashMap<>(); + fieldMap.put("fieldName", field.getName()); + fieldMap.put("label", schema.description().isEmpty() ?null:schema.description().split(";")[0]); + fieldMap.put("required", schema.requiredMode() == Schema.RequiredMode.REQUIRED); + fieldMap.put("example", schema.example()); + fieldMap.put("orgnType", "class"); + resultList.add(fieldMap); + } + } + + return resultList; + } + + /** + * 扫描指定包下的所有类(原有方法保持不变) + */ + private static void scanPackage(String basePackage) { + try { + String packageDirName = basePackage.replace('.', '/'); + Enumeration urls = Thread.currentThread().getContextClassLoader().getResources(packageDirName); + + while (urls.hasMoreElements()) { + URL url = urls.nextElement(); + String protocol = url.getProtocol(); + + if ("file".equals(protocol)) { + String filePath = URLDecoder.decode(url.getFile(), StandardCharsets.UTF_8.name()); + findAndAddClassesInPackageByFile(basePackage, filePath); + } else if ("jar".equals(protocol)) { + JarFile jar = ((JarURLConnection) url.openConnection()).getJarFile(); + Enumeration entries = jar.entries(); + processJarEntries(basePackage, entries); + } + } + } catch (IOException e) { + throw new RuntimeException("扫描包时发生错误: " + basePackage, e); + } + } + + /** + * 处理文件系统中的类文件 + */ + private static void findAndAddClassesInPackageByFile(String packageName, String packagePath) { + File dir = new File(packagePath); + if (!dir.exists() || !dir.isDirectory()) { + return; + } + + File[] dirFiles = dir.listFiles(file -> + (file.isDirectory()) || (file.getName().endsWith(".class")) + ); + + if (dirFiles == null) { + return; + } + + for (File file : dirFiles) { + if (file.isDirectory()) { + findAndAddClassesInPackageByFile(packageName + "." + file.getName(), + file.getAbsolutePath()); + } else { + String className = file.getName().substring(0, file.getName().length() - 6); + try { + Class clazz = Class.forName(packageName + '.' + className); + CLASS_CACHE.put(clazz.getSimpleName(), clazz); + } catch (ClassNotFoundException e) { + // 忽略无法加载的类 + } + } + } + } + + /** + * 处理JAR包中的类 + */ + private static void processJarEntries(String basePackage, Enumeration entries) { + String packageDirName = basePackage.replace('.', '/'); + + while (entries.hasMoreElements()) { + JarEntry entry = entries.nextElement(); + String name = entry.getName(); + + if (name.charAt(0) == '/') { + name = name.substring(1); + } + + if (name.startsWith(packageDirName) && !entry.isDirectory() && name.endsWith(".class")) { + String className = name.substring(0, name.length() - 6).replace('/', '.'); + try { + Class clazz = Class.forName(className); + CLASS_CACHE.put(clazz.getSimpleName(), clazz); + } catch (ClassNotFoundException e) { + // 忽略无法加载的类 + } + } + } + } + + /** + * 清除缓存,重新初始化时使用 + */ + public static synchronized void clearCache() { + CLASS_CACHE.clear(); + initialized = false; + } + + /** + * 获取缓存的类数量(用于调试) + */ + public static int getCachedClassCount() { + return CLASS_CACHE.size(); + } + + /** + * 获取所有缓存的类名(用于调试) + */ + public static Set getCachedClassNames() { + return CLASS_CACHE.keySet(); + } +} diff --git a/zt-module-base/zt-module-base-server/src/main/resources/mapper/tmpltp/TemplateInstanceDataMapper.xml b/zt-module-base/zt-module-base-server/src/main/resources/mapper/tmpltp/TemplateInstanceDataMapper.xml index c8afd1c..b496dad 100644 --- a/zt-module-base/zt-module-base-server/src/main/resources/mapper/tmpltp/TemplateInstanceDataMapper.xml +++ b/zt-module-base/zt-module-base-server/src/main/resources/mapper/tmpltp/TemplateInstanceDataMapper.xml @@ -9,4 +9,8 @@ 文档可见:https://www.iocoder.cn/MyBatis/x-plugins/ --> + + update BSE_TMPL_INSC_DAT set deleted = 1 + WHERE INSC_ID = #{templateInstanceId} + diff --git a/zt-module-base/zt-module-base-server/src/main/resources/mapper/tmpltp/TemplateInstanceItemMapper.xml b/zt-module-base/zt-module-base-server/src/main/resources/mapper/tmpltp/TemplateInstanceItemMapper.xml index b683367..300cdcd 100644 --- a/zt-module-base/zt-module-base-server/src/main/resources/mapper/tmpltp/TemplateInstanceItemMapper.xml +++ b/zt-module-base/zt-module-base-server/src/main/resources/mapper/tmpltp/TemplateInstanceItemMapper.xml @@ -9,4 +9,12 @@ 文档可见:https://www.iocoder.cn/MyBatis/x-plugins/ --> + + + + + + update BSE_TMPL_INSC_ITM set deleted = 1 + WHERE INSC_ID = #{templateInstanceId} +