音频管理管理功能调整, 音频模型调整
This commit is contained in:
@@ -34,6 +34,15 @@ export function getAudioByCustomerPhone(customerPhone) {
|
||||
})
|
||||
}
|
||||
|
||||
// 根据客户联系方式查询客户信息
|
||||
export function getCustomerByContact(contact) {
|
||||
return request({
|
||||
url: '/customerManagement/getByContact',
|
||||
method: 'get',
|
||||
params: { contact }
|
||||
})
|
||||
}
|
||||
|
||||
// 根据ID查询录音
|
||||
export function getAudioById(id) {
|
||||
return request({
|
||||
@@ -61,8 +70,11 @@ export function batchDeleteAudio(ids) {
|
||||
|
||||
// 添加新的录音信息
|
||||
export function addAudio(data) {
|
||||
console.log('=== addAudio API 调用 ===')
|
||||
console.log('调用URL: /audioManagement/uploadAndSubmit')
|
||||
console.log('提交数据:', data)
|
||||
return request({
|
||||
url: '/audioManagement/add',
|
||||
url: '/audioManagement/uploadAndSubmit',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
@@ -87,27 +99,76 @@ export function getAudioStatistics() {
|
||||
|
||||
// 分配项目
|
||||
export function allocateProject(data) {
|
||||
// 创建表单数据
|
||||
const formData = new FormData()
|
||||
formData.append('audioIds', data.audioIds)
|
||||
formData.append('projectId', data.projectId)
|
||||
formData.append('projectName', data.projectName)
|
||||
|
||||
return request({
|
||||
url: '/audioManagement/allocateProject',
|
||||
method: 'post',
|
||||
data
|
||||
data: formData,
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data'
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 分配销售
|
||||
export function allocateSales(data) {
|
||||
// 创建表单数据
|
||||
const formData = new FormData()
|
||||
formData.append('audioIds', data.audioIds)
|
||||
formData.append('salesId', data.salesId)
|
||||
formData.append('salesName', data.salesName)
|
||||
formData.append('salesPhone', data.salesPhone)
|
||||
|
||||
return request({
|
||||
url: '/audioManagement/allocateSales',
|
||||
method: 'post',
|
||||
data
|
||||
data: formData,
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data'
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 录音合并
|
||||
export function mergeRecordings(data) {
|
||||
// 转文本
|
||||
export function convertToText(data) {
|
||||
// 创建表单数据
|
||||
const formData = new FormData()
|
||||
formData.append('audioId', data.audioId)
|
||||
formData.append('audioName', data.audioName)
|
||||
|
||||
return request({
|
||||
url: '/audioManagement/mergeRecordings',
|
||||
url: '/audioManagement/convertAudioToText',
|
||||
method: 'post',
|
||||
data
|
||||
data: formData,
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data'
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 获取音频文件预签名URL
|
||||
export function getAudioPresignedUrl(params) {
|
||||
// 创建表单数据
|
||||
const formData = new FormData()
|
||||
if (params.audioId) {
|
||||
formData.append('audioId', params.audioId)
|
||||
}
|
||||
if (params.audioFileUrl) {
|
||||
formData.append('audioFileUrl', params.audioFileUrl)
|
||||
}
|
||||
formData.append('expires', params.expires || 3600)
|
||||
|
||||
return request({
|
||||
url: '/audioManagement/presigned-url',
|
||||
method: 'post',
|
||||
data: formData,
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data'
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -89,3 +89,54 @@ export function exportCustomerFlow(params) {
|
||||
responseType: 'blob'
|
||||
})
|
||||
}
|
||||
|
||||
// 沟通记录相关API
|
||||
// 分页查询沟通记录
|
||||
export function getCommunicationRecordPage(params) {
|
||||
return request({
|
||||
url: '/communication-record/page',
|
||||
method: 'get',
|
||||
params: {
|
||||
current: params.current || 1,
|
||||
size: params.size || 10,
|
||||
customerName: params.customerName,
|
||||
customerPhone: params.customerPhone,
|
||||
communicationType: params.communicationType,
|
||||
ownerName: params.ownerName
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 添加沟通记录
|
||||
export function addCommunicationRecord(data) {
|
||||
return request({
|
||||
url: '/communication-record/add',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 更新沟通记录
|
||||
export function updateCommunicationRecord(data) {
|
||||
return request({
|
||||
url: '/communication-record/update',
|
||||
method: 'put',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除沟通记录
|
||||
export function deleteCommunicationRecord(id) {
|
||||
return request({
|
||||
url: `/communication-record/delete/${id}`,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
// 根据ID查询沟通记录详情
|
||||
export function getCommunicationRecordById(id) {
|
||||
return request({
|
||||
url: `/communication-record/get/${id}`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
@@ -150,10 +150,19 @@ export const constantRoutes = [
|
||||
{
|
||||
path: '/customer',
|
||||
component: Layout,
|
||||
redirect: '/customer/management',
|
||||
name: 'CustomerRoot',
|
||||
meta: { title: '客户管理', icon: 'el-icon-user' },
|
||||
children: [
|
||||
{
|
||||
path: 'index',
|
||||
name: 'Customer',
|
||||
path: 'communication',
|
||||
name: 'CustomerCommunication',
|
||||
component: () => import('@/views/customer/communication'),
|
||||
meta: { title: '客户沟通', icon: 'el-icon-chat-dot-round' }
|
||||
},
|
||||
{
|
||||
path: 'management',
|
||||
name: 'CustomerManagement',
|
||||
component: () => import('@/views/customer/index'),
|
||||
meta: { title: '客户管理', icon: 'el-icon-user' }
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ service.interceptors.response.use(
|
||||
console.log('response 0811 :', res)
|
||||
|
||||
// 适配后端响应格式
|
||||
// 后端成功响应: { data: {...}, success: true, message: "..." }
|
||||
// 后端成功响应: { data: {...}, success: true, message: "..." } 或 { code: 200, data: [...], message: "..." }
|
||||
// 前端期望格式: { code: 20000, data: {...}, message: "..." }
|
||||
|
||||
if (res.success === true) {
|
||||
@@ -56,6 +56,17 @@ service.interceptors.response.use(
|
||||
pages: res.pages,
|
||||
size: res.size
|
||||
}
|
||||
} else if (res.code === 200) {
|
||||
// 后端返回格式:{ code: 200, data: [...], total: 1, current: 1, pages: 1, size: 10, message: "查询成功" }
|
||||
return {
|
||||
code: 200,
|
||||
data: res.data,
|
||||
total: res.total,
|
||||
current: res.current,
|
||||
pages: res.pages,
|
||||
size: res.size,
|
||||
message: res.message || 'Success'
|
||||
}
|
||||
} else if (res.success === false) {
|
||||
// 后端失败响应
|
||||
Message({
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
591
src/views/customer/communication.vue
Normal file
591
src/views/customer/communication.vue
Normal file
@@ -0,0 +1,591 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<!-- 页面标题 -->
|
||||
<div class="page-header">
|
||||
<h2>客户沟通</h2>
|
||||
<p>管理与客户的沟通记录和互动信息</p>
|
||||
</div>
|
||||
|
||||
<!-- 查询条件区域 -->
|
||||
<el-card class="filter-container" shadow="never">
|
||||
<el-form ref="queryForm" :model="queryParams" :inline="true" label-width="100px">
|
||||
<el-form-item label="客户姓名">
|
||||
<el-input
|
||||
v-model="queryParams.customerName"
|
||||
placeholder="请输入客户姓名"
|
||||
clearable
|
||||
style="width: 200px"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="客户电话">
|
||||
<el-input
|
||||
v-model="queryParams.customerPhone"
|
||||
placeholder="请输入客户电话"
|
||||
clearable
|
||||
style="width: 200px"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="沟通类型">
|
||||
<el-select v-model="queryParams.communicationType" placeholder="请选择沟通类型" clearable>
|
||||
<el-option label="电话沟通" value="phone" />
|
||||
<el-option label="微信沟通" value="wechat" />
|
||||
<el-option label="邮件沟通" value="email" />
|
||||
<el-option label="面谈沟通" value="meeting" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="所属人">
|
||||
<el-input
|
||||
v-model="queryParams.ownerName"
|
||||
placeholder="请输入所属人姓名"
|
||||
clearable
|
||||
style="width: 200px"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="沟通时间">
|
||||
<el-date-picker
|
||||
v-model="queryParams.communicationTimeRange"
|
||||
type="daterange"
|
||||
range-separator="至"
|
||||
start-placeholder="开始时间"
|
||||
end-placeholder="结束时间"
|
||||
format="yyyy-MM-dd"
|
||||
value-format="yyyy-MM-dd"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="el-icon-search" @click="handleQuery">筛选</el-button>
|
||||
<el-button icon="el-icon-delete" @click="resetQuery">清空</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<!-- 操作按钮区域 -->
|
||||
<el-card class="action-container" shadow="never">
|
||||
<el-button type="primary" icon="el-icon-plus" @click="handleAdd">添加沟通记录</el-button>
|
||||
<el-button type="success" icon="el-icon-upload2" @click="handleExport">导出记录</el-button>
|
||||
</el-card>
|
||||
|
||||
<!-- 数据表格区域 -->
|
||||
<el-card class="table-container" shadow="never">
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
:data="communicationList"
|
||||
style="width: 100%"
|
||||
@selection-change="handleSelectionChange"
|
||||
>
|
||||
<el-table-column type="selection" width="55" />
|
||||
<el-table-column label="序号" type="index" width="50" />
|
||||
<el-table-column label="客户姓名" prop="customerName" min-width="120" />
|
||||
<el-table-column label="客户电话" prop="customerPhone" min-width="150" />
|
||||
<el-table-column label="沟通类型" prop="communicationType" min-width="120">
|
||||
<template slot-scope="scope">
|
||||
<el-tag :type="getCommunicationTypeTag(scope.row.communicationType)">
|
||||
{{ getCommunicationTypeText(scope.row.communicationType) }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="沟通内容" prop="communicationContent" min-width="200" show-overflow-tooltip />
|
||||
<el-table-column label="所属人" prop="ownerName" min-width="120" />
|
||||
<el-table-column label="沟通时间" prop="communicationTime" min-width="150">
|
||||
<template slot-scope="scope">
|
||||
{{ formatTime(scope.row.communicationTime) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="沟通结果" prop="communicationResult" min-width="120" />
|
||||
<el-table-column label="待办建议" prop="todoSuggestion" min-width="150" show-overflow-tooltip />
|
||||
<el-table-column label="操作" width="200" fixed="right">
|
||||
<template slot-scope="scope">
|
||||
<el-button type="text" size="small" @click="handleViewDetails(scope.row)">查看详情</el-button>
|
||||
<el-button type="text" size="small" @click="handleEdit(scope.row)">编辑</el-button>
|
||||
<el-button type="text" size="small" style="color: #F56C6C;" @click="handleDelete(scope.row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<el-pagination
|
||||
:current-page="queryParams.current"
|
||||
:page-sizes="[10, 20, 50, 100]"
|
||||
:page-size="queryParams.size"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="total"
|
||||
style="margin-top: 20px; text-align: right;"
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
/>
|
||||
</el-card>
|
||||
|
||||
<!-- 添加/编辑沟通记录对话框 -->
|
||||
<el-dialog
|
||||
:title="dialogTitle"
|
||||
:visible.sync="dialogVisible"
|
||||
width="600px"
|
||||
@close="handleDialogClose"
|
||||
>
|
||||
<el-form ref="communicationForm" :model="communicationForm" :rules="communicationRules" label-width="100px">
|
||||
<el-form-item label="客户姓名" prop="customerName">
|
||||
<el-input v-model="communicationForm.customerName" placeholder="请输入客户姓名" />
|
||||
</el-form-item>
|
||||
<el-form-item label="客户电话" prop="customerPhone">
|
||||
<el-input v-model="communicationForm.customerPhone" placeholder="请输入客户电话" />
|
||||
</el-form-item>
|
||||
<el-form-item label="所属人" prop="ownerName">
|
||||
<el-input v-model="communicationForm.ownerName" placeholder="请输入所属人姓名" />
|
||||
</el-form-item>
|
||||
<el-form-item label="沟通类型" prop="communicationType">
|
||||
<el-select v-model="communicationForm.communicationType" placeholder="请选择沟通类型" style="width: 100%">
|
||||
<el-option label="电话沟通" value="phone" />
|
||||
<el-option label="微信沟通" value="wechat" />
|
||||
<el-option label="邮件沟通" value="email" />
|
||||
<el-option label="面谈沟通" value="meeting" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="沟通内容" prop="communicationContent">
|
||||
<el-input
|
||||
v-model="communicationForm.communicationContent"
|
||||
type="textarea"
|
||||
:rows="4"
|
||||
placeholder="请输入沟通内容"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="沟通时间" prop="communicationTime">
|
||||
<el-date-picker
|
||||
v-model="communicationForm.communicationTime"
|
||||
type="datetime"
|
||||
placeholder="选择沟通时间"
|
||||
format="yyyy-MM-dd HH:mm:ss"
|
||||
value-format="yyyy-MM-dd HH:mm:ss"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="沟通结果" prop="communicationResult">
|
||||
<el-input v-model="communicationForm.communicationResult" placeholder="请输入沟通结果" />
|
||||
</el-form-item>
|
||||
<el-form-item label="所属人电话" prop="ownerPhone">
|
||||
<el-input v-model="communicationForm.ownerPhone" placeholder="请输入所属人电话" />
|
||||
</el-form-item>
|
||||
<el-form-item label="待办建议" prop="todoSuggestion">
|
||||
<el-input
|
||||
v-model="communicationForm.todoSuggestion"
|
||||
type="textarea"
|
||||
:rows="3"
|
||||
placeholder="请输入待办建议"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit">确 定</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 沟通记录详情对话框 -->
|
||||
<el-dialog
|
||||
title="沟通记录详情"
|
||||
:visible.sync="detailVisible"
|
||||
width="800px"
|
||||
>
|
||||
<div v-if="currentCommunication" class="communication-detail">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<div class="detail-item">
|
||||
<label>客户姓名:</label>
|
||||
<span>{{ currentCommunication.customerName }}</span>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<div class="detail-item">
|
||||
<label>客户电话:</label>
|
||||
<span>{{ currentCommunication.customerPhone }}</span>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<div class="detail-item">
|
||||
<label>沟通类型:</label>
|
||||
<span>{{ getCommunicationTypeText(currentCommunication.communicationType) }}</span>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<div class="detail-item">
|
||||
<label>沟通时间:</label>
|
||||
<span>{{ formatTime(currentCommunication.communicationTime) }}</span>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="24">
|
||||
<div class="detail-item">
|
||||
<label>沟通内容:</label>
|
||||
<span>{{ currentCommunication.communicationContent }}</span>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<div class="detail-item">
|
||||
<label>所属人:</label>
|
||||
<span>{{ currentCommunication.ownerName }}</span>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<div class="detail-item">
|
||||
<label>所属人电话:</label>
|
||||
<span>{{ currentCommunication.ownerPhone }}</span>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<div class="detail-item">
|
||||
<label>沟通结果:</label>
|
||||
<span>{{ currentCommunication.communicationResult }}</span>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<div class="detail-item">
|
||||
<label>待办建议:</label>
|
||||
<span>{{ currentCommunication.todoSuggestion }}</span>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="detailVisible = false">关闭</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getCommunicationRecordPage, addCommunicationRecord, updateCommunicationRecord, deleteCommunicationRecord } from '@/api/customer'
|
||||
|
||||
export default {
|
||||
name: 'CustomerCommunication',
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
communicationList: [],
|
||||
total: 0,
|
||||
selectedIds: [],
|
||||
detailVisible: false,
|
||||
currentCommunication: null,
|
||||
// 添加/编辑对话框相关
|
||||
dialogVisible: false,
|
||||
dialogTitle: '',
|
||||
isEdit: false,
|
||||
communicationForm: {
|
||||
id: undefined,
|
||||
customerName: '',
|
||||
customerPhone: '',
|
||||
customerId: '',
|
||||
ownerName: '',
|
||||
ownerPhone: '',
|
||||
communicationType: '',
|
||||
communicationContent: '',
|
||||
communicationTime: '',
|
||||
communicationResult: '',
|
||||
todoSuggestion: ''
|
||||
},
|
||||
communicationRules: {
|
||||
customerName: [{ required: true, message: '请输入客户姓名', trigger: 'blur' }],
|
||||
customerPhone: [{ required: true, message: '请输入客户电话', trigger: 'blur' }],
|
||||
ownerName: [{ required: true, message: '请输入所属人姓名', trigger: 'blur' }],
|
||||
communicationType: [{ required: true, message: '请选择沟通类型', trigger: 'change' }],
|
||||
communicationContent: [{ required: true, message: '请输入沟通内容', trigger: 'blur' }],
|
||||
communicationTime: [{ required: true, message: '请选择沟通时间', trigger: 'change' }]
|
||||
},
|
||||
// 查询参数
|
||||
queryParams: {
|
||||
current: 1,
|
||||
size: 10,
|
||||
customerName: '',
|
||||
customerPhone: '',
|
||||
communicationType: '',
|
||||
ownerName: '',
|
||||
communicationTimeRange: []
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getList()
|
||||
},
|
||||
methods: {
|
||||
// 获取列表数据
|
||||
async getList() {
|
||||
this.loading = true
|
||||
try {
|
||||
const response = await getCommunicationRecordPage(this.queryParams)
|
||||
console.log('API响应:', response) // 调试日志
|
||||
|
||||
if (response.code === 200) {
|
||||
// 后端返回的数据结构:{ code: 200, data: [...], total: 1, current: 1, pages: 1, size: 10, message: "查询成功" }
|
||||
this.communicationList = response.data || []
|
||||
this.total = response.total || 0
|
||||
// 更新当前页码,确保分页组件显示正确的页码
|
||||
this.queryParams.current = response.current || 1
|
||||
} else {
|
||||
this.$message.error(response.message || '获取数据失败')
|
||||
this.communicationList = []
|
||||
this.total = 0
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取沟通记录失败:', error)
|
||||
this.$message.error('获取数据失败,请稍后重试')
|
||||
this.communicationList = []
|
||||
this.total = 0
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
|
||||
// 获取沟通类型标签样式
|
||||
getCommunicationTypeTag(type) {
|
||||
const tagMap = {
|
||||
phone: 'primary',
|
||||
wechat: 'success',
|
||||
email: 'info',
|
||||
meeting: 'warning'
|
||||
}
|
||||
return tagMap[type] || 'info'
|
||||
},
|
||||
|
||||
// 获取沟通类型文本
|
||||
getCommunicationTypeText(type) {
|
||||
const textMap = {
|
||||
phone: '电话沟通',
|
||||
wechat: '微信沟通',
|
||||
email: '邮件沟通',
|
||||
meeting: '面谈沟通'
|
||||
}
|
||||
return textMap[type] || type
|
||||
},
|
||||
|
||||
// 格式化时间显示
|
||||
formatTime(timeStr) {
|
||||
if (!timeStr) return '-'
|
||||
try {
|
||||
const date = new Date(timeStr)
|
||||
if (isNaN(date.getTime())) return timeStr
|
||||
return timeStr
|
||||
} catch (error) {
|
||||
console.error('时间格式化错误:', error)
|
||||
return timeStr
|
||||
}
|
||||
},
|
||||
|
||||
// 查询
|
||||
handleQuery() {
|
||||
this.queryParams.current = 1
|
||||
this.getList()
|
||||
},
|
||||
|
||||
// 重置查询
|
||||
resetQuery() {
|
||||
this.$refs.queryForm.resetFields()
|
||||
this.queryParams = {
|
||||
current: 1,
|
||||
size: 10,
|
||||
customerName: '',
|
||||
customerPhone: '',
|
||||
communicationType: '',
|
||||
ownerName: '',
|
||||
communicationTimeRange: []
|
||||
}
|
||||
this.getList()
|
||||
},
|
||||
|
||||
// 选择变化
|
||||
handleSelectionChange(selection) {
|
||||
this.selectedIds = selection.map(item => item.id)
|
||||
},
|
||||
|
||||
// 分页大小变化
|
||||
handleSizeChange(val) {
|
||||
this.queryParams.size = val
|
||||
this.getList()
|
||||
},
|
||||
|
||||
// 当前页变化
|
||||
handleCurrentChange(val) {
|
||||
this.queryParams.current = val
|
||||
this.getList()
|
||||
},
|
||||
|
||||
// 添加沟通记录
|
||||
handleAdd() {
|
||||
this.dialogTitle = '添加沟通记录'
|
||||
this.isEdit = false
|
||||
this.communicationForm = {
|
||||
id: undefined,
|
||||
customerName: '',
|
||||
customerPhone: '',
|
||||
customerId: '',
|
||||
ownerName: '',
|
||||
ownerPhone: '',
|
||||
communicationType: '',
|
||||
communicationContent: '',
|
||||
communicationTime: '',
|
||||
communicationResult: '',
|
||||
todoSuggestion: ''
|
||||
}
|
||||
this.dialogVisible = true
|
||||
},
|
||||
|
||||
// 编辑沟通记录
|
||||
handleEdit(row) {
|
||||
this.dialogTitle = '编辑沟通记录'
|
||||
this.isEdit = true
|
||||
this.communicationForm = { ...row }
|
||||
this.dialogVisible = true
|
||||
},
|
||||
|
||||
// 删除沟通记录
|
||||
handleDelete(row) {
|
||||
this.$confirm(`确定要删除与客户 "${row.customerName}" 的沟通记录吗?`, '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(async() => {
|
||||
try {
|
||||
const response = await deleteCommunicationRecord(row.id)
|
||||
if (response.code === 200) {
|
||||
this.$message.success('删除成功')
|
||||
this.getList()
|
||||
} else {
|
||||
this.$message.error(response.message || '删除失败')
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('删除沟通记录失败:', error)
|
||||
this.$message.error('删除失败,请稍后重试')
|
||||
}
|
||||
}).catch(() => {
|
||||
this.$message.info('已取消删除')
|
||||
})
|
||||
},
|
||||
|
||||
// 提交表单
|
||||
async handleSubmit() {
|
||||
this.$refs.communicationForm.validate(async(valid) => {
|
||||
if (valid) {
|
||||
try {
|
||||
let response
|
||||
if (this.isEdit) {
|
||||
response = await updateCommunicationRecord(this.communicationForm)
|
||||
} else {
|
||||
response = await addCommunicationRecord(this.communicationForm)
|
||||
}
|
||||
|
||||
if (response.code === 200) {
|
||||
this.$message.success(this.isEdit ? '更新成功' : '添加成功')
|
||||
this.dialogVisible = false
|
||||
this.getList()
|
||||
} else {
|
||||
this.$message.error(response.message || (this.isEdit ? '更新失败' : '添加失败'))
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('提交沟通记录失败:', error)
|
||||
this.$message.error('操作失败,请稍后重试')
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// 对话框关闭
|
||||
handleDialogClose() {
|
||||
this.$refs.communicationForm.resetFields()
|
||||
},
|
||||
|
||||
// 查看详情
|
||||
handleViewDetails(row) {
|
||||
this.currentCommunication = row
|
||||
this.detailVisible = true
|
||||
},
|
||||
|
||||
// 导出记录
|
||||
handleExport() {
|
||||
this.$message.success('导出成功')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.page-header {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.page-header h2 {
|
||||
margin: 0 0 8px 0;
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
.page-header p {
|
||||
margin: 0;
|
||||
color: #606266;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.filter-container,
|
||||
.action-container,
|
||||
.table-container {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.el-form-item {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.communication-detail {
|
||||
padding: 20px 0;
|
||||
}
|
||||
|
||||
.detail-item {
|
||||
display: flex;
|
||||
margin-bottom: 16px;
|
||||
font-size: 14px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.detail-item label {
|
||||
width: 100px;
|
||||
color: #909399;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.detail-item span {
|
||||
color: #303133;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.el-button--text {
|
||||
padding: 0;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.el-button--text:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.dialog-footer {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.el-table .el-button--text {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.el-table .el-button--text:hover {
|
||||
color: #409EFF;
|
||||
}
|
||||
|
||||
.el-table .el-button--text.el-button--danger:hover {
|
||||
color: #F56C6C;
|
||||
}
|
||||
</style>
|
||||
@@ -105,17 +105,19 @@
|
||||
<el-table-column label="联系方式" prop="contact" min-width="150" />
|
||||
<el-table-column label="所属机构" prop="dealershipName" min-width="150" />
|
||||
<el-table-column label="所属销售" prop="salesName" min-width="150" />
|
||||
<el-table-column label="录音条数" prop="recordingCount" sortable min-width="100" />
|
||||
<el-table-column label="意向车型" prop="intendedModel" min-width="120" />
|
||||
<el-table-column label="联系次数" prop="contactCount" sortable min-width="100" />
|
||||
<el-table-column label="客户意向" prop="intendedModel" min-width="120" />
|
||||
<el-table-column label="详细地址" prop="detailedAddress" min-width="200" show-overflow-tooltip />
|
||||
<el-table-column label="修改时间" prop="updateTime" min-width="150">
|
||||
<template slot-scope="scope">
|
||||
{{ formatTime(scope.row.updateTime) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="200" fixed="right">
|
||||
<el-table-column label="操作" width="280" fixed="right">
|
||||
<template slot-scope="scope">
|
||||
<el-button type="text" size="small" @click="handleViewDetails(scope.row)">查看详情</el-button>
|
||||
<el-button type="text" size="small" @click="handleEdit(scope.row)">编辑</el-button>
|
||||
<el-button type="text" size="small" style="color: #67C23A;" @click="handleAddCommunication(scope.row)">添加沟通记录</el-button>
|
||||
<el-button type="text" size="small" style="color: #F56C6C;" @click="handleDelete(scope.row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
@@ -156,13 +158,17 @@
|
||||
<span>{{ customer.salesName }}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<label>录音条数:</label>
|
||||
<span>{{ customer.recordingCount }}</span>
|
||||
<label>联系次数:</label>
|
||||
<span>{{ customer.contactCount }}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<label>意向车型:</label>
|
||||
<label>客户意向:</label>
|
||||
<span>{{ customer.intendedModel || '-' }}</span>
|
||||
</div>
|
||||
<div v-if="customer.detailedAddress" class="info-item">
|
||||
<label>详细地址:</label>
|
||||
<span>{{ customer.detailedAddress }}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<label>修改时间:</label>
|
||||
<span>{{ formatTime(customer.updateTime) || '-' }}</span>
|
||||
@@ -223,8 +229,16 @@
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="意向车型" prop="intendedModel">
|
||||
<el-input v-model="customerForm.intendedModel" placeholder="请输入意向车型" />
|
||||
<el-form-item label="客户意向" prop="intendedModel">
|
||||
<el-input v-model="customerForm.intendedModel" placeholder="请输入客户意向" />
|
||||
</el-form-item>
|
||||
<el-form-item label="客户详细地址" prop="detailedAddress">
|
||||
<el-input
|
||||
v-model="customerForm.detailedAddress"
|
||||
type="textarea"
|
||||
:rows="2"
|
||||
placeholder="请输入客户详细地址"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="备注" prop="remark">
|
||||
<el-input
|
||||
@@ -279,17 +293,25 @@
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<div class="detail-item">
|
||||
<label>录音条数:</label>
|
||||
<span>{{ currentCustomer.recordingCount }}</span>
|
||||
<label>联系次数:</label>
|
||||
<span>{{ currentCustomer.contactCount }}</span>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<div class="detail-item">
|
||||
<label>意向车型:</label>
|
||||
<label>客户意向:</label>
|
||||
<span>{{ currentCustomer.intendedModel || '-' }}</span>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row v-if="currentCustomer.detailedAddress" :gutter="20">
|
||||
<el-col :span="24">
|
||||
<div class="detail-item">
|
||||
<label>客户详细地址:</label>
|
||||
<span>{{ currentCustomer.detailedAddress }}</span>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<div class="detail-item">
|
||||
@@ -317,6 +339,99 @@
|
||||
<el-button @click="detailVisible = false">关闭</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 添加沟通记录对话框 -->
|
||||
<el-dialog
|
||||
title="添加沟通记录"
|
||||
:visible.sync="communicationDialogVisible"
|
||||
width="800px"
|
||||
@close="handleCommunicationDialogClose"
|
||||
>
|
||||
<el-form ref="communicationForm" :model="communicationForm" :rules="communicationRules" label-width="120px">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="客户姓名" prop="customerName">
|
||||
<el-input v-model="communicationForm.customerName" placeholder="请输入客户姓名" disabled />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="客户电话" prop="customerPhone">
|
||||
<el-input v-model="communicationForm.customerPhone" placeholder="请输入客户电话" disabled />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="沟通类型" prop="communicationType">
|
||||
<el-select v-model="communicationForm.communicationType" placeholder="请选择沟通类型" style="width: 100%">
|
||||
<el-option label="电话沟通" value="phone" />
|
||||
<el-option label="微信沟通" value="wechat" />
|
||||
<el-option label="邮件沟通" value="email" />
|
||||
<el-option label="面谈沟通" value="meeting" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="下次沟通时间" prop="nextCommunicationTime">
|
||||
<el-date-picker
|
||||
v-model="communicationForm.nextCommunicationTime"
|
||||
type="datetime"
|
||||
placeholder="选择下次沟通时间"
|
||||
format="yyyy-MM-dd HH:mm:ss"
|
||||
value-format="yyyy-MM-dd HH:mm:ss"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-form-item label="沟通内容" prop="communicationContent">
|
||||
<el-input
|
||||
v-model="communicationForm.communicationContent"
|
||||
type="textarea"
|
||||
:rows="4"
|
||||
placeholder="请输入沟通内容"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="沟通结果" prop="communicationResult">
|
||||
<el-input
|
||||
v-model="communicationForm.communicationResult"
|
||||
type="textarea"
|
||||
:rows="3"
|
||||
placeholder="请输入沟通结果"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="待办事项" prop="todoSuggestion">
|
||||
<el-input
|
||||
v-model="communicationForm.todoSuggestion"
|
||||
type="textarea"
|
||||
:rows="3"
|
||||
placeholder="请输入待办事项"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="所属人姓名" prop="ownerName">
|
||||
<el-input v-model="communicationForm.ownerName" placeholder="请输入所属人姓名" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="所属人电话" prop="ownerPhone">
|
||||
<el-input v-model="communicationForm.ownerPhone" placeholder="请输入所属人电话" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="communicationDialogVisible = false">取 消</el-button>
|
||||
<el-button type="success" icon="el-icon-cpu" @click="handleAIAnalysis">AI分析</el-button>
|
||||
<el-button type="primary" @click="handleCommunicationSubmit">提 交</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -328,7 +443,8 @@ import {
|
||||
updateCustomer,
|
||||
deleteCustomer,
|
||||
batchDeleteCustomer,
|
||||
exportCustomerFlow
|
||||
exportCustomerFlow,
|
||||
addCommunicationRecord
|
||||
} from '@/api/customer'
|
||||
import { getProjectList } from '@/api/project'
|
||||
import { getSalesList } from '@/api/sales'
|
||||
@@ -356,6 +472,7 @@ export default {
|
||||
dealershipId: '',
|
||||
salesId: '',
|
||||
intendedModel: '',
|
||||
detailedAddress: '',
|
||||
remark: ''
|
||||
},
|
||||
customerRules: {
|
||||
@@ -385,6 +502,26 @@ export default {
|
||||
currentUser: {
|
||||
name: '',
|
||||
phone: ''
|
||||
},
|
||||
// 沟通记录对话框相关
|
||||
communicationDialogVisible: false,
|
||||
communicationForm: {
|
||||
customerName: '',
|
||||
customerPhone: '',
|
||||
customerId: '',
|
||||
communicationType: '',
|
||||
communicationContent: '',
|
||||
communicationResult: '',
|
||||
todoSuggestion: '',
|
||||
nextCommunicationTime: '',
|
||||
ownerName: '',
|
||||
ownerPhone: ''
|
||||
},
|
||||
communicationRules: {
|
||||
communicationType: [{ required: true, message: '请选择沟通类型', trigger: 'change' }],
|
||||
communicationContent: [{ required: true, message: '请输入沟通内容', trigger: 'blur' }],
|
||||
communicationResult: [{ required: true, message: '请输入沟通结果', trigger: 'blur' }],
|
||||
ownerName: [{ required: true, message: '请输入所属人姓名', trigger: 'blur' }]
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -559,6 +696,7 @@ export default {
|
||||
dealershipId: '',
|
||||
salesId: '',
|
||||
intendedModel: '',
|
||||
detailedAddress: '',
|
||||
remark: ''
|
||||
}
|
||||
this.dialogVisible = true
|
||||
@@ -750,6 +888,59 @@ export default {
|
||||
console.error('时间格式化错误:', error)
|
||||
return timeStr
|
||||
}
|
||||
},
|
||||
|
||||
// 添加沟通记录
|
||||
handleAddCommunication(row) {
|
||||
this.communicationForm = {
|
||||
customerName: row.customerName,
|
||||
customerPhone: row.contact,
|
||||
customerId: row.id,
|
||||
communicationType: '',
|
||||
communicationContent: '',
|
||||
communicationResult: '',
|
||||
todoSuggestion: '',
|
||||
nextCommunicationTime: '',
|
||||
ownerName: this.currentUser.name,
|
||||
ownerPhone: ''
|
||||
}
|
||||
this.communicationDialogVisible = true
|
||||
},
|
||||
|
||||
// 提交沟通记录
|
||||
handleCommunicationSubmit() {
|
||||
this.$refs.communicationForm.validate(async(valid) => {
|
||||
if (valid) {
|
||||
try {
|
||||
// 设置沟通时间为当前时间
|
||||
const communicationData = {
|
||||
...this.communicationForm,
|
||||
communicationTime: new Date().toISOString().slice(0, 19).replace('T', ' ')
|
||||
}
|
||||
|
||||
const response = await addCommunicationRecord(communicationData)
|
||||
if (response.code === 200) {
|
||||
this.$message.success('沟通记录添加成功')
|
||||
this.communicationDialogVisible = false
|
||||
} else {
|
||||
this.$message.error(response.message || '添加沟通记录失败')
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('添加沟通记录失败:', error)
|
||||
this.$message.error('添加沟通记录失败,请稍后重试')
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// 沟通记录对话框关闭
|
||||
handleCommunicationDialogClose() {
|
||||
this.$refs.communicationForm.resetFields()
|
||||
},
|
||||
|
||||
// AI分析
|
||||
handleAIAnalysis() {
|
||||
this.$message.info('AI分析功能开发中,敬请期待!')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user