diff --git a/web-admin/src/views/crm/contract/detail.vue b/web-admin/src/views/crm/contract/detail.vue
index e6f6b2752..b8bdd6594 100644
--- a/web-admin/src/views/crm/contract/detail.vue
+++ b/web-admin/src/views/crm/contract/detail.vue
@@ -1111,6 +1111,9 @@
{{ showRedSeal ? '隐藏红章' : '显示红章' }}
打印
+
+ 生成 Word
+
生成PDF
@@ -1126,6 +1129,12 @@ import { list as listOperLog } from '@/api/monitor/operlog';
import type { OperLogVO, OperLogQuery } from '@/api/monitor/operlog/types';
import { parseTime } from '@/utils/format';
import { $modal } from '@/utils/modal'
+import FileSaver from 'file-saver'
+import {
+ buildContractDocxFileName,
+ generateContractDocxBlob,
+ prepareContractHtmlForDocx
+} from '@/utils/crm/contract-html-to-docx'
import { formatBrandForPrint } from '@/utils/crm-product-brand';
import { useDictStore } from '@/store/modules/dict';
import DictTag from '@/components/DictTag/index.vue';
@@ -1216,6 +1225,7 @@ const isPreviewMode = ref(false);
/** 打印弹窗内红章显隐(仅本次弹窗有效,打开时默认显示) */
const showRedSeal = ref(true);
const pdfGenerating = ref(false);
+const wordGenerating = ref(false);
/** 加载合同详情 */
const loadContractDetail = async () => {
@@ -2833,6 +2843,50 @@ const togglePreviewMode = () => {
isPreviewMode.value = !isPreviewMode.value;
};
+/** 从打印弹窗生成 Word */
+const handleGenerateWordFile = async () => {
+ if (!contract.value?.id) {
+ $modal.msgError('合同信息不存在');
+ return;
+ }
+
+ wordGenerating.value = true;
+ try {
+ $modal.loading('正在生成 Word...');
+
+ let htmlContent = contractContent.value;
+ const res = await getContract(contract.value.id);
+ if (res?.data) {
+ htmlContent = replacePlaceholders(htmlContent, res.data);
+ contractContent.value = htmlContent;
+ }
+
+ const prepared = prepareContractHtmlForDocx({
+ html: htmlContent,
+ contractNo: contract.value.contractNo,
+ origin: window.location.origin
+ });
+
+ const blob = await generateContractDocxBlob(
+ prepared,
+ contract.value.contractName || contract.value.contractNo
+ );
+ FileSaver.saveAs(
+ blob,
+ buildContractDocxFileName(contract.value.contractName, contract.value.contractNo)
+ );
+
+ $modal.closeLoading();
+ $modal.msgSuccess('Word 生成成功');
+ } catch (error) {
+ console.error('生成 Word 失败:', error);
+ $modal.closeLoading();
+ $modal.msgError('生成 Word 失败,请重试');
+ } finally {
+ wordGenerating.value = false;
+ }
+};
+
/** 生成PDF文件 */
const handleGeneratePdfFile = async () => {
try {