Commit 53686870 authored by puyongsong's avatar puyongsong

外呼策略

parent 2ea72dd3
import request from '@/utils/request' import request from '@/utils/request'
// codes // 策略新建
export function fetchCodesList(query) { export function addStrategySet(data) {
return request({ return request({
url: '/api/codes', url: '/api/strategySet',
method: 'post',
data
})
}
// 策略列表获取
export function getStrategySet(data) {
return request({
url: '/api/strategySet',
method: 'get', method: 'get',
params: query params: data
}) })
} }
export function addCodes(data) { // 话术流程项目列表
export function getProjectsList(data) {
return request({ return request({
url: '/api/codes', url: '/api/strategy/getProjectsList',
method: 'post', method: 'post',
data data
}) })
} }
export function editCodes(data) { // 主叫号码列表
export function getCallNumberList(data) {
return request({ return request({
url: '/api/codes/' + data.id, url: '/api/strategy/getCallNumberList',
method: 'patch', method: 'post',
data
})
}
// 子账号列表
export function getUsersList(data) {
return request({
url: '/api/strategy/getUsersList',
method: 'post',
data
})
}
// 导出模板
export function downloadModel(query) {
window.open(process.env.VUE_APP_BASE_API + '/api/strategy/downloadModel?user_sn=' + query.user_sn)
}
// 导入数据excel文件
export function importExcelData(data) {
return request({
url: '/api/strategy/importExcelData',
method: 'post',
data
})
}
// 任务数据列表
export function getStrategyTask(query) {
return request({
url: '/api/strategyTask',
method: 'get',
params: query
})
}
// 任务数据编辑
export function editStrategyTask(data) {
return request({
url: `/api/strategyTask/${data.id}`,
method: 'PUT',
data data
}) })
} }
export function deleteCodes(id) { // 策略删除
export function deleteStrategySet(data) {
return request({ return request({
url: '/api/codes/' + id, url: '/api/strategySet/' + data.strategy_sn + '?user_sn=' + data.user_sn,
method: 'delete' method: 'delete'
}) })
} }
......
...@@ -30,6 +30,7 @@ export default { ...@@ -30,6 +30,7 @@ export default {
width: 100%; width: 100%;
position: relative; position: relative;
overflow: hidden; overflow: hidden;
background: #fff;
} }
.fixed-header + .app-main { .fixed-header + .app-main {
...@@ -41,13 +42,13 @@ export default { ...@@ -41,13 +42,13 @@ export default {
/* 84 = navbar + tags-view = 50 + 34 */ /* 84 = navbar + tags-view = 50 + 34 */
// 84 + pagination // 84 + pagination
// min-height: calc(100vh - 84px); // min-height: calc(100vh - 84px);
height: calc(100vh - 84px); height: calc(100vh - 34px);
} }
.fixed-header + .app-main { .fixed-header + .app-main {
// padding-top: 84px; // padding-top: 84px;
padding-top: 0; padding-top: 0;
margin-top: 84px; margin-top: 94px;
} }
} }
</style> </style>
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
@toggleClick="toggleSideBar" @toggleClick="toggleSideBar"
/> />
<breadcrumb id="breadcrumb-container" class="breadcrumb-container" /> <!-- <breadcrumb id="breadcrumb-container" class="breadcrumb-container" /> -->
<div class="right-menu"> <div class="right-menu">
<template v-if="device!=='mobile'"> <template v-if="device!=='mobile'">
...@@ -75,7 +75,7 @@ export default { ...@@ -75,7 +75,7 @@ export default {
...mapGetters(['sidebar', 'avatar', 'device']) ...mapGetters(['sidebar', 'avatar', 'device'])
}, },
created() { created() {
let un = sessionStorage.getItem('user_name') let un = localStorage.getItem('user_name')
this.user_name = un ? this.$publicTools.decrypt(un) : '' this.user_name = un ? this.$publicTools.decrypt(un) : ''
}, },
methods: { methods: {
......
...@@ -2,11 +2,13 @@ ...@@ -2,11 +2,13 @@
<div class="sidebar-logo-container" :class="{'collapse':collapse}"> <div class="sidebar-logo-container" :class="{'collapse':collapse}">
<transition name="sidebarLogoFade"> <transition name="sidebarLogoFade">
<router-link v-if="collapse" key="collapse" class="sidebar-logo-link" to="/"> <router-link v-if="collapse" key="collapse" class="sidebar-logo-link" to="/">
<img v-if="logo" :src="logo" class="sidebar-logo" /> <!-- <img v-if="logo" :src="logo" class="sidebar-logo" />
<h1 v-else class="sidebar-title">{{ title }}</h1> <h1 v-else class="sidebar-title">{{ title }}</h1>-->
<h1 class="sidebar-title">{{ title }}</h1>
</router-link> </router-link>
<router-link v-else key="expand" class="sidebar-logo-link" to="/"> <router-link v-else key="expand" class="sidebar-logo-link" to="/">
<img v-if="logo" :src="logo" class="sidebar-logo" /> <!-- <img v-if="logo" :src="logo" class="sidebar-logo" />
<h1 class="sidebar-title">{{ title }}</h1> -->
<h1 class="sidebar-title">{{ title }}</h1> <h1 class="sidebar-title">{{ title }}</h1>
</router-link> </router-link>
</transition> </transition>
......
...@@ -13,7 +13,11 @@ ...@@ -13,7 +13,11 @@
@contextmenu.prevent.native="openMenu(tag,$event)" @contextmenu.prevent.native="openMenu(tag,$event)"
> >
{{ tag.title }} {{ tag.title }}
<span v-if="!isAffix(tag)" class="el-icon-close" @click.prevent.stop="closeSelectedTag(tag)" /> <span
v-if="!isAffix(tag)"
class="el-icon-circle-close"
@click.prevent.stop="closeSelectedTag(tag)"
/>
</router-link> </router-link>
</scroll-pane> </scroll-pane>
<ul v-show="visible" :style="{left:left+'px',top:top+'px'}" class="contextmenu"> <ul v-show="visible" :style="{left:left+'px',top:top+'px'}" class="contextmenu">
...@@ -94,7 +98,7 @@ export default { ...@@ -94,7 +98,7 @@ export default {
return tags return tags
}, },
initTags() { initTags() {
const affixTags = this.affixTags = this.filterAffixTags(this.routes) const affixTags = (this.affixTags = this.filterAffixTags(this.routes))
for (const tag of affixTags) { for (const tag of affixTags) {
// Must have tag name // Must have tag name
if (tag.name) { if (tag.name) {
...@@ -135,17 +139,21 @@ export default { ...@@ -135,17 +139,21 @@ export default {
}) })
}, },
closeSelectedTag(view) { closeSelectedTag(view) {
this.$store.dispatch('tagsView/delView', view).then(({ visitedViews }) => { this.$store
if (this.isActive(view)) { .dispatch('tagsView/delView', view)
this.toLastView(visitedViews, view) .then(({ visitedViews }) => {
} if (this.isActive(view)) {
}) this.toLastView(visitedViews, view)
}
})
}, },
closeOthersTags() { closeOthersTags() {
this.$router.push(this.selectedTag) this.$router.push(this.selectedTag)
this.$store.dispatch('tagsView/delOthersViews', this.selectedTag).then(() => { this.$store
this.moveToCurrentTag() .dispatch('tagsView/delOthersViews', this.selectedTag)
}) .then(() => {
this.moveToCurrentTag()
})
}, },
closeAllTags(view) { closeAllTags(view) {
this.$store.dispatch('tagsView/delAllViews').then(({ visitedViews }) => { this.$store.dispatch('tagsView/delAllViews').then(({ visitedViews }) => {
...@@ -200,7 +208,7 @@ export default { ...@@ -200,7 +208,7 @@ export default {
width: 100%; width: 100%;
background: #fff; background: #fff;
border-bottom: 1px solid #d8dce5; border-bottom: 1px solid #d8dce5;
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, .12), 0 0 3px 0 rgba(0, 0, 0, .04); box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.12), 0 0 3px 0 rgba(0, 0, 0, 0.04);
.tags-view-wrapper { .tags-view-wrapper {
.tags-view-item { .tags-view-item {
display: inline-block; display: inline-block;
...@@ -208,12 +216,12 @@ export default { ...@@ -208,12 +216,12 @@ export default {
cursor: pointer; cursor: pointer;
height: 26px; height: 26px;
line-height: 26px; line-height: 26px;
border: 1px solid #d8dce5; // border: 1px solid #d8dce5;
border-right: 1px solid rgba(238, 238, 238, 1);
color: #495060; color: #495060;
background: #fff; background: #fff;
padding: 0 8px; padding: 0 8px;
font-size: 12px; font-size: 12px;
margin-left: 5px;
margin-top: 4px; margin-top: 4px;
&:first-of-type { &:first-of-type {
margin-left: 15px; margin-left: 15px;
...@@ -222,19 +230,23 @@ export default { ...@@ -222,19 +230,23 @@ export default {
margin-right: 15px; margin-right: 15px;
} }
&.active { &.active {
background-color: #42b983; // background-color: #42b983;
color: #fff; color: #3791ff;
border-color: #42b983; // border-color: #42b983;
&::before { border-bottom: 1px solid rgba(54, 148, 255, 1);
content: ''; // &::before {
background: #fff; // content: '';
display: inline-block; // background: #fff;
width: 8px; // display: inline-block;
height: 8px; // width: 8px;
border-radius: 50%; // height: 8px;
position: relative; // border-radius: 50%;
margin-right: 2px; // position: relative;
} // margin-right: 2px;
// }
}
.el-icon-circle-close {
padding: 0 5px;
} }
} }
} }
...@@ -249,7 +261,7 @@ export default { ...@@ -249,7 +261,7 @@ export default {
font-size: 12px; font-size: 12px;
font-weight: 400; font-weight: 400;
color: #333; color: #333;
box-shadow: 2px 2px 3px 0 rgba(0, 0, 0, .3); box-shadow: 2px 2px 3px 0 rgba(0, 0, 0, 0.3);
li { li {
margin: 0; margin: 0;
padding: 7px 16px; padding: 7px 16px;
...@@ -272,10 +284,10 @@ export default { ...@@ -272,10 +284,10 @@ export default {
vertical-align: 2px; vertical-align: 2px;
border-radius: 50%; border-radius: 50%;
text-align: center; text-align: center;
transition: all .3s cubic-bezier(.645, .045, .355, 1); transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
transform-origin: 100% 50%; transform-origin: 100% 50%;
&:before { &:before {
transform: scale(.6); transform: scale(0.6);
display: inline-block; display: inline-block;
vertical-align: -3px; vertical-align: -3px;
} }
......
...@@ -66,9 +66,9 @@ const actions = { ...@@ -66,9 +66,9 @@ const actions = {
username: username.trim(), username: username.trim(),
password: password password: password
}).then(data => { }).then(data => {
if (Object.prototype.toString.call(data.info) === '[object Object]' && Object.prototype.toString.call(data.info.data) === '[object Object]') { if (Object.prototype.toString.call(data.info) === '[object Object]') {
commit('SET_TOKEN', data.info.data.api_key) commit('SET_TOKEN', data.info.api_key)
setToken(data.info.data.api_key) setToken(data.info.api_key)
} else { } else {
commit('SET_TOKEN', '') commit('SET_TOKEN', '')
setToken('') setToken('')
......
...@@ -221,7 +221,7 @@ aside { ...@@ -221,7 +221,7 @@ aside {
} }
.el-drawer__body { .el-drawer__body {
height: calc(100% - 40px); height: calc(100% - 100px);
overflow: auto; overflow: auto;
position: absolute; position: absolute;
top: 40px; top: 40px;
...@@ -246,3 +246,42 @@ aside { ...@@ -246,3 +246,42 @@ aside {
} }
// 抽屉公共样式end // 抽屉公共样式end
.el-table thead {
color: #161616;
tr {
th {
background: #F5F7FA;
}
}
}
.el-drawer__header {
color: #161616;
}
.el-dialog {
margin-top: 5% !important;
max-height: 85%;
overflow-y: scroll;
}
.el-dialog__header {
border-bottom: 1px solid rgba(228, 233, 239, 1);
}
.el-dialog__body {
padding: 10px 20px 20px;
}
.el-dialog__title {
font-size: 16px;
color: #161616;
font-weight: 800;
}
.el-form-item__label {
font-weight: normal;
color: #6D6F72;
padding: 0 !important;
}
...@@ -49,7 +49,7 @@ service.interceptors.response.use( ...@@ -49,7 +49,7 @@ service.interceptors.response.use(
duration: 5000 duration: 5000
}) })
// 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了; // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了;
if (res.status_code === 50008 || res.status_code === 50012 || res.status_code === 50014) { if (res.status_code === 50008 || res.status_code === 50012 || res.status_code === 50014 || (res.status_code === 401 && res.info === '登录失效')) {
MessageBox.confirm('你已被登出,可以取消继续留在该页面,或者重新登录', '确定登出', { MessageBox.confirm('你已被登出,可以取消继续留在该页面,或者重新登录', '确定登出', {
confirmButtonText: '重新登录', confirmButtonText: '重新登录',
cancelButtonText: '取消', cancelButtonText: '取消',
......
This diff is collapsed.
<template> <template>
<div> <div>
<div class="drawer_body_box"> <div>
<el-form <el-form ref="importForm" :model="temp" label-position="top" label-width="90px">
ref="importForm" <el-form-item label="文件模板(请按照模板格式填写数据)">
:rules="rules" <el-button
:model="temp" size="small"
label-position="left" icon="el-icon-download"
label-width="90px" class="down-btn"
> @click="downloadTemplate"
<el-form-item label="文件模板" prop="name"> >点击下载模板</el-button>
<el-button size="small" @click="downloadTemplate">下载模板</el-button>
<span>请按照模板格式填写数据</span>
</el-form-item> </el-form-item>
<el-form-item label="导入文件" prop="files"> <el-form-item label="导入文件(文件大小不可超过8MB)" class="import-box">
<!-- “文件大小不可超过8MB”、“请上传格式为以.xlsx或.xls结尾的excel文件” --> <!-- “文件大小不可超过8MB”、“请上传格式为以.xlsx或.xls结尾的excel文件” -->
<el-upload <el-upload
action="#" action="#"
...@@ -23,10 +21,10 @@ ...@@ -23,10 +21,10 @@
:on-remove="handleRemove" :on-remove="handleRemove"
:file-list="fileList" :file-list="fileList"
:auto-upload="false" :auto-upload="false"
accept="image/jpeg, image/gif, image/png" accept=".xls, .xlsx"
> >
<i class="el-icon-upload" slot="trigger"></i> <!-- <i class="el-icon-upload" slot="trigger"></i> -->
<!-- <el-button slot="trigger" size="small" type="primary">选取文件</el-button> --> <el-button slot="trigger" icon="el-icon-upload" class="upload-btn" size="small">点击导入文件</el-button>
<el-button <el-button
v-show="0" v-show="0"
style="margin-left: 10px;" style="margin-left: 10px;"
...@@ -38,51 +36,54 @@ ...@@ -38,51 +36,54 @@
</el-form-item> </el-form-item>
</el-form> </el-form>
</div> </div>
<div class="drawer__footer text-rt"> <div slot="footer" class="dialog-footer text-center">
<el-button type="primary" @click="saveData(1)">确定</el-button>
<el-button @click="saveData(0)">取消</el-button> <el-button @click="saveData(0)">取消</el-button>
<el-button type="primary" @click="saveData(1)">确定</el-button>
</div> </div>
<el-dialog <el-dialog
title="导入数据结果" title="导入数据结果"
:visible.sync="dialogResultVisible" :visible.sync="dialogResultVisible"
:append-to-body="true" :append-to-body="true"
:destroy-on-close="true"
:close-on-click-modal="false" :close-on-click-modal="false"
width="30%" width="30%"
:before-close="handleResultClose"
> >
<div class="result-box"> <div class="result-box">
<div> <div>
<i <i
v-if="num_f>0" v-if="failTotal>0"
class="el-icon-warning" class="el-icon-warning"
:class="[num_s===0&&num_f>0?'fail-all-bgc':'fail-bgc']" :class="[successTotal===0&&failTotal>0?'fail-all-bgc':'fail-bgc']"
></i> ></i>
<i v-else class="el-icon-success"></i> <i v-else class="el-icon-success"></i>
</div> </div>
<div>成功导入{{num_s}}个号码,{{num_f}}个号码导入失败</div> <div>成功导入{{successTotal}}个号码,{{failTotal}}个号码导入失败</div>
<div v-if="num_f>0"> <div v-if="failTotal>0">
<span>失败数据文件:</span> <span>失败数据文件:</span>
<a class="down-txt" @click="downloadFail">点击下载</a> <a class="down-txt" @click="downloadFail">点击下载</a>
</div> </div>
</div> </div>
<div slot="footer" class="dialog-footer text-center">
<el-button type="primary" @click="handleResultClose">确定</el-button>
</div>
</el-dialog> </el-dialog>
</div> </div>
</template> </template>
<script> <script>
// import { fetchCodesList } from '@/api/article' import { importExcelData, downloadModel } from '@/api/article'
export default { export default {
name: 'ImprtData', name: 'ImprtData',
props: ['temp'],
data() { data() {
return { return {
num_s: 10, failDataFile: '',
num_f: 11, successTotal: 0,
failTotal: 0,
dialogResultVisible: false, dialogResultVisible: false,
temp: {},
fileList: [], fileList: [],
dialogFormVisible: false, dialogFormVisible: false
rules: {}
} }
}, },
created() {}, created() {},
...@@ -101,12 +102,29 @@ export default { ...@@ -101,12 +102,29 @@ export default {
} }
}, },
downloadFail() { downloadFail() {
// failDataFile
console.log(this) console.log(this)
}, },
handleResultClose() { handleResultClose(va) {
this.dialogResultVisible = false this.dialogResultVisible = false
debugger
if (this.temp.isAddGo) {
if (va) {
this.$emit('addSave', this.fileList[0].raw)
} else {
this.$emit('addSave')
}
} else {
if (va) {
this.$emit('indexSave', va)
}
}
},
downloadTemplate() {
downloadModel({
user_sn: this.$publicTools.decrypt(localStorage.getItem('user_sn'))
})
}, },
downloadTemplate() {},
addCallback(status) {}, addCallback(status) {},
handleRemove(file, fileList) { handleRemove(file, fileList) {
console.log(file, fileList) console.log(file, fileList)
...@@ -121,31 +139,39 @@ export default { ...@@ -121,31 +139,39 @@ export default {
this.validateFiles() this.validateFiles()
}, },
submitUpload() { submitUpload() {
var form = new FormData() if (this.temp.isAddGo) {
form.append('photo', this.fileList[0].raw) this.$emit('addSave', this.fileList[0].raw)
const loading = this.$loading({ } else {
lock: true, var form = new FormData()
text: 'Loading', form.append(
spinner: 'el-icon-loading', 'user_sn',
background: 'rgba(0, 0, 0, 0.9)' this.$publicTools.decrypt(localStorage.getItem('user_sn'))
}) )
this.$store form.append('strategy_sn', this.temp.strategy_sn)
.dispatch('user/uploadAvatar', form) form.append('upload', this.fileList[0].raw)
.then(res => { const loading = this.$loading({
console.log(res) lock: true,
loading.close() text: 'Loading',
this.$emit('save', 1) spinner: 'el-icon-loading',
this.dialogResultVisible = true background: 'rgba(0, 0, 0, 0.9)'
})
.catch(err => {
loading.close()
this.$message.warning(err.status)
}) })
importExcelData(form)
.then(res => {
loading.close()
this.dialogResultVisible = true
this.failDataFile = res.info.failDataFile || ''
this.failTotal = res.info.failTotal || 0
this.successTotal = res.info.successTotal || 0
})
.catch(err => {
loading.close()
this.$message.warning(err)
})
}
}, },
handleDownload() {}, handleDownload() {},
saveData(status) { saveData(status) {
// console.log(this.fileList) // 0 cancel/close 1 addSave dialogStatus/create/update
// 0 cancel/close 1 save dialogStatus/create/update
if (status) { if (status) {
this.$refs['importForm'].validate(valid => { this.$refs['importForm'].validate(valid => {
if (!this.fileList.length) { if (!this.fileList.length) {
...@@ -157,7 +183,8 @@ export default { ...@@ -157,7 +183,8 @@ export default {
} }
}) })
} else { } else {
this.$emit('save') this.$emit('addSave', 0)
this.$emit('indexSave', 0)
} }
} }
} }
...@@ -189,4 +216,18 @@ export default { ...@@ -189,4 +216,18 @@ export default {
color: #f59a23; color: #f59a23;
} }
} }
.down-btn,
.upload-btn {
color: #3691ff;
}
label {
font-weight: normal;
}
.import-box::before {
content: '*';
color: #ff4949;
margin-right: 4px;
display: inline-block;
}
</style> </style>
<template> <template>
<div class="app-container"> <div class="app-container">
<div class="filter-container text-rt"> <div class="filter-container text-rt">
<!-- <el-input
clearable
v-model="listQuery.name"
placeholder="源码名称"
style="width: 200px;"
class="filter-item"
/>
<el-button <el-button
v-waves style="margin-left:10px;padding:10px;"
class="filter-item" icon="el-icon-circle-plus-outline"
type="primary"
icon="el-icon-search"
@click="handleFilter"
>查询</el-button>-->
<el-button
class="filter-item"
style="margin-left: 10px;"
type="primary"
icon="el-icon-plus"
@click="handleCreate" @click="handleCreate"
>新建</el-button> ></el-button>
</div> </div>
<div class="body-container"> <div class="body-container">
<el-table <el-table
...@@ -36,37 +20,37 @@ ...@@ -36,37 +20,37 @@
> >
<el-table-column label="策略名称" align="center"> <el-table-column label="策略名称" align="center">
<template slot-scope="{row}"> <template slot-scope="{row}">
<span>{{ row.name }}</span> <span>{{ row.strategy_name }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="话术流程" align="center"> <el-table-column label="话术流程" align="center">
<template slot-scope="{row}"> <template slot-scope="{row}">
<span>{{ row.typeCN }}</span> <span>{{ row.project_name }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="导入数据量" align="center"> <el-table-column label="导入数据量" align="center">
<template slot-scope="{row}"> <template slot-scope="{row}">
<span>{{ row.lang }}</span> <span>{{ row.total }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="外呼日期" align="center"> <el-table-column label="外呼日期" align="center">
<template slot-scope="{row}"> <template slot-scope="{row}">
<span>{{ $moment(row.created_at.date).format('YYYY-MM-DD HH:mm:ss') }}</span> <span>{{ row.day_type_name }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="外呼频率" align="center"> <el-table-column label="外呼频率" align="center">
<template slot-scope="{row}"> <template slot-scope="{row}">
<span>{{ row.source }}</span> <span>{{ row.frequency_type_name }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="状态" align="center"> <el-table-column label="状态" align="center">
<template slot-scope="{row}"> <template slot-scope="{row}">
<span>{{ row.url }}</span> <span>{{ row.disabled_name }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="创建时间" align="center"> <el-table-column label="创建时间" align="center">
<template slot-scope="{row}"> <template slot-scope="{row}">
<span>{{ $moment(row.created_at.date).format('YYYY-MM-DD HH:mm:ss') }}</span> <span>{{ row.created_at }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column <el-table-column
...@@ -76,30 +60,28 @@ ...@@ -76,30 +60,28 @@
width="180" width="180"
class-name="small-padding fixed-width" class-name="small-padding fixed-width"
> >
<template slot-scope="{row,$index}"> <template slot-scope="{row}">
<el-button type="text" size="small" @click="importData(row)">导入数据</el-button> <el-tooltip content="导入数据">
<el-button type="text" size="small" @click="goTaskData(row)">任务数据</el-button> <el-button size="small" plain icon="el-icon-edit-outline" @click="importData(row)"></el-button>
<el-button type="text" size="small" @click="handleDelete(row,$index)">删除</el-button> </el-tooltip>
<el-tooltip content="任务数据">
<el-button size="small" plain icon="el-icon-document" @click="goTaskData(row)"></el-button>
</el-tooltip>
<el-tooltip content="删除">
<el-button size="small" plain icon="el-icon-delete" @click="handleDelete(row)"></el-button>
</el-tooltip>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
</div> </div>
<pagination <el-dialog
v-show="total>0"
:total="total"
:page.sync="listQuery.page"
:limit.sync="listQuery.pageSize"
@pagination="getList"
/>
<el-drawer
:title="textMap[dialogStatus]+'外呼策略'" :title="textMap[dialogStatus]+'外呼策略'"
:visible.sync="dialogFormVisible" :visible.sync="dialogFormVisible"
:append-to-body="true" :append-to-body="true"
width="30%"
:destroy-on-close="true" :destroy-on-close="true"
:wrapperClosable="false" :close-on-click-modal="false"
@close="addCallback(0)"
direction="rtl"
> >
<AddOrEdit <AddOrEdit
v-if="dialogFormVisible" v-if="dialogFormVisible"
...@@ -107,65 +89,60 @@ ...@@ -107,65 +89,60 @@
:dialogStatus="dialogStatus" :dialogStatus="dialogStatus"
@save="addCallback" @save="addCallback"
></AddOrEdit> ></AddOrEdit>
</el-drawer> </el-dialog>
<el-drawer <el-dialog
title="导入数据" title="导入数据"
width="30%"
:visible.sync="importVisible" :visible.sync="importVisible"
:append-to-body="true" :append-to-body="true"
:destroy-on-close="true" :destroy-on-close="true"
:wrapperClosable="false" :close-on-click-modal="false"
@close="importCallback(0)"
direction="rtl"
> >
<ImprtData <ImprtData
v-if="importVisible" v-if="importVisible"
:temp="temp" :temp="temp"
:dialogStatus="dialogStatus" :dialogStatus="dialogStatus"
@save="importCallback" @indexSave="importCallbackIndex"
></ImprtData> ></ImprtData>
</el-drawer> </el-dialog>
</div> </div>
</template> </template>
<script> <script>
import { fetchCodesList, deleteCodes } from '@/api/article' import { getStrategySet, deleteStrategySet } from '@/api/article'
import waves from '@/directive/waves' import waves from '@/directive/waves'
import Pagination from '@/components/Pagination'
import AddOrEdit from './add' import AddOrEdit from './add'
import ImprtData from './import-data' import ImprtData from './import-data'
export default { export default {
name: 'Dashboard', name: 'Dashboard',
components: { Pagination, AddOrEdit, ImprtData }, components: { AddOrEdit, ImprtData },
directives: { waves }, directives: { waves },
filters: {}, filters: {},
data() { data() {
return { return {
textMap: { textMap: {
update: '编辑', update: '编辑',
create: '' create: ''
}, },
fileList: [], fileList: [],
multipleSelection: [], multipleSelection: [],
tableKey: 0, tableKey: 0,
list: null, list: [],
total: 0,
listLoading: true, listLoading: true,
listQuery: {
page: 1,
pageSize: 10
},
temp: { temp: {
name: '',
files: '',
account: '', account: '',
phone: '', strategy_name: '',
dates: '', call_number: '',
rate: '', day_type: '0',
frequency_type: '2',
call_time_set: '',
setdate1: '', setdate1: '',
setdate2: '', setdate2: '',
process: '', project_sn: '',
status: '' disabled: '',
upload: ''
}, },
dialogFormVisible: false, dialogFormVisible: false,
importVisible: false, importVisible: false,
...@@ -176,49 +153,44 @@ export default { ...@@ -176,49 +153,44 @@ export default {
this.getList() this.getList()
}, },
methods: { methods: {
addCallback(status) { addCallback() {
this.dialogFormVisible = false this.dialogFormVisible = false
if (status) { this.getList()
this.getList()
}
}, },
importCallback(status) { importCallbackIndex() {
debugger
this.importVisible = false this.importVisible = false
if (status) { this.getList()
this.getList()
}
}, },
getList() { getList() {
this.listLoading = true this.listLoading = true
fetchCodesList(this.listQuery) getStrategySet({
user_sn: this.$publicTools.decrypt(localStorage.getItem('user_sn'))
})
.then(response => { .then(response => {
this.listLoading = false this.listLoading = false
this.list = Array.from(response.data) this.list = Array.from(response.info)
this.total =
Object.prototype.toString.call(response.meta) === '[object Object]'
? response.meta.total
: this.list.length
}) })
.catch(() => { .catch(() => {
this.listLoading = false this.listLoading = false
}) })
}, },
handleFilter() { handleFilter() {
this.listQuery.page = 1
this.getList() this.getList()
}, },
resetTemp() { resetTemp() {
this.temp = { this.temp = {
name: '',
files: '',
account: '', account: '',
phone: '', strategy_name: '',
dates: '', call_number: '',
rate: '', day_type: '0',
frequency_type: '2',
call_time_set: '',
setdate1: '', setdate1: '',
setdate2: '', setdate2: '',
process: '', project_sn: '',
status: '' disabled: '',
upload: ''
} }
}, },
handleCreate() { handleCreate() {
...@@ -244,7 +216,7 @@ export default { ...@@ -244,7 +216,7 @@ export default {
this.temp = this.$publicTools.deepClone(row) // copy obj this.temp = this.$publicTools.deepClone(row) // copy obj
this.importVisible = true this.importVisible = true
}, },
handleDelete(row, index) { handleDelete(row) {
this.$confirm('确定要删除此条数据吗?', '删除提示', { this.$confirm('确定要删除此条数据吗?', '删除提示', {
confirmButtonText: '确定', confirmButtonText: '确定',
cancelButtonText: '取消', cancelButtonText: '取消',
...@@ -258,7 +230,10 @@ export default { ...@@ -258,7 +230,10 @@ export default {
spinner: 'el-icon-loading', spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)' background: 'rgba(0, 0, 0, 0.7)'
}) })
deleteCodes(row.id) deleteStrategySet({
user_sn: this.$publicTools.decrypt(localStorage.getItem('user_sn')),
strategy_sn: row.strategy_sn || ''
})
.then(res => { .then(res => {
loading.close() loading.close()
this.getList() this.getList()
...@@ -280,3 +255,11 @@ export default { ...@@ -280,3 +255,11 @@ export default {
} }
} }
</script> </script>
<style lang="scss" scoped>
table {
button {
border: none;
background: transparent;
}
}
</style>
...@@ -448,17 +448,19 @@ export default { ...@@ -448,17 +448,19 @@ export default {
.dispatch('user/login', { username, password }) .dispatch('user/login', { username, password })
.then(data => { .then(data => {
if ( if (
Object.prototype.toString.call(data.info) === Object.prototype.toString.call(data.info) === '[object Object]'
'[object Object]' &&
Object.prototype.toString.call(data.info.data) ===
'[object Object]'
) { ) {
sessionStorage.setItem( localStorage.setItem(
'user_name', 'user_name',
this.$publicTools.encrypt(data.info.data.user_name) this.$publicTools.encrypt(data.info.user_name)
)
localStorage.setItem(
'user_sn',
this.$publicTools.encrypt(data.info.user_sn)
) )
} else { } else {
sessionStorage.setItem('user_name', '') localStorage.setItem('user_name', '')
localStorage.setItem('user_sn', '')
} }
this.$router.push({ this.$router.push({
path: this.redirect || '/', path: this.redirect || '/',
......
<template> <template>
<div> <div>
<div class="drawer_body_box"> <div>
<el-form ref="dataForm" :rules="rules" :model="temp" label-position="left" label-width="80px"> <el-form ref="dataForm" :rules="rules" :model="temp" label-position="top" label-width="80px">
<el-form-item label="手机号码" prop="phone"> <el-form-item label="手机号码" prop="phone">
<el-input <el-input
type="number"
v-model="temp.phone" v-model="temp.phone"
:disabled="dialogStatus==='detail' || temp.phoneData" :disabled="dialogStatus==='detail' || temp.is_created===1"
clearable clearable
/> />
</el-form-item> </el-form-item>
<el-form-item label="客户姓名" prop="user_name"> <el-form-item label="客户姓名" prop="name">
<el-input <el-input
v-model="temp.user_name" v-model="temp.name"
maxlength="20" maxlength="20"
:disabled="dialogStatus==='detail' || temp.phoneData" :disabled="dialogStatus==='detail' || temp.is_created===1"
clearable clearable
/> />
</el-form-item> </el-form-item>
<el-form-item label="值班日期" prop="date1"> <el-form-item label="值班日期" prop="duty_date">
<el-input v-model="temp.date1" disabled clearable /> <el-input v-model="temp.duty_date" disabled clearable />
</el-form-item> </el-form-item>
<el-form-item label="外呼时间" prop="date2"> <el-form-item label="外呼日期" prop="call_date">
<el-input v-model="temp.date2" disabled clearable /> <el-input v-model="temp.call_date" disabled clearable />
</el-form-item> </el-form-item>
<el-form-item label="话术流程" prop="process"> <el-form-item label="话术流程" prop="project_name">
<el-input v-model="temp.process" disabled clearable /> <el-input v-model="temp.project_name" disabled clearable />
</el-form-item> </el-form-item>
<el-form-item label="呼叫设置" prop="sets"> <el-form-item label="外呼时间" prop="call_time">
<el-time-picker <el-time-picker
:disabled="dialogStatus==='detail' || temp.phoneData" :editable="false"
v-model="temp.sets" :disabled="dialogStatus==='detail' || temp.is_created===1"
:picker-options="{ v-model="temp.call_time"
selectableRange: '00:00:00 - 23:59:59' value-format="HH:mm:ss"
}" :picker-options="{selectableRange: '00:00:00 - 23:59:59'}"
placeholder="请选择呼叫时间点" placeholder="请选择呼叫时间点"
></el-time-picker> ></el-time-picker>
</el-form-item> </el-form-item>
</el-form> </el-form>
</div> </div>
<div class="drawer__footer text-rt"> <div slot="footer" class="dialog-footer text-rt">
<el-button type="primary" @click="saveData(1)">确定</el-button>
<el-button @click="saveData(0)">取消</el-button> <el-button @click="saveData(0)">取消</el-button>
<el-button type="primary" @click="saveData(1)">确定</el-button>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import { editCodes } from '@/api/article' import { editStrategyTask } from '@/api/article'
export default { export default {
name: 'AddOrEdit', name: 'AddOrEdit',
props: ['dialogStatus', 'temp'], props: ['dialogStatus', 'temp'],
data() { data() {
return { return {
sourceOptions: [
{ value: 'Git', key: 'Git' },
{ value: 'SVN', key: 'SVN' }
],
typeOptions: [ typeOptions: [
{ value: 1, key: 'Web端' }, { value: 1, key: 'Web端' },
{ value: 2, key: '后台代码' } { value: 2, key: '后台代码' }
...@@ -66,11 +63,10 @@ export default { ...@@ -66,11 +63,10 @@ export default {
{ {
required: true, required: true,
message: '手机号码必填且不能超过11位字符', message: '手机号码必填且不能超过11位字符',
trigger: 'blur', trigger: 'blur'
max: 11
} }
], ],
sets: [ call_time: [
{ {
required: true, required: true,
message: '呼叫设置时间必选', message: '呼叫设置时间必选',
...@@ -80,11 +76,7 @@ export default { ...@@ -80,11 +76,7 @@ export default {
} }
} }
}, },
created() { created() {},
if (this.dialogStatus === 'update') { // test
this.temp.phoneData = true
}
},
methods: { methods: {
saveData(status) { saveData(status) {
// 0 cancel/close 1 save dialogStatus/create/update // 0 cancel/close 1 save dialogStatus/create/update
...@@ -92,17 +84,26 @@ export default { ...@@ -92,17 +84,26 @@ export default {
if (status) { if (status) {
this.$refs['dataForm'].validate(valid => { this.$refs['dataForm'].validate(valid => {
if (valid) { if (valid) {
const tempData = this.$publicTools.deepClone(this.temp) const { name, phone, call_time } = this.temp
const tempData = {
id: this.temp.id,
user_sn: this.$publicTools.decrypt(
localStorage.getItem('user_sn')
),
name: name,
phone: phone,
call_time: call_time
}
const loading = this.$loading({ const loading = this.$loading({
lock: true, lock: true,
text: 'Loading', text: 'Loading',
spinner: 'el-icon-loading', spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)' background: 'rgba(0, 0, 0, 0.7)'
}) })
editCodes(tempData) editStrategyTask(tempData)
.then(res => { .then(res => {
loading.close() loading.close()
this.$emit('save', status) this.$emit('save')
this.$message({ this.$message({
message: message:
Object.prototype.toString.call(res) === Object.prototype.toString.call(res) ===
......
<template> <template>
<div class="app-container"> <div class="app-container">
<div class="filter-container"> <div class="filter-container">
<el-row class="txt-rt"> <el-row>
<div class="dis-ib"> <div class="dis-ib">
<el-input <el-input
clearable clearable
...@@ -13,13 +13,8 @@ ...@@ -13,13 +13,8 @@
</div> </div>
<div class="dis-ib"> <div class="dis-ib">
<el-select v-model="listQuery.status" placeholder="请选择处理状态" clearable> <el-select v-model="listQuery.is_created" placeholder="请选择处理状态" clearable>
<el-option <el-option v-for="item in createdData" :label="item.k" :key="item.v" :value="item.v"></el-option>
v-for="(item, key) in pushResultData"
:label="item"
:key="key"
:value="key"
>{{ item }}</el-option>
</el-select> </el-select>
</div> </div>
...@@ -27,10 +22,10 @@ ...@@ -27,10 +22,10 @@
v-model="dates" v-model="dates"
type="datetimerange" type="datetimerange"
range-separator="至" range-separator="至"
start-placeholder="推送开始日期" start-placeholder="选择外呼开始日期"
end-placeholder="推送结束日期" end-placeholder="选择外呼结束日期"
></el-date-picker> ></el-date-picker>
<el-button type="primary" icon="el-icon-search" @click="handleFilter"></el-button> <el-button type="primary" icon="el-icon-search" @click="handleFilter" style="padding:10px"></el-button>
</el-row> </el-row>
</div> </div>
...@@ -44,44 +39,44 @@ ...@@ -44,44 +39,44 @@
highlight-current-row highlight-current-row
style="width: 100%;" style="width: 100%;"
> >
<el-table-column label="客户姓名" prop="id" align="center"> <el-table-column label="客户姓名" align="center">
<template slot-scope="{row}"> <template slot-scope="{row}">
<span>{{ row.id }}</span> <span>{{ row.name }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="手机号码" align="center"> <el-table-column label="手机号码" align="center">
<template slot-scope="{row}"> <template slot-scope="{row}">
<span>{{ row.project_name }}</span> <span>{{ row.phone }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="值班日期" align="center"> <el-table-column label="值班日期" align="center">
<template slot-scope="{row}"> <template slot-scope="{row}">
<span>{{ row.version }}</span> <span>{{ row.duty_date }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="外呼日期" align="center"> <el-table-column label="外呼日期" align="center">
<template slot-scope="{row}"> <template slot-scope="{row}">
<span>{{ row.notes }}</span> <span>{{ row.call_date }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="呼叫时间" align="center"> <el-table-column label="呼叫时间" align="center">
<template slot-scope="{row}"> <template slot-scope="{row}">
<span>{{ row.code_statusCN }}</span> <span>{{ row.call_time }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="话术流程" align="center"> <el-table-column label="话术流程" align="center">
<template slot-scope="{row}"> <template slot-scope="{row}">
<span>{{ row.sql_statusCN }}</span> <span>{{ row.project_name }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="处理状态" align="center"> <el-table-column label="处理状态" align="center">
<template slot-scope="{row}"> <template slot-scope="{row}">
<span>{{ row.sql_upload_statusCN }}</span> <span>{{ row.is_created_name }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="导入时间" align="center"> <el-table-column label="导入时间" align="center">
<template slot-scope="{row}"> <template slot-scope="{row}">
<span>{{ $moment(row.created_at.date).format('YYYY-MM-DD HH:mm:ss') }}</span> <span>{{ row.import_date }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column <el-table-column
...@@ -92,8 +87,12 @@ ...@@ -92,8 +87,12 @@
class-name="small-padding fixed-width" class-name="small-padding fixed-width"
> >
<template slot-scope="{row}"> <template slot-scope="{row}">
<el-button type="text" size="small" @click="handleDetail(row)">查看</el-button> <el-tooltip content="查看">
<el-button type="text" size="small" @click="handleEdit(row)">编辑</el-button> <el-button size="small" plain icon="el-icon-tickets" @click="handleDetail(row)"></el-button>
</el-tooltip>
<el-tooltip content="编辑">
<el-button size="small" plain icon="el-icon-edit-outline" @click="handleEdit(row)"></el-button>
</el-tooltip>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
...@@ -107,14 +106,13 @@ ...@@ -107,14 +106,13 @@
@pagination="getList" @pagination="getList"
/> />
<el-drawer <el-dialog
:title="textMap[dialogStatus]" :title="textMap[dialogStatus]"
:append-to-body="true" :append-to-body="true"
width="30%"
:visible.sync="dialogFormVisible" :visible.sync="dialogFormVisible"
:destroy-on-close="true" :destroy-on-close="true"
:wrapperClosable="false" :close-on-click-modal="false"
@close="addCallback(0)"
direction="rtl"
> >
<AddOrEdit <AddOrEdit
v-if="dialogFormVisible" v-if="dialogFormVisible"
...@@ -122,12 +120,12 @@ ...@@ -122,12 +120,12 @@
:temp="temp" :temp="temp"
@save="addCallback" @save="addCallback"
></AddOrEdit> ></AddOrEdit>
</el-drawer> </el-dialog>
</div> </div>
</template> </template>
<script> <script>
import { fetchProjectsList } from '@/api/article' import { getStrategyTask } from '@/api/article'
import waves from '@/directive/waves' import waves from '@/directive/waves'
import Pagination from '@/components/Pagination' import Pagination from '@/components/Pagination'
import AddOrEdit from './add' import AddOrEdit from './add'
...@@ -144,17 +142,21 @@ export default { ...@@ -144,17 +142,21 @@ export default {
detail: '外呼详情', detail: '外呼详情',
update: '编辑详情' update: '编辑详情'
}, },
pushResultData: { 0: '部署中', 1: '部署失败', 2: '部署成功' }, createdData: [
{ v: 0, k: '未新建' },
{ v: 1, k: '已新建' }
],
list: [], list: [],
total: 0, total: 0,
listLoading: true, listLoading: true,
listQuery: { listQuery: {
user_sn: this.$publicTools.decrypt(localStorage.getItem('user_sn')),
page: 1, page: 1,
pageSize: 10, pageSize: 20,
phone: '', phone: '',
startDate: '', started_at: '',
endDate: '', stoped_at: '',
status: '' is_created: ''
}, },
temp: {}, temp: {},
dialogFormVisible: false, dialogFormVisible: false,
...@@ -166,33 +168,35 @@ export default { ...@@ -166,33 +168,35 @@ export default {
}, },
watch: { watch: {
dates: function(val) { dates: function(val) {
if (Array.isArray(val) && val.length === 2) { if (Array.isArray(val)) {
this.listQuery.startDate = this.$moment(val[0]).format( if (val.length > 0) {
'YYYY-MM-DD HH:mm:ss' this.listQuery.started_at = this.$moment(val[0]).format(
) 'YYYY-MM-DD HH:mm:ss'
this.listQuery.endDate = this.$moment(val[1]).format( )
'YYYY-MM-DD HH:mm:ss' }
) if (val.length > 1) {
this.listQuery.stoped_at = this.$moment(val[1]).format(
'YYYY-MM-DD HH:mm:ss'
)
}
} else { } else {
this.listQuery.startDate = '' this.listQuery.started_at = ''
this.listQuery.endDate = '' this.listQuery.stoped_at = ''
} }
} }
}, },
methods: { methods: {
addCallback(status) { addCallback() {
this.dialogFormVisible = false this.dialogFormVisible = false
if (status) { this.getList()
this.getList()
}
}, },
getList() { getList() {
// this.$route.query // this.$route.query
this.listLoading = true this.listLoading = true
fetchProjectsList(this.listQuery) getStrategyTask(this.listQuery)
.then(response => { .then(response => {
this.listLoading = false this.listLoading = false
this.list = Array.from(response.data) this.list = Array.from(response.info)
this.total = this.total =
Object.prototype.toString.call(response.meta) === '[object Object]' Object.prototype.toString.call(response.meta) === '[object Object]'
? response.meta.total ? response.meta.total
...@@ -227,9 +231,4 @@ export default { ...@@ -227,9 +231,4 @@ export default {
.txt-rt { .txt-rt {
text-align: right; text-align: right;
} }
.drawer_body_box {
.el-form-item {
margin-bottom: 0;
}
}
</style> </style>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment