音频管理管理功能调整, 音频模型调整

This commit is contained in:
ZLI263
2025-10-25 23:35:31 +08:00
parent ea21831191
commit 8695d81e16
8 changed files with 1882 additions and 197 deletions

View File

@@ -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'
}
})
}

View File

@@ -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'
})
}

View File

@@ -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' }
}

View File

@@ -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

View 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>

View File

@@ -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分析功能开发中敬请期待')
}
}
}