Browse Source

refactor(crm): use shared settlement clause in contract print views

Wire ContractDetailDialog and detail page to settlementClause helpers so new settlement methods resolve fifth-clause text correctly.

Co-authored-by: Cursor <cursoragent@cursor.com>
zlwu 2 months ago
parent
commit
144e50f42d

+ 10 - 50
web-admin/src/views/crm/contract/components/ContractDetailDialog.vue

@@ -890,6 +890,10 @@ import UploadDialog from './UploadDialog.vue';
 import ContractFormDialog from './ContractFormDialog.vue';
 import ViewKvTable from '@/components/business/system-view-dialog/ViewKvTable.vue';
 import type { ViewField } from '@/components/business/system-view-dialog/types';
+import {
+  parseSettlementClauseDrafts,
+  resolveSettlementClauseContent
+} from '../settlementClause';
 
 const CustomerDetailDialog = defineAsyncComponent(
   () => import('@/views/crm/customer/CustomerDetailDialog.vue')
@@ -1864,36 +1868,12 @@ const replacePlaceholders = (htmlContent: string, contractData: ContractVO | und
     '<tr><td colspan="11" style="padding: 5px 6px; border: 0.3px solid #000; text-align: center; font-size: 12px;">暂无产品信息</td></tr>';
 
   // 定义替换映射表
-  const getDefaultSettlementClauseContent = (method?: string): string => {
-    if (method === 'advance_payment') {
-      return '款到发货。需方付款后安排发货,需方收到货物后,供方开具13%增值税专用发票。';
-    }
-    return '货到付款,需方收到供方货物后,供方开具13%增值税专用发票,无异议后,以现汇方式月结。';
-  };
-  const parseSettlementClauseDrafts = (raw?: string): Record<string, string> => {
-    if (!raw) return {};
-    try {
-      const parsed = JSON.parse(raw);
-      if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
-        return {};
-      }
-      const drafts: Record<string, string> = {};
-      Object.entries(parsed).forEach(([key, value]) => {
-        if (typeof value === 'string' && value.trim()) {
-          drafts[key] = value.trim();
-        }
-      });
-      return drafts;
-    } catch (error) {
-      console.warn('解析第五条草稿失败,使用默认文案', error);
-      return {};
-    }
-  };
-  const getSettlementClauseContent = (): string => {
-    const method = contractData.settlementMethod || 'arrive_payment';
-    const drafts = parseSettlementClauseDrafts(contractData.settlementClauseDrafts);
-    return drafts[method] || getDefaultSettlementClauseContent(method);
-  };
+  const getSettlementClauseContent = (): string =>
+    resolveSettlementClauseContent({
+      settlementMethod: contractData.settlementMethod,
+      settlementClauseDrafts: contractData.settlementClauseDrafts,
+      labelResolver: (method) => dictStore.getLabel('crm_settlement_method', method) || undefined
+    });
 
   const replacements: Record<string, string> = {
     // 合同基本信息
@@ -2068,26 +2048,6 @@ const extractFifthClauseContent = (htmlContent: string): string => {
   return content.replace(/\u00a0/g, ' ').trim();
 };
 
-const parseSettlementClauseDrafts = (raw?: string): Record<string, string> => {
-  if (!raw) return {};
-  try {
-    const parsed = JSON.parse(raw);
-    if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
-      return {};
-    }
-    const drafts: Record<string, string> = {};
-    Object.entries(parsed).forEach(([key, value]) => {
-      if (typeof value === 'string' && value.trim()) {
-        drafts[key] = value.trim();
-      }
-    });
-    return drafts;
-  } catch (error) {
-    console.warn('解析第五条草稿失败,使用空草稿', error);
-    return {};
-  }
-};
-
 /** 生成合同HTML模版 */
 const generateContractTemplate = (contractData: ContractVO | undefined): string => {
   if (!contractData) return '';

+ 10 - 32
web-admin/src/views/crm/contract/detail.vue

@@ -1085,6 +1085,10 @@ import TinyMceEditor from '@/components/TinyMceEditor/index.vue';
 import { getOpportunity } from '@/api/crm/opportunity';
 import { getQuote } from '@/api/crm/quote';
 import { isFrameworkContractType, isContractEditableStatus, getContractReeditConfirmMessage } from './contractType';
+import {
+  parseSettlementClauseDrafts,
+  resolveSettlementClauseContent
+} from './settlementClause';
 import {
   parseCrmAttachmentField,
   resolveCrmAttachmentFiles,
@@ -1415,38 +1419,12 @@ const handleGeneratePdf = async () => {
   }
 };
 
-const getDefaultSettlementClauseContent = (settlementMethod?: string): string => {
-  if (settlementMethod === 'advance_payment') {
-    return '款到发货。需方付款后安排发货,需方收到货物后,供方开具13%增值税专用发票。';
-  }
-  return '货到付款,需方收到供方货物后,供方开具13%增值税专用发票,无异议后,以现汇方式月结。';
-};
-
-const parseSettlementClauseDrafts = (raw?: string): Record<string, string> => {
-  if (!raw) return {};
-  try {
-    const parsed = JSON.parse(raw);
-    if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
-      return {};
-    }
-    const drafts: Record<string, string> = {};
-    Object.entries(parsed).forEach(([key, value]) => {
-      if (typeof value === 'string' && value.trim()) {
-        drafts[key] = value.trim();
-      }
-    });
-    return drafts;
-  } catch (error) {
-    console.warn('解析第五条草稿失败,回退到默认文案', error);
-    return {};
-  }
-};
-
-const getSettlementClauseContent = (contractData: ContractVO): string => {
-  const method = contractData.settlementMethod || 'arrive_payment';
-  const drafts = parseSettlementClauseDrafts(contractData.settlementClauseDrafts);
-  return drafts[method] || getDefaultSettlementClauseContent(method);
-};
+const getSettlementClauseContent = (contractData: ContractVO): string =>
+  resolveSettlementClauseContent({
+    settlementMethod: contractData.settlementMethod,
+    settlementClauseDrafts: contractData.settlementClauseDrafts,
+    labelResolver: (method) => dictStore.getLabel('crm_settlement_method', method) || undefined
+  });
 
 const extractSettlementClauseContent = (htmlContent: string): string => {
   const marker = '第五条、结算方式及期限';