diff --git a/xinnengyuan/pom.xml b/xinnengyuan/pom.xml
index a58859e2..6cfadc39 100644
--- a/xinnengyuan/pom.xml
+++ b/xinnengyuan/pom.xml
@@ -153,6 +153,13 @@
${springdoc.version}
+
+
+ org.springdoc
+ springdoc-openapi-starter-webmvc-ui
+ ${springdoc.version}
+
+
com.github.therapi
therapi-runtime-javadoc
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/pom.xml b/xinnengyuan/ruoyi-modules/ruoyi-system/pom.xml
index 91bcc716..c15e821d 100644
--- a/xinnengyuan/ruoyi-modules/ruoyi-system/pom.xml
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/pom.xml
@@ -15,6 +15,50 @@
system系统模块
+
+
+
+
+ org.docx4j
+ docx4j-core
+ 11.5.3
+
+
+
+ org.docx4j
+ docx4j-JAXB-ReferenceImpl
+ 11.5.3
+
+
+
+ org.docx4j
+ docx4j-export-fo
+ 11.5.3
+
+
+ org.apache.pdfbox
+ pdfbox
+
+
+ org.apache.pdfbox
+ fontbox
+
+
+
+
+
+ org.apache.pdfbox
+ pdfbox
+ 2.0.29
+
+
+
+ org.apache.pdfbox
+ fontbox
+ 2.0.29
+
+
+
@@ -104,6 +148,10 @@
org.dromara
ruoyi-common-jts
+
+ org.springframework
+ spring-test
+
org.dromara
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/common/constant/MinioPathConstant.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/common/constant/MinioPathConstant.java
new file mode 100644
index 00000000..431ae5b4
--- /dev/null
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/common/constant/MinioPathConstant.java
@@ -0,0 +1,14 @@
+package org.dromara.common.constant;
+
+/**
+ * @Author: Cory·铁憨憨
+ * @Date: 2025-07-03-14:12
+ * @Description: minio存储路线
+ */
+
+public interface MinioPathConstant {
+ // 联系单
+ String ContactNotice = "contactNotice";
+ // 联系单模板
+ String ContactNoticeTemplate = "contactNotice/template";
+}
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/common/utils/documentOperations/WordToPdfToImg.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/common/utils/documentOperations/WordToPdfToImg.java
new file mode 100644
index 00000000..0e2bc1e9
--- /dev/null
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/common/utils/documentOperations/WordToPdfToImg.java
@@ -0,0 +1,162 @@
+package org.dromara.common.utils.documentOperations;
+
+import jakarta.annotation.Resource;
+import org.docx4j.Docx4J;
+import org.docx4j.openpackaging.exceptions.Docx4JException;
+import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
+
+import org.apache.pdfbox.pdmodel.PDDocument;
+import org.apache.pdfbox.rendering.PDFRenderer;
+import org.dromara.common.oss.core.OssClient;
+import org.dromara.system.domain.vo.SysOssUploadVo;
+import org.dromara.system.service.ISysOssService;
+import org.springframework.mock.web.MockMultipartFile;
+import org.springframework.stereotype.Component;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.imageio.ImageIO;
+import java.awt.*;
+import java.awt.image.BufferedImage;
+import java.io.*;
+import java.util.*;
+import java.util.List;
+
+import static org.dromara.common.constant.MinioPathConstant.ContactNotice;
+
+@Component
+public class WordToPdfToImg {
+ @Resource
+ private ISysOssService ossService;
+
+ /**
+ * wordToImg 根据file生成缩略图(路径)
+ * @param file 文件
+ */
+ public String wordToImg(MultipartFile file) throws Docx4JException, IOException {
+ String mergedPath = "output/merged.png";
+ // ✅ 1. Word → PDF(内存)
+ ByteArrayOutputStream pdfOut = new ByteArrayOutputStream();
+ // 直接走路径
+ // WordprocessingMLPackage wordML = WordprocessingMLPackage.load(new File(docxPath));
+ // 直接走文件,word不落地
+ WordprocessingMLPackage wordML = WordprocessingMLPackage.load(file.getInputStream());
+ Docx4J.toPDF(wordML, pdfOut);
+ // ✅ 2. PDF → 各页 PNG
+ List pages = new ArrayList<>();
+ try (PDDocument pdf = PDDocument.load(new ByteArrayInputStream(pdfOut.toByteArray()))) {
+ PDFRenderer renderer = new PDFRenderer(pdf);
+ for (int i = 0; i < pdf.getNumberOfPages(); i++) {
+ BufferedImage img = renderer.renderImageWithDPI(i, 144);
+ pages.add(img);
+// ImageIO.write(img, "png", new File(outDir, "page_" + i + ".png"));
+ }
+ }
+ // ✅ 3. 合成所有页为一张长图
+ int totalHeight = pages.stream().mapToInt(BufferedImage::getHeight).sum();
+ int maxWidth = pages.stream().mapToInt(BufferedImage::getWidth).max().orElse(0);
+ BufferedImage merged = new BufferedImage(maxWidth, totalHeight, BufferedImage.TYPE_INT_RGB);
+ Graphics2D g = merged.createGraphics();
+ g.setColor(Color.WHITE);
+ g.fillRect(0, 0, maxWidth, totalHeight);
+
+ int y = 0;
+ for (BufferedImage img : pages) {
+ g.drawImage(img, 0, y, null);
+ y += img.getHeight();
+ }
+ g.dispose();
+ ImageIO.write(merged, "png", new File(mergedPath));
+ System.out.println("✅ 成功合并图片:" + mergedPath);
+ return mergedPath;
+ }
+
+
+ /**
+ * convertWordToImage 根据MultipartFile转成缩略图 并上传至minio
+ * @param wordFile 文件
+ */
+ public SysOssUploadVo convertWordToImage(MultipartFile wordFile) throws Exception {
+ // 1. Word -> PDF (内存)
+ WordprocessingMLPackage wordML = WordprocessingMLPackage.load(wordFile.getInputStream());
+ ByteArrayOutputStream pdfOut = new ByteArrayOutputStream();
+ Docx4J.toPDF(wordML, pdfOut);
+
+ // 2. PDF -> BufferedImage 每页
+ List pages = new ArrayList<>();
+ try (PDDocument document = PDDocument.load(new ByteArrayInputStream(pdfOut.toByteArray()))) {
+ PDFRenderer renderer = new PDFRenderer(document);
+ for (int i = 0; i < document.getNumberOfPages(); i++) {
+ BufferedImage img = renderer.renderImageWithDPI(i, 144);
+ pages.add(img);
+ }
+ }
+
+ // 3. 合并图片为一张长图
+ int width = pages.stream().mapToInt(BufferedImage::getWidth).max().orElse(0);
+ int totalHeight = pages.stream().mapToInt(BufferedImage::getHeight).sum();
+
+ BufferedImage merged = new BufferedImage(width, totalHeight, BufferedImage.TYPE_INT_RGB);
+ Graphics2D g = merged.createGraphics();
+ g.setColor(Color.WHITE);
+ g.fillRect(0, 0, width, totalHeight);
+
+ int y = 0;
+ for (BufferedImage img : pages) {
+ g.drawImage(img, 0, y, null);
+ y += img.getHeight();
+ }
+ g.dispose();
+
+ // 4. 写入 ByteArrayOutputStream 并转换为 MultipartFile
+ ByteArrayOutputStream imageOut = new ByteArrayOutputStream();
+ ImageIO.write(merged, "png", imageOut);
+
+ MockMultipartFile image = new MockMultipartFile(
+ "image", // 字段名
+ wordFile.getOriginalFilename() + ".png", // 文件名
+ "image/png", // ContentType
+ new ByteArrayInputStream(imageOut.toByteArray()) // 文件内容
+ );
+ return ossService.uploadWithNoSave(image,ossService.minioFileName(ContactNotice,wordFile));
+ }
+
+// public static void main(String[] args) throws Exception {
+// String docxPath = "C:\\Users\\YuanJie-DSJ\\Downloads\\123.docx";
+// String outDir = "output/pages";
+// String mergedPath = "output/merged.png";
+//
+// new File(outDir).mkdirs();
+//
+// // ✅ 1. Word → PDF(内存)
+// ByteArrayOutputStream pdfOut = new ByteArrayOutputStream();
+// WordprocessingMLPackage wordML = WordprocessingMLPackage.load(new File(docxPath));
+// Docx4J.toPDF(wordML, pdfOut); // 推荐 facade 方法 :contentReference[oaicite:2]{index=2}
+// // ✅ 2. PDF → 各页 PNG
+// List pages = new ArrayList<>();
+// try (PDDocument pdf = PDDocument.load(new ByteArrayInputStream(pdfOut.toByteArray()))) {
+// PDFRenderer renderer = new PDFRenderer(pdf);
+// for (int i = 0; i < pdf.getNumberOfPages(); i++) {
+// BufferedImage img = renderer.renderImageWithDPI(i, 144);
+// pages.add(img);
+//// ImageIO.write(img, "png", new File(outDir, "page_" + i + ".png"));
+// }
+// }
+// // ✅ 3. 合成所有页为一张长图
+// int totalHeight = pages.stream().mapToInt(BufferedImage::getHeight).sum();
+// int maxWidth = pages.stream().mapToInt(BufferedImage::getWidth).max().orElse(0);
+// BufferedImage merged = new BufferedImage(maxWidth, totalHeight, BufferedImage.TYPE_INT_RGB);
+// Graphics2D g = merged.createGraphics();
+// g.setColor(Color.WHITE);
+// g.fillRect(0, 0, maxWidth, totalHeight);
+//
+// int y = 0;
+// for (BufferedImage img : pages) {
+// g.drawImage(img, 0, y, null);
+// y += img.getHeight();
+// }
+// g.dispose();
+//
+// ImageIO.write(merged, "png", new File(mergedPath));
+// System.out.println("✅ 成功合并图片:" + mergedPath);
+// }
+}
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/cory/controller/BusContactformtemplateController.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/cory/controller/BusContactformtemplateController.java
new file mode 100644
index 00000000..a864086a
--- /dev/null
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/cory/controller/BusContactformtemplateController.java
@@ -0,0 +1,105 @@
+package org.dromara.cory.controller;
+
+import java.util.List;
+
+import lombok.RequiredArgsConstructor;
+import jakarta.servlet.http.HttpServletResponse;
+import jakarta.validation.constraints.*;
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.validation.annotation.Validated;
+import org.dromara.common.idempotent.annotation.RepeatSubmit;
+import org.dromara.common.log.annotation.Log;
+import org.dromara.common.web.core.BaseController;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import org.dromara.common.log.enums.BusinessType;
+import org.dromara.common.excel.utils.ExcelUtil;
+import org.dromara.cory.domain.vo.BusContactformtemplateVo;
+import org.dromara.cory.domain.bo.BusContactformtemplateBo;
+import org.dromara.cory.service.IBusContactformtemplateService;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+
+/**
+ * 联系单模板
+ *
+ * @author Lion Li
+ * @date 2025-07-03
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/cory/contactformtemplate")
+public class BusContactformtemplateController extends BaseController {
+
+ private final IBusContactformtemplateService busContactformtemplateService;
+
+ /**
+ * 查询联系单模板列表
+ */
+ @SaCheckPermission("cory:contactformtemplate:list")
+ @GetMapping("/list")
+ public TableDataInfo list(BusContactformtemplateBo bo, PageQuery pageQuery) {
+ return busContactformtemplateService.queryPageList(bo, pageQuery);
+ }
+
+ /**
+ * 导出联系单模板列表
+ */
+ @SaCheckPermission("cory:contactformtemplate:export")
+ @Log(title = "联系单模板", businessType = BusinessType.EXPORT)
+ @PostMapping("/export")
+ public void export(BusContactformtemplateBo bo, HttpServletResponse response) {
+ List list = busContactformtemplateService.queryList(bo);
+ ExcelUtil.exportExcel(list, "联系单模板", BusContactformtemplateVo.class, response);
+ }
+
+ /**
+ * 获取联系单模板详细信息
+ *
+ * @param id 主键
+ */
+ @SaCheckPermission("cory:contactformtemplate:query")
+ @GetMapping("/{id}")
+ public R getInfo(@NotNull(message = "主键不能为空")
+ @PathVariable Long id) {
+ return R.ok(busContactformtemplateService.queryById(id));
+ }
+
+ /**
+ * 新增联系单模板
+ */
+ @SaCheckPermission("cory:contactformtemplate:add")
+ @Log(title = "联系单模板", businessType = BusinessType.INSERT)
+ @RepeatSubmit()
+ @PostMapping()
+ public R add(@Validated(AddGroup.class) @RequestBody BusContactformtemplateBo bo) {
+ return toAjax(busContactformtemplateService.insertByBo(bo));
+ }
+
+ /**
+ * 修改联系单模板
+ */
+ @SaCheckPermission("cory:contactformtemplate:edit")
+ @Log(title = "联系单模板", businessType = BusinessType.UPDATE)
+ @RepeatSubmit()
+ @PutMapping()
+ public R edit(@Validated(EditGroup.class) @RequestBody BusContactformtemplateBo bo) {
+ return toAjax(busContactformtemplateService.updateByBo(bo));
+ }
+
+ /**
+ * 删除联系单模板
+ *
+ * @param ids 主键串
+ */
+ @SaCheckPermission("cory:contactformtemplate:remove")
+ @Log(title = "联系单模板", businessType = BusinessType.DELETE)
+ @DeleteMapping("/{ids}")
+ public R remove(@NotEmpty(message = "主键不能为空")
+ @PathVariable Long[] ids) {
+ return toAjax(busContactformtemplateService.deleteWithValidByIds(List.of(ids), true));
+ }
+}
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/cory/domain/BusContactformtemplate.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/cory/domain/BusContactformtemplate.java
new file mode 100644
index 00000000..7c90e55f
--- /dev/null
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/cory/domain/BusContactformtemplate.java
@@ -0,0 +1,59 @@
+package org.dromara.cory.domain;
+
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.dromara.common.translation.annotation.Translation;
+import org.dromara.common.translation.constant.TransConstant;
+
+import java.io.Serial;
+
+/**
+ * 联系单模板对象 bus_contactformtemplate
+ *
+ * @author Lion Li
+ * @date 2025-07-03
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("bus_contactformtemplate")
+public class BusContactformtemplate extends BaseEntity {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 自增ID
+ */
+ @TableId(value = "id")
+ private Long id;
+
+ /**
+ * 模板名称
+ */
+ private String name;
+
+ /**
+ * 模板路径
+ */
+ private String path;
+
+ /**
+ * 缩略图
+ */
+ private String thumbnail;
+
+ /**
+ * 删除标志(0代表存在 1代表删除)
+ */
+ @TableLogic
+ private String delFlag;
+
+ /**
+ * 备注
+ */
+ private String remark;
+
+
+}
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/cory/domain/bo/BusContactformtemplateBo.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/cory/domain/bo/BusContactformtemplateBo.java
new file mode 100644
index 00000000..a0182e29
--- /dev/null
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/cory/domain/bo/BusContactformtemplateBo.java
@@ -0,0 +1,49 @@
+package org.dromara.cory.domain.bo;
+
+import org.dromara.cory.domain.BusContactformtemplate;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import jakarta.validation.constraints.*;
+import org.dromara.common.translation.annotation.Translation;
+import org.dromara.common.translation.constant.TransConstant;
+import org.springframework.web.multipart.MultipartFile;
+
+/**
+ * 联系单模板业务对象 bus_contactformtemplate
+ *
+ * @author Lion Li
+ * @date 2025-07-03
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = BusContactformtemplate.class, reverseConvertGenerate = false)
+public class BusContactformtemplateBo extends BaseEntity {
+
+
+ /**
+ * 模板名称
+ */
+ private String name;
+
+ /**
+ * 模板路径
+ */
+ private String path;
+
+ /**
+ * 缩略图
+ */
+ private String thumbnail;
+
+ /**
+ * 备注
+ */
+ private String remark;
+
+
+ private MultipartFile file;
+}
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/cory/domain/vo/BusContactformtemplateVo.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/cory/domain/vo/BusContactformtemplateVo.java
new file mode 100644
index 00000000..fb6c7fcf
--- /dev/null
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/cory/domain/vo/BusContactformtemplateVo.java
@@ -0,0 +1,69 @@
+package org.dromara.cory.domain.vo;
+
+import org.dromara.common.translation.annotation.Translation;
+import org.dromara.common.translation.constant.TransConstant;
+import org.dromara.cory.domain.BusContactformtemplate;
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.alibaba.excel.annotation.ExcelProperty;
+import org.dromara.common.excel.annotation.ExcelDictFormat;
+import org.dromara.common.excel.convert.ExcelDictConvert;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.Date;
+
+
+
+/**
+ * 联系单模板视图对象 bus_contactformtemplate
+ *
+ * @author Lion Li
+ * @date 2025-07-03
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = BusContactformtemplate.class)
+public class BusContactformtemplateVo implements Serializable {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 自增ID
+ */
+ @ExcelProperty(value = "自增ID")
+ private Long id;
+
+ /**
+ * 模板名称
+ */
+ @ExcelProperty(value = "模板名称")
+ private String name;
+
+ /**
+ * 模板路径
+ */
+ @ExcelProperty(value = "模板路径")
+ private String path;
+
+ /**
+ * 缩略图
+ */
+ @ExcelProperty(value = "缩略图")
+ private String thumbnail;
+
+ /**
+ * 缩略图Url
+ */
+ @Translation(type = TransConstant.OSS_ID_TO_URL, mapper = "thumbnail")
+ private String thumbnailUrl;
+ /**
+ * 备注
+ */
+ @ExcelProperty(value = "备注")
+ private String remark;
+
+
+}
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/cory/mapper/BusContactformtemplateMapper.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/cory/mapper/BusContactformtemplateMapper.java
new file mode 100644
index 00000000..f8ed3dfa
--- /dev/null
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/cory/mapper/BusContactformtemplateMapper.java
@@ -0,0 +1,15 @@
+package org.dromara.cory.mapper;
+
+import org.dromara.cory.domain.BusContactformtemplate;
+import org.dromara.cory.domain.vo.BusContactformtemplateVo;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+
+/**
+ * 联系单模板Mapper接口
+ *
+ * @author Lion Li
+ * @date 2025-07-03
+ */
+public interface BusContactformtemplateMapper extends BaseMapperPlus {
+
+}
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/cory/service/IBusContactformtemplateService.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/cory/service/IBusContactformtemplateService.java
new file mode 100644
index 00000000..4f6c6822
--- /dev/null
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/cory/service/IBusContactformtemplateService.java
@@ -0,0 +1,70 @@
+package org.dromara.cory.service;
+
+import org.docx4j.openpackaging.exceptions.Docx4JException;
+import org.dromara.cory.domain.vo.BusContactformtemplateVo;
+import org.dromara.cory.domain.bo.BusContactformtemplateBo;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.core.page.PageQuery;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * 联系单模板Service接口
+ *
+ * @author Lion Li
+ * @date 2025-07-03
+ */
+public interface IBusContactformtemplateService {
+
+ /**
+ * 查询联系单模板
+ *
+ * @param id 主键
+ * @return 联系单模板
+ */
+ BusContactformtemplateVo queryById(Long id);
+
+ /**
+ * 分页查询联系单模板列表
+ *
+ * @param bo 查询条件
+ * @param pageQuery 分页参数
+ * @return 联系单模板分页列表
+ */
+ TableDataInfo queryPageList(BusContactformtemplateBo bo, PageQuery pageQuery);
+
+ /**
+ * 查询符合条件的联系单模板列表
+ *
+ * @param bo 查询条件
+ * @return 联系单模板列表
+ */
+ List queryList(BusContactformtemplateBo bo);
+
+ /**
+ * 新增联系单模板
+ *
+ * @param bo 联系单模板
+ * @return 是否新增成功
+ */
+ Boolean insertByBo(BusContactformtemplateBo bo);
+
+ /**
+ * 修改联系单模板
+ *
+ * @param bo 联系单模板
+ * @return 是否修改成功
+ */
+ Boolean updateByBo(BusContactformtemplateBo bo);
+
+ /**
+ * 校验并批量删除联系单模板信息
+ *
+ * @param ids 待删除的主键集合
+ * @param isValid 是否进行有效性校验
+ * @return 是否删除成功
+ */
+ Boolean deleteWithValidByIds(Collection ids, Boolean isValid);
+}
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/cory/service/impl/BusContactformtemplateServiceImpl.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/cory/service/impl/BusContactformtemplateServiceImpl.java
new file mode 100644
index 00000000..050a2b85
--- /dev/null
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/cory/service/impl/BusContactformtemplateServiceImpl.java
@@ -0,0 +1,161 @@
+package org.dromara.cory.service.impl;
+
+import jakarta.annotation.Resource;
+import org.docx4j.openpackaging.exceptions.Docx4JException;
+import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import lombok.RequiredArgsConstructor;
+import org.dromara.common.utils.documentOperations.WordToPdfToImg;
+import org.dromara.system.domain.vo.SysOssUploadVo;
+import org.dromara.system.service.ISysOssService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.dromara.cory.domain.bo.BusContactformtemplateBo;
+import org.dromara.cory.domain.vo.BusContactformtemplateVo;
+import org.dromara.cory.domain.BusContactformtemplate;
+import org.dromara.cory.mapper.BusContactformtemplateMapper;
+import org.dromara.cory.service.IBusContactformtemplateService;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+import java.util.Collection;
+import java.util.Objects;
+
+import static org.dromara.common.constant.MinioPathConstant.ContactNotice;
+import static org.dromara.common.constant.MinioPathConstant.ContactNoticeTemplate;
+
+/**
+ * 联系单模板Service业务层处理
+ *
+ * @author Lion Li
+ * @date 2025-07-03
+ */
+@RequiredArgsConstructor
+@Service
+public class BusContactformtemplateServiceImpl implements IBusContactformtemplateService {
+
+ private final BusContactformtemplateMapper baseMapper;
+
+ @Autowired
+ private ISysOssService ossService;
+
+
+ /**
+ * 查询联系单模板
+ *
+ * @param id 主键
+ * @return 联系单模板
+ */
+ @Override
+ public BusContactformtemplateVo queryById(Long id){
+ return baseMapper.selectVoById(id);
+ }
+
+ /**
+ * 分页查询联系单模板列表
+ *
+ * @param bo 查询条件
+ * @param pageQuery 分页参数
+ * @return 联系单模板分页列表
+ */
+ @Override
+ public TableDataInfo queryPageList(BusContactformtemplateBo bo, PageQuery pageQuery) {
+ LambdaQueryWrapper lqw = buildQueryWrapper(bo);
+ Page result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+ return TableDataInfo.build(result);
+ }
+
+ /**
+ * 查询符合条件的联系单模板列表
+ *
+ * @param bo 查询条件
+ * @return 联系单模板列表
+ */
+ @Override
+ public List queryList(BusContactformtemplateBo bo) {
+ LambdaQueryWrapper lqw = buildQueryWrapper(bo);
+ return baseMapper.selectVoList(lqw);
+ }
+
+ private LambdaQueryWrapper buildQueryWrapper(BusContactformtemplateBo bo) {
+ Map params = bo.getParams();
+ LambdaQueryWrapper lqw = Wrappers.lambdaQuery();
+ lqw.orderByAsc(BusContactformtemplate::getId);
+ lqw.like(StringUtils.isNotBlank(bo.getName()), BusContactformtemplate::getName, bo.getName());
+// lqw.eq(StringUtils.isNotBlank(bo.getPath()), BusContactformtemplate::getPath, bo.getPath());
+// lqw.eq(StringUtils.isNotBlank(bo.getThumbnail()), BusContactformtemplate::getThumbnail, bo.getThumbnail());
+ return lqw;
+ }
+
+ /**
+ * 新增联系单模板
+ *
+ * @param bo 联系单模板
+ * @return 是否新增成功
+ */
+ @Override
+ public Boolean insertByBo(BusContactformtemplateBo bo) {
+ //1、将word文档转换成图片,随后存储到minio
+ try {
+ MultipartFile file = bo.getFile();
+ SysOssUploadVo wordEntity = ossService.uploadWithNoSave(file, ossService.minioFileName(ContactNotice,file));
+ if (wordEntity==null) {
+ throw new RuntimeException("未找到word模板文件!");
+ }
+ SysOssUploadVo imgEntity = new WordToPdfToImg().convertWordToImage(file);
+ if (imgEntity==null) {
+ throw new RuntimeException("未找到缩略图模板文件!");
+ }
+ bo.setName(wordEntity.getUrl());
+ bo.setThumbnail(imgEntity.getUrl());
+ }catch (Exception e){
+ throw new RuntimeException("word转图片错误!"+e.getMessage());
+ }
+ //2、新增数据
+ BusContactformtemplate add = MapstructUtils.convert(bo, BusContactformtemplate.class);
+ validEntityBeforeSave(add);
+ return baseMapper.insert(add) > 0;
+ }
+
+ /**
+ * 修改联系单模板
+ *
+ * @param bo 联系单模板
+ * @return 是否修改成功
+ */
+ @Override
+ public Boolean updateByBo(BusContactformtemplateBo bo) {
+ BusContactformtemplate update = MapstructUtils.convert(bo, BusContactformtemplate.class);
+ validEntityBeforeSave(update);
+ return baseMapper.updateById(update) > 0;
+ }
+
+ /**
+ * 保存前的数据校验
+ */
+ private void validEntityBeforeSave(BusContactformtemplate entity){
+ //TODO 做一些数据校验,如唯一约束
+ }
+
+ /**
+ * 校验并批量删除联系单模板信息
+ *
+ * @param ids 待删除的主键集合
+ * @param isValid 是否进行有效性校验
+ * @return 是否删除成功
+ */
+ @Override
+ public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) {
+ if(isValid){
+ //TODO 做一些业务上的校验,判断是否需要校验
+ }
+ return baseMapper.deleteByIds(ids) > 0;
+ }
+}
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysOssService.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysOssService.java
index 77253dc3..24a1eb30 100644
--- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysOssService.java
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysOssService.java
@@ -116,4 +116,13 @@ public interface ISysOssService {
*/
Boolean deleteWithValidByIds(Collection ids, Boolean isValid);
+
+ /**
+ * MinioFileName 获取minio的即将存储文件的路径
+ * @param prefix 前缀(举例:prefix)
+ * @param file 为了获取后缀(举例:.png)
+ * @return 返回全路径
+ */
+ String minioFileName (String prefix, MultipartFile file);
+
}
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysOssServiceImpl.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysOssServiceImpl.java
index d2bf077d..210f0fbd 100644
--- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysOssServiceImpl.java
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysOssServiceImpl.java
@@ -386,4 +386,19 @@ public class SysOssServiceImpl implements ISysOssService, OssService {
}
return oss;
}
+
+
+ /**
+ * MinioFileName 获取minio的即将存储文件的路径
+ * @param prefix 前缀(举例:prefix)
+ * @param file 为了获取后缀(举例:.png)
+ * @return 返回全路径
+ */
+ @Override
+ public String minioFileName (String prefix, MultipartFile file) {
+ String originalFilename = file.getOriginalFilename();
+ String suffix = StringUtils.substring(originalFilename, originalFilename.lastIndexOf("."), originalFilename.length());
+ OssClient storage = OssFactory.instance();
+ return storage.getPath(prefix, suffix);
+ }
}
diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/cory/BusContactformtemplateMapper.xml b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/cory/BusContactformtemplateMapper.xml
new file mode 100644
index 00000000..75cc9f2a
--- /dev/null
+++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/cory/BusContactformtemplateMapper.xml
@@ -0,0 +1,7 @@
+
+
+
+
+