提交 b7f32e79 作者: 毛细亚

更新代码

上级 6982fd8e
......@@ -45,26 +45,26 @@ export default {
path: '/roleInfo'
},
{
label: '订单信息',
path: '/orderList'
},
{
label: '快捷回复',
path: '/quickReply'
},
{
label: '礼包记录',
path: '/giftRecord'
label: '违规记录',
path: '/violationRecord'
},
{
label: '订单记录',
path: '/orderList'
label: '礼包记录',
path: '/giftRecord'
},
{
label: '违规记录',
path: '/violationRecord'
label: '任务记录',
path: '/taskRecord'
},
// {
// label: '申请记录',
// path: '/applyRecord'
// },
// {
// label: '快捷发送',
// path: '/quickSend'
......
......@@ -51,14 +51,19 @@ Vue.use(Element, {
size: Cookies.get('size') || 'small' // set element-ui default size
// locale: enLang, // 如果使用中文,无需设置,请删除123132
})
// 配置和原型方法设置应该在创建Vue实例之前
Vue.config.productionTip = false
// 配置 Vue DevTools
Vue.config.devtools = process.env.NODE_ENV === 'development'
Vue.prototype.$cookies = Cookies;
Vue.prototype.$lodash = _;
Vue.prototype.$moment = moment;
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
Vue.config.productionTip = false
Vue.prototype.$cookies = Cookies;
Vue.prototype.$lodash = _;
Vue.prototype.$moment = moment;
......@@ -9,6 +9,7 @@ import addressBook from '../views/addressBook.vue'
import orderList from '../views/orderList.vue'
import roleInfo from '../views/roleInfo.vue'
import violationRecord from '../views/ViolationRecord.vue'
import taskRecord from '../views/taskRecord.vue'
import Cookies from 'js-cookie'
import store from '@/store'
Vue.use(VueRouter)
......@@ -68,6 +69,11 @@ const routes = [
component: orderList
},
{
path: '/taskRecord',
name: 'taskRecord',
component: taskRecord
},
{
path: '/login',
name: 'login',
component: () => import('../views/login.vue')
......
......@@ -236,7 +236,7 @@
<script>
import { searchcondition, appealList, appealCancel, appealProcess } from '@/api/game'
import { mapState, mapMutations } from 'vuex'
import { removeDp, formatNumber } from '@/utils/index'
import { removeDp, formatNumber,debounce } from '@/utils/index'
import resubmitApproval from './layer/appeal.vue'
// 导入审批状态图标
import shenpi1 from '@/assets/icon/shenpi1.svg'
......@@ -245,13 +245,22 @@
import shenpi4 from '@/assets/icon/shenpi4.svg'
import shenpi5 from '@/assets/icon/shenpi5.svg'
import noContent from "@/components/noContent.vue";
import { debounce } from '@/utils'
import watchMember from '@/mixins/watchMember'
export default {
computed: {
...mapState('game', ['accountSelect']),
...mapState('user', ['userInfo'])
},
watch: {
accountSelect: {
handler:debounce(function(newVal, oldVal) {
if (newVal && newVal !== "" && newVal !== oldVal) {
this.filterChange()
}
},200),
immediate: false
}
},
components: {
resubmitApproval,
noContent
......
......@@ -271,7 +271,7 @@
<script>
import { searchcondition, reportIndex, reportCancel, reportProcess } from '@/api/game'
import { mapState, mapMutations } from 'vuex'
import { removeDp, formatNumber } from '@/utils/index'
import { removeDp, formatNumber,debounce } from '@/utils/index'
import resubmitReport from './layer/report.vue'
import approvalTask from './layer/approvalTask.vue'
// 导入审批状态图标
......@@ -282,9 +282,16 @@
import shenpi5 from '@/assets/icon/shenpi5.svg'
export default {
computed: {
...mapState('game', ['accountSelect', 'report_is_send']),
...mapState('game', ['accountSelect']),
...mapState('user', ['cser_id','cser_name'])
},
watch: {
accountSelect(newVal,oldVal){
if (newVal && newVal !== "" && newVal !== oldVal) {
this.filterChange()
}
}
},
components: {
resubmitReport,
approvalTask
......@@ -326,15 +333,6 @@
taskTypeList: []
}
},
watch: {
// 监听到变化
report_is_send(newVal, oldVal) {
console.log('变化了')
this.reportForm.register_type = 2
this.reportForm.approval_status = 1
this.filterChange()
}
},
mounted() {
// this.request_register_type()
this.requstApprovalList()
......
......@@ -7,7 +7,7 @@
<el-tab-pane label="举报信息" name="report">
<report v-if="roleActive === 'report'" />
</el-tab-pane>
<el-tab-pane label="违规记录" name="approval">
<el-tab-pane label="申诉记录" name="approval">
<approval v-if="roleActive === 'approval'" />
</el-tab-pane>
</el-tabs>
......
<template>
<div class="task-info-container columnFlex">
<!-- <div class="detailsTitle rowFlex spaceBetween columnCenter">
<p>任务记录</p>
</div> -->
<div class="account-task-container-content">
<div class="tabSelect rowFlex">
<div
v-for="(item, index) in orderTypeList"
:key="index"
class="rowFlex allCenter flex1"
>
<span
class="tabSelectItem"
:class="activeType == item.type ? 'tabSelectItemActive' : ''"
@click="handleClick(item)"
> {{ item.label }}</span>
</div>
</div>
<!-- 订单列表 -->
<div
v-infinite-scroll="requestTaskList"
v-loading="loading"
:infinite-scroll-disabled="!isloadMore"
class="orderDetailsScroll"
>
<div v-if="taskList.length > 0">
<div
v-for="(item, index) in taskList"
:key="index"
class="orderDetails"
>
<div class="orderDetailsList">
<el-collapse
v-model="collapseValue"
@change="handleChange(item,$event)"
>
<el-collapse-item :name="item.order_id">
<template slot="title">
<div class="orderDetailsTitle">
<div class="money rowFlex spaceBetween">
<p class="text">{{ item.role_name }} - {{ item.server_name }} - ¥{{ item.recharge_total }}</p>
<div class="btns">
<span style="color: #0988f2">{{ taskTypeList.find((items) => items.value == item.plan_type) && taskTypeList.find((items) => items.value == item.plan_type).label?taskTypeList.find((items) => items.value == item.plan_type).label:'' }}</span>
<span
v-if="item.status_name"
class="btn"
:class="[item.status_name == '待跟进' ? 'noSend' : '', item.status_name == '已跟进' ? 'sended' : '', item.status_name == '已完成' ? 'sended' : '', item.status_name == '跟进中' ? 'noSend' : '']"
>{{ item.status_name }}</span>
</div>
</div>
</div>
</template>
<div class="item rowFlex columnCenter spaceBetween">
<div class="rowFlex columnCenter">
<span class="label">跟进客服</span>
<p class="text">{{ item.tracer_name }}</p>
</div>
</div>
<div class="item rowFlex columnCenter spaceBetween">
<div class="rowFlex">
<span class="label">待维护日期</span>
<p class="text">{{ item.assignment_time }}</p>
</div>
</div>
<div class="editLayer">
<el-form
:model="webForm"
>
<!-- 新增异常原因筛选 当 plan_type==5 5:为大R异跟进异常时 新增异常原因筛选 -->
<el-form-item
v-if="taskInfo.plan_type && taskInfo.plan_type==5"
label="异常原因"
prop="abnormal_types"
label-width="100px"
>
<el-select
v-model="webForm.abnormal_types"
style="width: 90%"
placeholder="请选择"
multiple
collapse-tags
>
<el-option
v-for="item in errorTypeList"
:key="item.value"
:label="item.label"
:value="item.value"
>
</el-option>
</el-select>
</el-form-item>
<el-form-item
label="跟进结果:"
prop="trace_result"
label-width="100px"
>
<el-select
v-model="webForm.trace_result"
style="width: 90%"
placeholder="请选择"
>
<el-option
v-for="item in traceList"
:key="item.value"
:label="item.label"
:value="item.value"
> </el-option>
</el-select>
</el-form-item>
<el-form-item
v-if="activeType == 2"
label="免打扰:"
label-width="80px"
prop="no_trouble"
>
<el-checkbox
v-model="webForm.no_trouble"
class="noDisturb rowFlex allCenter"
:true-label="1"
:false-label="0"
>免打扰(勾选后该用户不会再被分配任务)</el-checkbox>
</el-form-item>
</el-form>
</div>
<div
v-for="(remark, indexs) in item.remarks"
:key="indexs"
class="item rowFlex columnCenter spaceBetween"
>
<div
class="rowFlex spaceBetween"
style="width: 100%;"
>
<span
class="label"
style="width: 50px"
>备注:</span>
<div class="text rowFlex remark flex1">
<textEditor
:remark.sync="remark.remark"
:domid="'taskRemark' + indexs"
:contenteditable="!Boolean(remark.id)"
@resultReamrk="resultReamrk"
/>
</div>
<i
v-if="indexs == 0"
class="el-icon-circle-plus-outline remarkHandle"
type="primary"
@click="addRemark(index)"
></i>
<i
v-else-if="indexs != 0 && !remark.id"
class="el-icon-remove-outline remarkHandle"
type="primary"
@click="removeRemark(index, indexs)"
></i>
</div>
</div>
<div
class="btns rowFlex allCenter"
style="margin-top: 20px"
>
<el-button
:disabled="item.status==3"
:loading="remarkLoading"
@click="saveRemak(item, index)"
>保存</el-button>
<el-button
type="primary"
:disabled="item.status==3"
:loading="taskLoading"
@click="completeTask(item, index)"
>保存并完成任务</el-button>
</div>
</el-collapse-item>
</el-collapse>
</div>
</div>
</div>
<div
v-else-if="!loading && taskList.length == 0"
class="noContent rowFlex allCenter"
>
<NoContent />
</div>
</div>
</div>
</div>
</template>
<script>
import { taskTrack, taskRecord, logsSave, searchcondition } from '@/api/game'
import { mapState } from 'vuex'
import textEditor from '@/components/textEditor.vue'
import NoContent from '@/components/noContent.vue'
export default {
components: {
textEditor,
NoContent
},
data() {
return {
isloadMore: true,
loading: false,
collapseValue: ['1'],
taskList: [],
gameUserInfo: {
recharge_total: 0,
today_amount: 0
},
orderTypeList: [
{ label: '账号任务', type: 1 },
{ label: '用户任务', type: 2 }
],
activeType: 1,
traceList: [],
webForm: {
trace_result: '',
remark: '',
abnormal_types: [],
no_trouble: 0
},
taskTypeList: [],
errorTypeList: [],
taskInfo: {},
showLayer: false,
taskLoading: false,
remarkLoading: false,
pageInfo: {
page: 0,
page_size: 20,
total: 0
}
}
},
computed: {
...mapState('game', ['accountSelect',]),
...mapState('user', ['userInfo'])
},
watch: {
accountSelect(newVal, oldVal) {
if (newVal && newVal !== '') {
this.pageInfo = {
page: 0,
page_size: 20,
total: 0
}
this.isloadMore = true
this.taskList = []
this.requestTaskList()
// this.gameMemberView()
this.searchcondition()
this.searchTrackList()
this.searchconditionError()
}
}
},
mounted() {
// this.gameMemberView()
this.requestTaskList()
this.searchcondition()
this.searchTrackList()
this.searchconditionError()
},
methods: {
searchcondition() {
const data = {
type: 'dictionaries',
table_name: 'zs_operator_plan',
field_name: 'plan_type'
}
searchcondition(data).then((res) => {
this.taskTypeList = res.data.data
})
},
searchconditionError() {
const data = {
type: 'dictionaries',
table_name: 'zs_operator_task',
field_name: 'abnormal_type'
}
searchcondition(data).then((res) => {
this.errorTypeList = res.data.data
})
},
handleClick(item) {
this.activeType = item.type
this.isloadMore = true
this.pageInfo = {
page: 0,
page_size: 20,
total: 0
}
this.taskList = []
this.requestTaskList()
},
resultReamrk(text) {
console.log(text, '最后编辑器的内容')
},
searchTrackList() {
const data = {
type: 'dictionaries',
table_name: 'zs_operator_task',
field_name: 'trace_result'
}
searchcondition(data).then((res) => {
this.traceList = res.data.data
})
},
completeTask(item, index) {
this.taskInfo = item
this.onConfirm(item, index)
},
saveRemak(item, index) {
this.remarkLoading = true
const remarks = item.remarks.filter((item) => !item.id && item.remark.trim() !== '')
const data = {
task_id: item.id,
create_name: this.userInfo.username,
create_department: this.userInfo.department_name,
remarks: remarks || []
}
logsSave(data).then((res) => {
if (res.status_code == 1) {
this.remarkLoading = false
this.$message.success(res.msg)
this.isloadMore = true
this.pageInfo = {
page: 0,
page_size: 20,
total: 0
}
this.taskList = []
this.requestTaskList()
this.$forceUpdate()
} else {
this.remarkLoading = false
}
}, (err) => {
console.log(err, 'err')
this.remarkLoading = false
})
},
submitForm(item) {
this.taskLoading = true
const remarks = item.remarks.filter((item) => !item.id && item.remark.trim() !== '')
console.log(item, remarks, 'remarks')
const data = {
id: this.taskInfo.id,
trace_result: this.webForm.trace_result,
abnormal_types: this.webForm.abnormal_types,
create_user: this.userInfo.username,
remark: remarks,
create_department: this.userInfo.department_name
}
this.activeType == 1 ? data.no_trouble = this.webForm.no_trouble : ''
taskTrack(data).then((res) => {
if (res.status_code == 1) {
this.taskLoading = false
this.$message.success(res.msg)
this.showLayer = false
this.webForm = {
trace_result: '',
remark: '',
abnormal_types: [],
no_trouble: 0
}
this.isloadMore = true
this.pageInfo = {
page: 0,
page_size: 20,
total: 0
}
this.taskList = []
this.requestTaskList()
} else {
this.taskLoading = false
}
}, (err) => {
console.log(err, 'err')
this.taskLoading = false
})
},
onConfirm(item, index) {
if (this.webForm.trace_result === '') {
this.$message.warning('请选择跟进结果')
return false
}
if (this.webForm.abnormal_types.length === 0 && this.taskInfo.plan_type === 5) {
this.$message.warning('请选择异常原因')
return false
}
this.submitForm(item, index)
},
addRemark(index) {
this.taskList[index].remarks.push({ remark: '' })
this.$forceUpdate()
},
removeRemark(index, indexs) {
this.taskList[index].remarks.splice(indexs, 1)
},
handleChange(item, $event) {
this.taskInfo = item
this.webForm = {
trace_result: '',
remark: '',
abnormal_types: [],
no_trouble: 0
}
},
requestTaskList() {
if (this.accountSelect == '') {
this.$message.warning('暂无关联的账号,请先去关联账号!')
return false
}
if (!this.isloadMore) {
console.log('没有更多数据了')
return false
}
this.pageInfo.page += 1
this.loading = true
const data = {
member_id: this.accountSelect,
user_type: this.activeType,
...this.pageInfo
}
taskRecord(data).then(
(res) => {
this.loading = false
if (res.data.data && res.data.data.length < 20) {
this.isloadMore = false
}
this.taskList = this.taskList.concat(res.data.data)
this.taskList.map((item) => {
!item.remarks || item.remarks.length === 0 ? (item.remarks = [{ remark: '' }]) : ''
})
if (res.status_code == 1) {
this.$message.success(res.msg)
}
},
(err) => {
this.loading = false
}
)
}
}
}
</script>
<style lang="scss" scoped>
.task-info-container {
width: vw(424);
height: 100%;
background: #fff;
margin-left: 2px;
position: relative;
overflow: hidden;
.detailsTitle {
width: 100%;
padding: 0 vw(20);
height: 60px;
font-size: 18px;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #333333;
border-bottom: 1px solid #ebeef5;
border-left: 1px solid #ebeef5;
p {
color: #333333;
}
}
.account-task-container-content {
width: 100%;
height: calc(100% - 60px);
padding: 20px 10px;
padding-top: 0px;
.tabSelect {
width: 100%;
height: 60px;
border-bottom: 1px solid #ebeef5;
cursor: pointer;
.tabSelectItem {
font-size: 18px;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #333333;
padding-top: 10px;
line-height: 47px;
cursor: pointer;
}
.tabSelectItemActive {
color: #00bf8a;
border-bottom: 2px solid #00bf8a;
}
}
.contentItem {
position: relative;
.title {
position: absolute;
left: 10px;
top: 14px;
font-size: 14px;
color: #999999;
}
}
.item {
width: 100%;
height: auto;
font-size: 14px;
font-weight: 400;
color: #333333;
transition: all 0.5s;
position: relative;
cursor: pointer;
div {
width: 100%;
margin-bottom: 5px;
}
.remark {
::v-deep .el-textarea__inner {
height: 80px;
}
}
.tableImage {
width: 40px;
height: 40px;
border-radius: 6px;
margin-right: vw(10);
}
.label {
color: #999999;
}
.text {
color: #333333;
margin-left: 10px;
word-break: break-all;
max-width: 75%;
}
.icon {
display: none;
position: absolute;
right: 0;
top: 12px;
}
.dianFail {
display: inline-block;
width: 8px;
height: 8px;
background: #f45454;
border-radius: 5px;
}
.dian {
display: inline-block;
width: 8px;
height: 8px;
background: #00bf8a;
border-radius: 5px;
}
.dian2 {
display: inline-block;
width: 8px;
height: 8px;
background: #ff9d02;
border-radius: 5px;
}
}
.orderMoney {
width: calc(100% + 40px);
height: 80px;
// margin-left: -20px;
padding: 10px 0;
.orderMoneyItem {
width: 50%;
text-align: center;
margin-top: 5px;
span {
font-size: 14px;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #333333;
}
p {
font-size: 22px;
color: #00bf8a;
}
}
}
.filterList {
margin-bottom: 10px;
.filterListInput {
width: 60%;
margin-left: 15px;
margin-bottom: 10px;
}
.filterListDate {
width: 150px;
margin-bottom: 10px;
}
::v-deep .search-item .item-label {
margin-right: 20px;
}
}
.orderDetailsScroll {
width: 100%;
height: calc(100% - 20px);
overflow: auto;
overflow-x: hidden;
}
.orderDetails {
width: 100%;
height: auto;
margin-top: 20px;
position: relative;
.bridgeMain {
position: absolute;
top: 0px;
right: 0px;
width: 50px;
height: 50px;
.text {
font-size: 8px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #ff9d02;
transform: rotate(48deg);
z-index: 100;
position: absolute;
right: -6px;
top: 10px;
width: 50px;
text-align: center;
}
.bridge {
font-size: 50px;
position: absolute;
top: 0;
right: 0;
}
}
.orderDetailsTitle {
width: 100%;
background: #f9faff;
.money {
width: 100%;
height: auto;
padding-left: 10px;
.btns {
padding-right: 40px;
}
.btn {
background: #fff;
border-radius: 4px;
padding: 2px 5px;
margin-left: 10px;
font-size: 12px;
border: 1px solid rgba(0, 0, 0, 0.15);
color: #333333;
cursor: pointer;
}
.btnnot {
background: #ffdddd;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #f56c6c;
border: none;
}
.btnsuccess {
background: #e1fff0;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #00bf8a;
border: none;
}
.sended {
padding: 0 8px;
height: 20px;
line-height: 20px;
background: #e1fff0;
border-radius: 4px;
font-size: 12px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #00bf8a;
}
.noSend {
padding: 0 8px;
height: 20px;
line-height: 20px;
background: #fffae0;
border-radius: 4px;
font-size: 12px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #ffa81d;
}
}
.text {
font-size: 14px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #333333;
max-width: 200px;
overflow: hidden;
white-space: nowrap; /* 防止文字换行 */
text-overflow: ellipsis; /* 超出部分显示省略号 */
}
}
.orderDetailsList {
width: 100%;
height: auto;
background: #ffffff;
border: 1px solid #ebeef5;
position: relative;
.titleFix {
position: absolute;
left: 10px;
top: 20px;
color: #999999;
}
}
}
}
.remarkHandle {
font-size: 20px;
color: #0ac358;
cursor: pointer;
margin-right: 5px;
position:absolute;
right: 0;
top: 0;
}
::v-deep .el-tabs__item {
line-height: 26px;
font-size: 16px;
font-weight: 500;
}
::v-deep .el-collapse {
border: none;
}
::v-deep .el-collapse-item__header {
width: 100%;
color: #333333;
font-size: 14px;
font-weight: 400;
/* 单行显示省略号 */
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
::v-deep .el-collapse-item__arrow {
position: absolute;
right: 0px;
}
::v-deep .el-collapse-item__content{
padding: 10px;
}
.editLayer {
margin-left: -20px;
.noDisturb{
// 换行
white-space: wrap;
}
::v-deep .el-form-item__label{
font-weight: normal;
color: #999999;
}
::v-deep .el-form-item--small.el-form-item{
margin-bottom: 10px;
}
}
}
</style>
<template>
<div class="userInfo-content">
<!-- 用 el-tabs 有三个 tab 分别是 客户资料 角色信息 违规记录 用 v-for 循环 -->
<el-tabs v-model="activeTab" >
<el-tab-pane label="客户资料" name="userInfo">
<Info v-if="activeTab === 'userInfo'" :chatUserDetails="chatUserInfo"/>
</el-tab-pane>
<!-- <el-tab-pane label="角色信息" name="roleInfo">
<RoleInfo v-if="activeTab === 'roleInfo'"/>
</el-tab-pane> -->
<!-- <el-tab-pane label="违规记录" name="violationRecord">
<ViolationRecord v-if="activeTab === 'violationRecord'"/>
</el-tab-pane> -->
</el-tabs>
<Info :chatUserDetails="chatUserInfo"/>
</div>
</template>
<script>
......@@ -34,21 +23,6 @@ export default {
},
data() {
return {
activeTab:'userInfo',
tabList:[
{
name:'客户资料',
value:'userInfo'
},
{
name:'角色信息',
value:'roleInfo'
},
{
name:'违规记录',
value:'violationRecord'
}
]
}
},
created(){
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论