|
|
@@ -48,16 +48,16 @@
|
|
|
<!-- >删除-->
|
|
|
<!-- </el-button>-->
|
|
|
<!-- </el-col>-->
|
|
|
-<!-- <el-col :span="1.5">-->
|
|
|
-<!-- <el-button-->
|
|
|
-<!-- type="warning"-->
|
|
|
-<!-- icon="el-icon-download"-->
|
|
|
-<!-- size="mini"-->
|
|
|
-<!-- @click="handleExport"-->
|
|
|
-<!-- v-hasPermi="['system:companyVoiceRobotic:export']"-->
|
|
|
-<!-- >导出-->
|
|
|
-<!-- </el-button>-->
|
|
|
-<!-- </el-col>-->
|
|
|
+ <el-col :span="1.5">
|
|
|
+ <el-button
|
|
|
+ type="warning"
|
|
|
+ icon="el-icon-download"
|
|
|
+ size="mini"
|
|
|
+ @click="handleExport"
|
|
|
+ v-hasPermi="['system:companyVoiceRobotic:export']"
|
|
|
+ >导出
|
|
|
+ </el-button>
|
|
|
+ </el-col>
|
|
|
<!-- <el-col :span="1.5">-->
|
|
|
<!-- <el-button-->
|
|
|
<!-- type="success"-->
|
|
|
@@ -116,13 +116,10 @@
|
|
|
<template slot-scope="scope">
|
|
|
<el-tag v-if="scope.row.taskStatus == 0">未启动</el-tag>
|
|
|
<el-tag v-if="scope.row.taskStatus == 1" type="warning">执行中</el-tag>
|
|
|
- <el-tag v-if="scope.row.taskStatus == 2" type="danger">执行中断</el-tag>
|
|
|
+ <el-tag v-if="scope.row.taskStatus == 2" type="danger">任务暂停</el-tag>
|
|
|
<el-tag v-if="scope.row.taskStatus == 3" type="success">执行完成</el-tag>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
-
|
|
|
- <el-table-column label="创建人" align="center" prop="createByName"/>
|
|
|
- <el-table-column label="创建部门" align="center" prop="createByDeptName"/>
|
|
|
<!-- <el-table-column label="外呼状态" align="center">-->
|
|
|
<!-- <template slot-scope="scope">-->
|
|
|
<!-- <div v-loading="loadingStatus">-->
|
|
|
@@ -163,6 +160,18 @@
|
|
|
v-if="scope.row.taskStatus == 0"
|
|
|
@click="taskRunFun(scope.row.id)"
|
|
|
>启动任务</el-button>
|
|
|
+ <el-button
|
|
|
+ size="mini"
|
|
|
+ type="text"
|
|
|
+ v-if="scope.row.taskStatus == 1"
|
|
|
+ @click="handlePauseTask(scope.row)"
|
|
|
+ >暂停任务</el-button>
|
|
|
+ <el-button
|
|
|
+ size="mini"
|
|
|
+ type="text"
|
|
|
+ v-if="scope.row.taskStatus == 2"
|
|
|
+ @click="handleResumeTask(scope.row)"
|
|
|
+ >继续任务</el-button>
|
|
|
<!-- <el-button
|
|
|
size="mini"
|
|
|
type="text"
|
|
|
@@ -230,7 +239,7 @@
|
|
|
</el-button>
|
|
|
</el-form-item>
|
|
|
<el-form-item label="任务流程" prop="companyAiWorkflowId">
|
|
|
- <el-select v-model="form.companyAiWorkflowId" filterable placeholder="请选择任务流程">
|
|
|
+ <el-select v-model="form.companyAiWorkflowId" filterable placeholder="请选择任务流程" @change="onWorkflowChange">
|
|
|
<el-option v-for="item in workflowList" :key="item.value" :label="item.label" :value="item.value"/>
|
|
|
</el-select>
|
|
|
</el-form-item>
|
|
|
@@ -279,7 +288,7 @@
|
|
|
<el-input v-model="form.name" placeholder="请输入任务名称" clearable/>
|
|
|
</el-form-item>
|
|
|
<el-form-item label="任务流程" prop="companyAiWorkflowId">
|
|
|
- <el-select v-model="form.companyAiWorkflowId" filterable placeholder="请选择任务流程">
|
|
|
+ <el-select v-model="form.companyAiWorkflowId" filterable placeholder="请选择任务流程" @change="onWorkflowChange">
|
|
|
<el-option v-for="item in workflowList" :key="item.value" :label="item.label" :value="item.value"/>
|
|
|
</el-select>
|
|
|
</el-form-item>
|
|
|
@@ -358,7 +367,7 @@
|
|
|
|
|
|
</div>
|
|
|
|
|
|
- <div class="form-section">
|
|
|
+ <div class="form-section" v-if="workflowHasAddWx">
|
|
|
<div class="section-title">
|
|
|
<i class="el-icon-setting"></i>
|
|
|
<span>加微设置</span>
|
|
|
@@ -377,7 +386,7 @@
|
|
|
</el-form-item>
|
|
|
</div>
|
|
|
|
|
|
- <div class="form-section account-section">
|
|
|
+ <div class="form-section account-section" v-if="workflowHasAddWx">
|
|
|
<div class="section-title">
|
|
|
<i class="el-icon-user-solid"></i>
|
|
|
<span>分配账号</span>
|
|
|
@@ -455,7 +464,7 @@
|
|
|
</el-form-item> -->
|
|
|
</el-form>
|
|
|
<div slot="footer" class="dialog-footer" style="text-align:right">
|
|
|
- <el-button type="primary" @click="submitForm">确 定</el-button>
|
|
|
+ <el-button type="primary" :loading="submitFormLoading" @click="submitForm">确 定</el-button>
|
|
|
<el-button @click="cancel">取 消</el-button>
|
|
|
</div>
|
|
|
</div>
|
|
|
@@ -506,6 +515,20 @@
|
|
|
<span v-else class="no-tags">暂无标签</span>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
+ <el-table-column label="是否添加客服" align="center" prop="isAdd">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <el-tag
|
|
|
+ :type="scope.row.isAdd === 1 ? 'success' : 'info'"
|
|
|
+ :style="{
|
|
|
+ backgroundColor: scope.row.isAdd === 1 ? '#67C23A' : '#909399',
|
|
|
+ color: '#fff',
|
|
|
+ border: 'none'
|
|
|
+ }"
|
|
|
+ >
|
|
|
+ {{ scope.row.isAdd === 1 ? '已添加' : '未添加' }}
|
|
|
+ </el-tag>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
|
|
<template slot-scope="scope">
|
|
|
<el-button
|
|
|
@@ -666,15 +689,6 @@
|
|
|
<div class="customer-detail">
|
|
|
<div class="customer-name-row">
|
|
|
<span class="customer-name">{{ record.customerName }}</span>
|
|
|
-
|
|
|
- <el-tag
|
|
|
- v-if="record.intention"
|
|
|
- size="small"
|
|
|
- type="info"
|
|
|
- class="status-tag">
|
|
|
- 意向度:{{ getIntentionLabel(record.intention) }}
|
|
|
- </el-tag>
|
|
|
-
|
|
|
<el-tag
|
|
|
:type="getWorkflowStatusType(record.workflowStatus)"
|
|
|
size="small"
|
|
|
@@ -774,6 +788,7 @@
|
|
|
耗时: {{ formatDuration(log.duration) }}
|
|
|
</span>
|
|
|
</div>
|
|
|
+
|
|
|
</el-card>
|
|
|
</el-timeline-item>
|
|
|
</el-timeline>
|
|
|
@@ -864,12 +879,14 @@
|
|
|
|
|
|
<script>
|
|
|
import {
|
|
|
- myListRobotic,
|
|
|
+ listRobotic,
|
|
|
+ myListRobotic,
|
|
|
getRobotic,
|
|
|
delRobotic,
|
|
|
addRobotic,
|
|
|
updateRobotic,
|
|
|
exportRobotic,
|
|
|
+ exportMyRobotic,
|
|
|
calleesList,
|
|
|
statusList,
|
|
|
startRobotic,
|
|
|
@@ -877,11 +894,12 @@ import {
|
|
|
companyUserList,
|
|
|
wxList,
|
|
|
taskRun,
|
|
|
- wxListQw,
|
|
|
+ // getTypes,
|
|
|
getSmsTempList,
|
|
|
// getCIDGroupList,
|
|
|
getExecRecords,
|
|
|
- getCurrentCompanyId
|
|
|
+ getCurrentCompanyId,
|
|
|
+ pauseRoboticActive
|
|
|
} from "@/api/company/companyVoiceRobotic";
|
|
|
import draggable from 'vuedraggable'
|
|
|
// import { listAll } from '@/api/company/wxDialog';
|
|
|
@@ -890,17 +908,21 @@ import qwUserSelect from '@/views/components/QwUserSelect.vue';
|
|
|
import qwUserSelectTwo from '@/views/components/QwUserSelectTwo.vue';
|
|
|
import customerDetails from "@/views/crm/components/customerDetails.vue";
|
|
|
import {getDicts} from "@/api/system/dict/data";
|
|
|
-import { optionList } from '@/api/company/companyWorkflow'
|
|
|
+import { optionList, getWorkflowNodeTypeCodes } from '@/api/company/companyWorkflow'
|
|
|
+import {wxListQw} from "../../../api/company/companyVoiceRobotic";
|
|
|
import CallCenterPhoneBar from '../../aiSipCall/aiSipCallManualOutbound.vue'
|
|
|
+import AiTagPanel from "../../crm/components/AiTagPanel.vue";
|
|
|
|
|
|
export default {
|
|
|
- name: "myRobotic",
|
|
|
- components: { draggable, customerDetails, customerSelect, qwUserSelect,qwUserSelectTwo,CallCenterPhoneBar},
|
|
|
+ name: "MyRobotic",
|
|
|
+ components: {AiTagPanel, draggable, customerDetails, customerSelect, qwUserSelect,qwUserSelectTwo,CallCenterPhoneBar},
|
|
|
data() {
|
|
|
return {
|
|
|
+ submitFormLoading:false,
|
|
|
taskType:1,
|
|
|
taskTypeList:[{id:1,name:"普通任务"},{id:2,name:"场景任务"}],
|
|
|
currentCompanyId:null,
|
|
|
+ workflowHasAddWx: false,
|
|
|
// 遮罩层
|
|
|
loading: true,
|
|
|
// CIDGroupList:[],
|
|
|
@@ -1159,6 +1181,7 @@ export default {
|
|
|
};
|
|
|
return intentionMap[intention] || intention;
|
|
|
},
|
|
|
+
|
|
|
getSmsTempDropList(){
|
|
|
getSmsTempList().then(res=>{
|
|
|
this.smsTempList = res.data;
|
|
|
@@ -1170,7 +1193,7 @@ export default {
|
|
|
/** 查询机器人外呼任务列表 */
|
|
|
getList() {
|
|
|
this.loading = true;
|
|
|
- myListRobotic(this.queryParams).then(response => {
|
|
|
+ myListRobotic(this.queryParams).then(response => {
|
|
|
this.roboticList = response.rows;
|
|
|
this.roboticList.forEach(e => {
|
|
|
if(e.weekDay1){
|
|
|
@@ -1179,7 +1202,6 @@ export default {
|
|
|
})
|
|
|
this.total = response.total;
|
|
|
this.loading = false;
|
|
|
- this.updateStatusFun();
|
|
|
});
|
|
|
},
|
|
|
updateStatusFun(){
|
|
|
@@ -1232,6 +1254,7 @@ export default {
|
|
|
availableStartTime :null,
|
|
|
availableEndTime: null
|
|
|
};
|
|
|
+ this.workflowHasAddWx = false;
|
|
|
this.resetForm("form");
|
|
|
},
|
|
|
/** 搜索按钮操作 */
|
|
|
@@ -1265,6 +1288,9 @@ export default {
|
|
|
const id = row.id || this.ids
|
|
|
getRobotic(id).then(response => {
|
|
|
this.form = response.data;
|
|
|
+ if (this.form.companyAiWorkflowId) {
|
|
|
+ this.onWorkflowChange(this.form.companyAiWorkflowId);
|
|
|
+ }
|
|
|
this.open = true;
|
|
|
this.title = "修改机器人外呼任务";
|
|
|
});
|
|
|
@@ -1277,43 +1303,35 @@ export default {
|
|
|
this.form.weekDay1 = this.form.weekDay.join(",")
|
|
|
}
|
|
|
|
|
|
- // 验证加微方案
|
|
|
- if(!this.form.qwUser || this.form.qwUser.length == 0){
|
|
|
- this.msgError("请添加分配账号");
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- // 验证每个账号是否选择了企微和话术
|
|
|
- for(let i = 0; i < this.form.qwUser.length; i++) {
|
|
|
- const account = this.form.qwUser[i];
|
|
|
- if(!account.companyUserId || account.companyUserId.length == 0) {
|
|
|
- this.msgError(`第 ${i + 1} 个账号请选择企微`);
|
|
|
+ if (this.workflowHasAddWx) {
|
|
|
+ if(!this.form.qwUser || this.form.qwUser.length == 0){
|
|
|
+ this.msgError("请添加分配账号");
|
|
|
return;
|
|
|
}
|
|
|
- // if(!account.wxDialogId) {
|
|
|
- // this.msgError(`第 ${i + 1} 个账号请选择话术`);
|
|
|
- // return;
|
|
|
- // }
|
|
|
+
|
|
|
+ for(let i = 0; i < this.form.qwUser.length; i++) {
|
|
|
+ const account = this.form.qwUser[i];
|
|
|
+ if(!account.companyUserId || account.companyUserId.length == 0) {
|
|
|
+ this.msgError(`第 ${i + 1} 个账号请选择企微`);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
let list = [];
|
|
|
- this.form.qwUser.forEach(l => {
|
|
|
- list = list.concat(l.companyUserId.map(e => {return {intention: l.intention, companyUserId: e,wxDialogId: l.wxDialogId,smsTempId:l.smsTempId}}))
|
|
|
- })
|
|
|
+ if (this.workflowHasAddWx && this.form.qwUser) {
|
|
|
+ this.form.qwUser.forEach(l => {
|
|
|
+ list = list.concat(l.companyUserId.map(e => {return {intention: l.intention, companyUserId: e,wxDialogId: l.wxDialogId,smsTempId:l.smsTempId}}))
|
|
|
+ })
|
|
|
+ }
|
|
|
this.form.qwUserList = list;
|
|
|
console.log(this.form);
|
|
|
- // if(this.form.addType != 0 ){
|
|
|
- // let firstTask = this.taskFlowList[0];
|
|
|
- // if(firstTask.key != "cellPhone"){
|
|
|
- // this.msgError("【意向】加微方式下,任务流程第一步必须为外呼!");
|
|
|
- // return;
|
|
|
- // }
|
|
|
- // }
|
|
|
- if(!this.form.qwUserList || this.form.qwUserList.length == 0){
|
|
|
+ if(this.workflowHasAddWx && (!this.form.qwUserList || this.form.qwUserList.length == 0)){
|
|
|
this.msgError("请选者加微方案");
|
|
|
return;
|
|
|
}
|
|
|
this.form.taskFlow = this.taskFlowList.map(e => e.key).join();
|
|
|
+ this.submitFormLoading = true;
|
|
|
if (this.form.id != null) {
|
|
|
updateRobotic(this.form).then(response => {
|
|
|
if (response.code === 200) {
|
|
|
@@ -1321,6 +1339,9 @@ export default {
|
|
|
this.open = false;
|
|
|
this.getList();
|
|
|
}
|
|
|
+ this.submitFormLoading = false;
|
|
|
+ }).catch(res=>{
|
|
|
+ this.submitFormLoading = false;
|
|
|
});
|
|
|
} else {
|
|
|
addRobotic(this.form).then(response => {
|
|
|
@@ -1329,6 +1350,9 @@ export default {
|
|
|
this.open = false;
|
|
|
this.getList();
|
|
|
}
|
|
|
+ this.submitFormLoading = false;
|
|
|
+ }).catch(res=>{
|
|
|
+ this.submitFormLoading = false;
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
@@ -1352,12 +1376,12 @@ export default {
|
|
|
/** 导出按钮操作 */
|
|
|
handleExport() {
|
|
|
const queryParams = this.queryParams;
|
|
|
- this.$confirm('是否确认导出所有机器人外呼任务数据项?', "警告", {
|
|
|
+ this.$confirm('是否确认导出所有我的机器人外呼任务数据项?', "警告", {
|
|
|
confirmButtonText: "确定",
|
|
|
cancelButtonText: "取消",
|
|
|
type: "warning"
|
|
|
}).then(function () {
|
|
|
- return exportRobotic(queryParams);
|
|
|
+ return exportMyRobotic(queryParams);
|
|
|
}).then(response => {
|
|
|
this.download(response.msg);
|
|
|
}).catch(function () {
|
|
|
@@ -1444,6 +1468,32 @@ export default {
|
|
|
this.getList();
|
|
|
})
|
|
|
},
|
|
|
+ // 暂停任务
|
|
|
+ handlePauseTask(row) {
|
|
|
+ this.$confirm('暂停后,该任务下所有工作流将停止执行,正在进行的节点将完成当前操作后停止。确认暂停?', "警告", {
|
|
|
+ confirmButtonText: "确定",
|
|
|
+ cancelButtonText: "取消",
|
|
|
+ type: "warning"
|
|
|
+ }).then(() => {
|
|
|
+ return pauseRoboticActive({ taskId: row.id, activeType: 1 });
|
|
|
+ }).then(() => {
|
|
|
+ this.msgSuccess("暂停成功");
|
|
|
+ this.getList();
|
|
|
+ }).catch(() => {});
|
|
|
+ },
|
|
|
+ // 继续任务
|
|
|
+ handleResumeTask(row) {
|
|
|
+ this.$confirm('确认继续执行该任务?恢复后工作流将继续运行。', "警告", {
|
|
|
+ confirmButtonText: "确定",
|
|
|
+ cancelButtonText: "取消",
|
|
|
+ type: "warning"
|
|
|
+ }).then(() => {
|
|
|
+ return pauseRoboticActive({ taskId: row.id, activeType: 2 });
|
|
|
+ }).then(() => {
|
|
|
+ this.msgSuccess("继续成功");
|
|
|
+ this.getList();
|
|
|
+ }).catch(() => {});
|
|
|
+ },
|
|
|
stopRoboticFun(id){
|
|
|
stopRobotic(id).then(e => {
|
|
|
this.updateStatusFun();
|
|
|
@@ -1583,10 +1633,28 @@ export default {
|
|
|
this.form.name = null;
|
|
|
this.form.availableStartTime = null;
|
|
|
this.form.availableEndTime = null;
|
|
|
+ this.workflowHasAddWx = false;
|
|
|
this.$nextTick(() => {
|
|
|
this.$refs.form.clearValidate();
|
|
|
})
|
|
|
},
|
|
|
+ onWorkflowChange(workflowId) {
|
|
|
+ if (!workflowId) {
|
|
|
+ this.workflowHasAddWx = false;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ getWorkflowNodeTypeCodes(workflowId).then(res => {
|
|
|
+ const typeCodes = res.data || [];
|
|
|
+ this.workflowHasAddWx = typeCodes.includes('AI_ADD_WX_TASK_NEW') || typeCodes.includes('AI_QW_ADD_WX_TASK');
|
|
|
+ if (!this.workflowHasAddWx) {
|
|
|
+ this.form.addType = 0;
|
|
|
+ this.form.isWeCom = 1;
|
|
|
+ this.form.qwUser = [];
|
|
|
+ }
|
|
|
+ }).catch(() => {
|
|
|
+ this.workflowHasAddWx = false;
|
|
|
+ });
|
|
|
+ },
|
|
|
async getExecLogs() {
|
|
|
this.execLogs.loading = true
|
|
|
try {
|
|
|
@@ -1600,8 +1668,7 @@ export default {
|
|
|
})
|
|
|
this.execLogs.list = (res.rows || []).map(item => ({
|
|
|
...item,
|
|
|
- contentList: item.contentList || '',
|
|
|
- intention: item.intention || ''
|
|
|
+ contentList: item.contentList || ''
|
|
|
}))
|
|
|
this.execLogs.total = res.total || 0
|
|
|
// this.execLogs.stats = res.stats || {
|
|
|
@@ -1679,7 +1746,7 @@ export default {
|
|
|
this.manualCallDialog.workflowInstanceId = null;
|
|
|
this.manualCallDialog.customerId = null;
|
|
|
},
|
|
|
- handleShowContent(record,log) {
|
|
|
+ handleShowContent(record,log) {
|
|
|
this.contentDialog.customerName = record.customerName || '';
|
|
|
this.contentDialog.customerPhone = record.customerPhone || '';
|
|
|
this.contentDialog.content = log.nodeContentList || '';
|
|
|
@@ -1734,15 +1801,7 @@ export default {
|
|
|
} catch (e) {
|
|
|
return false
|
|
|
}
|
|
|
- },
|
|
|
- getIntentionLabel(val) {
|
|
|
- if (val === null || val === undefined || val === '') {
|
|
|
- return '-'
|
|
|
- }
|
|
|
-
|
|
|
- const item = (this.levelList || []).find(e => String(e.dictValue) === String(val))
|
|
|
- return item ? item.dictLabel : val
|
|
|
- },
|
|
|
+ }
|
|
|
}
|
|
|
};
|
|
|
</script>
|
|
|
@@ -1780,9 +1839,11 @@ export default {
|
|
|
position: absolute;
|
|
|
}
|
|
|
.sortable-ghost{
|
|
|
+ /* background: #FFF !important; */
|
|
|
background: rgb(217, 236, 255) !important;
|
|
|
}
|
|
|
|
|
|
+/* 执行日志样式 */
|
|
|
.exec-logs-container {
|
|
|
padding: 20px;
|
|
|
background: #f5f7fa;
|
|
|
@@ -1810,6 +1871,7 @@ export default {
|
|
|
font-size: 16px;
|
|
|
}
|
|
|
|
|
|
+/* 统计卡片 */
|
|
|
.stats-card {
|
|
|
margin-bottom: 20px;
|
|
|
border-radius: 8px;
|
|
|
@@ -1855,6 +1917,7 @@ export default {
|
|
|
color: #303133;
|
|
|
}
|
|
|
|
|
|
+/* 日志列表 */
|
|
|
.logs-list {
|
|
|
background: #fff;
|
|
|
border-radius: 8px;
|
|
|
@@ -1865,7 +1928,7 @@ export default {
|
|
|
.el-collapse-item__header{
|
|
|
height: auto !important;
|
|
|
}
|
|
|
-
|
|
|
+/* 记录头部 */
|
|
|
.record-header {
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
@@ -1960,6 +2023,7 @@ export default {
|
|
|
color: #303133;
|
|
|
}
|
|
|
|
|
|
+/* 节点日志 */
|
|
|
.node-logs {
|
|
|
padding: 20px;
|
|
|
background: #fafafa;
|
|
|
@@ -2032,6 +2096,7 @@ export default {
|
|
|
font-size: 14px;
|
|
|
}
|
|
|
|
|
|
+/* 任务表单样式 */
|
|
|
.task-form-drawer ::v-deep .el-drawer__body {
|
|
|
padding: 0;
|
|
|
}
|
|
|
@@ -2123,7 +2188,6 @@ export default {
|
|
|
.account-item ::v-deep .el-select {
|
|
|
width: 100%;
|
|
|
}
|
|
|
-
|
|
|
.chat-container {
|
|
|
max-height: 600px;
|
|
|
overflow-y: auto;
|
|
|
@@ -2195,6 +2259,7 @@ export default {
|
|
|
color: #606266;
|
|
|
}
|
|
|
|
|
|
+/* AI标签样式优化 */
|
|
|
.ai-tags-container {
|
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
|
@@ -2303,5 +2368,4 @@ export default {
|
|
|
font-size: 13px;
|
|
|
font-style: italic;
|
|
|
}
|
|
|
-
|
|
|
</style>
|