Pārlūkot izejas kodu

修改营销活动

Fan 3 nedēļas atpakaļ
vecāks
revīzija
42565b4f5f

+ 2 - 0
ui/smarttrade-platform/src/components/marketing/emailList.vue

@@ -69,6 +69,7 @@ import { useRouter } from 'vue-router'
 import { getEmailList, getEmailCount, cancelEmail } from '@/api/marketing'
 import { ElMessageBox } from 'element-plus'
 
+const emits = defineEmits(['refresh']);
 const selectedCampaign = ref(null)
 const emailList = ref([])
 
@@ -143,6 +144,7 @@ const cancelSend = (item) => {
       ElMessage.success('操作成功')
       getList()
       getStatusCounts()
+      emits('refresh')
     }).catch((err) => {
       ElMessage.error(err.message || '操作失败')
     })

+ 2 - 0
ui/smarttrade-platform/src/components/marketing/interventionCustomers.vue

@@ -61,6 +61,7 @@
     import { getInterventionCustomer, setProtectCustomer, setSuspendCustomer } from '@/api/marketing'
     import { ElMessageBox } from 'element-plus'
 
+    const emits = defineEmits(['refresh']);
     const showInterventionModal = ref(false);
     // 客户保护白名单 - 防止AI营销影响
     const protectedCustomersList = ref([])
@@ -102,6 +103,7 @@
         request(params).then(res => {
           getData()
           ElMessage.success('操作成功')
+          emits('refresh')
         }).catch(err => {
           ElMessage.error('操作失败')
         })

+ 4 - 10
ui/smarttrade-platform/src/components/marketing/openedCustomers.vue

@@ -78,19 +78,11 @@
     import { getOpenCustomer, setProtectCustomer, setSuspendCustomer } from '@/api/marketing'
     import { ElMessageBox } from 'element-plus'
 
+    const emits = defineEmits(['refresh']);
     const showOpenedCustomersModal = ref(false)
     const selectedOpenedCampaign = ref()
     // 打开邮件的客户列表 - 需要人工跟进
