|
|
@@ -7,61 +7,62 @@
|
|
|
</div>
|
|
|
<button class="modal-close" @click="showReplyReviewModal = false"><i class="fas fa-times"></i></button>
|
|
|
</div>
|
|
|
- <div class="modal-body">
|
|
|
+ <div class="modal-body" v-loading="loading">
|
|
|
<div class="review-stats">
|
|
|
<div class="stat-box">
|
|
|
<span class="stat-label">全部</span>
|
|
|
- <span class="stat-value">{{ repliedCustomers.filter(r => r.status === 'pending-review').length }}</span>
|
|
|
+ <span class="stat-value">{{ repliedCustomers.length }}</span>
|
|
|
</div>
|
|
|
<div class="stat-box">
|
|
|
<span class="stat-label">已保护</span>
|
|
|
- <span class="stat-value">{{ repliedCustomers.filter(r => r.requiresHumanReview).length }}</span>
|
|
|
+ <span class="stat-value">{{ repliedCustomers.filter(r => r.hasProtect).length }}</span>
|
|
|
</div>
|
|
|
<div class="stat-box">
|
|
|
<span class="stat-label">营销暂停</span>
|
|
|
- <span class="stat-value">{{ repliedCustomers.filter(r => r.priority === '高').length }}</span>
|
|
|
+ <span class="stat-value">{{ repliedCustomers.filter(r => r.hasSuspend).length }}</span>
|
|
|
</div>
|
|
|
</div>
|
|
|
- <div class="replies-list">
|
|
|
- <div v-for="reply in repliedCustomers" :key="reply.id" class="reply-item" :class="[reply.status, { 'requires-review': reply.requiresHumanReview }]">
|
|
|
+ <div class="replies-list" v-if="repliedCustomers.length > 0">
|
|
|
+ <div v-for="reply in repliedCustomers" :key="reply.id" class="reply-item" :class="['pending-review', { 'requires-review': !reply.requiresHumanReview }]">
|
|
|
<div class="reply-header">
|
|
|
<div class="reply-info">
|
|
|
<div class="reply-name">
|
|
|
- {{ reply.name }}
|
|
|
+ {{ reply.customerName }}
|
|
|
</div>
|
|
|
- <div class="reply-email">{{ reply.email }}</div>
|
|
|
+ <div class="reply-email">{{ reply.recipient }}</div>
|
|
|
</div>
|
|
|
- <div class="reply-badges">
|
|
|
+ <!-- <div class="reply-badges">
|
|
|
<span class="priority-badge" :class="reply.priority">
|
|
|
{{ reply.priority }}优先级
|
|
|
</span>
|
|
|
<span class="value-badge" :class="reply.value">{{ reply.value }}</span>
|
|
|
- </div>
|
|
|
+ </div> -->
|
|
|
</div>
|
|
|
- <div class="reply-time">回复时间: {{ reply.replyTime }}</div>
|
|
|
+ <div class="reply-time">回复时间: {{ reply.firstReplyTime }}</div>
|
|
|
<div class="reply-content">
|
|
|
<p>{{ reply.replyContent }}</p>
|
|
|
</div>
|
|
|
- <div class="reply-review-notes" v-if="reply.reviewNotes">
|
|
|
+ <!-- <div class="reply-review-notes" v-if="reply.reviewNotes">
|
|
|
<i class="fas fa-lightbulb"></i>
|
|
|
<span>{{ reply.reviewNotes }}</span>
|
|
|
- </div>
|
|
|
+ </div> -->
|
|
|
<div class="reply-actions">
|
|
|
- <button v-if="!reply.protected" class="btn btn-secondary btn-sm" @click="protectCustomer(reply)" title="添加到保护白名单">
|
|
|
+ <button v-if="!reply.hasProtect" class="btn btn-secondary btn-sm" @click="protectCustomer(reply)" title="添加到保护白名单">
|
|
|
<i class="fas fa-shield-alt"></i> 保护
|
|
|
</button>
|
|
|
- <button v-else class="btn btn-secondary btn-sm" @click="unprotectCustomer(reply)" title="从保护白名单中移除">
|
|
|
+ <button v-else class="btn btn-secondary btn-sm" @click="protectCustomer(reply)" title="从保护白名单中移除">
|
|
|
<i class="fas fa-times"></i> 取消保护
|
|
|
</button>
|
|
|
- <button class="btn btn-secondary btn-sm" @click="pauseCampaignForCustomer(reply)" v-if="reply.interventionStatus !== 'paused'" title="暂停向该客户发送邮件">
|
|
|
+ <button class="btn btn-secondary btn-sm" @click="pauseCampaignForCustomer(reply)" v-if="!reply.hasSuspend" title="暂停向该客户发送邮件">
|
|
|
<i class="fas fa-pause"></i> 暂停
|
|
|
</button>
|
|
|
- <button class="btn btn-secondary btn-sm" @click="resumeCampaignForCustomer(reply)" v-else title="恢复向该客户发送邮件">
|
|
|
+ <button class="btn btn-secondary btn-sm" @click="pauseCampaignForCustomer(reply)" v-else title="恢复向该客户发送邮件">
|
|
|
<i class="fas fa-play"></i> 恢复
|
|
|
</button>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
+ <div v-else class="no-data">暂无数据</div>
|
|
|
</div>
|
|
|
<div class="modal-footer">
|
|
|
<button class="btn btn-secondary" @click="showReplyReviewModal = false">关闭</button>
|
|
|
@@ -76,23 +77,74 @@
|
|
|
<script setup>
|
|
|
import { ref } from 'vue';
|
|
|
import { getReplyCustomer, setProtectCustomer, setSuspendCustomer } from '@/api/marketing'
|
|
|
+ import { ElMessageBox } from 'element-plus'
|
|
|
|
|
|
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: '' }
|
|
|
+ // { 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 loading = ref(false);
|
|
|
const open = (data) => {
|
|
|
showReplyReviewModal.value = true;
|
|
|
+ loading.value = true;
|
|
|
getReplyCustomer({ id: data.id }).then(res => {
|
|
|
- console.log('res :>> ', res);
|
|
|
+ repliedCustomers.value = res.result || [];
|
|
|
+ }).finally(() => {
|
|
|
+ loading.value = false;
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ const protectCustomer = (customer) => {
|
|
|
+ ElMessageBox.confirm(
|
|
|
+ `请确认是否${ customer.hasProtect ? '取消保护' : '添加到保护白名单' }?`,
|
|
|
+ '提示',
|
|
|
+ {
|
|
|
+ confirmButtonText: '确认',
|
|
|
+ cancelButtonText: '取消',
|
|
|
+ type: 'warning',
|
|
|
+ }
|
|
|
+ ).then(() => {
|
|
|
+ let params = {
|
|
|
+ id: customer.id,
|
|
|
+ hasProtect: customer.hasProtect ? 0 : 1
|
|
|
+ }
|
|
|
+ setProtectCustomer(params).then(res => {
|
|
|
+ customer.hasProtect = !customer.hasProtect
|
|
|
+ ElMessage.success('操作成功')
|
|
|
+ }).catch(err => {
|
|
|
+ ElMessage.error('操作失败')
|
|
|
+ })
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ const pauseCampaignForCustomer = (customer) => {
|
|
|
+ ElMessageBox.confirm(
|
|
|
+ `请确认是否${ customer.hasSuspend ? '恢复' : '暂停' }?`,
|
|
|
+ '提示',
|
|
|
+ {
|
|
|
+ confirmButtonText: '确认',
|
|
|
+ cancelButtonText: '取消',
|
|
|
+ type: 'warning',
|
|
|
+ }
|
|
|
+ ).then(() => {
|
|
|
+ let params = {
|
|
|
+ id: customer.id,
|
|
|
+ hasSuspend: customer.hasSuspend ? 0 : 1
|
|
|
+ }
|
|
|
+ setSuspendCustomer(params).then(res => {
|
|
|
+ customer.hasSuspend = !customer.hasSuspend
|
|
|
+ ElMessage.success('操作成功')
|
|
|
+ }).catch(err => {
|
|
|
+ ElMessage.error('操作失败')
|
|
|
})
|
|
|
+ })
|
|
|
}
|
|
|
|
|
|
defineExpose({
|