feat: 导入增强 + 客户合并 + 同伴自定义 + 性能优化
=== 导入系统全面增强 === - 5 Sheet 完整导入:拜访/计划/商机/要客/纪要 - 同访人智能解析:中英文逗号/顿号/分号 → 系统用户UUID + 外部人员TEXT - 客户自动创建:Excel中不存在的客户自动入库 - 模糊名称匹配:去空格 + 包含关系纠错 - manager_id 修正:导入时用客户分配的经理(非Excel列/非导入人) - 模板更新:Sheet5「客户经理」→「填报人」,同访人示例含逗号分隔 === 客户合并功能 === - PUT 改名碰撞检测 → 409 + 合并预览 - GET merge-preview / POST merge 端点 - 事务级迁移:Visit/WorkPlan/MiniBusiness/KeyVisit/联系人/分配 - 去重逻辑:联系人(name+phone)、分配(manager+role) - last_visit_date 取最大值 === 拜访记录完善 === - visits 新增 companion_names TEXT[] 列 - 同访人支持自定义输入(外部人员),el-select allow-create - 移动端 VisitForm + PC端 ManagerWorkspace 统一 - 周报「客户经理」→「相关人员」(创建人+同访人) - 纪要「客户经理」→「填报人」 - 删除拜访后重新计算 customer.last_visit_date === 客户选择放开 === - 客户经理可看到全部客户(不再限自己分配的) - 拜访时客户下拉返回全量 === 前端性能优化 === - Element Plus 按需加载 (unplugin-vue-components + unplugin-element-plus) - 周报照片URL并行请求 (Promise.all) - onMounted 三路并行 (loadReport + dropdowns + AI) - nginx Cache-Control: immutable for /assets/ - Google Fonts preconnect hints - 图片上传前 Canvas 压缩 (max 1920px, quality 0.8) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -144,7 +144,44 @@ async function handleSubmit() {
|
||||
}
|
||||
dialogVisible.value = false
|
||||
await loadCustomers()
|
||||
} catch (e: any) { ElMessage.error('操作失败: ' + (e.response?.data?.detail || e.message)) }
|
||||
} catch (e: any) {
|
||||
// Handle name collision → offer merge
|
||||
if (e.response?.status === 409 && e.response?.data?.detail?.preview) {
|
||||
const d = e.response.data.detail
|
||||
mergeSourceId.value = d.source_id
|
||||
mergeSourceName.value = d.source_name
|
||||
mergeTargetId.value = d.target_id
|
||||
mergeTargetName.value = d.target_name
|
||||
mergePreview.value = d.preview
|
||||
mergeDialogVisible.value = true
|
||||
return
|
||||
}
|
||||
ElMessage.error('操作失败: ' + (typeof e.response?.data?.detail === 'object' ? e.response.data.detail.message : (e.response?.data?.detail || e.message)))
|
||||
}
|
||||
}
|
||||
|
||||
// ── Merge ──
|
||||
const mergeDialogVisible = ref(false)
|
||||
const mergeSourceId = ref('')
|
||||
const mergeSourceName = ref('')
|
||||
const mergeTargetId = ref('')
|
||||
const mergeTargetName = ref('')
|
||||
const mergePreview = ref<any>({})
|
||||
const mergeLoading = ref(false)
|
||||
|
||||
async function handleMerge() {
|
||||
mergeLoading.value = true
|
||||
try {
|
||||
const res = await api.post(`/customers/${mergeSourceId.value}/merge`, { target_id: mergeTargetId.value })
|
||||
ElMessage.success(res.data.result || '合并完成')
|
||||
mergeDialogVisible.value = false
|
||||
dialogVisible.value = false
|
||||
await loadCustomers()
|
||||
} catch (e: any) {
|
||||
ElMessage.error('合并失败: ' + (e.response?.data?.detail || e.message))
|
||||
} finally {
|
||||
mergeLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function removeExistingContact(contactId: string) {
|
||||
@@ -413,6 +450,37 @@ async function handleImport() {
|
||||
<el-button type="primary" :loading="importLoading" @click="handleImport" :disabled="!importFile">确认导入</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<!-- Merge confirmation dialog -->
|
||||
<el-dialog v-model="mergeDialogVisible" title="合并客户" width="520px" :close-on-click-modal="false">
|
||||
<div style="line-height:1.8">
|
||||
<el-alert type="warning" :closable="false" style="margin-bottom:16px">
|
||||
⚠ 客户「<b>{{ mergeTargetName }}</b>」已存在。是否将「<b>{{ mergeSourceName }}</b>」合并到「{{ mergeTargetName }}」?
|
||||
</el-alert>
|
||||
|
||||
<el-descriptions :column="2" border size="small">
|
||||
<el-descriptions-item label="源客户">{{ mergeSourceName }}</el-descriptions-item>
|
||||
<el-descriptions-item label="目标客户">{{ mergeTargetName }}</el-descriptions-item>
|
||||
<el-descriptions-item label="拜访记录">{{ mergePreview.visits || 0 }} 条</el-descriptions-item>
|
||||
<el-descriptions-item label="工作计划">{{ mergePreview.work_plans || 0 }} 条</el-descriptions-item>
|
||||
<el-descriptions-item label="商机跟单">{{ mergePreview.mini_business || 0 }} 条</el-descriptions-item>
|
||||
<el-descriptions-item label="要客拜访">{{ mergePreview.key_visits || 0 }} 条</el-descriptions-item>
|
||||
<el-descriptions-item label="联系人">{{ mergePreview.contacts || 0 }} 人</el-descriptions-item>
|
||||
<el-descriptions-item label="经理分配">{{ mergePreview.assignments || 0 }} 条</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
|
||||
<div v-if="mergePreview.note" style="margin-top:12px; color:var(--amber); font-size:13px">
|
||||
⚠ {{ mergePreview.note }}
|
||||
</div>
|
||||
<div style="margin-top:12px; color:var(--vermilion); font-size:13px">
|
||||
合并后「{{ mergeSourceName }}」将被删除,此操作不可撤销。
|
||||
</div>
|
||||
</div>
|
||||
<template #footer>
|
||||
<el-button @click="mergeDialogVisible = false">取消</el-button>
|
||||
<el-button type="danger" :loading="mergeLoading" @click="handleMerge">确认合并</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user