-    const openedCustomers = ref([
-        // { id: 1, name: '阿里巴巴国际', email: 'contact@alibaba-intl.com', openTime: '2026-03-23 10:30', clickCount: 2, status: 'opened', engagement: '高', value: '高价值', annualPurchase: '¥500K+', lastOrder: '2026-02-15', protected: true, protectionReason: '高价值客户', interventionStatus: 'assigned-to-sales' },
-        // { id: 2, name: '沙特阿美贸易', email: 'trade@aramco-sa.com', openTime: '2026-03-23 09:15', clickCount: 1, status: 'opened', engagement: '中', value: '中价值', annualPurchase: '¥200K', lastOrder: '2026-03-01', protected: true, protectionReason: '活跃客户', interventionStatus: 'pending-review' },
-        // { id: 3, name: '迪拜电子商务', email: 'info@dubai-ecom.ae', openTime: '2026-03-23 08:45', clickCount: 3, status: 'opened', engagement: '高', value: '高价值', annualPurchase: '¥800K+', lastOrder: '2026-02-28', protected: true, protectionReason: '高价值客户', interventionStatus: 'assigned-to-sales' },
-        // { id: 4, name: '新加坡科技', email: 'sales@sg-tech.com.sg', openTime: '2026-03-22 16:20', clickCount: 0, status: 'opened', engagement: '低', value: '低价值', annualPurchase: '¥50K', lastOrder: '2025-12-10', protected: false, protectionReason: '', interventionStatus: 'auto-follow' },
-        // { id: 5, name: '印度IT服务', email: 'contact@india-it.in', openTime: '2026-03-22 14:50', clickCount: 2, status: 'opened', engagement: '中', value: '中价值', annualPurchase: '¥150K', lastOrder: '2026-01-20', protected: true, protectionReason: '活跃客户', interventionStatus: 'pending-review' },
-        // { id: 6, name: '巴西进出口', email: 'export@brasil-trade.br', openTime: '2026-03-22 11:30', clickCount: 1, status: 'opened', engagement: '低', value: '低价值', annualPurchase: '¥30K', lastOrder: '2025-11-05', protected: false, protectionReason: '', interventionStatus: 'auto-follow' },
-        // { id: 7, name: '德国工业集团', email: 'procurement@de-industry.de', openTime: '2026-03-21 15:45', clickCount: 4, status: 'opened', engagement: '高', value: '高价值', annualPurchase: '¥1.2M+', lastOrder: '2026-03-10', protected: true, protectionReason: '高价值客户', interventionStatus: 'assigned-to-sales' },
-        // { id: 8, name: '英国分销商', email: 'sales@uk-dist.co.uk', openTime: '2026-03-21 13:20', clickCount: 2, status: 'opened', engagement: '中', value: '中价值', annualPurchase: '¥300K', lastOrder: '2026-02-20', protected: true, protectionReason: '活跃客户', interventionStatus: 'pending-review' }
-    ])
+    const openedCustomers = ref([])
 
     const loading = ref(false)
     const open = (data) => {
@@ -121,6 +113,7 @@
         setProtectCustomer(params).then(res => {
           customer.hasProtect = !customer.hasProtect
           ElMessage.success('操作成功')
+          emits('refresh')
         }).catch(err => {
           ElMessage.error('操作失败')
         })
@@ -144,6 +137,7 @@
         setSuspendCustomer(params).then(res => {
           customer.hasSuspend = !customer.hasSuspend
           ElMessage.success('操作成功')
+          emits('refresh')
         }).catch(err => {
           ElMessage.error('操作失败')
         })

+ 4 - 8
ui/smarttrade-platform/src/components/marketing/replyCustomers.vue

@@ -79,16 +79,10 @@
     import { getReplyCustomer, setProtectCustomer, setSuspendCustomer } from '@/api/marketing'
     import { ElMessageBox } from 'element-plus'
 
+    const emits = defineEmits(['refresh']);
     const showReplyReviewModal = ref(false);
     // 回复邮件的客户列表 - 需要人工审核和介入
-    const repliedCustomers = ref([
-        // { id: 1, name: '中东贸易公司', email: 'buyer@middle-east-trade.com', replyTime: '2026-03-23 11:45', replyContent: '感谢您的邮件,我们对您的产品很感兴趣,能否提供详细的产品规格和价格?', status: 'pending-review', sentiment: '正面', priority: '高', value: '高价值', annualPurchase: '¥600K+', lastOrder: '2026-02-10', requiresHumanReview: true, reviewNotes: '需要销售人员立即跟进,客户明确表示感兴趣', assignedTo: '', reviewedBy: '', reviewTime: '' },
-        // { id: 2, name: '欧洲数据中心', email: 'procurement@eu-datacenter.eu', replyTime: '2026-03-23 10:20', replyContent: '我们正在评估新的存储解决方案,您能否安排一次技术演示?', status: 'pending-review', sentiment: '正面', priority: '高', value: '高价值', annualPurchase: '¥1M+', lastOrder: '2026-03-05', requiresHumanReview: true, reviewNotes: '需要技术团队配合,安排产品演示', assignedTo: '', reviewedBy: '', reviewTime: '' },
-        // { id: 3, name: '北美分销', email: 'sales@na-dist.com', replyTime: '2026-03-22 16:30', replyContent: '价格太高了,能否提供折扣?', status: 'pending-review', sentiment: '中立', priority: '中', value: '中价值', annualPurchase: '¥250K', lastOrder: '2026-01-15', requiresHumanReview: true, reviewNotes: '需要销售经理评估折扣空间', assignedTo: '', reviewedBy: '', reviewTime: '' },
-        // { id: 4, name: '东南亚进口商', email: 'import@sea-import.com', replyTime: '2026-03-22 14:15', replyContent: '我们有兴趣,但需要了解更多关于技术支持的信息。', status: 'pending-review', sentiment: '正面', priority: '中', value: '中价值', annualPurchase: '¥180K', lastOrder: '2026-02-01', requiresHumanReview: true, reviewNotes: '需要技术支持团队提供详细信息', assignedTo: '', reviewedBy: '', reviewTime: '' },
-        // { id: 5, name: '日本电子商社', email: 'trade@japan-elec.jp', replyTime: '2026-03-21 17:00', replyContent: '暂时不需要,但会保留您的联系方式。', status: 'pending-review', sentiment: '中立', priority: '低', value: '低价值', annualPurchase: '¥80K', lastOrder: '2025-10-20', requiresHumanReview: false, reviewNotes: '可自动标记为后续跟进', assignedTo: '', reviewedBy: '', reviewTime: '' },
-        // { id: 6, name: '韩国科技公司', email: 'contact@korea-tech.kr', replyTime: '2026-03-21 15:30', replyContent: '这不是我们需要的产品类型。', status: 'pending-review', sentiment: '负面', priority: '低', value: '低价值', annualPurchase: '¥40K', lastOrder: '2025-09-10', requiresHumanReview: false, reviewNotes: '可自动标记为不适配,从列表中移除', assignedTo: '', reviewedBy: '', reviewTime: '' }
-    ])
+    const repliedCustomers = ref([])
 
     const loading = ref(false);
     const open = (data) => {
@@ -118,6 +112,7 @@
         setProtectCustomer(params).then(res => {
           customer.hasProtect = !customer.hasProtect
           ElMessage.success('操作成功')
+          emits('refresh')
         }).catch(err => {
           ElMessage.error('操作失败')
         })
@@ -141,6 +136,7 @@
         setSuspendCustomer(params).then(res => {
           customer.hasSuspend = !customer.hasSuspend
           ElMessage.success('操作成功')
+          emits('refresh')
         }).catch(err => {
           ElMessage.error('操作失败')
         })

+ 5 - 5
ui/smarttrade-platform/src/views/MarketingView.vue

@@ -110,7 +110,7 @@
         <div class="card-progress">
           <div class="progress-header">
             <span>进度</span>
-            <span>{{ (campaign.sentRate * 100) }}%</span>
+            <span>{{ (campaign.sentRate * 100).toFixed(2) }}%</span>
           </div>
           <div class="progress-bar">
             <div class="progress-fill" :style="{ width: (campaign.sentRate * 100) + '%' }"></div>
@@ -218,7 +218,7 @@
     <!-- AI Email Generator Modal -->
     <AiGenerator ref="aiGeneratorRef" />
 
-    <EmailList ref="emailListRef" />
+    <EmailList ref="emailListRef" @refresh="getData()" />
 
     <!-- History Modal -->
     <div v-if="showHistoryModal" class="modal-overlay" @click.self="showHistoryModal = false">
@@ -713,13 +713,13 @@
     </div>
 
     <!-- Opened Customers Modal -->
-    <OpenedCustomers ref="openedCustomersRef" />
+    <OpenedCustomers ref="openedCustomersRef" @refresh="getData()" />
 
     <!-- Reply Review Modal -->
-    <ReplyCustomers ref="replyCustomersRef" />
+    <ReplyCustomers ref="replyCustomersRef" @refresh="getData()" />
 
     <!-- Intervention Modal -->
-    <InterventionCustomers ref="interventionCustomersRef" />
+    <InterventionCustomers ref="interventionCustomersRef" @refresh="getData" />
 
     <transition name="toast">
       <div v-if="showToast" class="toast" :class="toastType">