feat(web-admin): add Generate Word on contract detail print dialog

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
zlwuandCursor committed 2026-09-05 14:50:00 +08:00
1 parent 9ac37d1196
commit 591736f11f
1 file changed
+54
@@ -1111,6 +1111,9 @@
{{ showRedSeal ? '隐藏红章' : '显示红章' }}
</el-button>
<el-button type="success" icon="Printer" @click="handlePrintContract">打印</el-button>
<el-button :loading="wordGenerating" @click="handleGenerateWordFile">
<el-icon><Document /></el-icon>生成 Word
</el-button>
<el-button type="primary" icon="Download" @click="handleGeneratePdfFile" :loading="pdfGenerating">生成PDF</el-button>
</div>
</template>
@@ -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 {