增加外呼

This commit is contained in:
lcc
2025-08-14 15:25:32 +08:00
parent 20bb32c8d7
commit 3f2db2b624
7 changed files with 521 additions and 6 deletions
+25
View File
@@ -0,0 +1,25 @@
import request from '@/utils/request';
/**
* 分页查询
* @param params 查询条件
*/
export async function pageLog(params) {
const res = await request.get('/call/log/page', {
params
});
if (res.data.code === 0) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
export async function logSearch(params) {
const res = await request.get('/call/log/search', {
params
});
if (res.data.code === 0) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
+8
View File
@@ -69,3 +69,11 @@ export async function updateClues(data) {
}
return Promise.reject(new Error(res.data.message));
}
export async function callPhone(data) {
const res = await request.post('/receiver/clues/call', data);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
+8
View File
@@ -17,3 +17,11 @@ export async function getUserInfo(params) {
}
return Promise.reject(new Error(res.data.message));
}
export async function updateUserMobile(params) {
const res = await request.put('/user/userInfo/mobile', params);
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}
+105
View File
@@ -0,0 +1,105 @@
<template>
<div class="ele-body">
<el-card shadow="never" body-style="padding: 20px;">
<el-row :gutter="24">
<el-form
ref="form"
:model="form"
:rules="rules"
label-width="300px"
style="padding: 34px 20px 0 20px"
@keyup.enter.native="save"
@submit.native.prevent
>
<el-form-item label="分机号码:" prop="mobile">
<el-input
placeholder="请输入分机号码"
v-model="form.mobile"
style="width: 300px"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" :loading="loading" @click="save">
保存
</el-button>
</el-form-item>
</el-form>
</el-row>
</el-card>
</div>
</template>
<script>
import { getUserInfo, updateUserMobile } from '@/api/user/userinfo';
export default {
name: 'CallConfig',
components: {},
data() {
return {
// 表单数据
form: {
mobile: ''
},
// 表单验证规则
rules: {
mobile: [
{
required: true,
message: '请输入分机号码',
trigger: 'blur'
}
]
},
// 保存按钮loading
loading: false
};
},
computed: {
// 是否开启响应式布局
styleResponsive() {
return this.$store.state.theme.styleResponsive;
}
},
created() {
Object.assign(this.form, this.loginUser);
this.loadUserInfo();
},
methods: {
loadUserInfo() {
getUserInfo()
.then((res) => {
console.log(res);
Object.assign(this.form, res);
})
.catch((e) => {
this.$message.error(e.message);
});
},
save() {
this.$refs.form.validate((valid) => {
if (!valid) {
return false;
}
this.loading = true;
updateUserMobile({ ...this.form })
.then((res) => {
this.loading = false;
this.$message.success(res);
this.loadUserInfo();
})
.catch((e) => {
this.loading = false;
this.$message.error(e.message);
});
});
}
}
};
</script>
<style lang="scss" scoped>
.ele-body {
padding-bottom: 0;
}
</style>
@@ -0,0 +1,186 @@
<!-- 搜索表单 -->
<template>
<el-form
label-width="100px"
class="ele-form-search"
@keyup.enter.native="search"
@submit.native.prevent
>
<el-row :gutter="15">
<el-col v-bind="styleResponsive ? { lg: 6, md: 12 } : { span: 6 }">
<el-form-item label="工号:">
<el-input clearable v-model="where.agentId" placeholder="请输入" />
</el-form-item>
</el-col>
<el-col v-bind="styleResponsive ? { lg: 6, md: 12 } : { span: 6 }">
<el-form-item label="录音流水号:">
<el-input clearable v-model="where.voiceId" placeholder="请输入" />
</el-form-item>
</el-col>
<el-col v-bind="styleResponsive ? { lg: 6, md: 12 } : { span: 6 }">
<el-form-item label="客户联系方式:">
<el-input
clearable
v-model="where.customerPhoneNo"
placeholder="请输入"
/>
</el-form-item>
</el-col>
<el-col v-bind="styleResponsive ? { lg: 6, md: 12 } : { span: 6 }">
<el-form-item label="结束类型:">
<el-select
clearable
v-model="where.finishType"
placeholder="请选择"
style="width: 100%"
>
<el-option
v-for="(item, index) in finishTypeList"
:key="index"
:label="item"
:value="index"
></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col v-bind="styleResponsive ? { lg: 6, md: 12 } : { span: 6 }">
<el-form-item label="呼叫类型:">
<el-select
clearable
v-model="where.callType"
placeholder="请选择"
style="width: 100%"
>
<el-option
v-for="(item, index) in callTypeList"
:key="index"
:label="item"
:value="index"
></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col v-bind="styleResponsive ? { lg: 6, md: 12 } : { span: 6 }">
<el-form-item label="挂断类型:">
<el-select
clearable
v-model="where.hangupType"
placeholder="请选择"
style="width: 100%"
>
<el-option
v-for="(item, index) in hangupTypeList"
:key="index"
:label="item"
:value="index"
></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col v-bind="styleResponsive ? { lg: 12, md: 12 } : { span: 6 }">
<el-form-item label="通话开始时间:">
<el-date-picker
unlink-panels
v-model="where.startTime"
range-separator="-"
type="daterange"
end-placeholder="结束日期"
start-placeholder="开始日期"
value-format="yyyy-MM-dd"
class="ele-fluid"
/>
</el-form-item>
</el-col>
<el-col v-bind="styleResponsive ? { lg: 12, md: 12 } : { span: 6 }">
<el-form-item label="通话结束时间:">
<el-date-picker
unlink-panels
v-model="where.endTime"
range-separator="-"
type="daterange"
end-placeholder="结束日期"
start-placeholder="开始日期"
value-format="yyyy-MM-dd"
class="ele-fluid"
/>
</el-form-item>
</el-col>
<el-col v-bind="styleResponsive ? { lg: 6, md: 12 } : { span: 6 }">
<el-form-item label="业务订单号:">
<el-input clearable v-model="where.orderId" placeholder="请输入" />
</el-form-item>
</el-col>
<el-col v-bind="styleResponsive ? { lg: 6, md: 12 } : { span: 6 }">
<div class="ele-form-actions">
<el-button
type="primary"
icon="el-icon-search"
class="ele-btn-icon"
@click="search"
>
查询
</el-button>
<el-button @click="reset">重置</el-button>
</div>
</el-col>
</el-row>
</el-form>
</template>
<script>
import { logSearch } from '@/api/call';
export default {
data() {
// 默认表单数据
const defaultWhere = {
orderId: '',
agentId: '',
voiceId: '',
customerPhoneNo: '',
finishType: '',
callType: '',
hangupType: '',
startTime: '',
endTime: ''
};
return {
// 表单数据
where: { ...defaultWhere },
finishTypeList: [],
callTypeList: [],
hangupTypeList: []
};
},
computed: {
// 是否开启响应式布局
styleResponsive() {
return this.$store.state.theme.styleResponsive;
}
},
mounted() {
this.initSearch();
},
methods: {
initSearch() {
logSearch()
.then((data) => {
this.finishTypeList = data.finishTypeList;
this.callTypeList = data.callTypeList;
this.hangupTypeList = data.hangupTypeList;
})
.catch((e) => {
this.$message.error(e.message);
});
},
/* 搜索 */
search() {
this.$emit('search', this.where);
},
/* 重置 */
reset() {
this.where = { ...this.defaultWhere };
this.search();
}
}
};
</script>
+154
View File
@@ -0,0 +1,154 @@
<template>
<div class="ele-body">
<el-card shadow="never">
<!-- 搜索表单 -->
<search @search="reload" />
<!-- 数据表格 -->
<ele-pro-table
ref="table"
:columns="columns"
:datasource="datasource"
:selection.sync="selection"
cache-key="CallLog"
>
<!-- 表头工具栏 -->
<template v-slot:toolbar></template>
<!-- 操作列 -->
</ele-pro-table>
</el-card>
</div>
</template>
<script>
import search from './components/search.vue';
import { pageLog } from '@/api/call';
export default {
name: 'CallLog',
components: {
search
},
data() {
return {
// 表格列配置
columns: [
{
prop: 'id',
label: 'ID',
width: 110,
align: 'center',
fixed: 'left'
},
{
prop: 'orderId',
label: '业务订单号',
align: 'center',
width: 250
},
{
prop: 'customerPhoneNo',
label: '客户联系方式',
align: 'center',
width: 150
},
{
prop: 'agentPhoneNo',
label: '坐席分机号',
align: 'center',
width: 150
},
{
prop: 'agentId',
label: '工号',
align: 'center',
width: 150
},
{
prop: 'agentUm',
label: '姓名',
align: 'center',
width: 150
},
{
prop: 'customerDispNo',
label: '呼客户外显号码',
align: 'center',
width: 150
},
{
prop: 'agentDispNo',
label: '呼坐席外显号码',
align: 'center',
width: 150
},
{
prop: 'voiceId',
label: '录音流水号',
align: 'center',
width: 150
},
{
prop: 'ringDuration',
label: '振铃时长(秒)',
align: 'center',
width: 110
},
{
prop: 'telDuration',
label: '通话时长(秒)',
align: 'center',
width: 110
},
{
prop: 'startTime',
label: '通话开始时间',
align: 'center',
width: 150
},
{
prop: 'endTime',
label: '通话结束时间',
align: 'center',
width: 150
},
{
prop: 'finishTypeCn',
label: '结束类型',
align: 'center',
width: 110
},
{
prop: 'callTypeCn',
label: '呼叫类型',
align: 'center',
width: 110
},
{
prop: 'hangupTypeCn',
label: '挂断类型',
align: 'center',
width: 110
},
{
prop: 'reqId',
label: '请求id',
align: 'center',
width: 180
}
],
// 表格选中数据
selection: []
};
},
methods: {
/* 表格数据源 */
datasource({ page, limit, where, order }) {
return pageLog({ ...where, ...order, page, limit });
},
/* 刷新表格 */
reload(where) {
this.$refs.table.reload({ page: 1, where: where });
}
}
};
</script>
+35 -6
View File
@@ -167,20 +167,23 @@
}}</div>
</template>
<!-- 操作列 -->
<!--
<template v-slot:action="{ row }">
<el-link type="primary" :underline="false" @click="goDetail(row)">
查看
</el-link>
<el-button
size="small"
type="primary"
:underline="false"
@click="call(row)"
>
拨打电话
</el-button>
</template>
-->
</ele-pro-table>
</el-card>
</div>
</template>
<script>
import { pageClues, getSearch } from '@/api/receiver/clues';
import { pageClues, getSearch, callPhone } from '@/api/receiver/clues';
import RegionsSelect from '@/components/RegionsSelect/index.vue';
import BrandSelect from '@/components/BrandSelect/index.vue';
import { pageCenterList, pageOrgNameList } from '@/api/auto';
@@ -260,6 +263,13 @@
align: 'center',
minWidth: 80,
resizable: false
},
{
prop: 'action',
label: '操作',
align: 'center',
width: 100,
slot: 'action'
}
],
// 表格选中数据
@@ -402,6 +412,25 @@
reset() {
this.where = {};
this.reload();
},
/* 拨打电话 */
call(row) {
this.$confirm('确定拨打电话【' + row.mobile + '】吗?', '提示', {
type: 'warning'
})
.then(() => {
const loading = this.$loading({ lock: true });
callPhone({ id: row.id })
.then((msg) => {
loading.close();
this.$message.success(msg);
})
.catch((e) => {
loading.close();
this.$message.error(e.message);
});
})
.catch(() => {});
}
}
};