From 66845dcfabebd58f2846af93c752f89c41781545 Mon Sep 17 00:00:00 2001
From: hewencai <2357300448@qq.com>
Date: Wed, 29 Oct 2025 10:57:45 +0800
Subject: [PATCH] =?UTF-8?q?feat:=E6=96=B0=E5=A2=9E=E6=96=87=E6=A1=A3?=
=?UTF-8?q?=E6=A8=A1=E6=9D=BF=E7=AE=A1=E7=90=86=E5=8A=9F=E8=83=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.gitignore | 2 +
.../module/base/enums/ErrorCodeConstants.java | 16 ++
zt-module-base/zt-module-base-server/pom.xml | 7 +
.../DocTemplateCategoryController.java | 89 ++++++++++
.../doctemplate/DocTemplateController.java | 82 +++++++++
.../DocTemplateInstanceController.java | 107 ++++++++++++
.../doctemplate/DocTemplateTagController.java | 82 +++++++++
.../vo/DocTemplateCategoryPageReqVO.java | 27 +++
.../vo/DocTemplateCategoryRespVO.java | 43 +++++
.../vo/DocTemplateCategorySaveReqVO.java | 37 ++++
.../vo/DocTemplateInstancePageReqVO.java | 36 ++++
.../vo/DocTemplateInstanceRespVO.java | 51 ++++++
.../vo/DocTemplateInstanceSaveReqVO.java | 49 ++++++
.../doctemplate/vo/DocTemplatePageReqVO.java | 39 +++++
.../doctemplate/vo/DocTemplateRespVO.java | 57 +++++++
.../doctemplate/vo/DocTemplateSaveReqVO.java | 53 ++++++
.../vo/DocTemplateTagPageReqVO.java | 27 +++
.../doctemplate/vo/DocTemplateTagRespVO.java | 63 +++++++
.../vo/DocTemplateTagSaveReqVO.java | 44 +++++
.../DocTemplateCategoryConvert.java | 30 ++++
.../doctemplate/DocTemplateConvert.java | 30 ++++
.../DocTemplateInstanceConvert.java | 30 ++++
.../doctemplate/DocTemplateTagConvert.java | 30 ++++
.../DocTemplateCategoryMapper.java | 28 ++++
.../DocTemplateInstanceMapper.java | 28 ++++
.../dao/doctemplate/DocTemplateMapper.java | 29 ++++
.../dao/doctemplate/DocTemplateTagMapper.java | 28 ++++
.../doctemplate/DocTemplateCategoryDO.java | 63 +++++++
.../dataobject/doctemplate/DocTemplateDO.java | 99 +++++++++++
.../doctemplate/DocTemplateInstanceDO.java | 87 ++++++++++
.../doctemplate/DocTemplateTagDO.java | 81 +++++++++
.../DocTemplateCategoryService.java | 78 +++++++++
.../DocTemplateCategoryServiceImpl.java | 158 ++++++++++++++++++
.../DocTemplateInstanceService.java | 63 +++++++
.../DocTemplateInstanceServiceImpl.java | 136 +++++++++++++++
.../doctemplate/DocTemplateRenderService.java | 31 ++++
.../DocTemplateRenderServiceImpl.java | 144 ++++++++++++++++
.../doctemplate/DocTemplateService.java | 63 +++++++
.../doctemplate/DocTemplateServiceImpl.java | 115 +++++++++++++
.../doctemplate/DocTemplateTagService.java | 63 +++++++
.../DocTemplateTagServiceImpl.java | 115 +++++++++++++
41 files changed, 2440 insertions(+)
create mode 100644 zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/doctemplate/DocTemplateCategoryController.java
create mode 100644 zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/doctemplate/DocTemplateController.java
create mode 100644 zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/doctemplate/DocTemplateInstanceController.java
create mode 100644 zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/doctemplate/DocTemplateTagController.java
create mode 100644 zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/doctemplate/vo/DocTemplateCategoryPageReqVO.java
create mode 100644 zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/doctemplate/vo/DocTemplateCategoryRespVO.java
create mode 100644 zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/doctemplate/vo/DocTemplateCategorySaveReqVO.java
create mode 100644 zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/doctemplate/vo/DocTemplateInstancePageReqVO.java
create mode 100644 zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/doctemplate/vo/DocTemplateInstanceRespVO.java
create mode 100644 zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/doctemplate/vo/DocTemplateInstanceSaveReqVO.java
create mode 100644 zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/doctemplate/vo/DocTemplatePageReqVO.java
create mode 100644 zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/doctemplate/vo/DocTemplateRespVO.java
create mode 100644 zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/doctemplate/vo/DocTemplateSaveReqVO.java
create mode 100644 zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/doctemplate/vo/DocTemplateTagPageReqVO.java
create mode 100644 zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/doctemplate/vo/DocTemplateTagRespVO.java
create mode 100644 zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/doctemplate/vo/DocTemplateTagSaveReqVO.java
create mode 100644 zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/convert/doctemplate/DocTemplateCategoryConvert.java
create mode 100644 zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/convert/doctemplate/DocTemplateConvert.java
create mode 100644 zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/convert/doctemplate/DocTemplateInstanceConvert.java
create mode 100644 zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/convert/doctemplate/DocTemplateTagConvert.java
create mode 100644 zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/dal/dao/doctemplate/DocTemplateCategoryMapper.java
create mode 100644 zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/dal/dao/doctemplate/DocTemplateInstanceMapper.java
create mode 100644 zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/dal/dao/doctemplate/DocTemplateMapper.java
create mode 100644 zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/dal/dao/doctemplate/DocTemplateTagMapper.java
create mode 100644 zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/dal/dataobject/doctemplate/DocTemplateCategoryDO.java
create mode 100644 zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/dal/dataobject/doctemplate/DocTemplateDO.java
create mode 100644 zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/dal/dataobject/doctemplate/DocTemplateInstanceDO.java
create mode 100644 zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/dal/dataobject/doctemplate/DocTemplateTagDO.java
create mode 100644 zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/service/doctemplate/DocTemplateCategoryService.java
create mode 100644 zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/service/doctemplate/DocTemplateCategoryServiceImpl.java
create mode 100644 zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/service/doctemplate/DocTemplateInstanceService.java
create mode 100644 zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/service/doctemplate/DocTemplateInstanceServiceImpl.java
create mode 100644 zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/service/doctemplate/DocTemplateRenderService.java
create mode 100644 zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/service/doctemplate/DocTemplateRenderServiceImpl.java
create mode 100644 zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/service/doctemplate/DocTemplateService.java
create mode 100644 zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/service/doctemplate/DocTemplateServiceImpl.java
create mode 100644 zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/service/doctemplate/DocTemplateTagService.java
create mode 100644 zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/service/doctemplate/DocTemplateTagServiceImpl.java
diff --git a/.gitignore b/.gitignore
index e55eb64..c652c40 100644
--- a/.gitignore
+++ b/.gitignore
@@ -73,3 +73,5 @@ functions/mock
screenshot
.firebase
sessionStore
+/CLAUDE.md
+/nul
diff --git a/zt-module-base/zt-module-base-api/src/main/java/com/zt/plat/module/base/enums/ErrorCodeConstants.java b/zt-module-base/zt-module-base-api/src/main/java/com/zt/plat/module/base/enums/ErrorCodeConstants.java
index c36bd6e..954c17c 100644
--- a/zt-module-base/zt-module-base-api/src/main/java/com/zt/plat/module/base/enums/ErrorCodeConstants.java
+++ b/zt-module-base/zt-module-base-api/src/main/java/com/zt/plat/module/base/enums/ErrorCodeConstants.java
@@ -29,4 +29,20 @@ public interface ErrorCodeConstants {
ErrorCode BUSINESS_DICTIONARY_TYPE_NOT_EXISTS = new ErrorCode(1_027_200_003, "业务字典类型不存在");
ErrorCode BUSINESS_DEPARTMENT_INDICATOR_NOT_EXISTS = new ErrorCode(1_027_200_004, "部门持有指标不存在");
+ // ========== 模板文档管理系统 1-006-xxx-xxx ==========
+ // 模板分类 1-006-001-xxx
+ ErrorCode TEMPLATE_CATEGORY_NOT_EXISTS = new ErrorCode(1_006_001_001, "模板分类不存在");
+
+ // 标签库 1-006-002-xxx
+ ErrorCode TEMPLATE_TAG_NOT_EXISTS = new ErrorCode(1_006_002_001, "标签不存在");
+ ErrorCode TEMPLATE_TAG_CODE_DUPLICATE = new ErrorCode(1_006_002_002, "标签编码已存在");
+
+ // 模板 1-006-003-xxx
+ ErrorCode TEMPLATE_NOT_EXISTS = new ErrorCode(1_006_003_001, "模板不存在");
+ ErrorCode TEMPLATE_CODE_DUPLICATE = new ErrorCode(1_006_003_002, "模板编码已存在");
+
+ // 模板实例 1-006-004-xxx
+ ErrorCode TEMPLATE_INSTANCE_NOT_EXISTS = new ErrorCode(1_006_004_001, "模板实例不存在");
+ ErrorCode TEMPLATE_INSTANCE_CODE_DUPLICATE = new ErrorCode(1_006_004_002, "实例编码已存在");
+
}
diff --git a/zt-module-base/zt-module-base-server/pom.xml b/zt-module-base/zt-module-base-server/pom.xml
index acd97ea..431837b 100644
--- a/zt-module-base/zt-module-base-server/pom.xml
+++ b/zt-module-base/zt-module-base-server/pom.xml
@@ -122,6 +122,13 @@
zt-spring-boot-starter-excel
+
+
+ org.apache.velocity
+ velocity-engine-core
+ 2.3
+
+
com.zt.plat
diff --git a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/doctemplate/DocTemplateCategoryController.java b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/doctemplate/DocTemplateCategoryController.java
new file mode 100644
index 0000000..d673d01
--- /dev/null
+++ b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/doctemplate/DocTemplateCategoryController.java
@@ -0,0 +1,89 @@
+package com.zt.plat.module.base.controller.admin.doctemplate;
+
+import com.zt.plat.framework.common.pojo.CommonResult;
+import com.zt.plat.framework.common.pojo.PageResult;
+import com.zt.plat.module.base.controller.admin.doctemplate.vo.DocTemplateCategoryPageReqVO;
+import com.zt.plat.module.base.controller.admin.doctemplate.vo.DocTemplateCategoryRespVO;
+import com.zt.plat.module.base.controller.admin.doctemplate.vo.DocTemplateCategorySaveReqVO;
+import com.zt.plat.module.base.service.doctemplate.DocTemplateCategoryService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import jakarta.annotation.Resource;
+import jakarta.validation.Valid;
+import java.util.List;
+
+import static com.zt.plat.framework.common.pojo.CommonResult.success;
+
+/**
+ * 模板分类 Controller
+ *
+ * @author 系统生成
+ */
+@Tag(name = "管理后台 - 模板分类")
+@RestController
+@RequestMapping("/base/doc-template-category")
+@Validated
+public class DocTemplateCategoryController {
+
+ @Resource
+ private DocTemplateCategoryService templateCategoryService;
+
+ @PostMapping("/create")
+ @Operation(summary = "创建模板分类")
+ @PreAuthorize("@ss.hasPermission('base:template-category:create')")
+ public CommonResult createTemplateCategory(@Valid @RequestBody DocTemplateCategorySaveReqVO createReqVO) {
+ return success(templateCategoryService.createTemplateCategory(createReqVO));
+ }
+
+ @PutMapping("/update")
+ @Operation(summary = "更新模板分类")
+ @PreAuthorize("@ss.hasPermission('base:template-category:update')")
+ public CommonResult updateTemplateCategory(@Valid @RequestBody DocTemplateCategorySaveReqVO updateReqVO) {
+ templateCategoryService.updateTemplateCategory(updateReqVO);
+ return success(true);
+ }
+
+ @DeleteMapping("/delete")
+ @Operation(summary = "删除模板分类")
+ @Parameter(name = "id", description = "编号", required = true)
+ @PreAuthorize("@ss.hasPermission('base:template-category:delete')")
+ public CommonResult deleteTemplateCategory(@RequestParam("id") Long id) {
+ templateCategoryService.deleteTemplateCategory(id);
+ return success(true);
+ }
+
+ @GetMapping("/get")
+ @Operation(summary = "获得模板分类")
+ @Parameter(name = "id", description = "编号", required = true, example = "1024")
+ @PreAuthorize("@ss.hasPermission('base:template-category:query')")
+ public CommonResult getTemplateCategory(@RequestParam("id") Long id) {
+ return success(templateCategoryService.getTemplateCategory(id));
+ }
+
+ @GetMapping("/page")
+ @Operation(summary = "获得模板分类分页")
+ @PreAuthorize("@ss.hasPermission('base:template-category:query')")
+ public CommonResult> getTemplateCategoryPage(@Valid DocTemplateCategoryPageReqVO pageReqVO) {
+ return success(templateCategoryService.getTemplateCategoryPage(pageReqVO));
+ }
+
+ @GetMapping("/list")
+ @Operation(summary = "获得模板分类列表")
+ @PreAuthorize("@ss.hasPermission('base:template-category:query')")
+ public CommonResult> getTemplateCategoryList() {
+ return success(templateCategoryService.getTemplateCategoryList());
+ }
+
+ @GetMapping("/tree")
+ @Operation(summary = "获得模板分类树形结构")
+ @PreAuthorize("@ss.hasPermission('base:template-category:query')")
+ public CommonResult> getTemplateCategoryTree() {
+ return success(templateCategoryService.buildTree());
+ }
+
+}
diff --git a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/doctemplate/DocTemplateController.java b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/doctemplate/DocTemplateController.java
new file mode 100644
index 0000000..0b23670
--- /dev/null
+++ b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/doctemplate/DocTemplateController.java
@@ -0,0 +1,82 @@
+package com.zt.plat.module.base.controller.admin.doctemplate;
+
+import com.zt.plat.framework.common.pojo.CommonResult;
+import com.zt.plat.framework.common.pojo.PageResult;
+import com.zt.plat.module.base.controller.admin.doctemplate.vo.DocTemplatePageReqVO;
+import com.zt.plat.module.base.controller.admin.doctemplate.vo.DocTemplateRespVO;
+import com.zt.plat.module.base.controller.admin.doctemplate.vo.DocTemplateSaveReqVO;
+import com.zt.plat.module.base.service.doctemplate.DocTemplateService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import jakarta.annotation.Resource;
+import jakarta.validation.Valid;
+import java.util.List;
+
+import static com.zt.plat.framework.common.pojo.CommonResult.success;
+
+/**
+ * 模板 Controller
+ *
+ * @author 系统生成
+ */
+@Tag(name = "管理后台 - 模板")
+@RestController
+@RequestMapping("/base/doc-template")
+@Validated
+public class DocTemplateController {
+
+ @Resource
+ private DocTemplateService templateService;
+
+ @PostMapping("/create")
+ @Operation(summary = "创建模板")
+ @PreAuthorize("@ss.hasPermission('base:template:create')")
+ public CommonResult createTemplate(@Valid @RequestBody DocTemplateSaveReqVO createReqVO) {
+ return success(templateService.createTemplate(createReqVO));
+ }
+
+ @PutMapping("/update")
+ @Operation(summary = "更新模板")
+ @PreAuthorize("@ss.hasPermission('base:template:update')")
+ public CommonResult updateTemplate(@Valid @RequestBody DocTemplateSaveReqVO updateReqVO) {
+ templateService.updateTemplate(updateReqVO);
+ return success(true);
+ }
+
+ @DeleteMapping("/delete")
+ @Operation(summary = "删除模板")
+ @Parameter(name = "id", description = "编号", required = true)
+ @PreAuthorize("@ss.hasPermission('base:template:delete')")
+ public CommonResult deleteTemplate(@RequestParam("id") Long id) {
+ templateService.deleteTemplate(id);
+ return success(true);
+ }
+
+ @GetMapping("/get")
+ @Operation(summary = "获得模板")
+ @Parameter(name = "id", description = "编号", required = true, example = "1024")
+ @PreAuthorize("@ss.hasPermission('base:template:query')")
+ public CommonResult getTemplate(@RequestParam("id") Long id) {
+ return success(templateService.getTemplate(id));
+ }
+
+ @GetMapping("/page")
+ @Operation(summary = "获得模板分页")
+ @PreAuthorize("@ss.hasPermission('base:template:query')")
+ public CommonResult> getTemplatePage(@Valid DocTemplatePageReqVO pageReqVO) {
+ return success(templateService.getTemplatePage(pageReqVO));
+ }
+
+ @GetMapping("/list")
+ @Operation(summary = "获得模板列表")
+ @PreAuthorize("@ss.hasPermission('base:template:query')")
+ public CommonResult> getTemplateList() {
+ return success(templateService.getTemplateList());
+ }
+
+}
diff --git a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/doctemplate/DocTemplateInstanceController.java b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/doctemplate/DocTemplateInstanceController.java
new file mode 100644
index 0000000..4b3b513
--- /dev/null
+++ b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/doctemplate/DocTemplateInstanceController.java
@@ -0,0 +1,107 @@
+package com.zt.plat.module.base.controller.admin.doctemplate;
+
+import com.zt.plat.framework.common.pojo.CommonResult;
+import com.zt.plat.framework.common.pojo.PageResult;
+import com.zt.plat.module.base.controller.admin.doctemplate.vo.DocTemplateInstancePageReqVO;
+import com.zt.plat.module.base.controller.admin.doctemplate.vo.DocTemplateInstanceRespVO;
+import com.zt.plat.module.base.controller.admin.doctemplate.vo.DocTemplateInstanceSaveReqVO;
+import com.zt.plat.module.base.service.doctemplate.DocTemplateInstanceService;
+import com.zt.plat.module.base.service.doctemplate.DocTemplateRenderService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import jakarta.annotation.Resource;
+import jakarta.validation.Valid;
+import java.util.List;
+import java.util.Map;
+
+import static com.zt.plat.framework.common.pojo.CommonResult.success;
+
+/**
+ * 模板实例 Controller
+ *
+ * @author 系统生成
+ */
+@Tag(name = "管理后台 - 模板实例")
+@RestController
+@RequestMapping("/base/doc-template-instance")
+@Validated
+public class DocTemplateInstanceController {
+
+ @Resource
+ private DocTemplateInstanceService templateInstanceService;
+
+ @Resource
+ private DocTemplateRenderService renderService;
+
+ @PostMapping("/create")
+ @Operation(summary = "创建模板实例")
+ @PreAuthorize("@ss.hasPermission('base:template-instance:create')")
+ public CommonResult createTemplateInstance(@Valid @RequestBody DocTemplateInstanceSaveReqVO createReqVO) {
+ return success(templateInstanceService.createTemplateInstance(createReqVO));
+ }
+
+ @PutMapping("/update")
+ @Operation(summary = "更新模板实例")
+ @PreAuthorize("@ss.hasPermission('base:template-instance:update')")
+ public CommonResult updateTemplateInstance(@Valid @RequestBody DocTemplateInstanceSaveReqVO updateReqVO) {
+ templateInstanceService.updateTemplateInstance(updateReqVO);
+ return success(true);
+ }
+
+ @DeleteMapping("/delete")
+ @Operation(summary = "删除模板实例")
+ @Parameter(name = "id", description = "编号", required = true)
+ @PreAuthorize("@ss.hasPermission('base:template-instance:delete')")
+ public CommonResult deleteTemplateInstance(@RequestParam("id") Long id) {
+ templateInstanceService.deleteTemplateInstance(id);
+ return success(true);
+ }
+
+ @GetMapping("/get")
+ @Operation(summary = "获得模板实例")
+ @Parameter(name = "id", description = "编号", required = true, example = "1024")
+ @PreAuthorize("@ss.hasPermission('base:template-instance:query')")
+ public CommonResult getTemplateInstance(@RequestParam("id") Long id) {
+ return success(templateInstanceService.getTemplateInstance(id));
+ }
+
+ @GetMapping("/page")
+ @Operation(summary = "获得模板实例分页")
+ @PreAuthorize("@ss.hasPermission('base:template-instance:query')")
+ public CommonResult> getTemplateInstancePage(@Valid DocTemplateInstancePageReqVO pageReqVO) {
+ return success(templateInstanceService.getTemplateInstancePage(pageReqVO));
+ }
+
+ @GetMapping("/list")
+ @Operation(summary = "获得模板实例列表")
+ @PreAuthorize("@ss.hasPermission('base:template-instance:query')")
+ public CommonResult> getTemplateInstanceList() {
+ return success(templateInstanceService.getTemplateInstanceList());
+ }
+
+ @PostMapping("/render")
+ @Operation(summary = "渲染模板实例")
+ @PreAuthorize("@ss.hasPermission('base:template-instance:query')")
+ public CommonResult renderTemplateInstance(
+ @Parameter(name = "instanceId", description = "实例ID", required = true) @RequestParam("instanceId") Long instanceId,
+ @Parameter(name = "dataMap", description = "数据Map") @RequestBody(required = false) Map dataMap) {
+ String renderedContent = renderService.render(null, instanceId, null, dataMap);
+ return success(renderedContent);
+ }
+
+ @PostMapping("/render-and-save")
+ @Operation(summary = "渲染并保存模板实例")
+ @PreAuthorize("@ss.hasPermission('base:template-instance:update')")
+ public CommonResult renderAndSaveTemplateInstance(
+ @Parameter(name = "instanceId", description = "实例ID", required = true) @RequestParam("instanceId") Long instanceId,
+ @Parameter(name = "dataMap", description = "数据Map", required = true) @RequestBody Map dataMap) {
+ renderService.renderAndSave(instanceId, dataMap);
+ return success(true);
+ }
+
+}
diff --git a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/doctemplate/DocTemplateTagController.java b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/doctemplate/DocTemplateTagController.java
new file mode 100644
index 0000000..25e2ecf
--- /dev/null
+++ b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/doctemplate/DocTemplateTagController.java
@@ -0,0 +1,82 @@
+package com.zt.plat.module.base.controller.admin.doctemplate;
+
+import com.zt.plat.framework.common.pojo.CommonResult;
+import com.zt.plat.framework.common.pojo.PageResult;
+import com.zt.plat.module.base.controller.admin.doctemplate.vo.DocTemplateTagPageReqVO;
+import com.zt.plat.module.base.controller.admin.doctemplate.vo.DocTemplateTagRespVO;
+import com.zt.plat.module.base.controller.admin.doctemplate.vo.DocTemplateTagSaveReqVO;
+import com.zt.plat.module.base.service.doctemplate.DocTemplateTagService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import jakarta.annotation.Resource;
+import jakarta.validation.Valid;
+import java.util.List;
+
+import static com.zt.plat.framework.common.pojo.CommonResult.success;
+
+/**
+ * 标签库 Controller
+ *
+ * @author 系统生成
+ */
+@Tag(name = "管理后台 - 标签库")
+@RestController
+@RequestMapping("/base/doc-template-tag")
+@Validated
+public class DocTemplateTagController {
+
+ @Resource
+ private DocTemplateTagService templateTagService;
+
+ @PostMapping("/create")
+ @Operation(summary = "创建标签")
+ @PreAuthorize("@ss.hasPermission('base:template-tag:create')")
+ public CommonResult createTemplateTag(@Valid @RequestBody DocTemplateTagSaveReqVO createReqVO) {
+ return success(templateTagService.createTemplateTag(createReqVO));
+ }
+
+ @PutMapping("/update")
+ @Operation(summary = "更新标签")
+ @PreAuthorize("@ss.hasPermission('base:template-tag:update')")
+ public CommonResult updateTemplateTag(@Valid @RequestBody DocTemplateTagSaveReqVO updateReqVO) {
+ templateTagService.updateTemplateTag(updateReqVO);
+ return success(true);
+ }
+
+ @DeleteMapping("/delete")
+ @Operation(summary = "删除标签")
+ @Parameter(name = "id", description = "编号", required = true)
+ @PreAuthorize("@ss.hasPermission('base:template-tag:delete')")
+ public CommonResult deleteTemplateTag(@RequestParam("id") Long id) {
+ templateTagService.deleteTemplateTag(id);
+ return success(true);
+ }
+
+ @GetMapping("/get")
+ @Operation(summary = "获得标签")
+ @Parameter(name = "id", description = "编号", required = true, example = "1024")
+ @PreAuthorize("@ss.hasPermission('base:template-tag:query')")
+ public CommonResult getTemplateTag(@RequestParam("id") Long id) {
+ return success(templateTagService.getTemplateTag(id));
+ }
+
+ @GetMapping("/page")
+ @Operation(summary = "获得标签分页")
+ @PreAuthorize("@ss.hasPermission('base:template-tag:query')")
+ public CommonResult> getTemplateTagPage(@Valid DocTemplateTagPageReqVO pageReqVO) {
+ return success(templateTagService.getTemplateTagPage(pageReqVO));
+ }
+
+ @GetMapping("/list")
+ @Operation(summary = "获得标签列表")
+ @PreAuthorize("@ss.hasPermission('base:template-tag:query')")
+ public CommonResult> getTemplateTagList() {
+ return success(templateTagService.getTemplateTagList());
+ }
+
+}
diff --git a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/doctemplate/vo/DocTemplateCategoryPageReqVO.java b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/doctemplate/vo/DocTemplateCategoryPageReqVO.java
new file mode 100644
index 0000000..da89763
--- /dev/null
+++ b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/doctemplate/vo/DocTemplateCategoryPageReqVO.java
@@ -0,0 +1,27 @@
+package com.zt.plat.module.base.controller.admin.doctemplate.vo;
+
+import com.zt.plat.framework.common.pojo.PageParam;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+
+@Schema(description = "管理后台 - 模板分类分页 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class DocTemplateCategoryPageReqVO extends PageParam {
+
+ @Schema(description = "分类名称", example = "采购类")
+ private String categoryName;
+
+ @Schema(description = "分类编码", example = "PURCHASE")
+ private String categoryCode;
+
+ @Schema(description = "父分类ID", example = "1")
+ private Long parentId;
+
+ @Schema(description = "层级(1=大类,2=小类)", example = "1")
+ private Integer level;
+
+}
diff --git a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/doctemplate/vo/DocTemplateCategoryRespVO.java b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/doctemplate/vo/DocTemplateCategoryRespVO.java
new file mode 100644
index 0000000..fe74244
--- /dev/null
+++ b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/doctemplate/vo/DocTemplateCategoryRespVO.java
@@ -0,0 +1,43 @@
+package com.zt.plat.module.base.controller.admin.doctemplate.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+import java.util.List;
+
+@Schema(description = "管理后台 - 模板分类 Response VO")
+@Data
+public class DocTemplateCategoryRespVO {
+
+ @Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
+ private Long id;
+
+ @Schema(description = "分类名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "采购类")
+ private String categoryName;
+
+ @Schema(description = "分类编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "PURCHASE")
+ private String categoryCode;
+
+ @Schema(description = "父分类ID", example = "1")
+ private Long parentId;
+
+ @Schema(description = "层级(1=大类,2=小类)", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+ private Integer level;
+
+ @Schema(description = "排序号", example = "1")
+ private Integer sort;
+
+ @Schema(description = "备注", example = "采购业务相关文档分类")
+ private String remark;
+
+ @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
+ private LocalDateTime createTime;
+
+ @Schema(description = "创建人", example = "admin")
+ private String creator;
+
+ @Schema(description = "子分类列表")
+ private List children;
+
+}
diff --git a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/doctemplate/vo/DocTemplateCategorySaveReqVO.java b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/doctemplate/vo/DocTemplateCategorySaveReqVO.java
new file mode 100644
index 0000000..21217ac
--- /dev/null
+++ b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/doctemplate/vo/DocTemplateCategorySaveReqVO.java
@@ -0,0 +1,37 @@
+package com.zt.plat.module.base.controller.admin.doctemplate.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+
+@Schema(description = "管理后台 - 模板分类新增/修改 Request VO")
+@Data
+public class DocTemplateCategorySaveReqVO {
+
+ @Schema(description = "主键", example = "1024")
+ private Long id;
+
+ @Schema(description = "分类名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "采购类")
+ @NotBlank(message = "分类名称不能为空")
+ private String categoryName;
+
+ @Schema(description = "分类编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "PURCHASE")
+ @NotBlank(message = "分类编码不能为空")
+ private String categoryCode;
+
+ @Schema(description = "父分类ID", example = "1")
+ private Long parentId;
+
+ @Schema(description = "层级(1=大类,2=小类)", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+ @NotNull(message = "层级不能为空")
+ private Integer level;
+
+ @Schema(description = "排序号", example = "1")
+ private Integer sort;
+
+ @Schema(description = "备注", example = "采购业务相关文档分类")
+ private String remark;
+
+}
diff --git a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/doctemplate/vo/DocTemplateInstancePageReqVO.java b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/doctemplate/vo/DocTemplateInstancePageReqVO.java
new file mode 100644
index 0000000..ab6f3cb
--- /dev/null
+++ b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/doctemplate/vo/DocTemplateInstancePageReqVO.java
@@ -0,0 +1,36 @@
+package com.zt.plat.module.base.controller.admin.doctemplate.vo;
+
+import com.zt.plat.framework.common.pojo.PageParam;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.time.LocalDateTime;
+
+import static com.zt.plat.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
+
+@Schema(description = "管理后台 - 模板实例分页 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class DocTemplateInstancePageReqVO extends PageParam {
+
+ @Schema(description = "实例名称", example = "采购合同")
+ private String instanceName;
+
+ @Schema(description = "模板ID", example = "1")
+ private Long templateId;
+
+ @Schema(description = "业务关联类型", example = "contract")
+ private String businessType;
+
+ @Schema(description = "状态", example = "draft")
+ private String status;
+
+ @Schema(description = "创建时间")
+ @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+ private LocalDateTime[] createTime;
+
+}
diff --git a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/doctemplate/vo/DocTemplateInstanceRespVO.java b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/doctemplate/vo/DocTemplateInstanceRespVO.java
new file mode 100644
index 0000000..b27bab0
--- /dev/null
+++ b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/doctemplate/vo/DocTemplateInstanceRespVO.java
@@ -0,0 +1,51 @@
+package com.zt.plat.module.base.controller.admin.doctemplate.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Schema(description = "管理后台 - 模板实例 Response VO")
+@Data
+public class DocTemplateInstanceRespVO {
+
+ @Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
+ private Long id;
+
+ @Schema(description = "实例名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "2025年上海XX供应商采购合同")
+ private String instanceName;
+
+ @Schema(description = "实例编码", example = "DOC-20250127-001")
+ private String instanceCode;
+
+ @Schema(description = "引用的模板ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+ private Long templateId;
+
+ @Schema(description = "业务关联类型", example = "contract")
+ private String businessType;
+
+ @Schema(description = "业务关联ID", example = "100")
+ private Long businessId;
+
+ @Schema(description = "业务关联标签", example = "PC-2025-001")
+ private String businessLabel;
+
+ @Schema(description = "用户编辑后的内容")
+ private String editedContent;
+
+ @Schema(description = "渲染后的最终内容")
+ private String renderedContent;
+
+ @Schema(description = "备注", example = "采购合同文档")
+ private String remark;
+
+ @Schema(description = "状态", example = "draft")
+ private String status;
+
+ @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
+ private LocalDateTime createTime;
+
+ @Schema(description = "创建人", example = "admin")
+ private String creator;
+
+}
diff --git a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/doctemplate/vo/DocTemplateInstanceSaveReqVO.java b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/doctemplate/vo/DocTemplateInstanceSaveReqVO.java
new file mode 100644
index 0000000..49e0a13
--- /dev/null
+++ b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/doctemplate/vo/DocTemplateInstanceSaveReqVO.java
@@ -0,0 +1,49 @@
+package com.zt.plat.module.base.controller.admin.doctemplate.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+
+@Schema(description = "管理后台 - 模板实例新增/修改 Request VO")
+@Data
+public class DocTemplateInstanceSaveReqVO {
+
+ @Schema(description = "主键", example = "1024")
+ private Long id;
+
+ @Schema(description = "实例名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "2025年上海XX供应商采购合同")
+ @NotBlank(message = "实例名称不能为空")
+ private String instanceName;
+
+ @Schema(description = "实例编码", example = "DOC-20250127-001")
+ private String instanceCode;
+
+ @Schema(description = "引用的模板ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+ @NotNull(message = "模板ID不能为空")
+ private Long templateId;
+
+ @Schema(description = "业务关联类型", example = "contract")
+ private String businessType;
+
+ @Schema(description = "业务关联ID", example = "100")
+ private Long businessId;
+
+ @Schema(description = "业务关联标签", example = "PC-2025-001")
+ private String businessLabel;
+
+ @Schema(description = "用户编辑后的内容", requiredMode = Schema.RequiredMode.REQUIRED)
+ @NotBlank(message = "内容不能为空")
+ private String editedContent;
+
+ @Schema(description = "渲染后的最终内容")
+ private String renderedContent;
+
+ @Schema(description = "备注", example = "采购合同文档")
+ private String remark;
+
+ @Schema(description = "状态", example = "draft")
+ private String status;
+
+}
diff --git a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/doctemplate/vo/DocTemplatePageReqVO.java b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/doctemplate/vo/DocTemplatePageReqVO.java
new file mode 100644
index 0000000..ee8f37c
--- /dev/null
+++ b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/doctemplate/vo/DocTemplatePageReqVO.java
@@ -0,0 +1,39 @@
+package com.zt.plat.module.base.controller.admin.doctemplate.vo;
+
+import com.zt.plat.framework.common.pojo.PageParam;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.time.LocalDateTime;
+
+import static com.zt.plat.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
+
+@Schema(description = "管理后台 - 模板分页 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class DocTemplatePageReqVO extends PageParam {
+
+ @Schema(description = "模板名称", example = "采购合同模板")
+ private String tmplName;
+
+ @Schema(description = "模板编码", example = "PO_CONTRACT_001")
+ private String tmplCode;
+
+ @Schema(description = "所属大类", example = "1")
+ private Long bigCategoryId;
+
+ @Schema(description = "所属小类", example = "11")
+ private Long smallCategoryId;
+
+ @Schema(description = "状态(1=启用,0=停用,2=草稿)", example = "1")
+ private String enabled;
+
+ @Schema(description = "创建时间")
+ @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+ private LocalDateTime[] createTime;
+
+}
diff --git a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/doctemplate/vo/DocTemplateRespVO.java b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/doctemplate/vo/DocTemplateRespVO.java
new file mode 100644
index 0000000..3a86c8e
--- /dev/null
+++ b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/doctemplate/vo/DocTemplateRespVO.java
@@ -0,0 +1,57 @@
+package com.zt.plat.module.base.controller.admin.doctemplate.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Schema(description = "管理后台 - 模板 Response VO")
+@Data
+public class DocTemplateRespVO {
+
+ @Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
+ private Long id;
+
+ @Schema(description = "模板名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "采购合同模板")
+ private String tmplName;
+
+ @Schema(description = "模板编码(唯一)", requiredMode = Schema.RequiredMode.REQUIRED, example = "PO_CONTRACT_001")
+ private String tmplCode;
+
+ @Schema(description = "模板图标", example = "📄")
+ private String icon;
+
+ @Schema(description = "所属大类", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+ private Long bigCategoryId;
+
+ @Schema(description = "所属小类", example = "11")
+ private Long smallCategoryId;
+
+ @Schema(description = "版本号", example = "v1.2")
+ private String version;
+
+ @Schema(description = "模板描述", example = "标准采购合同范本")
+ private String description;
+
+ @Schema(description = "模板内容(HTML,含占位符)", requiredMode = Schema.RequiredMode.REQUIRED)
+ private String content;
+
+ @Schema(description = "SQL配置(JSON格式,可选)")
+ private String sqlConfig;
+
+ @Schema(description = "数据源标识", example = "default")
+ private String dataSource;
+
+ @Schema(description = "使用次数", example = "10")
+ private Integer useCount;
+
+ @Schema(description = "状态(1=启用,0=停用,2=草稿)", example = "1")
+ private String enabled;
+
+ @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
+ private LocalDateTime createTime;
+
+ @Schema(description = "创建人", example = "admin")
+ private String creator;
+
+}
diff --git a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/doctemplate/vo/DocTemplateSaveReqVO.java b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/doctemplate/vo/DocTemplateSaveReqVO.java
new file mode 100644
index 0000000..19003af
--- /dev/null
+++ b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/doctemplate/vo/DocTemplateSaveReqVO.java
@@ -0,0 +1,53 @@
+package com.zt.plat.module.base.controller.admin.doctemplate.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+
+@Schema(description = "管理后台 - 模板新增/修改 Request VO")
+@Data
+public class DocTemplateSaveReqVO {
+
+ @Schema(description = "主键", example = "1024")
+ private Long id;
+
+ @Schema(description = "模板名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "采购合同模板")
+ @NotBlank(message = "模板名称不能为空")
+ private String tmplName;
+
+ @Schema(description = "模板编码(唯一)", requiredMode = Schema.RequiredMode.REQUIRED, example = "PO_CONTRACT_001")
+ @NotBlank(message = "模板编码不能为空")
+ private String tmplCode;
+
+ @Schema(description = "模板图标", example = "📄")
+ private String icon;
+
+ @Schema(description = "所属大类", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+ @NotNull(message = "所属大类不能为空")
+ private Long bigCategoryId;
+
+ @Schema(description = "所属小类", example = "11")
+ private Long smallCategoryId;
+
+ @Schema(description = "版本号", example = "v1.2")
+ private String version;
+
+ @Schema(description = "模板描述", example = "标准采购合同范本")
+ private String description;
+
+ @Schema(description = "模板内容(HTML,含占位符)", requiredMode = Schema.RequiredMode.REQUIRED)
+ @NotBlank(message = "模板内容不能为空")
+ private String content;
+
+ @Schema(description = "SQL配置(JSON格式,可选)")
+ private String sqlConfig;
+
+ @Schema(description = "数据源标识", example = "default")
+ private String dataSource;
+
+ @Schema(description = "状态(1=启用,0=停用,2=草稿)", example = "2")
+ private String enabled;
+
+}
diff --git a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/doctemplate/vo/DocTemplateTagPageReqVO.java b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/doctemplate/vo/DocTemplateTagPageReqVO.java
new file mode 100644
index 0000000..8d7f922
--- /dev/null
+++ b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/doctemplate/vo/DocTemplateTagPageReqVO.java
@@ -0,0 +1,27 @@
+package com.zt.plat.module.base.controller.admin.doctemplate.vo;
+
+import com.zt.plat.framework.common.pojo.PageParam;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+
+@Schema(description = "管理后台 - 标签库分页 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class DocTemplateTagPageReqVO extends PageParam {
+
+ @Schema(description = "标签名称", example = "合同编号")
+ private String tagName;
+
+ @Schema(description = "标签编码", example = "contractNo")
+ private String tagCode;
+
+ @Schema(description = "所属分类ID", example = "1")
+ private Long categoryId;
+
+ @Schema(description = "是否启用(1=启用,0=停用)", example = "1")
+ private String enabled;
+
+}
diff --git a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/doctemplate/vo/DocTemplateTagRespVO.java b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/doctemplate/vo/DocTemplateTagRespVO.java
new file mode 100644
index 0000000..9c03138
--- /dev/null
+++ b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/doctemplate/vo/DocTemplateTagRespVO.java
@@ -0,0 +1,63 @@
+package com.zt.plat.module.base.controller.admin.doctemplate.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Schema(description = "管理后台 - 标签库 Response VO")
+@Data
+public class DocTemplateTagRespVO {
+
+ @Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
+ private Long id;
+
+ @Schema(description = "标签名称(中文)", requiredMode = Schema.RequiredMode.REQUIRED, example = "合同编号")
+ private String tagName;
+
+ @Schema(description = "标签编码(Velocity变量名)", requiredMode = Schema.RequiredMode.REQUIRED, example = "contractNo")
+ private String tagCode;
+
+ @Schema(description = "所属分类ID", example = "1")
+ private Long categoryId;
+
+ @Schema(description = "所属分类名称", example = "合同管理")
+ private String categoryName;
+
+ @Schema(description = "数据类型", example = "String")
+ private String dataType;
+
+ @Schema(description = "默认值", example = "")
+ private String defaultValue;
+
+ @Schema(description = "SQL脚本(可选,仅保存参考)", example = "SELECT contract_no FROM contract_main WHERE id = #{businessId}")
+ private String sqlScript;
+
+ @Schema(description = "描述", example = "合同主表的合同编号字段")
+ private String description;
+
+ @Schema(description = "排序号", example = "1")
+ private Integer sort;
+
+ @Schema(description = "是否启用(1=启用,0=停用)", example = "1")
+ private String enabled;
+
+ @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
+ private LocalDateTime createTime;
+
+ @Schema(description = "创建人ID", example = "1")
+ private String creator;
+
+ @Schema(description = "创建人名称", example = "管理员")
+ private String creatorName;
+
+ @Schema(description = "更新时间")
+ private LocalDateTime updateTime;
+
+ @Schema(description = "更新人ID", example = "1")
+ private String updater;
+
+ @Schema(description = "更新人名称", example = "管理员")
+ private String updaterName;
+
+}
diff --git a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/doctemplate/vo/DocTemplateTagSaveReqVO.java b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/doctemplate/vo/DocTemplateTagSaveReqVO.java
new file mode 100644
index 0000000..4e06601
--- /dev/null
+++ b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/controller/admin/doctemplate/vo/DocTemplateTagSaveReqVO.java
@@ -0,0 +1,44 @@
+package com.zt.plat.module.base.controller.admin.doctemplate.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import jakarta.validation.constraints.NotBlank;
+
+@Schema(description = "管理后台 - 标签库新增/修改 Request VO")
+@Data
+public class DocTemplateTagSaveReqVO {
+
+ @Schema(description = "主键", example = "1024")
+ private Long id;
+
+ @Schema(description = "标签名称(中文)", requiredMode = Schema.RequiredMode.REQUIRED, example = "合同编号")
+ @NotBlank(message = "标签名称不能为空")
+ private String tagName;
+
+ @Schema(description = "标签编码(Velocity变量名)", requiredMode = Schema.RequiredMode.REQUIRED, example = "contractNo")
+ @NotBlank(message = "标签编码不能为空")
+ private String tagCode;
+
+ @Schema(description = "所属分类ID", example = "1")
+ private Long categoryId;
+
+ @Schema(description = "数据类型", example = "String")
+ private String dataType;
+
+ @Schema(description = "默认值", example = "")
+ private String defaultValue;
+
+ @Schema(description = "SQL脚本(可选,仅保存参考)", example = "SELECT contract_no FROM contract_main WHERE id = #{businessId}")
+ private String sqlScript;
+
+ @Schema(description = "描述", example = "合同主表的合同编号字段")
+ private String description;
+
+ @Schema(description = "排序号", example = "1")
+ private Integer sort;
+
+ @Schema(description = "是否启用(1=启用,0=停用)", example = "1")
+ private String enabled;
+
+}
diff --git a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/convert/doctemplate/DocTemplateCategoryConvert.java b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/convert/doctemplate/DocTemplateCategoryConvert.java
new file mode 100644
index 0000000..2ec2402
--- /dev/null
+++ b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/convert/doctemplate/DocTemplateCategoryConvert.java
@@ -0,0 +1,30 @@
+package com.zt.plat.module.base.convert.doctemplate;
+
+import com.zt.plat.framework.common.pojo.PageResult;
+import com.zt.plat.module.base.controller.admin.doctemplate.vo.DocTemplateCategoryRespVO;
+import com.zt.plat.module.base.controller.admin.doctemplate.vo.DocTemplateCategorySaveReqVO;
+import com.zt.plat.module.base.dal.dataobject.doctemplate.DocTemplateCategoryDO;
+import org.mapstruct.Mapper;
+import org.mapstruct.factory.Mappers;
+
+import java.util.List;
+
+/**
+ * 模板分类 Convert
+ *
+ * @author 系统生成
+ */
+@Mapper
+public interface DocTemplateCategoryConvert {
+
+ DocTemplateCategoryConvert INSTANCE = Mappers.getMapper(DocTemplateCategoryConvert.class);
+
+ DocTemplateCategoryDO convert(DocTemplateCategorySaveReqVO bean);
+
+ DocTemplateCategoryRespVO convert(DocTemplateCategoryDO bean);
+
+ List convertList(List list);
+
+ PageResult convertPage(PageResult page);
+
+}
diff --git a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/convert/doctemplate/DocTemplateConvert.java b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/convert/doctemplate/DocTemplateConvert.java
new file mode 100644
index 0000000..9559053
--- /dev/null
+++ b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/convert/doctemplate/DocTemplateConvert.java
@@ -0,0 +1,30 @@
+package com.zt.plat.module.base.convert.doctemplate;
+
+import com.zt.plat.framework.common.pojo.PageResult;
+import com.zt.plat.module.base.controller.admin.doctemplate.vo.DocTemplateRespVO;
+import com.zt.plat.module.base.controller.admin.doctemplate.vo.DocTemplateSaveReqVO;
+import com.zt.plat.module.base.dal.dataobject.doctemplate.DocTemplateDO;
+import org.mapstruct.Mapper;
+import org.mapstruct.factory.Mappers;
+
+import java.util.List;
+
+/**
+ * 模板 Convert
+ *
+ * @author 系统生成
+ */
+@Mapper
+public interface DocTemplateConvert {
+
+ DocTemplateConvert INSTANCE = Mappers.getMapper(DocTemplateConvert.class);
+
+ DocTemplateDO convert(DocTemplateSaveReqVO bean);
+
+ DocTemplateRespVO convert(DocTemplateDO bean);
+
+ List convertList(List list);
+
+ PageResult convertPage(PageResult page);
+
+}
diff --git a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/convert/doctemplate/DocTemplateInstanceConvert.java b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/convert/doctemplate/DocTemplateInstanceConvert.java
new file mode 100644
index 0000000..716cedc
--- /dev/null
+++ b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/convert/doctemplate/DocTemplateInstanceConvert.java
@@ -0,0 +1,30 @@
+package com.zt.plat.module.base.convert.doctemplate;
+
+import com.zt.plat.framework.common.pojo.PageResult;
+import com.zt.plat.module.base.controller.admin.doctemplate.vo.DocTemplateInstanceRespVO;
+import com.zt.plat.module.base.controller.admin.doctemplate.vo.DocTemplateInstanceSaveReqVO;
+import com.zt.plat.module.base.dal.dataobject.doctemplate.DocTemplateInstanceDO;
+import org.mapstruct.Mapper;
+import org.mapstruct.factory.Mappers;
+
+import java.util.List;
+
+/**
+ * 模板实例 Convert
+ *
+ * @author 系统生成
+ */
+@Mapper
+public interface DocTemplateInstanceConvert {
+
+ DocTemplateInstanceConvert INSTANCE = Mappers.getMapper(DocTemplateInstanceConvert.class);
+
+ DocTemplateInstanceDO convert(DocTemplateInstanceSaveReqVO bean);
+
+ DocTemplateInstanceRespVO convert(DocTemplateInstanceDO bean);
+
+ List convertList(List list);
+
+ PageResult convertPage(PageResult page);
+
+}
diff --git a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/convert/doctemplate/DocTemplateTagConvert.java b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/convert/doctemplate/DocTemplateTagConvert.java
new file mode 100644
index 0000000..1ef73be
--- /dev/null
+++ b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/convert/doctemplate/DocTemplateTagConvert.java
@@ -0,0 +1,30 @@
+package com.zt.plat.module.base.convert.doctemplate;
+
+import com.zt.plat.framework.common.pojo.PageResult;
+import com.zt.plat.module.base.controller.admin.doctemplate.vo.DocTemplateTagRespVO;
+import com.zt.plat.module.base.controller.admin.doctemplate.vo.DocTemplateTagSaveReqVO;
+import com.zt.plat.module.base.dal.dataobject.doctemplate.DocTemplateTagDO;
+import org.mapstruct.Mapper;
+import org.mapstruct.factory.Mappers;
+
+import java.util.List;
+
+/**
+ * 标签库 Convert
+ *
+ * @author 系统生成
+ */
+@Mapper
+public interface DocTemplateTagConvert {
+
+ DocTemplateTagConvert INSTANCE = Mappers.getMapper(DocTemplateTagConvert.class);
+
+ DocTemplateTagDO convert(DocTemplateTagSaveReqVO bean);
+
+ DocTemplateTagRespVO convert(DocTemplateTagDO bean);
+
+ List convertList(List list);
+
+ PageResult convertPage(PageResult page);
+
+}
diff --git a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/dal/dao/doctemplate/DocTemplateCategoryMapper.java b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/dal/dao/doctemplate/DocTemplateCategoryMapper.java
new file mode 100644
index 0000000..b6310e0
--- /dev/null
+++ b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/dal/dao/doctemplate/DocTemplateCategoryMapper.java
@@ -0,0 +1,28 @@
+package com.zt.plat.module.base.dal.dao.doctemplate;
+
+import com.zt.plat.framework.common.pojo.PageResult;
+import com.zt.plat.framework.mybatis.core.mapper.BaseMapperX;
+import com.zt.plat.framework.mybatis.core.query.LambdaQueryWrapperX;
+import com.zt.plat.module.base.controller.admin.doctemplate.vo.DocTemplateCategoryPageReqVO;
+import com.zt.plat.module.base.dal.dataobject.doctemplate.DocTemplateCategoryDO;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 模板分类 Mapper
+ *
+ * @author 系统生成
+ */
+@Mapper
+public interface DocTemplateCategoryMapper extends BaseMapperX {
+
+ default PageResult selectPage(DocTemplateCategoryPageReqVO reqVO) {
+ return selectPage(reqVO, new LambdaQueryWrapperX()
+ .likeIfPresent(DocTemplateCategoryDO::getCategoryName, reqVO.getCategoryName())
+ .eqIfPresent(DocTemplateCategoryDO::getCategoryCode, reqVO.getCategoryCode())
+ .eqIfPresent(DocTemplateCategoryDO::getParentId, reqVO.getParentId())
+ .eqIfPresent(DocTemplateCategoryDO::getLevel, reqVO.getLevel())
+ .orderByAsc(DocTemplateCategoryDO::getSort)
+ .orderByDesc(DocTemplateCategoryDO::getId));
+ }
+
+}
diff --git a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/dal/dao/doctemplate/DocTemplateInstanceMapper.java b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/dal/dao/doctemplate/DocTemplateInstanceMapper.java
new file mode 100644
index 0000000..8063083
--- /dev/null
+++ b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/dal/dao/doctemplate/DocTemplateInstanceMapper.java
@@ -0,0 +1,28 @@
+package com.zt.plat.module.base.dal.dao.doctemplate;
+
+import com.zt.plat.framework.common.pojo.PageResult;
+import com.zt.plat.framework.mybatis.core.mapper.BaseMapperX;
+import com.zt.plat.framework.mybatis.core.query.LambdaQueryWrapperX;
+import com.zt.plat.module.base.controller.admin.doctemplate.vo.DocTemplateInstancePageReqVO;
+import com.zt.plat.module.base.dal.dataobject.doctemplate.DocTemplateInstanceDO;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 模板实例 Mapper
+ *
+ * @author 系统生成
+ */
+@Mapper
+public interface DocTemplateInstanceMapper extends BaseMapperX {
+
+ default PageResult selectPage(DocTemplateInstancePageReqVO reqVO) {
+ return selectPage(reqVO, new LambdaQueryWrapperX()
+ .likeIfPresent(DocTemplateInstanceDO::getInstanceName, reqVO.getInstanceName())
+ .eqIfPresent(DocTemplateInstanceDO::getTemplateId, reqVO.getTemplateId())
+ .eqIfPresent(DocTemplateInstanceDO::getBusinessType, reqVO.getBusinessType())
+ .eqIfPresent(DocTemplateInstanceDO::getStatus, reqVO.getStatus())
+ .betweenIfPresent(DocTemplateInstanceDO::getCreateTime, reqVO.getCreateTime())
+ .orderByDesc(DocTemplateInstanceDO::getId));
+ }
+
+}
diff --git a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/dal/dao/doctemplate/DocTemplateMapper.java b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/dal/dao/doctemplate/DocTemplateMapper.java
new file mode 100644
index 0000000..8de6f6b
--- /dev/null
+++ b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/dal/dao/doctemplate/DocTemplateMapper.java
@@ -0,0 +1,29 @@
+package com.zt.plat.module.base.dal.dao.doctemplate;
+
+import com.zt.plat.framework.common.pojo.PageResult;
+import com.zt.plat.framework.mybatis.core.mapper.BaseMapperX;
+import com.zt.plat.framework.mybatis.core.query.LambdaQueryWrapperX;
+import com.zt.plat.module.base.controller.admin.doctemplate.vo.DocTemplatePageReqVO;
+import com.zt.plat.module.base.dal.dataobject.doctemplate.DocTemplateDO;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 模板 Mapper
+ *
+ * @author 系统生成
+ */
+@Mapper
+public interface DocTemplateMapper extends BaseMapperX {
+
+ default PageResult selectPage(DocTemplatePageReqVO reqVO) {
+ return selectPage(reqVO, new LambdaQueryWrapperX()
+ .likeIfPresent(DocTemplateDO::getTmplName, reqVO.getTmplName())
+ .likeIfPresent(DocTemplateDO::getTmplCode, reqVO.getTmplCode())
+ .eqIfPresent(DocTemplateDO::getBigCategoryId, reqVO.getBigCategoryId())
+ .eqIfPresent(DocTemplateDO::getSmallCategoryId, reqVO.getSmallCategoryId())
+ .eqIfPresent(DocTemplateDO::getEnabled, reqVO.getEnabled())
+ .betweenIfPresent(DocTemplateDO::getCreateTime, reqVO.getCreateTime())
+ .orderByDesc(DocTemplateDO::getId));
+ }
+
+}
diff --git a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/dal/dao/doctemplate/DocTemplateTagMapper.java b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/dal/dao/doctemplate/DocTemplateTagMapper.java
new file mode 100644
index 0000000..d791d60
--- /dev/null
+++ b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/dal/dao/doctemplate/DocTemplateTagMapper.java
@@ -0,0 +1,28 @@
+package com.zt.plat.module.base.dal.dao.doctemplate;
+
+import com.zt.plat.framework.common.pojo.PageResult;
+import com.zt.plat.framework.mybatis.core.mapper.BaseMapperX;
+import com.zt.plat.framework.mybatis.core.query.LambdaQueryWrapperX;
+import com.zt.plat.module.base.controller.admin.doctemplate.vo.DocTemplateTagPageReqVO;
+import com.zt.plat.module.base.dal.dataobject.doctemplate.DocTemplateTagDO;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 标签库 Mapper
+ *
+ * @author 系统生成
+ */
+@Mapper
+public interface DocTemplateTagMapper extends BaseMapperX {
+
+ default PageResult selectPage(DocTemplateTagPageReqVO reqVO) {
+ return selectPage(reqVO, new LambdaQueryWrapperX()
+ .likeIfPresent(DocTemplateTagDO::getTagName, reqVO.getTagName())
+ .likeIfPresent(DocTemplateTagDO::getTagCode, reqVO.getTagCode())
+ .eqIfPresent(DocTemplateTagDO::getCategoryId, reqVO.getCategoryId())
+ .eqIfPresent(DocTemplateTagDO::getEnabled, reqVO.getEnabled())
+ .orderByAsc(DocTemplateTagDO::getSort)
+ .orderByDesc(DocTemplateTagDO::getId));
+ }
+
+}
diff --git a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/dal/dataobject/doctemplate/DocTemplateCategoryDO.java b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/dal/dataobject/doctemplate/DocTemplateCategoryDO.java
new file mode 100644
index 0000000..390706f
--- /dev/null
+++ b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/dal/dataobject/doctemplate/DocTemplateCategoryDO.java
@@ -0,0 +1,63 @@
+package com.zt.plat.module.base.dal.dataobject.doctemplate;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.zt.plat.framework.mybatis.core.dataobject.BusinessBaseDO;
+import lombok.*;
+
+/**
+ * 模板分类 DO
+ *
+ * @author 系统生成
+ */
+@TableName(value = "bse_doc_category")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class DocTemplateCategoryDO extends BusinessBaseDO {
+
+ /**
+ * 主键
+ */
+ @TableId(type = IdType.ASSIGN_ID)
+ private Long id;
+
+ /**
+ * 分类名称
+ */
+ @TableField("category_name")
+ private String categoryName;
+
+ /**
+ * 分类编码
+ */
+ @TableField("category_code")
+ private String categoryCode;
+
+ /**
+ * 父分类ID(NULL=大类)
+ */
+ @TableField("parent_id")
+ private Long parentId;
+
+ /**
+ * 层级(1=大类,2=小类)
+ */
+ @TableField("level")
+ private Integer level;
+
+ /**
+ * 排序号
+ */
+ @TableField("sort")
+ private Integer sort;
+
+ /**
+ * 备注
+ */
+ @TableField("remark")
+ private String remark;
+
+}
diff --git a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/dal/dataobject/doctemplate/DocTemplateDO.java b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/dal/dataobject/doctemplate/DocTemplateDO.java
new file mode 100644
index 0000000..344835a
--- /dev/null
+++ b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/dal/dataobject/doctemplate/DocTemplateDO.java
@@ -0,0 +1,99 @@
+package com.zt.plat.module.base.dal.dataobject.doctemplate;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.zt.plat.framework.mybatis.core.dataobject.BusinessBaseDO;
+import lombok.*;
+
+/**
+ * 模板 DO
+ *
+ * @author 系统生成
+ */
+@TableName(value = "bse_doc_tmpl")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class DocTemplateDO extends BusinessBaseDO {
+
+ /**
+ * 主键
+ */
+ @TableId(type = IdType.ASSIGN_ID)
+ private Long id;
+
+ /**
+ * 模板名称
+ */
+ @TableField("tmpl_name")
+ private String tmplName;
+
+ /**
+ * 模板编码(唯一)
+ */
+ @TableField("tmpl_code")
+ private String tmplCode;
+
+ /**
+ * 模板图标
+ */
+ @TableField("icon")
+ private String icon;
+
+ /**
+ * 所属大类
+ */
+ @TableField("big_category_id")
+ private Long bigCategoryId;
+
+ /**
+ * 所属小类
+ */
+ @TableField("small_category_id")
+ private Long smallCategoryId;
+
+ /**
+ * 版本号
+ */
+ @TableField("version")
+ private String version;
+
+ /**
+ * 模板描述
+ */
+ @TableField("description")
+ private String description;
+
+ /**
+ * 模板内容(HTML,含占位符)
+ */
+ @TableField("content")
+ private String content;
+
+ /**
+ * SQL配置(JSON格式,可选)
+ */
+ @TableField("sql_config")
+ private String sqlConfig;
+
+ /**
+ * 数据源标识
+ */
+ @TableField("data_source")
+ private String dataSource;
+
+ /**
+ * 使用次数(引用创建实例的次数)
+ */
+ @TableField("use_count")
+ private Integer useCount;
+
+ /**
+ * 状态(1=启用,0=停用,2=草稿)
+ */
+ @TableField("enabled")
+ private String enabled;
+
+}
diff --git a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/dal/dataobject/doctemplate/DocTemplateInstanceDO.java b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/dal/dataobject/doctemplate/DocTemplateInstanceDO.java
new file mode 100644
index 0000000..88621fd
--- /dev/null
+++ b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/dal/dataobject/doctemplate/DocTemplateInstanceDO.java
@@ -0,0 +1,87 @@
+package com.zt.plat.module.base.dal.dataobject.doctemplate;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.zt.plat.framework.mybatis.core.dataobject.BusinessBaseDO;
+import lombok.*;
+
+/**
+ * 模板实例 DO
+ *
+ * @author 系统生成
+ */
+@TableName(value = "bse_doc_instance")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class DocTemplateInstanceDO extends BusinessBaseDO {
+
+ /**
+ * 主键
+ */
+ @TableId(type = IdType.ASSIGN_ID)
+ private Long id;
+
+ /**
+ * 实例名称
+ */
+ @TableField("instance_name")
+ private String instanceName;
+
+ /**
+ * 实例编码(唯一)
+ */
+ @TableField("instance_code")
+ private String instanceCode;
+
+ /**
+ * 引用的模板ID
+ */
+ @TableField("template_id")
+ private Long templateId;
+
+ /**
+ * 业务关联类型
+ */
+ @TableField("business_type")
+ private String businessType;
+
+ /**
+ * 业务关联ID
+ */
+ @TableField("business_id")
+ private Long businessId;
+
+ /**
+ * 业务关联标签(如 PC-2025-001)
+ */
+ @TableField("business_label")
+ private String businessLabel;
+
+ /**
+ * 用户编辑后的内容(含占位符)
+ */
+ @TableField("edited_content")
+ private String editedContent;
+
+ /**
+ * 渲染后的最终内容(占位符已替换)
+ */
+ @TableField("rendered_content")
+ private String renderedContent;
+
+ /**
+ * 备注
+ */
+ @TableField("remark")
+ private String remark;
+
+ /**
+ * 状态(draft=草稿,published=已发布)
+ */
+ @TableField("status")
+ private String status;
+
+}
diff --git a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/dal/dataobject/doctemplate/DocTemplateTagDO.java b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/dal/dataobject/doctemplate/DocTemplateTagDO.java
new file mode 100644
index 0000000..564561f
--- /dev/null
+++ b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/dal/dataobject/doctemplate/DocTemplateTagDO.java
@@ -0,0 +1,81 @@
+package com.zt.plat.module.base.dal.dataobject.doctemplate;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.zt.plat.framework.mybatis.core.dataobject.BusinessBaseDO;
+import lombok.*;
+
+/**
+ * 标签库 DO
+ *
+ * @author 系统生成
+ */
+@TableName(value = "bse_doc_tag")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class DocTemplateTagDO extends BusinessBaseDO {
+
+ /**
+ * 主键
+ */
+ @TableId(type = IdType.ASSIGN_ID)
+ private Long id;
+
+ /**
+ * 标签名称(中文)
+ */
+ @TableField("tag_name")
+ private String tagName;
+
+ /**
+ * 标签编码(Velocity变量名)
+ */
+ @TableField("tag_code")
+ private String tagCode;
+
+ /**
+ * 所属分类ID
+ */
+ @TableField("category_id")
+ private Long categoryId;
+
+ /**
+ * 数据类型(String/Number/Date/Boolean)
+ */
+ @TableField("data_type")
+ private String dataType;
+
+ /**
+ * 默认值
+ */
+ @TableField("default_value")
+ private String defaultValue;
+
+ /**
+ * SQL脚本(可选,仅保存参考)
+ */
+ @TableField("sql_script")
+ private String sqlScript;
+
+ /**
+ * 描述
+ */
+ @TableField("description")
+ private String description;
+
+ /**
+ * 排序号
+ */
+ @TableField("sort")
+ private Integer sort;
+
+ /**
+ * 是否启用(1=启用,0=停用)
+ */
+ @TableField("enabled")
+ private String enabled;
+
+}
diff --git a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/service/doctemplate/DocTemplateCategoryService.java b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/service/doctemplate/DocTemplateCategoryService.java
new file mode 100644
index 0000000..6b1d7eb
--- /dev/null
+++ b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/service/doctemplate/DocTemplateCategoryService.java
@@ -0,0 +1,78 @@
+package com.zt.plat.module.base.service.doctemplate;
+
+import com.zt.plat.framework.common.pojo.PageResult;
+import com.zt.plat.module.base.controller.admin.doctemplate.vo.DocTemplateCategoryPageReqVO;
+import com.zt.plat.module.base.controller.admin.doctemplate.vo.DocTemplateCategoryRespVO;
+import com.zt.plat.module.base.controller.admin.doctemplate.vo.DocTemplateCategorySaveReqVO;
+
+import jakarta.validation.Valid;
+import java.util.List;
+
+/**
+ * 模板分类 Service 接口
+ *
+ * @author 系统生成
+ */
+public interface DocTemplateCategoryService {
+
+ /**
+ * 创建模板分类
+ *
+ * @param createReqVO 创建信息
+ * @return 编号
+ */
+ Long createTemplateCategory(@Valid DocTemplateCategorySaveReqVO createReqVO);
+
+ /**
+ * 更新模板分类
+ *
+ * @param updateReqVO 更新信息
+ */
+ void updateTemplateCategory(@Valid DocTemplateCategorySaveReqVO updateReqVO);
+
+ /**
+ * 删除模板分类
+ *
+ * @param id 编号
+ */
+ void deleteTemplateCategory(Long id);
+
+ /**
+ * 获得模板分类
+ *
+ * @param id 编号
+ * @return 模板分类
+ */
+ DocTemplateCategoryRespVO getTemplateCategory(Long id);
+
+ /**
+ * 获得模板分类分页
+ *
+ * @param pageReqVO 分页查询
+ * @return 模板分类分页
+ */
+ PageResult getTemplateCategoryPage(DocTemplateCategoryPageReqVO pageReqVO);
+
+ /**
+ * 获得模板分类列表
+ *
+ * @return 模板分类列表
+ */
+ List getTemplateCategoryList();
+
+ /**
+ * 获得模板分类树形结构
+ *
+ * @return 模板分类树
+ */
+ List buildTree();
+
+ /**
+ * 获得分类完整路径(包含所有父级)
+ *
+ * @param categoryId 分类ID
+ * @return 分类路径,用"/"分隔,如"合同管理/销售合同"
+ */
+ String getCategoryFullPath(Long categoryId);
+
+}
diff --git a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/service/doctemplate/DocTemplateCategoryServiceImpl.java b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/service/doctemplate/DocTemplateCategoryServiceImpl.java
new file mode 100644
index 0000000..326d8a2
--- /dev/null
+++ b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/service/doctemplate/DocTemplateCategoryServiceImpl.java
@@ -0,0 +1,158 @@
+package com.zt.plat.module.base.service.doctemplate;
+
+import com.zt.plat.framework.common.pojo.PageResult;
+import com.zt.plat.module.base.controller.admin.doctemplate.vo.DocTemplateCategoryPageReqVO;
+import com.zt.plat.module.base.controller.admin.doctemplate.vo.DocTemplateCategoryRespVO;
+import com.zt.plat.module.base.controller.admin.doctemplate.vo.DocTemplateCategorySaveReqVO;
+import com.zt.plat.module.base.convert.doctemplate.DocTemplateCategoryConvert;
+import com.zt.plat.module.base.dal.dataobject.doctemplate.DocTemplateCategoryDO;
+import com.zt.plat.module.base.dal.dao.doctemplate.DocTemplateCategoryMapper;
+import org.springframework.stereotype.Service;
+import org.springframework.validation.annotation.Validated;
+
+import jakarta.annotation.Resource;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import static com.zt.plat.framework.common.exception.util.ServiceExceptionUtil.exception;
+import static com.zt.plat.module.base.enums.ErrorCodeConstants.TEMPLATE_CATEGORY_NOT_EXISTS;
+
+/**
+ * 模板分类 Service 实现类
+ *
+ * @author 系统生成
+ */
+@Service
+@Validated
+public class DocTemplateCategoryServiceImpl implements DocTemplateCategoryService {
+
+ @Resource
+ private DocTemplateCategoryMapper templateCategoryMapper;
+
+ @Override
+ public Long createTemplateCategory(DocTemplateCategorySaveReqVO createReqVO) {
+ // 插入
+ DocTemplateCategoryDO templateCategory = DocTemplateCategoryConvert.INSTANCE.convert(createReqVO);
+ // 设置默认值
+ if (templateCategory.getSort() == null) {
+ templateCategory.setSort(0);
+ }
+ templateCategoryMapper.insert(templateCategory);
+ // 返回
+ return templateCategory.getId();
+ }
+
+ @Override
+ public void updateTemplateCategory(DocTemplateCategorySaveReqVO updateReqVO) {
+ // 校验存在
+ validateTemplateCategoryExists(updateReqVO.getId());
+ // 更新
+ DocTemplateCategoryDO updateObj = DocTemplateCategoryConvert.INSTANCE.convert(updateReqVO);
+ templateCategoryMapper.updateById(updateObj);
+ }
+
+ @Override
+ public void deleteTemplateCategory(Long id) {
+ // 校验存在
+ validateTemplateCategoryExists(id);
+ // 删除
+ templateCategoryMapper.deleteById(id);
+ }
+
+ private void validateTemplateCategoryExists(Long id) {
+ if (templateCategoryMapper.selectById(id) == null) {
+ throw exception(TEMPLATE_CATEGORY_NOT_EXISTS);
+ }
+ }
+
+ @Override
+ public DocTemplateCategoryRespVO getTemplateCategory(Long id) {
+ DocTemplateCategoryDO templateCategory = templateCategoryMapper.selectById(id);
+ return DocTemplateCategoryConvert.INSTANCE.convert(templateCategory);
+ }
+
+ @Override
+ public PageResult getTemplateCategoryPage(DocTemplateCategoryPageReqVO pageReqVO) {
+ PageResult pageResult = templateCategoryMapper.selectPage(pageReqVO);
+ return DocTemplateCategoryConvert.INSTANCE.convertPage(pageResult);
+ }
+
+ @Override
+ public List getTemplateCategoryList() {
+ List list = templateCategoryMapper.selectList();
+ return DocTemplateCategoryConvert.INSTANCE.convertList(list);
+ }
+
+ @Override
+ public List buildTree() {
+ // 1. 查询所有分类数据
+ List allCategories = templateCategoryMapper.selectList();
+
+ // 2. 转换为 VO
+ List categoryVOs = DocTemplateCategoryConvert.INSTANCE.convertList(allCategories);
+
+ // 3. 构建树形结构
+ return buildTreeStructure(categoryVOs);
+ }
+
+ /**
+ * 构建树形结构
+ */
+ private List buildTreeStructure(List categories) {
+ // 1. 按 parentId 分组
+ Map> groupByParentId = categories.stream()
+ .collect(Collectors.groupingBy(node ->
+ node.getParentId() != null ? node.getParentId().toString() : "null"));
+
+ // 2. 设置子节点并排序
+ categories.forEach(node -> {
+ List children = groupByParentId.get(node.getId().toString());
+ if (children != null && !children.isEmpty()) {
+ // 按排序号升序排列
+ children.sort(Comparator.comparing(DocTemplateCategoryRespVO::getSort,
+ Comparator.nullsLast(Comparator.naturalOrder())));
+ node.setChildren(children);
+ }
+ });
+
+ // 3. 返回根节点(parentId 为 null 的节点)
+ List rootNodes = groupByParentId.get("null");
+ if (rootNodes != null) {
+ // 根节点也要排序
+ rootNodes.sort(Comparator.comparing(DocTemplateCategoryRespVO::getSort,
+ Comparator.nullsLast(Comparator.naturalOrder())));
+ return rootNodes;
+ }
+ return List.of();
+ }
+
+ @Override
+ public String getCategoryFullPath(Long categoryId) {
+ if (categoryId == null) {
+ return "";
+ }
+
+ // 构建分类路径
+ List pathNames = new ArrayList<>();
+ Long currentId = categoryId;
+
+ // 递归查找父级分类
+ while (currentId != null) {
+ DocTemplateCategoryDO category = templateCategoryMapper.selectById(currentId);
+ if (category == null) {
+ break;
+ }
+ // 将当前分类名称添加到列表开头
+ pathNames.add(0, category.getCategoryName());
+ // 继续查找父级
+ currentId = category.getParentId();
+ }
+
+ // 用"/"拼接分类路径
+ return String.join("/", pathNames);
+ }
+
+}
diff --git a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/service/doctemplate/DocTemplateInstanceService.java b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/service/doctemplate/DocTemplateInstanceService.java
new file mode 100644
index 0000000..4c9acf2
--- /dev/null
+++ b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/service/doctemplate/DocTemplateInstanceService.java
@@ -0,0 +1,63 @@
+package com.zt.plat.module.base.service.doctemplate;
+
+import com.zt.plat.framework.common.pojo.PageResult;
+import com.zt.plat.module.base.controller.admin.doctemplate.vo.DocTemplateInstancePageReqVO;
+import com.zt.plat.module.base.controller.admin.doctemplate.vo.DocTemplateInstanceRespVO;
+import com.zt.plat.module.base.controller.admin.doctemplate.vo.DocTemplateInstanceSaveReqVO;
+
+import jakarta.validation.Valid;
+import java.util.List;
+
+/**
+ * 模板实例 Service 接口
+ *
+ * @author 系统生成
+ */
+public interface DocTemplateInstanceService {
+
+ /**
+ * 创建模板实例
+ *
+ * @param createReqVO 创建信息
+ * @return 编号
+ */
+ Long createTemplateInstance(@Valid DocTemplateInstanceSaveReqVO createReqVO);
+
+ /**
+ * 更新模板实例
+ *
+ * @param updateReqVO 更新信息
+ */
+ void updateTemplateInstance(@Valid DocTemplateInstanceSaveReqVO updateReqVO);
+
+ /**
+ * 删除模板实例
+ *
+ * @param id 编号
+ */
+ void deleteTemplateInstance(Long id);
+
+ /**
+ * 获得模板实例
+ *
+ * @param id 编号
+ * @return 模板实例
+ */
+ DocTemplateInstanceRespVO getTemplateInstance(Long id);
+
+ /**
+ * 获得模板实例分页
+ *
+ * @param pageReqVO 分页查询
+ * @return 模板实例分页
+ */
+ PageResult getTemplateInstancePage(DocTemplateInstancePageReqVO pageReqVO);
+
+ /**
+ * 获得模板实例列表
+ *
+ * @return 模板实例列表
+ */
+ List getTemplateInstanceList();
+
+}
diff --git a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/service/doctemplate/DocTemplateInstanceServiceImpl.java b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/service/doctemplate/DocTemplateInstanceServiceImpl.java
new file mode 100644
index 0000000..17100c4
--- /dev/null
+++ b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/service/doctemplate/DocTemplateInstanceServiceImpl.java
@@ -0,0 +1,136 @@
+package com.zt.plat.module.base.service.doctemplate;
+
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.zt.plat.framework.common.pojo.PageResult;
+import com.zt.plat.module.base.controller.admin.doctemplate.vo.DocTemplateInstancePageReqVO;
+import com.zt.plat.module.base.controller.admin.doctemplate.vo.DocTemplateInstanceRespVO;
+import com.zt.plat.module.base.controller.admin.doctemplate.vo.DocTemplateInstanceSaveReqVO;
+import com.zt.plat.module.base.convert.doctemplate.DocTemplateInstanceConvert;
+import com.zt.plat.module.base.dal.dataobject.doctemplate.DocTemplateInstanceDO;
+import com.zt.plat.module.base.dal.dataobject.doctemplate.DocTemplateDO;
+import com.zt.plat.module.base.dal.dao.doctemplate.DocTemplateInstanceMapper;
+import com.zt.plat.module.base.dal.dao.doctemplate.DocTemplateMapper;
+import org.springframework.stereotype.Service;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.transaction.annotation.Transactional;
+
+import jakarta.annotation.Resource;
+import java.util.List;
+
+import static com.zt.plat.framework.common.exception.util.ServiceExceptionUtil.exception;
+import static com.zt.plat.module.base.enums.ErrorCodeConstants.*;
+
+/**
+ * 模板实例 Service 实现类
+ *
+ * @author 系统生成
+ */
+@Service
+@Validated
+public class DocTemplateInstanceServiceImpl implements DocTemplateInstanceService {
+
+ @Resource
+ private DocTemplateInstanceMapper docTemplateInstanceMapper;
+
+ @Resource
+ private DocTemplateMapper docTemplateMapper;
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public Long createTemplateInstance(DocTemplateInstanceSaveReqVO createReqVO) {
+ // 校验模板存在
+ DocTemplateDO template = docTemplateMapper.selectById(createReqVO.getTemplateId());
+ if (template == null) {
+ throw exception(TEMPLATE_NOT_EXISTS);
+ }
+ // 校验实例编码唯一性
+ validateInstanceCodeUnique(null, createReqVO.getInstanceCode());
+
+ // 插入实例
+ DocTemplateInstanceDO templateInstance = DocTemplateInstanceConvert.INSTANCE.convert(createReqVO);
+ docTemplateInstanceMapper.insert(templateInstance);
+
+ // 更新模板使用次数
+ incrementTemplateUseCount(createReqVO.getTemplateId());
+
+ // 返回
+ return templateInstance.getId();
+ }
+
+ @Override
+ public void updateTemplateInstance(DocTemplateInstanceSaveReqVO updateReqVO) {
+ // 校验存在
+ validateTemplateInstanceExists(updateReqVO.getId());
+ // 校验实例编码唯一性
+ validateInstanceCodeUnique(updateReqVO.getId(), updateReqVO.getInstanceCode());
+ // 更新
+ DocTemplateInstanceDO updateObj = DocTemplateInstanceConvert.INSTANCE.convert(updateReqVO);
+ docTemplateInstanceMapper.updateById(updateObj);
+ }
+
+ @Override
+ public void deleteTemplateInstance(Long id) {
+ // 校验存在
+ validateTemplateInstanceExists(id);
+ // 删除
+ docTemplateInstanceMapper.deleteById(id);
+ }
+
+ private void validateTemplateInstanceExists(Long id) {
+ if (docTemplateInstanceMapper.selectById(id) == null) {
+ throw exception(TEMPLATE_INSTANCE_NOT_EXISTS);
+ }
+ }
+
+ /**
+ * 校验实例编码唯一性
+ */
+ private void validateInstanceCodeUnique(Long id, String instanceCode) {
+ if (StrUtil.isBlank(instanceCode)) {
+ return;
+ }
+ DocTemplateInstanceDO instance = docTemplateInstanceMapper.selectOne(new LambdaQueryWrapper()
+ .eq(DocTemplateInstanceDO::getInstanceCode, instanceCode));
+ if (instance == null) {
+ return;
+ }
+ // 如果是更新操作,排除自己
+ if (id != null && id.equals(instance.getId())) {
+ return;
+ }
+ throw exception(TEMPLATE_INSTANCE_CODE_DUPLICATE);
+ }
+
+ /**
+ * 增加模板使用次数
+ */
+ private void incrementTemplateUseCount(Long templateId) {
+ DocTemplateDO template = docTemplateMapper.selectById(templateId);
+ if (template != null) {
+ DocTemplateDO updateObj = new DocTemplateDO();
+ updateObj.setId(templateId);
+ updateObj.setUseCount(template.getUseCount() == null ? 1 : template.getUseCount() + 1);
+ docTemplateMapper.updateById(updateObj);
+ }
+ }
+
+ @Override
+ public DocTemplateInstanceRespVO getTemplateInstance(Long id) {
+ DocTemplateInstanceDO templateInstance = docTemplateInstanceMapper.selectById(id);
+ return DocTemplateInstanceConvert.INSTANCE.convert(templateInstance);
+ }
+
+ @Override
+ public PageResult getTemplateInstancePage(DocTemplateInstancePageReqVO pageReqVO) {
+ PageResult pageResult = docTemplateInstanceMapper.selectPage(pageReqVO);
+ return DocTemplateInstanceConvert.INSTANCE.convertPage(pageResult);
+ }
+
+ @Override
+ public List getTemplateInstanceList() {
+ List list = docTemplateInstanceMapper.selectList();
+ return DocTemplateInstanceConvert.INSTANCE.convertList(list);
+ }
+
+}
diff --git a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/service/doctemplate/DocTemplateRenderService.java b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/service/doctemplate/DocTemplateRenderService.java
new file mode 100644
index 0000000..277d3e0
--- /dev/null
+++ b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/service/doctemplate/DocTemplateRenderService.java
@@ -0,0 +1,31 @@
+package com.zt.plat.module.base.service.doctemplate;
+
+import java.util.Map;
+
+/**
+ * 文档模板渲染 Service 接口
+ *
+ * @author 系统生成
+ */
+public interface DocTemplateRenderService {
+
+ /**
+ * 渲染模板内容
+ *
+ * @param templateId 模板ID(可选,与instanceId二选一)
+ * @param instanceId 实例ID(可选,与templateId二选一)
+ * @param content 直接传入内容(可选,优先级最高)
+ * @param dataMap 数据Map(必填)
+ * @return 渲染后的内容
+ */
+ String render(Long templateId, Long instanceId, String content, Map dataMap);
+
+ /**
+ * 渲染模板并保存到实例
+ *
+ * @param instanceId 实例ID
+ * @param dataMap 数据Map
+ */
+ void renderAndSave(Long instanceId, Map dataMap);
+
+}
diff --git a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/service/doctemplate/DocTemplateRenderServiceImpl.java b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/service/doctemplate/DocTemplateRenderServiceImpl.java
new file mode 100644
index 0000000..18374ae
--- /dev/null
+++ b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/service/doctemplate/DocTemplateRenderServiceImpl.java
@@ -0,0 +1,144 @@
+package com.zt.plat.module.base.service.doctemplate;
+
+import cn.hutool.core.util.StrUtil;
+import com.zt.plat.module.base.dal.dataobject.doctemplate.DocTemplateDO;
+import com.zt.plat.module.base.dal.dataobject.doctemplate.DocTemplateInstanceDO;
+import com.zt.plat.module.base.dal.dao.doctemplate.DocTemplateMapper;
+import com.zt.plat.module.base.dal.dao.doctemplate.DocTemplateInstanceMapper;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.velocity.VelocityContext;
+import org.apache.velocity.app.Velocity;
+import org.springframework.stereotype.Service;
+
+import jakarta.annotation.PostConstruct;
+import jakarta.annotation.Resource;
+import java.io.StringWriter;
+import java.util.Map;
+import java.util.Properties;
+
+import static com.zt.plat.framework.common.exception.util.ServiceExceptionUtil.exception;
+import static com.zt.plat.module.base.enums.ErrorCodeConstants.*;
+
+/**
+ * 文档模板渲染 Service 实现类
+ * 使用 Apache Velocity 模板引擎进行渲染
+ *
+ * @author 系统生成
+ */
+@Service
+@Slf4j
+public class DocTemplateRenderServiceImpl implements DocTemplateRenderService {
+
+ @Resource
+ private DocTemplateMapper templateMapper;
+
+ @Resource
+ private DocTemplateInstanceMapper instanceMapper;
+
+ /**
+ * 初始化 Velocity 引擎
+ */
+ @PostConstruct
+ public void initVelocity() {
+ try {
+ Properties props = new Properties();
+ // 设置编码
+ props.setProperty("input.encoding", "UTF-8");
+ props.setProperty("output.encoding", "UTF-8");
+ // 设置资源加载器为字符串
+ props.setProperty("resource.loader", "string");
+ props.setProperty("string.resource.loader.class",
+ "org.apache.velocity.runtime.resource.loader.StringResourceLoader");
+ // 关闭日志(可选)
+ props.setProperty("runtime.log.logsystem.class",
+ "org.apache.velocity.runtime.log.NullLogChute");
+
+ Velocity.init(props);
+ log.info("Velocity 模板引擎初始化成功");
+ } catch (Exception e) {
+ log.error("Velocity 模板引擎初始化失败", e);
+ throw new RuntimeException("Velocity 模板引擎初始化失败", e);
+ }
+ }
+
+ @Override
+ public String render(Long templateId, Long instanceId, String content, Map dataMap) {
+ // 1. 获取模板内容
+ String templateContent = getTemplateContent(templateId, instanceId, content);
+
+ if (StrUtil.isBlank(templateContent)) {
+ throw exception(TEMPLATE_NOT_EXISTS);
+ }
+
+ // 2. 创建 Velocity 上下文
+ VelocityContext context = new VelocityContext();
+ if (dataMap != null && !dataMap.isEmpty()) {
+ dataMap.forEach(context::put);
+ }
+
+ // 3. 渲染模板
+ try {
+ StringWriter writer = new StringWriter();
+ Velocity.evaluate(context, writer, "DocTemplateRender", templateContent);
+ String result = writer.toString();
+
+ log.debug("模板渲染成功,数据量: {}, 内容长度: {}",
+ dataMap != null ? dataMap.size() : 0, result.length());
+
+ return result;
+ } catch (Exception e) {
+ log.error("模板渲染失败,templateId: {}, instanceId: {}", templateId, instanceId, e);
+ throw new RuntimeException("模板渲染失败: " + e.getMessage(), e);
+ }
+ }
+
+ @Override
+ public void renderAndSave(Long instanceId, Map dataMap) {
+ // 1. 校验实例存在
+ DocTemplateInstanceDO instance = instanceMapper.selectById(instanceId);
+ if (instance == null) {
+ throw exception(TEMPLATE_INSTANCE_NOT_EXISTS);
+ }
+
+ // 2. 渲染内容
+ String renderedContent = render(null, instanceId, null, dataMap);
+
+ // 3. 更新实例的渲染内容
+ DocTemplateInstanceDO updateObj = new DocTemplateInstanceDO();
+ updateObj.setId(instanceId);
+ updateObj.setRenderedContent(renderedContent);
+ instanceMapper.updateById(updateObj);
+
+ log.info("模板实例渲染并保存成功,instanceId: {}", instanceId);
+ }
+
+ /**
+ * 获取模板内容
+ * 优先级:content > instanceId > templateId
+ */
+ private String getTemplateContent(Long templateId, Long instanceId, String content) {
+ // 优先使用直接传入的内容
+ if (StrUtil.isNotBlank(content)) {
+ return content;
+ }
+
+ // 其次使用实例的编辑内容
+ if (instanceId != null) {
+ DocTemplateInstanceDO instance = instanceMapper.selectById(instanceId);
+ if (instance != null && StrUtil.isNotBlank(instance.getEditedContent())) {
+ return instance.getEditedContent();
+ }
+ }
+
+ // 最后使用模板内容
+ if (templateId != null) {
+ DocTemplateDO template = templateMapper.selectById(templateId);
+ if (template != null && StrUtil.isNotBlank(template.getContent())) {
+ return template.getContent();
+ }
+ }
+
+ return null;
+ }
+
+}
diff --git a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/service/doctemplate/DocTemplateService.java b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/service/doctemplate/DocTemplateService.java
new file mode 100644
index 0000000..4bc15f7
--- /dev/null
+++ b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/service/doctemplate/DocTemplateService.java
@@ -0,0 +1,63 @@
+package com.zt.plat.module.base.service.doctemplate;
+
+import com.zt.plat.framework.common.pojo.PageResult;
+import com.zt.plat.module.base.controller.admin.doctemplate.vo.DocTemplatePageReqVO;
+import com.zt.plat.module.base.controller.admin.doctemplate.vo.DocTemplateRespVO;
+import com.zt.plat.module.base.controller.admin.doctemplate.vo.DocTemplateSaveReqVO;
+
+import jakarta.validation.Valid;
+import java.util.List;
+
+/**
+ * 模板 Service 接口
+ *
+ * @author 系统生成
+ */
+public interface DocTemplateService {
+
+ /**
+ * 创建模板
+ *
+ * @param createReqVO 创建信息
+ * @return 编号
+ */
+ Long createTemplate(@Valid DocTemplateSaveReqVO createReqVO);
+
+ /**
+ * 更新模板
+ *
+ * @param updateReqVO 更新信息
+ */
+ void updateTemplate(@Valid DocTemplateSaveReqVO updateReqVO);
+
+ /**
+ * 删除模板
+ *
+ * @param id 编号
+ */
+ void deleteTemplate(Long id);
+
+ /**
+ * 获得模板
+ *
+ * @param id 编号
+ * @return 模板
+ */
+ DocTemplateRespVO getTemplate(Long id);
+
+ /**
+ * 获得模板分页
+ *
+ * @param pageReqVO 分页查询
+ * @return 模板分页
+ */
+ PageResult getTemplatePage(DocTemplatePageReqVO pageReqVO);
+
+ /**
+ * 获得模板列表
+ *
+ * @return 模板列表
+ */
+ List getTemplateList();
+
+}
diff --git a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/service/doctemplate/DocTemplateServiceImpl.java b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/service/doctemplate/DocTemplateServiceImpl.java
new file mode 100644
index 0000000..b5e353b
--- /dev/null
+++ b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/service/doctemplate/DocTemplateServiceImpl.java
@@ -0,0 +1,115 @@
+package com.zt.plat.module.base.service.doctemplate;
+
+import com.zt.plat.framework.common.pojo.PageResult;
+import com.zt.plat.module.base.controller.admin.doctemplate.vo.DocTemplatePageReqVO;
+import com.zt.plat.module.base.controller.admin.doctemplate.vo.DocTemplateRespVO;
+import com.zt.plat.module.base.controller.admin.doctemplate.vo.DocTemplateSaveReqVO;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.zt.plat.module.base.convert.doctemplate.DocTemplateConvert;
+import com.zt.plat.module.base.dal.dataobject.doctemplate.DocTemplateDO;
+import com.zt.plat.module.base.dal.dao.doctemplate.DocTemplateMapper;
+import org.springframework.stereotype.Service;
+import org.springframework.validation.annotation.Validated;
+
+import jakarta.annotation.Resource;
+import java.util.List;
+
+import static com.zt.plat.framework.common.exception.util.ServiceExceptionUtil.exception;
+import static com.zt.plat.module.base.enums.ErrorCodeConstants.*;
+
+/**
+ * 模板 Service 实现类
+ *
+ * @author 系统生成
+ */
+@Service
+@Validated
+public class DocTemplateServiceImpl implements DocTemplateService {
+
+ @Resource
+ private DocTemplateMapper templateMapper;
+
+ @Override
+ public Long createTemplate(DocTemplateSaveReqVO createReqVO) {
+ // 校验模板编码唯一性
+ validateTemplateCodeUnique(null, createReqVO.getTmplCode());
+
+ // 插入
+ DocTemplateDO template = DocTemplateConvert.INSTANCE.convert(createReqVO);
+ // 设置默认值
+ if (template.getUseCount() == null) {
+ template.setUseCount(0);
+ }
+ if (template.getEnabled() == null) {
+ template.setEnabled("2"); // 默认为草稿状态
+ }
+ templateMapper.insert(template);
+ // 返回
+ return template.getId();
+ }
+
+ @Override
+ public void updateTemplate(DocTemplateSaveReqVO updateReqVO) {
+ // 校验存在
+ validateTemplateExists(updateReqVO.getId());
+ // 校验模板编码唯一性
+ validateTemplateCodeUnique(updateReqVO.getId(), updateReqVO.getTmplCode());
+
+ // 更新
+ DocTemplateDO updateObj = DocTemplateConvert.INSTANCE.convert(updateReqVO);
+ templateMapper.updateById(updateObj);
+ }
+
+ @Override
+ public void deleteTemplate(Long id) {
+ // 校验存在
+ validateTemplateExists(id);
+ // 删除
+ templateMapper.deleteById(id);
+ }
+
+ private void validateTemplateExists(Long id) {
+ if (templateMapper.selectById(id) == null) {
+ throw exception(TEMPLATE_NOT_EXISTS);
+ }
+ }
+
+ /**
+ * 校验模板编码唯一性
+ */
+ private void validateTemplateCodeUnique(Long id, String tmplCode) {
+ if (StrUtil.isBlank(tmplCode)) {
+ return;
+ }
+ DocTemplateDO template = templateMapper.selectOne(new LambdaQueryWrapper()
+ .eq(DocTemplateDO::getTmplCode, tmplCode));
+ if (template == null) {
+ return;
+ }
+ // 如果是更新操作,排除自己
+ if (id != null && id.equals(template.getId())) {
+ return;
+ }
+ throw exception(TEMPLATE_CODE_DUPLICATE);
+ }
+
+ @Override
+ public DocTemplateRespVO getTemplate(Long id) {
+ DocTemplateDO template = templateMapper.selectById(id);
+ return DocTemplateConvert.INSTANCE.convert(template);
+ }
+
+ @Override
+ public PageResult getTemplatePage(DocTemplatePageReqVO pageReqVO) {
+ PageResult pageResult = templateMapper.selectPage(pageReqVO);
+ return DocTemplateConvert.INSTANCE.convertPage(pageResult);
+ }
+
+ @Override
+ public List getTemplateList() {
+ List list = templateMapper.selectList();
+ return DocTemplateConvert.INSTANCE.convertList(list);
+ }
+
+}
diff --git a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/service/doctemplate/DocTemplateTagService.java b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/service/doctemplate/DocTemplateTagService.java
new file mode 100644
index 0000000..15954ed
--- /dev/null
+++ b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/service/doctemplate/DocTemplateTagService.java
@@ -0,0 +1,63 @@
+package com.zt.plat.module.base.service.doctemplate;
+
+import com.zt.plat.framework.common.pojo.PageResult;
+import com.zt.plat.module.base.controller.admin.doctemplate.vo.DocTemplateTagPageReqVO;
+import com.zt.plat.module.base.controller.admin.doctemplate.vo.DocTemplateTagRespVO;
+import com.zt.plat.module.base.controller.admin.doctemplate.vo.DocTemplateTagSaveReqVO;
+
+import jakarta.validation.Valid;
+import java.util.List;
+
+/**
+ * 标签库 Service 接口
+ *
+ * @author 系统生成
+ */
+public interface DocTemplateTagService {
+
+ /**
+ * 创建标签
+ *
+ * @param createReqVO 创建信息
+ * @return 编号
+ */
+ Long createTemplateTag(@Valid DocTemplateTagSaveReqVO createReqVO);
+
+ /**
+ * 更新标签
+ *
+ * @param updateReqVO 更新信息
+ */
+ void updateTemplateTag(@Valid DocTemplateTagSaveReqVO updateReqVO);
+
+ /**
+ * 删除标签
+ *
+ * @param id 编号
+ */
+ void deleteTemplateTag(Long id);
+
+ /**
+ * 获得标签
+ *
+ * @param id 编号
+ * @return 标签
+ */
+ DocTemplateTagRespVO getTemplateTag(Long id);
+
+ /**
+ * 获得标签分页
+ *
+ * @param pageReqVO 分页查询
+ * @return 标签分页
+ */
+ PageResult getTemplateTagPage(DocTemplateTagPageReqVO pageReqVO);
+
+ /**
+ * 获得标签列表
+ *
+ * @return 标签列表
+ */
+ List getTemplateTagList();
+
+}
diff --git a/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/service/doctemplate/DocTemplateTagServiceImpl.java b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/service/doctemplate/DocTemplateTagServiceImpl.java
new file mode 100644
index 0000000..194c6e9
--- /dev/null
+++ b/zt-module-base/zt-module-base-server/src/main/java/com/zt/plat/module/base/service/doctemplate/DocTemplateTagServiceImpl.java
@@ -0,0 +1,115 @@
+package com.zt.plat.module.base.service.doctemplate;
+
+import com.zt.plat.framework.common.pojo.PageResult;
+import com.zt.plat.module.base.controller.admin.doctemplate.vo.DocTemplateTagPageReqVO;
+import com.zt.plat.module.base.controller.admin.doctemplate.vo.DocTemplateTagRespVO;
+import com.zt.plat.module.base.controller.admin.doctemplate.vo.DocTemplateTagSaveReqVO;
+import com.zt.plat.module.base.convert.doctemplate.DocTemplateTagConvert;
+import com.zt.plat.module.base.dal.dataobject.doctemplate.DocTemplateTagDO;
+import com.zt.plat.module.base.dal.dao.doctemplate.DocTemplateTagMapper;
+import org.springframework.stereotype.Service;
+import org.springframework.validation.annotation.Validated;
+
+import jakarta.annotation.Resource;
+import java.util.List;
+
+import static com.zt.plat.framework.common.exception.util.ServiceExceptionUtil.exception;
+import static com.zt.plat.module.base.enums.ErrorCodeConstants.TEMPLATE_TAG_NOT_EXISTS;
+
+/**
+ * 标签库 Service 实现类
+ *
+ * @author 系统生成
+ */
+@Service
+@Validated
+public class DocTemplateTagServiceImpl implements DocTemplateTagService {
+
+ @Resource
+ private DocTemplateTagMapper templateTagMapper;
+
+ @Resource
+ private DocTemplateCategoryService templateCategoryService;
+
+ @Override
+ public Long createTemplateTag(DocTemplateTagSaveReqVO createReqVO) {
+ // 插入
+ DocTemplateTagDO templateTag = DocTemplateTagConvert.INSTANCE.convert(createReqVO);
+ // 设置默认值
+ if (templateTag.getSort() == null) {
+ templateTag.setSort(0);
+ }
+ if (templateTag.getEnabled() == null) {
+ templateTag.setEnabled("1");
+ }
+ templateTagMapper.insert(templateTag);
+ // 返回
+ return templateTag.getId();
+ }
+
+ @Override
+ public void updateTemplateTag(DocTemplateTagSaveReqVO updateReqVO) {
+ // 校验存在
+ validateTemplateTagExists(updateReqVO.getId());
+ // 更新
+ DocTemplateTagDO updateObj = DocTemplateTagConvert.INSTANCE.convert(updateReqVO);
+ templateTagMapper.updateById(updateObj);
+ }
+
+ @Override
+ public void deleteTemplateTag(Long id) {
+ // 校验存在
+ validateTemplateTagExists(id);
+ // 删除
+ templateTagMapper.deleteById(id);
+ }
+
+ private void validateTemplateTagExists(Long id) {
+ if (templateTagMapper.selectById(id) == null) {
+ throw exception(TEMPLATE_TAG_NOT_EXISTS);
+ }
+ }
+
+ @Override
+ public DocTemplateTagRespVO getTemplateTag(Long id) {
+ DocTemplateTagDO templateTag = templateTagMapper.selectById(id);
+ DocTemplateTagRespVO respVO = DocTemplateTagConvert.INSTANCE.convert(templateTag);
+ // 填充分类名称
+ fillCategoryName(respVO);
+ return respVO;
+ }
+
+ @Override
+ public PageResult getTemplateTagPage(DocTemplateTagPageReqVO pageReqVO) {
+ PageResult pageResult = templateTagMapper.selectPage(pageReqVO);
+ PageResult result = DocTemplateTagConvert.INSTANCE.convertPage(pageResult);
+ // 填充分类名称
+ result.getList().forEach(this::fillCategoryName);
+ return result;
+ }
+
+ @Override
+ public List getTemplateTagList() {
+ List list = templateTagMapper.selectList();
+ List result = DocTemplateTagConvert.INSTANCE.convertList(list);
+ // 填充分类名称
+ result.forEach(this::fillCategoryName);
+ return result;
+ }
+
+ /**
+ * 填充分类名称(包含父级路径)
+ *
+ * @param respVO 标签响应VO
+ */
+ private void fillCategoryName(DocTemplateTagRespVO respVO) {
+ if (respVO == null || respVO.getCategoryId() == null) {
+ return;
+ }
+
+ // 调用分类Service获取完整路径
+ String categoryPath = templateCategoryService.getCategoryFullPath(respVO.getCategoryId());
+ respVO.setCategoryName(categoryPath);
+ }
+
+}