|
|
@@ -1,210 +1,332 @@
|
|
|
<template>
|
|
|
- <div class="contents" v-if="item!=null">
|
|
|
- <div class="customer-title" >
|
|
|
- <div class="customer-name">
|
|
|
- {{ showDuplicate?item.customerName+"[从]":item.customerName}}
|
|
|
- <el-button size="mini" v-if="showDuplicate" v-hasPermi="['crm:customer:lookDuplicate']" @click=" getDetails" >主客户</el-button>
|
|
|
+ <div class="customer-detail-container" v-if="item!=null">
|
|
|
+ <!-- 顶部客户信息卡片 -->
|
|
|
+ <div class="customer-header-card">
|
|
|
+ <div class="customer-avatar">
|
|
|
+ <el-avatar :size="64" icon="el-icon-user-solid"></el-avatar>
|
|
|
+ </div>
|
|
|
+ <div class="customer-info">
|
|
|
+ <div class="customer-main-info">
|
|
|
+ <h2 class="customer-name-title">
|
|
|
+ {{ showDuplicate ? item.customerName + '[从]' : item.customerName }}
|
|
|
+ <el-tag v-if="item.status" :type="getStatusType(item.status)" size="medium"
|
|
|
+ style="margin-left: 12px;"
|
|
|
+ >
|
|
|
+ {{ getStatusText(item.status) }}
|
|
|
+ </el-tag>
|
|
|
+ </h2>
|
|
|
+ <div class="customer-meta">
|
|
|
+ <span class="meta-item">
|
|
|
+ <i class="el-icon-phone"></i>
|
|
|
+ {{ item.mobile || '未填写' }}
|
|
|
+ <el-button type="text" v-if="isReceive" size="mini"
|
|
|
+ @click="callNumber(item.customerId,null,null,null)" icon="el-icon-phone-outline"
|
|
|
+ >拨打</el-button>
|
|
|
+ <el-button type="text" v-if="isReceive" size="mini" @click="handleSms(item.mobile)"
|
|
|
+ icon="el-icon-message"
|
|
|
+ >短信</el-button>
|
|
|
+ </span>
|
|
|
+ <span class="meta-item">
|
|
|
+ <i class="el-icon-location"></i>
|
|
|
+ {{ item.address || '未填写' }}
|
|
|
+ </span>
|
|
|
+ <span class="meta-item">
|
|
|
+ <i class="el-icon-time"></i>
|
|
|
+ 创建于 {{ item.createTime }}
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="customer-actions">
|
|
|
+ <el-button type="primary" size="small" icon="el-icon-edit" v-hasPermi="['crm:customer:edit']"
|
|
|
+ @click="handleEdit()"
|
|
|
+ >编辑客户
|
|
|
+ </el-button>
|
|
|
+ <el-button type="warning" size="small" icon="el-icon-price-tag" v-hasPermi="['crm:customer:addTag']"
|
|
|
+ @click="handleAddTag()"
|
|
|
+ >打标签
|
|
|
+ </el-button>
|
|
|
+ <el-button type="info" size="small" icon="el-icon-document" v-hasPermi="['crm:customer:addRemark']"
|
|
|
+ @click="handleAddRemark()"
|
|
|
+ >备注
|
|
|
+ </el-button>
|
|
|
+ <el-button size="small" v-if="showDuplicate" v-hasPermi="['crm:customer:lookDuplicate']"
|
|
|
+ @click="getDetails"
|
|
|
+ >
|
|
|
+ 主客户
|
|
|
+ </el-button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 标签展示区 -->
|
|
|
+ <div class="customer-tags-section" v-if="item && item.tags">
|
|
|
+ <span class="tags-label">客户标签:</span>
|
|
|
+ <el-tag v-for="tag in item.tags.split(',')" :key="tag" size="small" effect="plain"
|
|
|
+ style="margin-right: 8px;"
|
|
|
+ >
|
|
|
+ {{ tag }}
|
|
|
+ </el-tag>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 信息分组展示 -->
|
|
|
+ <div class="info-sections">
|
|
|
+ <!-- 基本信息 -->
|
|
|
+ <div class="info-section">
|
|
|
+ <div class="section-header">
|
|
|
+ <span class="section-title"><i class="el-icon-user"></i> 基本信息</span>
|
|
|
+ </div>
|
|
|
+ <div class="section-content">
|
|
|
+ <el-row :gutter="24">
|
|
|
+ <el-col :span="6">
|
|
|
+ <div class="info-item">
|
|
|
+ <span class="info-label">客户编号</span>
|
|
|
+ <span class="info-value">{{ item.customerCode || '-' }}</span>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="6">
|
|
|
+ <div class="info-item">
|
|
|
+ <span class="info-label">客户名称</span>
|
|
|
+ <span class="info-value">{{ item.customerName || '-' }}</span>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="6">
|
|
|
+ <div class="info-item">
|
|
|
+ <span class="info-label">性别</span>
|
|
|
+ <span class="info-value">
|
|
|
+ <el-tag v-for="dict in sexOptions" :key="dict.dictValue"
|
|
|
+ v-if="item.sex==dict.dictValue" size="mini"
|
|
|
+ >{{ dict.dictLabel }}</el-tag>
|
|
|
+ <span v-if="!item.sex">-</span>
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="6">
|
|
|
+ <div class="info-item">
|
|
|
+ <span class="info-label">微信号</span>
|
|
|
+ <span class="info-value">{{ item.weixin || '-' }}</span>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ <el-row :gutter="24">
|
|
|
+ <el-col :span="6">
|
|
|
+ <div class="info-item">
|
|
|
+ <span class="info-label">客户来源</span>
|
|
|
+ <span class="info-value">
|
|
|
+ <el-tag v-for="dict in sourceOptions" :key="dict.dictValue"
|
|
|
+ v-if="item.source==dict.dictValue" size="mini" type="info"
|
|
|
+ >{{ dict.dictLabel }}</el-tag>
|
|
|
+ <span v-if="!item.source">-</span>
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="6">
|
|
|
+ <div class="info-item">
|
|
|
+ <span class="info-label">客户类型</span>
|
|
|
+ <span class="info-value">
|
|
|
+ <el-tag v-for="dict in typeOptions" :key="dict.dictValue"
|
|
|
+ v-if="item.customerType==dict.dictValue" size="mini" type="warning"
|
|
|
+ >{{ dict.dictLabel }}</el-tag>
|
|
|
+ <span v-if="!item.customerType">-</span>
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="6">
|
|
|
+ <div class="info-item">
|
|
|
+ <span class="info-label">最后一次跟进</span>
|
|
|
+ <span class="info-value">{{ item.visitTime || '-' }}</span>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="6">
|
|
|
+ <div class="info-item">
|
|
|
+ <span class="info-label">入公海时间</span>
|
|
|
+ <span class="info-value">{{ item.poolTime || '-' }}</span>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 购买信息 -->
|
|
|
+ <div class="info-section">
|
|
|
+ <div class="section-header">
|
|
|
+ <span class="section-title"><i class="el-icon-shopping-cart-2"></i> 购买信息</span>
|
|
|
+ </div>
|
|
|
+ <div class="section-content">
|
|
|
+ <el-row :gutter="24">
|
|
|
+ <el-col :span="6">
|
|
|
+ <div class="info-item">
|
|
|
+ <span class="info-label">购买渠道</span>
|
|
|
+ <span class="info-value">{{ item.platformName || '-' }}</span>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="6">
|
|
|
+ <div class="info-item">
|
|
|
+ <span class="info-label">购买商品</span>
|
|
|
+ <span class="info-value">{{ item.goodsName || '-' }} {{
|
|
|
+ item.goodsSpecification || ''
|
|
|
+ }}</span>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="6">
|
|
|
+ <div class="info-item">
|
|
|
+ <span class="info-label">购买店铺</span>
|
|
|
+ <span class="info-value">{{ item.shopName || '-' }}</span>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="6">
|
|
|
+ <div class="info-item">
|
|
|
+ <span class="info-label">消费金额</span>
|
|
|
+ <span class="info-value highlight">¥{{ item.payMoney || '0' }}</span>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ <el-row :gutter="24">
|
|
|
+ <el-col :span="6">
|
|
|
+ <div class="info-item">
|
|
|
+ <span class="info-label">购买次数</span>
|
|
|
+ <span class="info-value">{{ item.buyCount || '0' }} 次</span>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="6">
|
|
|
+ <div class="info-item">
|
|
|
+ <span class="info-label">来源渠道编码</span>
|
|
|
+ <span class="info-value">{{ item.sourceCode || '-' }}</span>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="6">
|
|
|
+ <div class="info-item">
|
|
|
+ <span class="info-label">推荐编码</span>
|
|
|
+ <span class="info-value">{{ item.pushCode || '-' }}</span>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="6">
|
|
|
+ <div class="info-item">
|
|
|
+ <span class="info-label">推荐时间</span>
|
|
|
+ <span class="info-value">{{ item.pushTime || '-' }}</span>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 进线信息 -->
|
|
|
+ <div class="info-section">
|
|
|
+ <div class="section-header">
|
|
|
+ <span class="section-title"><i class="el-icon-connection"></i> 进线信息</span>
|
|
|
+ </div>
|
|
|
+ <div class="section-content">
|
|
|
+ <el-row :gutter="24">
|
|
|
+ <el-col :span="6">
|
|
|
+ <div class="info-item">
|
|
|
+ <span class="info-label">进线日期</span>
|
|
|
+ <span class="info-value">{{ item.registerDate || '-' }}</span>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="6">
|
|
|
+ <div class="info-item">
|
|
|
+ <span class="info-label">进线方式</span>
|
|
|
+ <span class="info-value">{{ item.registerType || '-' }}</span>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="6">
|
|
|
+ <div class="info-item">
|
|
|
+ <span class="info-label">进线填写时间</span>
|
|
|
+ <span class="info-value">{{ item.registerSubmitTime || '-' }}</span>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="6">
|
|
|
+ <div class="info-item">
|
|
|
+ <span class="info-label">进线链接</span>
|
|
|
+ <span class="info-value text-ellipsis" :title="item.registerLinkUrl">{{
|
|
|
+ item.registerLinkUrl || '-'
|
|
|
+ }}</span>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ <el-row :gutter="24">
|
|
|
+ <el-col :span="24">
|
|
|
+ <div class="info-item">
|
|
|
+ <span class="info-label">进线客户详情</span>
|
|
|
+ <span class="info-value">{{ item.registerDesc || '-' }}</span>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 扩展信息 -->
|
|
|
+ <div class="info-section" v-if="exts && exts.length > 0">
|
|
|
+ <div class="section-header">
|
|
|
+ <span class="section-title"><i class="el-icon-tickets"></i> 扩展信息</span>
|
|
|
+ </div>
|
|
|
+ <div class="section-content">
|
|
|
+ <el-row :gutter="24">
|
|
|
+ <el-col :span="6" v-for="ext in exts" :key="ext.extId">
|
|
|
+ <div class="info-item">
|
|
|
+ <span class="info-label">{{ ext.name }}</span>
|
|
|
+ <span class="info-value">{{ ext.value || '-' }}</span>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 备注信息 -->
|
|
|
+ <div class="info-section" v-if="item.remark">
|
|
|
+ <div class="section-header">
|
|
|
+ <span class="section-title"><i class="el-icon-document"></i> 备注信息</span>
|
|
|
+ </div>
|
|
|
+ <div class="section-content">
|
|
|
+ <div class="remark-content">{{ item.remark }}</div>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
- <div>
|
|
|
- <el-button size="mini" v-hasPermi="['crm:customer:edit']" @click=" handleEdit()">修改客户</el-button>
|
|
|
- <el-button size="mini" v-hasPermi="['crm:customer:addTag']" @click=" handleAddTag()" >打标签</el-button>
|
|
|
- <el-button size="mini" v-hasPermi="['crm:customer:addRemark']" @click=" handleAddRemark()" >修改备注</el-button>
|
|
|
|
|
|
+ <!-- AI标签 -->
|
|
|
+ <div class="info-section">
|
|
|
+ <div class="ai-tag-wrapper" v-if="item && item.customerId">
|
|
|
+ <ai-tag-panel ref="aiTagPanel" :customer-id="item.customerId" @tag-change="handleTagChange"
|
|
|
+ ></ai-tag-panel>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
</div>
|
|
|
- <el-descriptions title="" :column="3" border>
|
|
|
- <el-descriptions-item label="客户编号" >
|
|
|
- <span v-if="item!=null">{{item.customerCode}}</span>
|
|
|
- </el-descriptions-item>
|
|
|
- <el-descriptions-item label="客户名称" >
|
|
|
- <span v-if="item!=null">{{item.customerName}}</span>
|
|
|
- </el-descriptions-item>
|
|
|
- <el-descriptions-item label="手机号" >
|
|
|
- <span v-if="item!=null">{{item.mobile}}</span>
|
|
|
- <el-button type="text" v-if="isReceive" size="mini" @click="callNumber(item.customerId,null,null,null)">拨号</el-button>
|
|
|
- <el-button type="text" v-if="isReceive" size="mini" @click="handleSms(item.mobile)">短信</el-button>
|
|
|
- <el-button icon="el-icon-search" size="mini" @click="handleMobile" style="margin-left: 20px;" circle v-hasPermi="['crm:customer:query2']"></el-button>
|
|
|
- </el-descriptions-item>
|
|
|
- <el-descriptions-item label="性别" >
|
|
|
- <span v-if="item!=null">
|
|
|
- <el-tag v-for="(dict, index) in sexOptions" v-if="item.sex==dict.dictValue">{{dict.dictLabel}}</el-tag>
|
|
|
- </span>
|
|
|
- </el-descriptions-item>
|
|
|
- <el-descriptions-item label="微信号" >
|
|
|
- <span v-if="item!=null">
|
|
|
- {{item.weixin}}
|
|
|
- </span>
|
|
|
- </el-descriptions-item>
|
|
|
- <el-descriptions-item label="所在地">
|
|
|
- <span v-if="item!=null">
|
|
|
- {{item.address}}
|
|
|
- </span>
|
|
|
- </el-descriptions-item>
|
|
|
- <el-descriptions-item label="客户来源" >
|
|
|
- <span v-if="item!=null">
|
|
|
- <el-tag v-for="(dict, index) in sourceOptions" v-if="item.source==dict.dictValue">{{dict.dictLabel}}</el-tag>
|
|
|
- </span>
|
|
|
- </el-descriptions-item>
|
|
|
- <el-descriptions-item label="客户类型" >
|
|
|
- <span v-if="item!=null">
|
|
|
- <el-tag v-for="(dict, index) in typeOptions" v-if="item.customerType==dict.dictValue">{{dict.dictLabel}}</el-tag>
|
|
|
- </span>
|
|
|
- </el-descriptions-item>
|
|
|
- <el-descriptions-item label="客户状态" >
|
|
|
- <span v-if="item!=null">
|
|
|
- <el-tag v-for="(dict, index) in statusOptions" v-if="item.status==dict.dictValue">{{dict.dictLabel}}</el-tag>
|
|
|
- </span>
|
|
|
- </el-descriptions-item>
|
|
|
- <el-descriptions-item label="创建时间" >
|
|
|
- <span v-if="item!=null">
|
|
|
- {{item.createTime}}
|
|
|
- </span>
|
|
|
- </el-descriptions-item>
|
|
|
- <el-descriptions-item label="最后一次跟进时间" label-class-name="my-label">
|
|
|
- <span v-if="item!=null">
|
|
|
- {{item.visitTime}}
|
|
|
- </span>
|
|
|
- </el-descriptions-item>
|
|
|
- <el-descriptions-item label="入公海时间" label-class-name="my-label">
|
|
|
- <span v-if="item!=null">
|
|
|
- {{item.poolTime}}
|
|
|
- </span>
|
|
|
- </el-descriptions-item>
|
|
|
-
|
|
|
- <el-descriptions-item label="标签" label-class-name="my-label">
|
|
|
- <span v-if="item!=null && item.tags != null">
|
|
|
- <el-tag v-for="tag in item.tags.split(',')" size="mini">{{ tag }}</el-tag>
|
|
|
- </span>
|
|
|
- <!-- <el-button size="mini" icon="el-icon-edit"></el-button> -->
|
|
|
- </el-descriptions-item>
|
|
|
-
|
|
|
- <el-descriptions-item label="进线日期" label-class-name="my-label">
|
|
|
- <span v-if="item!=null">
|
|
|
- {{item.registerDate}}
|
|
|
- </span>
|
|
|
- <!-- <el-button size="mini" icon="el-icon-edit"></el-button> -->
|
|
|
- </el-descriptions-item>
|
|
|
- <el-descriptions-item label="进线链接" label-class-name="my-label">
|
|
|
- <span v-if="item!=null">
|
|
|
- {{item.registerLinkUrl}}
|
|
|
- </span>
|
|
|
- <!-- <el-button size="mini" icon="el-icon-edit"></el-button> -->
|
|
|
- </el-descriptions-item>
|
|
|
- <el-descriptions-item label="进线客户详情" label-class-name="my-label">
|
|
|
- <span v-if="item!=null">
|
|
|
- {{item.registerDesc}}
|
|
|
- </span>
|
|
|
- <!-- <el-button size="mini" icon="el-icon-edit"></el-button> -->
|
|
|
- </el-descriptions-item>
|
|
|
- <el-descriptions-item label="进线客户填写时间" label-class-name="my-label">
|
|
|
- <span v-if="item!=null">
|
|
|
- {{item.registerSubmitTime}}
|
|
|
- </span>
|
|
|
- <!-- <el-button size="mini" icon="el-icon-edit"></el-button> -->
|
|
|
- </el-descriptions-item>
|
|
|
- <el-descriptions-item label="进线方式" label-class-name="my-label">
|
|
|
- <span v-if="item!=null">
|
|
|
- {{item.registerType}}
|
|
|
- </span>
|
|
|
- <!-- <el-button size="mini" icon="el-icon-edit"></el-button> -->
|
|
|
- </el-descriptions-item>
|
|
|
- <el-descriptions-item label="购买渠道" label-class-name="my-label">
|
|
|
- <span v-if="item!=null">
|
|
|
- {{item.platformName || ''}}
|
|
|
- </span>
|
|
|
-
|
|
|
- </el-descriptions-item>
|
|
|
- <el-descriptions-item label="购买商品" label-class-name="my-label">
|
|
|
- <span v-if="item!=null">
|
|
|
- {{item.goodsName || ''}} - {{item.goodsSpecification || ''}}
|
|
|
- </span>
|
|
|
-
|
|
|
- </el-descriptions-item>
|
|
|
- <el-descriptions-item label="购买店铺" label-class-name="my-label">
|
|
|
- <span v-if="item!=null">
|
|
|
- {{item.shopName || ''}}
|
|
|
- </span>
|
|
|
-
|
|
|
- </el-descriptions-item>
|
|
|
- <el-descriptions-item label="消费金额" label-class-name="my-label">
|
|
|
- <span v-if="item!=null">
|
|
|
- {{item.payMoney}}
|
|
|
- </span>
|
|
|
- <!-- <el-button size="mini" icon="el-icon-edit"></el-button> -->
|
|
|
- </el-descriptions-item>
|
|
|
- <el-descriptions-item label="购买次数" label-class-name="my-label">
|
|
|
- <span v-if="item!=null">
|
|
|
- {{item.buyCount}}
|
|
|
- </span>
|
|
|
- <!-- <el-button size="mini" icon="el-icon-edit"></el-button> -->
|
|
|
- </el-descriptions-item>
|
|
|
- <el-descriptions-item label="来源渠道编码" label-class-name="my-label">
|
|
|
- <span v-if="item!=null">
|
|
|
- {{item.sourceCode}}
|
|
|
- </span>
|
|
|
- <!-- <el-button size="mini" icon="el-icon-edit"></el-button> -->
|
|
|
- </el-descriptions-item>
|
|
|
- <el-descriptions-item label="推荐编码" label-class-name="my-label">
|
|
|
- <span v-if="item!=null">
|
|
|
- {{item.pushCode}}
|
|
|
- </span>
|
|
|
- <!-- <el-button size="mini" icon="el-icon-edit"></el-button> -->
|
|
|
- </el-descriptions-item>
|
|
|
- <el-descriptions-item label="推荐时间" label-class-name="my-label">
|
|
|
- <span v-if="item!=null">
|
|
|
- {{item.pushTime}}
|
|
|
- </span>
|
|
|
- <!-- <el-button size="mini" icon="el-icon-edit"></el-button> -->
|
|
|
- </el-descriptions-item>
|
|
|
-
|
|
|
- <el-descriptions-item :label="ext.name" v-for="ext in exts" label-class-name="my-label">
|
|
|
- <span >
|
|
|
- {{ext.value}}
|
|
|
- </span>
|
|
|
- </el-descriptions-item>
|
|
|
- <el-descriptions-item label="备注" label-class-name="my-label">
|
|
|
- <span v-if="item!=null">
|
|
|
- {{item.remark}}
|
|
|
- </span>
|
|
|
- <!-- <el-button size="mini" icon="el-icon-edit"></el-button> -->
|
|
|
- </el-descriptions-item>
|
|
|
-
|
|
|
- </el-descriptions>
|
|
|
-
|
|
|
- <el-tabs style="margin-top:15px;" z-index = "99" type="border-card" v-model="activeName" @tab-click="handleClick">
|
|
|
- <el-tab-pane label="跟进记录" name="visit">
|
|
|
- <customer-visit-list ref="visit"></customer-visit-list>
|
|
|
- </el-tab-pane>
|
|
|
- <el-tab-pane label="联系人" name="contacts">
|
|
|
- <customer-contacts ref="contacts"></customer-contacts>
|
|
|
- </el-tab-pane>
|
|
|
- <el-tab-pane label="订单记录" name="storeOrder">
|
|
|
- <customer-store-order-list ref="storeOrder"></customer-store-order-list>
|
|
|
- </el-tab-pane>
|
|
|
-
|
|
|
- <el-tab-pane label="通话记录" name="voiceLogs">
|
|
|
- <customer-voice-logs-list ref="voiceLogs"></customer-voice-logs-list>
|
|
|
- </el-tab-pane>
|
|
|
- <el-tab-pane label="短信记录" name="smsLogs">
|
|
|
- <customer-sms-logs-list ref="smsLogs"></customer-sms-logs-list>
|
|
|
- </el-tab-pane>
|
|
|
- <el-tab-pane label="客户日志" name="logs">
|
|
|
- <customer-logs-list ref="logs"></customer-logs-list>
|
|
|
- </el-tab-pane>
|
|
|
- <el-tab-pane label="历史订单" name="hisOrder">
|
|
|
- <customer-his-order-list ref="hisOrder"></customer-his-order-list>
|
|
|
- </el-tab-pane>
|
|
|
- <el-tab-pane label="AI通话记录" name="aiVoiceLogs">
|
|
|
- <ai-call-voice-log ref="aiVoiceRef"></ai-call-voice-log>
|
|
|
- </el-tab-pane>
|
|
|
- <el-tab-pane label="AI加微记录" name="aiAddWxLogs">
|
|
|
- <ai-add-wx-log ref="aiAddWxRef"></ai-add-wx-log>
|
|
|
- </el-tab-pane>
|
|
|
- <el-tab-pane label="AI短信记录" name="aiSendMsgLogs">
|
|
|
- <ai-send-msg-log ref="aiSendMsgRef"></ai-send-msg-log>
|
|
|
- </el-tab-pane>
|
|
|
- </el-tabs>
|
|
|
|
|
|
+ <!-- Tab 和 AI 标签区域 -->
|
|
|
+ <div class="content-area">
|
|
|
+ <el-tabs v-model="activeName" type="card" @tab-click="handleClick" class="customer-tabs">
|
|
|
+ <el-tab-pane label="跟进记录" name="visit">
|
|
|
+ <customer-visit-list ref="visit"></customer-visit-list>
|
|
|
+ </el-tab-pane>
|
|
|
+ <el-tab-pane label="联系人" name="contacts">
|
|
|
+ <customer-contacts ref="contacts"></customer-contacts>
|
|
|
+ </el-tab-pane>
|
|
|
+ <el-tab-pane label="订单记录" name="storeOrder">
|
|
|
+ <customer-store-order-list ref="storeOrder"></customer-store-order-list>
|
|
|
+ </el-tab-pane>
|
|
|
+ <el-tab-pane label="通话记录" name="voiceLogs">
|
|
|
+ <customer-voice-logs-list ref="voiceLogs"></customer-voice-logs-list>
|
|
|
+ </el-tab-pane>
|
|
|
+ <el-tab-pane label="短信记录" name="smsLogs">
|
|
|
+ <customer-sms-logs-list ref="smsLogs"></customer-sms-logs-list>
|
|
|
+ </el-tab-pane>
|
|
|
+ <el-tab-pane label="客户日志" name="logs">
|
|
|
+ <customer-logs-list ref="logs"></customer-logs-list>
|
|
|
+ </el-tab-pane>
|
|
|
+ <el-tab-pane label="历史订单" name="hisOrder">
|
|
|
+ <customer-his-order-list ref="hisOrder"></customer-his-order-list>
|
|
|
+ </el-tab-pane>
|
|
|
+ <el-tab-pane label="AI 通话" name="aiVoiceLogs">
|
|
|
+ <ai-call-voice-log ref="aiVoiceRef"></ai-call-voice-log>
|
|
|
+ </el-tab-pane>
|
|
|
+ <el-tab-pane label="AI 加微" name="aiAddWxLogs">
|
|
|
+ <ai-add-wx-log ref="aiAddWxRef"></ai-add-wx-log>
|
|
|
+ </el-tab-pane>
|
|
|
+ <el-tab-pane label="AI 短信" name="aiSendMsgLogs">
|
|
|
+ <ai-send-msg-log ref="aiSendMsgRef"></ai-send-msg-log>
|
|
|
+ </el-tab-pane>
|
|
|
+ </el-tabs>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 弹窗 -->
|
|
|
<el-dialog :title="addTag.title" :visible.sync="addTag.open" width="600px" append-to-body>
|
|
|
<add-tag ref="tag" @close="closeTag()"></add-tag>
|
|
|
</el-dialog>
|
|
|
@@ -214,290 +336,426 @@
|
|
|
<el-dialog :title="addSms.title" :visible.sync="addSms.open" width="800px" append-to-body>
|
|
|
<add-sms ref="sms" @close="closeSms()"></add-sms>
|
|
|
</el-dialog>
|
|
|
-
|
|
|
<el-dialog :title="customer.title" :visible.sync="customer.open" width="1000px" append-to-body>
|
|
|
<add-or-edit-customer ref="customer" @close="closeCustomer()"></add-or-edit-customer>
|
|
|
</el-dialog>
|
|
|
-
|
|
|
- <!-- <el-dialog :title="duplicate.title" :visible.sync="duplicate.open" width="800px" append-to-body>
|
|
|
- <duplicate-customer ref="duplicateCustomer" @close="closeDuplicate()"></duplicate-customer>
|
|
|
- </el-dialog> -->
|
|
|
-
|
|
|
- <el-drawer size="75%" :modal="false" :title="duplicate.title" :visible.sync="duplicate.open">
|
|
|
- <duplicate-customer ref="duplicateCustomer" />
|
|
|
+ <el-drawer size="75%" :modal="false" :title="duplicate.title" :visible.sync="duplicate.open">
|
|
|
+ <duplicate-customer ref="duplicateCustomer"/>
|
|
|
</el-drawer>
|
|
|
-
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
- import { listCustomerExt } from "@/api/crm/customerExt";
|
|
|
- import customerVisitList from '../components/customerVisitList.vue';
|
|
|
- import customerLogsList from '../components/customerLogsList.vue';
|
|
|
- import customerSmsLogsList from '../components/customerSmsLogsList.vue';
|
|
|
- import customerVoiceLogsList from '../components/customerVoiceLogsList.vue';
|
|
|
- import customerStoreOrderList from '../components/customerStoreOrderList.vue';
|
|
|
- import duplicateCustomer from '../components/duplicateCustomer.vue';
|
|
|
- import customerContacts from './customerContacts.vue';
|
|
|
- import customerHisOrderList from '../components/customerHisOrderList.vue';
|
|
|
- import aiCallVoiceLog from './aiCallVoiceLog';
|
|
|
- import aiAddWxLog from './aiAddWxLog';
|
|
|
- import aiSendMsgLog from './aiSendMsgLog';
|
|
|
- import { getCustomerDetails1,updateCustomer,getCustomer1 } from "@/api/crm/customer";
|
|
|
- import addTag from './addTag.vue';
|
|
|
- import addRemark from './addRemark.vue';
|
|
|
- import addSms from './addSms.vue';
|
|
|
- import addOrEditCustomer from '../components/addOrEditCustomer.vue';
|
|
|
- export default {
|
|
|
- name: "customer",
|
|
|
- components: {customerHisOrderList,addOrEditCustomer,addSms,addTag,addRemark, customerContacts,customerVisitList,customerLogsList,
|
|
|
- customerVoiceLogsList,customerStoreOrderList,customerSmsLogsList,duplicateCustomer,aiCallVoiceLog,aiAddWxLog,aiSendMsgLog },
|
|
|
- data() {
|
|
|
- return {
|
|
|
- calleesId:null,
|
|
|
- roboticId:null,
|
|
|
- customer:{
|
|
|
- open:false,
|
|
|
- title:"修改客户"
|
|
|
- },
|
|
|
- isReceive:false,
|
|
|
- tagId:null,
|
|
|
- tagsOptions:[],
|
|
|
- addSms:{
|
|
|
- open:false,
|
|
|
- title:"发短信"
|
|
|
- },
|
|
|
- addTag:{
|
|
|
- open:false,
|
|
|
- title:"打标签"
|
|
|
- },
|
|
|
- addRemark:{
|
|
|
- open:false,
|
|
|
- title:"客户备注"
|
|
|
- },
|
|
|
- duplicate:{
|
|
|
- open:false,
|
|
|
- title:"客户详情"
|
|
|
- },
|
|
|
- customerId:null,
|
|
|
- // 弹出层标题
|
|
|
- title: "",
|
|
|
- // 是否显示弹出层
|
|
|
- open: false,
|
|
|
- cityIds:[],
|
|
|
- citys:[],
|
|
|
- tags:[],
|
|
|
- inputVisible: false,
|
|
|
- inputValue: '',
|
|
|
- receiveOptions:[],
|
|
|
- statusOptions:[],
|
|
|
- typeOptions:[],
|
|
|
- sourceOptions:[],
|
|
|
- sexOptions:[],
|
|
|
- customerExts:[],
|
|
|
- activeName:"",
|
|
|
- item:null,
|
|
|
- showDuplicate:false,
|
|
|
- dCustomerId:null,
|
|
|
-
|
|
|
- };
|
|
|
- },
|
|
|
- created() {
|
|
|
- this.getDicts("crm_customer_source").then((response) => {
|
|
|
- this.sourceOptions = response.data;
|
|
|
- });
|
|
|
- this.getDicts("sys_sex").then((response) => {
|
|
|
- this.sexOptions = response.data;
|
|
|
- });
|
|
|
- this.getDicts("crm_customer_tag").then((response) => {
|
|
|
- this.tagsOptions = response.data;
|
|
|
- });
|
|
|
- this.getDicts("crm_customer_status").then((response) => {
|
|
|
- this.statusOptions = response.data;
|
|
|
- });
|
|
|
- this.getDicts("crm_customer_type").then((response) => {
|
|
|
- this.typeOptions = response.data;
|
|
|
- });
|
|
|
- this.getDicts("crm_customer_is_receive").then((response) => {
|
|
|
- this.receiveOptions = response.data;
|
|
|
- });
|
|
|
+import { listCustomerExt } from '@/api/crm/customerExt'
|
|
|
+import customerVisitList from '../components/customerVisitList.vue'
|
|
|
+import customerLogsList from '../components/customerLogsList.vue'
|
|
|
+import customerSmsLogsList from '../components/customerSmsLogsList.vue'
|
|
|
+import customerVoiceLogsList from '../components/customerVoiceLogsList.vue'
|
|
|
+import customerStoreOrderList from '../components/customerStoreOrderList.vue'
|
|
|
+import duplicateCustomer from '../components/duplicateCustomer.vue'
|
|
|
+import customerContacts from './customerContacts.vue'
|
|
|
+import customerHisOrderList from '../components/customerHisOrderList.vue'
|
|
|
+import aiCallVoiceLog from './aiCallVoiceLog'
|
|
|
+import aiAddWxLog from './aiAddWxLog'
|
|
|
+import aiSendMsgLog from './aiSendMsgLog'
|
|
|
+import AiTagPanel from './AiTagPanel.vue'
|
|
|
+import { getCustomerDetails1, updateCustomer, getCustomer1 } from '@/api/crm/customer'
|
|
|
+import addTag from './addTag.vue'
|
|
|
+import addRemark from './addRemark.vue'
|
|
|
+import addSms from './addSms.vue'
|
|
|
+import addOrEditCustomer from '../components/addOrEditCustomer.vue'
|
|
|
|
|
|
+export default {
|
|
|
+ name: 'customer',
|
|
|
+ components: {
|
|
|
+ customerHisOrderList,
|
|
|
+ addOrEditCustomer,
|
|
|
+ addSms,
|
|
|
+ addTag,
|
|
|
+ addRemark,
|
|
|
+ customerContacts,
|
|
|
+ customerVisitList,
|
|
|
+ customerLogsList,
|
|
|
+ customerVoiceLogsList,
|
|
|
+ customerStoreOrderList,
|
|
|
+ customerSmsLogsList,
|
|
|
+ duplicateCustomer,
|
|
|
+ aiCallVoiceLog,
|
|
|
+ aiAddWxLog,
|
|
|
+ aiSendMsgLog,
|
|
|
+ AiTagPanel
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ calleesId: null,
|
|
|
+ roboticId: null,
|
|
|
+ customer: { open: false, title: '修改客户' },
|
|
|
+ isReceive: false,
|
|
|
+ tagId: null,
|
|
|
+ tagsOptions: [],
|
|
|
+ addSms: { open: false, title: '发短信' },
|
|
|
+ addTag: { open: false, title: '打标签' },
|
|
|
+ addRemark: { open: false, title: '客户备注' },
|
|
|
+ duplicate: { open: false, title: '客户详情' },
|
|
|
+ customerId: null,
|
|
|
+ title: '',
|
|
|
+ open: false,
|
|
|
+ cityIds: [],
|
|
|
+ citys: [],
|
|
|
+ tags: [],
|
|
|
+ inputVisible: false,
|
|
|
+ inputValue: '',
|
|
|
+ receiveOptions: [],
|
|
|
+ statusOptions: [],
|
|
|
+ typeOptions: [],
|
|
|
+ sourceOptions: [],
|
|
|
+ sexOptions: [],
|
|
|
+ customerExts: [],
|
|
|
+ activeName: '',
|
|
|
+ item: null,
|
|
|
+ showDuplicate: false,
|
|
|
+ dCustomerId: null
|
|
|
+ }
|
|
|
+ },
|
|
|
+ created() {
|
|
|
+ this.getDicts('crm_customer_source').then((response) => {
|
|
|
+ this.sourceOptions = response.data
|
|
|
+ })
|
|
|
+ this.getDicts('sys_sex').then((response) => {
|
|
|
+ this.sexOptions = response.data
|
|
|
+ })
|
|
|
+ this.getDicts('crm_customer_tag').then((response) => {
|
|
|
+ this.tagsOptions = response.data
|
|
|
+ })
|
|
|
+ this.getDicts('crm_customer_status').then((response) => {
|
|
|
+ this.statusOptions = response.data
|
|
|
+ })
|
|
|
+ this.getDicts('crm_customer_type').then((response) => {
|
|
|
+ this.typeOptions = response.data
|
|
|
+ })
|
|
|
+ this.getDicts('crm_customer_is_receive').then((response) => {
|
|
|
+ this.receiveOptions = response.data
|
|
|
+ })
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ getStatusType(status) {
|
|
|
+ const statusMap = { '1': 'success', '2': 'warning', '3': 'danger', '4': 'info' }
|
|
|
+ return statusMap[status] || 'info'
|
|
|
},
|
|
|
- mounted(){
|
|
|
-
|
|
|
+ getStatusText(status) {
|
|
|
+ const item = this.statusOptions.find(d => d.dictValue === status)
|
|
|
+ return item ? item.dictLabel : status
|
|
|
+ },
|
|
|
+ handleMobile() {
|
|
|
+ const customerId = this.item.customerId
|
|
|
+ getCustomer1(customerId).then(response => {
|
|
|
+ this.item.mobile = response.mobile
|
|
|
+ })
|
|
|
+ },
|
|
|
+ handleEdit() {
|
|
|
+ this.customer.open = true
|
|
|
+ var that = this
|
|
|
+ setTimeout(() => {
|
|
|
+ that.$refs.customer.handleUpdate(that.customerId)
|
|
|
+ }, 200)
|
|
|
+ },
|
|
|
+ closeCustomer() {
|
|
|
+ this.customer.open = false
|
|
|
+ this.getDetails(this.customerId)
|
|
|
+ },
|
|
|
+ tagsChange(e) {
|
|
|
+ var item = this.tagsOptions.find(val => val.dictValue === e)
|
|
|
+ this.tags.push(item.dictLabel)
|
|
|
+ this.form.tags = this.tags.toString()
|
|
|
},
|
|
|
- methods: {
|
|
|
- handleMobile(){
|
|
|
- const customerId = this.item.customerId;
|
|
|
- getCustomer1(customerId).then(response =>{
|
|
|
- this.item.mobile = response.mobile;
|
|
|
+ closeSms() {
|
|
|
+ this.addSms.open = false
|
|
|
+ this.getDetails(this.customerId)
|
|
|
+ },
|
|
|
+ handleSms(mobile) {
|
|
|
+ this.addSms.open = true
|
|
|
+ var that = this
|
|
|
+ setTimeout(() => {
|
|
|
+ that.$refs.sms.reset(this.item.customerId, mobile, 1)
|
|
|
+ }, 500)
|
|
|
+ },
|
|
|
+ closeRemark() {
|
|
|
+ this.addRemark.open = false
|
|
|
+ this.getDetails(this.customerId)
|
|
|
+ },
|
|
|
+ handleAddRemark() {
|
|
|
+ this.addRemark.open = true
|
|
|
+ var that = this
|
|
|
+ setTimeout(() => {
|
|
|
+ that.$refs.remark.reset(this.item)
|
|
|
+ }, 500)
|
|
|
+ },
|
|
|
+ closeTag() {
|
|
|
+ this.addTag.open = false
|
|
|
+ this.getDetails(this.customerId)
|
|
|
+ },
|
|
|
+ handleAddTag() {
|
|
|
+ this.addTag.open = true
|
|
|
+ var that = this
|
|
|
+ setTimeout(() => {
|
|
|
+ that.$refs.tag.reset(this.item)
|
|
|
+ }, 500)
|
|
|
+ },
|
|
|
+ handleClick(tab, event) {
|
|
|
+ if (tab.name == 'contacts') {
|
|
|
+ this.$refs.contacts.getData(this.item.customerId)
|
|
|
+ }
|
|
|
+ if (tab.name == 'visit') {
|
|
|
+ this.$refs.visit.getData(this.item.customerId, this.isReceive)
|
|
|
+ }
|
|
|
+ if (tab.name == 'logs') {
|
|
|
+ this.$refs.logs.getData(this.item.customerId)
|
|
|
+ }
|
|
|
+ if (tab.name == 'voiceLogs') {
|
|
|
+ this.$refs.voiceLogs.getData(this.item.customerId)
|
|
|
+ }
|
|
|
+ if (tab.name == 'storeOrder') {
|
|
|
+ this.$refs.storeOrder.getData(this.item.customerId)
|
|
|
+ }
|
|
|
+ if (tab.name == 'smsLogs') {
|
|
|
+ this.$refs.smsLogs.getData(this.item.customerId)
|
|
|
+ }
|
|
|
+ if (tab.name == 'hisOrder') {
|
|
|
+ this.$refs.hisOrder.getData(this.item.customerId)
|
|
|
+ }
|
|
|
+ if (tab.name == 'aiVoiceLogs') {
|
|
|
+ this.$refs.aiVoiceRef.getData(this.item.customerId, this.calleesId)
|
|
|
+ } else if (tab.name == 'aiAddWxLogs') {
|
|
|
+ this.$refs.aiAddWxRef.getData(this.item.customerId, this.roboticId)
|
|
|
+ } else if (tab.name == 'aiSendMsgLogs') {
|
|
|
+ this.$refs.aiSendMsgRef.getData(this.item.customerId, this.calleesId, this.roboticId)
|
|
|
+ }
|
|
|
+ },
|
|
|
+ getDetails(customerId, calleesId, roboticId) {
|
|
|
+ if (!!calleesId) {
|
|
|
+ this.calleesId = calleesId
|
|
|
+ }
|
|
|
+ if (!!roboticId) {
|
|
|
+ this.roboticId = roboticId
|
|
|
+ }
|
|
|
+ var data = { customerId: customerId }
|
|
|
+ this.customerId = customerId
|
|
|
+ var that = this
|
|
|
+ this.exts = []
|
|
|
+ listCustomerExt(data).then(response => {
|
|
|
+ this.customerExts = response.data
|
|
|
+ this.customerExts.forEach(element => {
|
|
|
+ var data = { extId: element.extId, name: element.name, value: '' }
|
|
|
+ this.exts.push(data)
|
|
|
})
|
|
|
- },
|
|
|
- handleEdit() {
|
|
|
- this.customer.open = true;
|
|
|
- var that=this;
|
|
|
- setTimeout(() => {
|
|
|
- that.$refs.customer.handleUpdate(that.customerId);
|
|
|
- }, 200);
|
|
|
- },
|
|
|
- closeCustomer(){
|
|
|
- this.customer.open=false;
|
|
|
- this.getDetails(this.customerId)
|
|
|
- },
|
|
|
- tagsChange(e){
|
|
|
- var item=this.tagsOptions.find(val => val.dictValue === e);
|
|
|
- console.log(item);
|
|
|
- this.tags.push(item.dictLabel);
|
|
|
- this.form.tags=this.tags.toString();
|
|
|
- },
|
|
|
- closeSms(){
|
|
|
- this.addSms.open=false;
|
|
|
- this.getDetails(this.customerId)
|
|
|
- },
|
|
|
- handleSms(mobile){
|
|
|
- this.addSms.open=true;
|
|
|
- var that=this;
|
|
|
- setTimeout(() => {
|
|
|
- that.$refs.sms.reset(this.item.customerId,mobile,1);
|
|
|
- }, 500);
|
|
|
-
|
|
|
- },
|
|
|
- closeRemark(){
|
|
|
- this.addRemark.open=false;
|
|
|
- this.getDetails(this.customerId)
|
|
|
- },
|
|
|
- handleAddRemark(){
|
|
|
- this.addRemark.open=true;
|
|
|
- var that=this;
|
|
|
- setTimeout(() => {
|
|
|
- that.$refs.remark.reset(this.item);
|
|
|
- }, 500);
|
|
|
- },
|
|
|
- closeTag(){
|
|
|
- this.addTag.open=false;
|
|
|
- this.getDetails(this.customerId)
|
|
|
- },
|
|
|
- handleAddTag(){
|
|
|
- this.addTag.open=true;
|
|
|
- var that=this;
|
|
|
- setTimeout(() => {
|
|
|
- that.$refs.tag.reset(this.item);
|
|
|
- }, 500);
|
|
|
-
|
|
|
- },
|
|
|
- handleClick(tab, event) {
|
|
|
- if(tab.name=="contacts"){
|
|
|
- this.$refs.contacts.getData(this.item.customerId);
|
|
|
- }
|
|
|
- if(tab.name == "visit"){
|
|
|
- this.$refs.visit.getData(this.item.customerId,this.isReceive);
|
|
|
- }
|
|
|
- if(tab.name=="logs"){
|
|
|
- this.$refs.logs.getData(this.item.customerId);
|
|
|
+ })
|
|
|
+ getCustomerDetails1(data).then(response => {
|
|
|
+ this.item = response.customer
|
|
|
+ this.isReceive = response.isReceive
|
|
|
+ if (this.item.extJson != null) {
|
|
|
+ var extList = JSON.parse(this.item.extJson)
|
|
|
+ that.exts.forEach(item => {
|
|
|
+ extList.forEach(element => {
|
|
|
+ if (item.extId == element.extId) {
|
|
|
+ item.value = element.value
|
|
|
+ }
|
|
|
+ })
|
|
|
+ })
|
|
|
}
|
|
|
- if(tab.name=="voiceLogs"){
|
|
|
- this.$refs.voiceLogs.getData(this.item.customerId);
|
|
|
- }
|
|
|
- if(tab.name=="storeOrder"){
|
|
|
- this.$refs.storeOrder.getData(this.item.customerId);
|
|
|
- }
|
|
|
- if(tab.name=="smsLogs"){
|
|
|
- this.$refs.smsLogs.getData(this.item.customerId);
|
|
|
- }
|
|
|
- if(tab.name=="hisOrder"){
|
|
|
- this.$refs.hisOrder.getData(this.item.customerId);
|
|
|
- }
|
|
|
- if(tab.name=="aiVoiceLogs"){
|
|
|
- console.log(this.item.customerId);
|
|
|
- this.$refs.aiVoiceRef.getData(this.item.customerId,this.calleesId);
|
|
|
- } else if(tab.name=="aiAddWxLogs"){
|
|
|
- console.log(this.item.customerId);
|
|
|
- this.$refs.aiAddWxRef.getData(this.item.customerId,this.roboticId);
|
|
|
- } else if(tab.name=="aiSendMsgLogs"){
|
|
|
- console.log(this.item.customerId);
|
|
|
- this.$refs.aiSendMsgRef.getData(this.item.customerId,this.calleesId,this.roboticId);
|
|
|
- }
|
|
|
- },
|
|
|
- getDetails(customerId,calleesId,roboticId) {
|
|
|
- if(!!calleesId){
|
|
|
- this.calleesId = calleesId;
|
|
|
- console.log(this.calleesId);
|
|
|
- }
|
|
|
- if(!!roboticId){
|
|
|
- this.roboticId = roboticId;
|
|
|
- console.log(this.roboticId);
|
|
|
- }
|
|
|
- var data={customerId:customerId}
|
|
|
- this.customerId=customerId;
|
|
|
- var that=this;
|
|
|
- this.exts=[];
|
|
|
- listCustomerExt(data).then(response => {
|
|
|
- this.customerExts = response.data;
|
|
|
- this.customerExts.forEach(element => {
|
|
|
- var data={extId:element.extId,name:element.name,value:""};
|
|
|
- this.exts.push(data)
|
|
|
- });
|
|
|
- });
|
|
|
- getCustomerDetails1(data).then(response => {
|
|
|
- this.item = response.customer;
|
|
|
- this.isReceive=response.isReceive;
|
|
|
- if(this.item.extJson!=null){
|
|
|
- var extList=JSON.parse(this.item.extJson);
|
|
|
- that.exts.forEach(item => {
|
|
|
- extList.forEach(element => {
|
|
|
- if(item.extId==element.extId){
|
|
|
- item.value=element.value
|
|
|
- }
|
|
|
- });
|
|
|
-
|
|
|
- });
|
|
|
- }
|
|
|
- this.activeName="visit"
|
|
|
- setTimeout(() => {
|
|
|
- that.$refs.visit.getData(customerId);
|
|
|
- }, 500);
|
|
|
- });
|
|
|
- },
|
|
|
- initDuplicate(isDuplicate,dCustomerId){
|
|
|
-
|
|
|
- this.showDuplicate=isDuplicate;
|
|
|
- this.dCustomerId=dCustomerId;
|
|
|
- },
|
|
|
- handleDuplicate(){
|
|
|
- this.duplicate.open=true;
|
|
|
- var that=this;
|
|
|
-
|
|
|
+ this.activeName = 'visit'
|
|
|
setTimeout(() => {
|
|
|
- that.$refs.duplicateCustomer.getDetails(that.dCustomerId);
|
|
|
- }, 200);
|
|
|
- },
|
|
|
- closeDuplicate(){
|
|
|
- this.duplicate.open=false;
|
|
|
- this.getDetails(this.customerId)
|
|
|
- },
|
|
|
+ that.$refs.visit.getData(customerId)
|
|
|
+ }, 500)
|
|
|
+ })
|
|
|
+ },
|
|
|
+ initDuplicate(isDuplicate, dCustomerId) {
|
|
|
+ this.showDuplicate = isDuplicate
|
|
|
+ this.dCustomerId = dCustomerId
|
|
|
+ },
|
|
|
+ handleDuplicate() {
|
|
|
+ this.duplicate.open = true
|
|
|
+ var that = this
|
|
|
+ setTimeout(() => {
|
|
|
+ that.$refs.duplicateCustomer.getDetails(that.dCustomerId)
|
|
|
+ }, 200)
|
|
|
+ },
|
|
|
+ closeDuplicate() {
|
|
|
+ this.duplicate.open = false
|
|
|
+ this.getDetails(this.customerId)
|
|
|
+ },
|
|
|
+ handleTagChange() {
|
|
|
+ console.log('AI 标签发生变化')
|
|
|
}
|
|
|
- };
|
|
|
+ }
|
|
|
+}
|
|
|
</script>
|
|
|
+
|
|
|
<style lang="scss" scoped>
|
|
|
-.contents{
|
|
|
- height: 100%;
|
|
|
- background-color: #fff;
|
|
|
- padding: 0px 20px;
|
|
|
+.customer-detail-container {
|
|
|
+ background-color: #f5f7fa;
|
|
|
+ min-height: 100%;
|
|
|
+ padding: 20px;
|
|
|
+}
|
|
|
+
|
|
|
+.customer-header-card {
|
|
|
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
|
+ border-radius: 12px;
|
|
|
+ padding: 24px;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ margin-bottom: 20px;
|
|
|
+ box-shadow: 0 4px 15px rgba(102, 126, 234, 0.3);
|
|
|
+
|
|
|
+ .customer-avatar {
|
|
|
+ margin-right: 20px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .customer-info {
|
|
|
+ flex: 1;
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+ }
|
|
|
+
|
|
|
+ .customer-main-info {
|
|
|
+ .customer-name-title {
|
|
|
+ color: #fff;
|
|
|
+ font-size: 24px;
|
|
|
+ margin: 0 0 12px 0;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ }
|
|
|
+
|
|
|
+ .customer-meta {
|
|
|
+ display: flex;
|
|
|
+ gap: 24px;
|
|
|
|
|
|
+ .meta-item {
|
|
|
+ color: rgba(255, 255, 255, 0.9);
|
|
|
+ font-size: 14px;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 6px;
|
|
|
+
|
|
|
+ i {
|
|
|
+ font-size: 16px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .el-button {
|
|
|
+ color: rgba(255, 255, 255, 0.9);
|
|
|
+ padding: 0 8px;
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ color: #fff;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .customer-actions {
|
|
|
+ display: flex;
|
|
|
+ gap: 12px;
|
|
|
+ }
|
|
|
}
|
|
|
-.customer-title{
|
|
|
- margin-bottom: 15px;
|
|
|
+
|
|
|
+.customer-tags-section {
|
|
|
+ background: #fff;
|
|
|
+ border-radius: 8px;
|
|
|
+ padding: 16px 20px;
|
|
|
+ margin-bottom: 20px;
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
- justify-content: space-between;
|
|
|
- .customer-name{
|
|
|
- font-size: 28px;
|
|
|
+
|
|
|
+ .tags-label {
|
|
|
+ font-weight: 500;
|
|
|
+ color: #606266;
|
|
|
+ margin-right: 12px;
|
|
|
}
|
|
|
}
|
|
|
-</style>
|
|
|
-<style>
|
|
|
- .el-descriptions-item__label.is-bordered-label{
|
|
|
- font-weight: normal;
|
|
|
- }
|
|
|
|
|
|
+.info-sections {
|
|
|
+ margin-bottom: 20px;
|
|
|
+}
|
|
|
+
|
|
|
+.info-section {
|
|
|
+ background: #fff;
|
|
|
+ border-radius: 8px;
|
|
|
+ margin-bottom: 16px;
|
|
|
+ overflow: hidden;
|
|
|
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
|
|
|
+
|
|
|
+ .section-header {
|
|
|
+ padding: 16px 20px;
|
|
|
+ border-bottom: 1px solid #ebeef5;
|
|
|
+ background: #fafbfc;
|
|
|
+
|
|
|
+ .section-title {
|
|
|
+ font-size: 15px;
|
|
|
+ font-weight: 600;
|
|
|
+ color: #303133;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 8px;
|
|
|
+
|
|
|
+ i {
|
|
|
+ color: #409eff;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .section-content {
|
|
|
+ padding: 20px;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.info-item {
|
|
|
+ margin-bottom: 16px;
|
|
|
+
|
|
|
+ .info-label {
|
|
|
+ display: block;
|
|
|
+ font-size: 12px;
|
|
|
+ color: #909399;
|
|
|
+ margin-bottom: 6px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .info-value {
|
|
|
+ font-size: 14px;
|
|
|
+ color: #303133;
|
|
|
+
|
|
|
+ &.highlight {
|
|
|
+ color: #f56c6c;
|
|
|
+ font-weight: 600;
|
|
|
+ font-size: 16px;
|
|
|
+ }
|
|
|
+
|
|
|
+ &.text-ellipsis {
|
|
|
+ overflow: hidden;
|
|
|
+ text-overflow: ellipsis;
|
|
|
+ white-space: nowrap;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.remark-content {
|
|
|
+ background: #fafbfc;
|
|
|
+ padding: 16px;
|
|
|
+ border-radius: 6px;
|
|
|
+ color: #606266;
|
|
|
+ line-height: 1.6;
|
|
|
+}
|
|
|
+
|
|
|
+.content-area {
|
|
|
+ .customer-tabs {
|
|
|
+ background: #fff;
|
|
|
+ border-radius: 8px;
|
|
|
+ padding: 16px;
|
|
|
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
|
|
|
+ }
|
|
|
+
|
|
|
+ .ai-tag-wrapper {
|
|
|
+ position: sticky;
|
|
|
+ top: 20px;
|
|
|
+ }
|
|
|
+}
|
|
|
</style>
|