Fan преди 1 седмица
родител
ревизия
33d728b6de

+ 26 - 48
ui/smarttrade-platform/src/components/addMarketing.vue

@@ -210,14 +210,6 @@
                                     v-model="regionValue" clearable filterable @change="getRegion" />
                             </div>
                             <div class="form-group">
-                                <!-- <label class="form-label">行业</label>
-                                <el-select v-model="newCampaign.filters.industry" clearable placeholder="全部行业">
-                                    <el-option label="数据中心" value="datacenter" />
-                                    <el-option label="消费电子" value="consumer" />
-                                    <el-option label="电子分销" value="distributor" />
-                                    <el-option label="零售" value="retail" />
-                                    <el-option label="制造业" value="manufacturing" />
-                                </el-select> -->
                                 <label class="form-label">客户状态</label>
                                 <el-select v-model="customerParams.customerStatusDictValue" clearable placeholder="客户状态">
                                     <el-option label="暂无需求" value="1" />
@@ -235,12 +227,6 @@
                         </div>
                         <div class="filter-row">
                             <div class="form-group">
-                                <!-- <label class="form-label">意向分数</label>
-                                <el-select v-model="newCampaign.filters.scoreRange" clearable placeholder="不限">
-                                    <el-option label="80-100分" value="high" />
-                                    <el-option label="60-79分" value="medium" />
-                                    <el-option label="40-59分" value="low" />
-                                </el-select> -->
                                 <label class="form-label">客户类型</label>
                                 <el-select v-model="customerParams.customerTypeDictValue" clearable placeholder="客户类型">
                                     <el-option label="供应厂商" value="4" />
@@ -254,12 +240,6 @@
                                 </el-select>
                             </div>
                             <div class="form-group">
-                                <!-- <label class="form-label">客户规模</label>
-                                <el-select v-model="newCampaign.filters.companySize" clearable placeholder="不限">
-                                    <el-option label="大型企业(500+)" value="large" />
-                                    <el-option label="中型企业(100-500)" value="medium" />
-                                    <el-option label="小微企业(<100)" value="small" />
-                                </el-select> -->
                                 <label class="form-label">客户等级</label>
                                 <el-select v-model="customerParams.customerLevelDictValue" clearable placeholder="客户等级">
                                     <el-option label="A级" value="1" />
@@ -270,7 +250,7 @@
                             </div>
                         </div>
                         <!-- 自定义关键词搜索 -->
-                        <div class="form-group">
+                        <!-- <div class="form-group">
                             <label class="form-label">关键词搜索</label>
                             <div class="keyword-search">
                                 <el-input v-model="customerParams.blurry" placeholder="搜索公司名、联系人、产品关键词..." clearable />
@@ -278,14 +258,14 @@
                                     <i class="fas fa-search"></i>
                                 </button>
                             </div>
-                        </div>
+                        </div> -->
                         <!-- 已选客户标签 -->
-                        <div class="selected-tags" v-if="newCampaign.filters.selectedTags.length > 0">
+                        <!-- <div class="selected-tags" v-if="newCampaign.filters.selectedTags.length > 0">
                             <span v-for="tag in newCampaign.filters.selectedTags" :key="tag" class="selected-tag">
                                 {{ tag }}
                                 <i class="fas fa-times" @click="removeTag(tag)"></i>
                             </span>
-                        </div>
+                        </div> -->
                     </div>
 
                     <div class="preview-count">
@@ -296,8 +276,11 @@
                             </div>
                             <div class="count-detail">基于当前筛选条件</div>
                         </div>
-                        <button class="btn btn-sm btn-outline" @click="showCustomerPreview = true" v-if="customerList.length != 0">
-                            <i class="fas fa-eye"></i> 预览客户
+                        <button class="btn btn-sm btn-outline" @click="showCustomerDetail('add')">
+                            精确添加
+                        </button>
+                        <button class="btn btn-sm btn-outline" @click="showCustomerDetail('detail')" v-if="customerList.length != 0">
+                            客户详情
                         </button>
                     </div>
 
@@ -744,20 +727,16 @@
         </div>
     </div>
 
-    <PreviewCustomerModal
-      :visible="showCustomerPreview"
-      :customers="customerList"
-      @close="showCustomerPreview = false"
-    />
+    <CustomerDetail ref="customerDetailRef" />
 </template>
 
 <script setup>
     import { ref, computed } from 'vue'
-    import PreviewCustomerModal from './PreviewCustomerModal.vue'
     import { getSopList, addMarketing, editMarketing, addSop, editSop, getTradeCustomer } from '@/api/marketing'
     import { getListTree } from '@/api/layout'
     import { getUserEmails } from '@/api/emails'
     import { region } from '@/utils/region';
+    import CustomerDetail from '@/components/marketing/customerDetail.vue'
 
     const emits = defineEmits(['refresh'])
 
@@ -769,7 +748,7 @@
     const getDefaultCampaign = () => ({
         name: '', type: 'prospect', priority: 'medium', description: '',
         startDate: '', endDate: '', owner: [], relatedOpportunity: '',
-        segment: 'all', aiRecommend: 'high-value',
+        segment: '', aiRecommend: 'high-value',
         filters: {
             region: '', industry: '', scoreRange: '', stage: '', companySize: '', purchaseCycle: '',
             keyword: '', selectedTags: []
@@ -864,25 +843,20 @@
         }
     }
     const segmentOptions = [
-        { id: 'all', name: '全部潜客', count: 847, icon: 'fas fa-globe' },
-        { id: 'new', name: '本周新增', count: 56, icon: 'fas fa-star' },
-        { id: 'high-intent', name: '高评分客户', count: 124, icon: 'fas fa-fire' },
-        { id: 'silent', name: '沉默客户', count: 89, icon: 'fas fa-moon' }
+        { id: 'all', name: '全部潜客', count: 0, icon: 'fas fa-globe' },
+        { id: 'new', name: '本周新增', count: 0, icon: 'fas fa-star' },
+        { id: 'high-intent', name: '高评分客户', count: 0, icon: 'fas fa-fire' },
+        { id: 'silent', name: '沉默客户', count: 0, icon: 'fas fa-moon' }
     ]
     const availableChannels = [
         { id: 'email', name: '邮件营销', icon: 'fas fa-envelope', iconBg: 'rgba(99, 102, 241, 0.2)', iconColor: 'var(--primary)', description: '专业邮件营销', enabled: true, avgOpenRate: 45 },
     ]
-    const selectedCustomerCount = computed(() => {
-        const counts = { all: 847, new: 56, 'high-intent': 124, silent: 89 }
-        return counts[newCampaign.value.segment] || 847
-    })
-    const showCustomerPreview = ref(false)
-    const previewCustomers = ref([
-        // { id: 1, name: 'Riyadh Tech Distribution', company: 'Riyadh Tech Distribution', role: '采购总监', location: '沙特 · 利雅得', annualPurchase: '年采购约$1.5M', score: 92, tag: '潜客', logoText: 'RT' },
-        // { id: 2, name: 'Riyadh Tech Distribution', company: 'Riyadh Tech Distribution', role: '采购总监', location: '沙特 · 利雅得', annualPurchase: '年采购约$1.5M', score: 92, tag: '潜客', logoText: 'RT' },
-        // { id: 3, name: 'Riyadh Tech Distribution', company: 'Riyadh Tech Distribution', role: '采购总监', location: '沙特 · 利雅得', annualPurchase: '年采购约$1.5M', score: 92, tag: '潜客', logoText: 'RT' },
-        // { id: 4, name: 'Riyadh Tech Distribution', company: 'Riyadh Tech Distribution', role: '采购总监', location: '沙特 · 利雅得', annualPurchase: '年采购约$1.5M', score: 92, tag: '潜客', logoText: 'RT' }
-    ])
+    
+    const customerDetailRef = ref()
+    const showCustomerDetail = (type) => {
+        customerDetailRef.value.open()
+    }
+
     const sopTemplates = ref([])
     const getTypeLabel = (type) => ({ prospect: '潜客开发', nurture: '客户培育', reactivate: '客户唤醒', promote: '产品推广', seasonal: '节日营销', exhibition: '展会跟进' }[type] || type)
     const getPriorityLabel = (priority) => ({ urgent: '紧急', high: '高优先', medium: '中等', low: '低优先' }[priority] || priority)
@@ -1049,6 +1023,10 @@
     const removeCustomSopStep = (index) => {
         if (customSopData.value.details.length > 1) {
             customSopData.value.details.splice(index, 1)
+            //重新排序customSopData.value.details里面的step字段
+            customSopData.value.details.forEach((step, idx) => {
+                step.step = idx + 1
+            })
         }
     }
 

+ 140 - 0
ui/smarttrade-platform/src/components/marketing/customerDetail.vue

@@ -0,0 +1,140 @@
+<template>
+    <div v-if="showCustomerPreview" class="modal-overlay" @click.self="showCustomerPreview = false">
+        <div class="modal" style="max-width: 860px;">
+            <div class="modal-header">
+                <div class="modal-title"><i class="fas fa-user-tag"></i>客户详情</div>
+                <button class="modal-close" @click="showCustomerPreview = false"><i class="fas fa-times"></i></button>
+            </div>
+            <div class="modal-body">
+                <div class="list-header">
+                    <el-form>
+                        <el-form-item label="">
+                            <el-input v-model="customerParams.blurry" :prefix-icon="Search" placeholder="搜索客户信息"></el-input>
+                        </el-form-item>
+                        <el-form-item label="">
+                            <el-input v-model="customerParams.liaisonName" :prefix-icon="Search" placeholder="搜索联系人"></el-input>
+                        </el-form-item>
+                        <el-form-item label="">
+                            <el-select v-model="customerParams.customerStatusDictValue" clearable placeholder="客户状态">
+                                <el-option label="暂无需求" value="1" />
+                                <el-option label="潜在客户" value="2" />
+                                <el-option label="意向客户" value="3" />
+                                <el-option label="忠诚客户" value="4" />
+                                <el-option label="了解产品" value="11" />
+                                <el-option label="正在跟进" value="22" />
+                                <el-option label="寄样试用" value="33" />
+                                <el-option label="意向购买" value="44" />
+                                <el-option label="准备付款" value="55" />
+                                <el-option label="暂时搁置" value="66" />
+                            </el-select>
+                        </el-form-item>
+                        <el-form-item label="">
+                            <el-cascader style="width: 100%" placeholder="区域名称" :options="region"
+                                    v-model="regionValue" clearable filterable @change="getRegion" />
+                        </el-form-item>
+                        <el-form-item label="">
+                            <el-select v-model="customerParams.customerTypeDictValue" clearable placeholder="客户类型">
+                                <el-option label="供应厂商" value="4" />
+                                <el-option label="代理合作" value="5" />
+                                <el-option label="普通客户" value="1" />
+                                <el-option label="友商客户" value="3" />
+                                <el-option label="定制客户" value="2" />
+                                <el-option label="内部客户" value="6" />
+                                <el-option label="客户保护" value="10" />
+                                <el-option label="协助项目" value="11" />
+                            </el-select>
+                        </el-form-item>
+                        <el-form-item label="">
+                            <el-select v-model="customerParams.customerLevelDictValue" clearable placeholder="客户等级">
+                                <el-option label="A级" value="1" />
+                                <el-option label="B级" value="2" />
+                                <el-option label="C级" value="3" />
+                                <el-option label="D级" value="4" />
+                            </el-select>
+                        </el-form-item>
+                    </el-form>
+                    <div class="btn-div">
+                        <button class="btn btn-primary" @click="getCustomerList">
+                            <el-icon><Search /></el-icon>搜索</button>
+                        <button class="btn btn-secondary" @click="resetCustomerParams">
+                            <el-icon><Refresh /></el-icon>重置</button>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+</template>
+
+<script setup>
+    import { ref } from 'vue'
+    import { Search, Refresh } from '@element-plus/icons-vue'
+    import { region } from '@/utils/region';
+
+    const showCustomerPreview = ref(false)
+    const open = () => {
+        showCustomerPreview.value = true
+    }
+
+    const customerParams = ref({
+        blurry: '',
+        country: '',
+        customerStatusDictValue: '',
+        customerTypeDictValue: '',
+        customerLevelDictValue: '',
+        liaisonName: ''
+    })
+    const regionValue = ref([])
+    const getRegion = (value) => {
+        customerParams.value.country = value ? value[1] : ''
+    }
+
+    defineExpose({
+        open
+    })
+</script>
+
+<style scoped>
+    .modal :deep(.el-input__wrapper),
+    .modal :deep(.el-select .el-select__wrapper) {
+        background: var(--bg-dark);
+        border: 1px solid var(--border);
+        box-shadow: none;
+        border-radius: 8px;
+        color: var(--text-primary);
+        width: 100%;
+        box-sizing: border-box;
+        min-width: 0;
+    }
+    .modal :deep(.el-input__inner){
+        background: transparent;
+        color: var(--text-primary);
+    }
+    .modal :deep(.el-select__selection .el-select__placeholder:not(.is-transparent)) {
+        color: var(--text-primary);
+    }
+    .list-header{
+        display: flex;
+        align-items: center;
+    }
+    .el-form{
+        flex: 1;
+        display: flex;
+        flex-wrap: wrap;
+        gap: 8px;
+    }
+    .el-form .el-form-item{
+        margin-bottom: 8px;
+    }
+    .el-form :deep(.el-input), .el-form :deep(.el-select), .el-form :deep(.el-cascader){
+        width: 200px;
+    }
+    .btn-div{
+        display: flex;
+        gap: 8px;
+    }
+    .btn-div .btn{
+        border-radius: 5px;
+        height: 32px;
+        padding: 10px 13px;
+    }
+</style>

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

@@ -1334,12 +1334,12 @@ const toggleCampaign = (c) => { c.status = c.status === 'paused' ? 'active' : 'p
 const sopDetails = ref()
 const showCampaignDetail = (campaign) => {
   selectedCampaign.value = campaign
+  showCampaignDetailModal.value = true
   getSopById(campaign.sopId).then(res => {
     if(res.code == 200){
       sopDetails.value = res.result
     }
   })
-  showCampaignDetailModal.value = true
 }
 
 const showAllInteractions = () => {