Commit abd95d58 authored by 赵茹林's avatar 赵茹林

新增 增长运营列表、用户服务列表

parent 8e2e3494
......@@ -42,10 +42,10 @@
<el-checkbox v-model="data.refund" v-if="data.cover ==='5-1'|| data.cover=== '5-10'|| data.cover=== '5-9'">退款</el-checkbox>
<el-checkbox v-model="data.refund" v-if="data.cover ==='10-1' ">类别管理</el-checkbox>
<el-checkbox v-model="data.promoter" v-if="data.cover ==='5-1' ">编辑推广人</el-checkbox>
<el-checkbox v-model="data.refund" v-if="data.cover ==='2-3'|| data.cover=== '3-1'|| data.cover=== '3-2' ">添加观摩班用户</el-checkbox>
<el-checkbox v-model="data.classManage" v-if="data.cover ==='2-3'|| data.cover=== '3-1'|| data.cover=== '3-2' ">添加带班班用户</el-checkbox>
<el-checkbox v-model="data.classManageUnlimited" v-if="data.cover ==='2-3'|| data.cover=== '3-1'|| data.cover=== '3-2' ">添加观摩班(无限制)</el-checkbox>
<el-checkbox v-model="data.classTakeUnlimited" v-if="data.cover ==='2-3'|| data.cover=== '3-1'|| data.cover=== '3-2' ">添加带班班(无限制)</el-checkbox>
<el-checkbox v-model="data.refund" v-if="data.cover ==='2-3'|| data.cover=== '3-1'|| data.cover=== '3-2' || data.cover=== '3-6' || data.cover=== '3-7' ">添加观摩班用户</el-checkbox>
<el-checkbox v-model="data.classManage" v-if="data.cover ==='2-3'|| data.cover=== '3-1'|| data.cover=== '3-2' || data.cover=== '3-6' || data.cover=== '3-7' ">添加带班班用户</el-checkbox>
<el-checkbox v-model="data.classManageUnlimited" v-if="data.cover ==='2-3'|| data.cover=== '3-1'|| data.cover=== '3-2' || data.cover=== '3-6' || data.cover=== '3-7' ">添加观摩班(无限制)</el-checkbox>
<el-checkbox v-model="data.classTakeUnlimited" v-if="data.cover ==='2-3'|| data.cover=== '3-1'|| data.cover=== '3-2' || data.cover=== '3-6' || data.cover=== '3-7' ">添加带班班(无限制)</el-checkbox>
<el-checkbox v-model="data.distribution" v-if="data.cover ==='5-9'||data.cover ==='7-9'" @change="distribution">批量分配</el-checkbox>
<el-checkbox v-model="data.exportFinish" v-if="data.cover === '2-3'">导出完课用户</el-checkbox>
<el-checkbox v-model="data.import" v-if="data.cover ==='6-3'||data.cover ==='5-3'||data.cover ==='5-9'">导入</el-checkbox>
......@@ -88,7 +88,7 @@
limit: 10,
roleList: [],
exportMenuList: [ // 导出权限
'2-3', '5-10', '5-2', '5-1', '5-3', '5-8', '5-9', '6-4', '3-1', '7-9', '6-3', '10-8'
'2-3', '5-10', '5-2', '5-1', '5-3', '5-8', '5-9', '6-4', '3-1', '3-6', '3-7', '7-9', '6-3', '10-8'
],
dialog: {
title: '新增角色',
......
......@@ -38,8 +38,7 @@
<span v-if="type===1">{{teacherDetail.status}}</span>
<el-form-item v-if="type !== 1">
<el-select v-model="form.status" placeholder="请选择">
<el-option v-for="data in statusOption" :key="data.value" :label="data.label"
:value="data.value"></el-option>
<el-option v-for="data in statusOption" :key="data.value" :label="data.label" :value="data.value"></el-option>
</el-select>
</el-form-item>
</el-col>
......@@ -47,9 +46,9 @@
<el-col :span="8">
<span v-if="type===1">{{teacherDetail.type}}</span>
<el-form-item v-if="type !== 1">
<el-select v-model="form.type" placeholder="请选择">
<el-option v-for="data in dialogObj.teacherTypeList" :key="data.type" :label="data.name"
:value="data.type"></el-option>
<!--<el-select v-model="form.type" placeholder="请选择" disabled>-->
<el-select v-model="form.type" placeholder="请选择" :disabled="typeList.length < 2">
<el-option v-for="data in typeList" :key="data.type" :label="data.name" :value="data.type"></el-option>
</el-select>
</el-form-item>
</el-col>
......@@ -141,6 +140,7 @@
],
loading:true,
type:0,
typeList: [],
title:'',
form:{
name:'',
......@@ -181,8 +181,8 @@
switch(this.dialogObj.type){
case 2:
this.$refs['form'].validate((valid) => {
if(valid){
editTeacherApi(this.id,json).then(res=>{
if (valid) {
editTeacherApi(this.id, json).then(res => {
this.$message({
type: 'success',
message: '修改成功!'
......@@ -235,11 +235,33 @@
this.loading = false;
})
},
initType() {
// debugger
if (this.dialogObj.teacherTypeList && this.dialogObj.teacherTypeList.length) {
if (String(this.dialogObj.typeAdd).indexOf(',') > -1) { // 3,4
let typeAddArr = this.dialogObj.typeAdd.split(','), arr = [];
typeAddArr.forEach(val => {
let idx = this.dialogObj.teacherTypeList.findIndex(i => i.type == val);
if (idx > -1) {
arr.push(this.dialogObj.teacherTypeList[idx])
}
})
this.typeList = arr;
} else if (this.dialogObj.typeAdd == 0 || this.dialogObj.typeAdd == 2) {
let idx = this.dialogObj.teacherTypeList.findIndex(i => i.type == this.dialogObj.typeAdd);
if (idx > -1) {
this.typeList = [this.dialogObj.teacherTypeList[idx]]
}
}
}
},
initDialog(){
console.log(this.dialogObj)
// console.log(this.dialogObj)
this.initType();
switch(this.dialogObj.type){
case 0:
this.title = '新增教师';
case 0: // 添加
this.title = '新增';
this.show = this.dialogObj.show;
this.type = 0;
this.form.name = "";
......@@ -247,29 +269,29 @@
this.form.qr = "";
this.form.squad = "";
this.form.type = 0;
this.form.type = String(this.dialogObj.typeAdd).indexOf(',')>-1 ? 3 : this.dialogObj.typeAdd;
this.form.status = 0;
this.imageList = [];
this.loading = false;
this.uploadShow = true;
this.form.media_id = '';
break;
case 1:
this.title = '教师详情';
case 1: // 查看
this.title = '详情';
this.show = this.dialogObj.show;
this.id = this.dialogObj.id;
this.type = 1;
getTeacherDetailApi(this.id).then(res=>{
getTeacherDetailApi(this.id).then(res => {
this.teacherDetail = res;
this.loading = false
});
break;
case 2:
case 2: // 编辑
this.title = '编辑';
this.show = this.dialogObj.show;
this.id = this.dialogObj.id;
this.type = 2;
getTeacherDetailApi(this.id).then(res=>{
getTeacherDetailApi(this.id).then(res => {
this.form.name = res.name;
this.form.squad = res.squad;
this.form.alias = res.alias;
......@@ -277,7 +299,7 @@
this.form.type = res.type;
this.form.status = res.status;
this.form.media_id = res.media_id ? res.media_id : '';
this.imageList = [{name:res.qr,url:res.qr}];
this.imageList = [{name: res.qr, url: res.qr}];
this.uploadShow = !res.qr;
this.loading = false;
});
......@@ -287,6 +309,10 @@
}
},
watch:{
'dialogObj.teacherTypeList'() {
console.log('listUpdate'); // todo 似乎无用?
this.initType();
},
dialogObj:{
handler: function () {
this.loading = true;
......
<template>
<div class="user">
<el-form ref="searchFrom" :model="searchFrom" size="mini" label-width="68px" inline>
<el-form-item label="昵称">
<el-input v-model="searchFrom.name" style="width: 90px"></el-input>
</el-form-item>
<el-form-item label="手机号">
<el-input v-model="searchFrom.alias" style="width: 110px"></el-input>
</el-form-item>
<el-form-item label="老师状态" clearable>
<el-select v-model="searchFrom.status" @change="getUser" style="width: 88px" clearable>
<el-option label="带班" value="0"></el-option>
<el-option label="不带班" value="1"></el-option>
</el-select>
</el-form-item>
<!--<el-form-item label="教师类型">
<el-select v-model="searchFrom.type" style="width: 95px" placeholder="请选择" @change="getUser" clearable>
&lt;!&ndash; <el-option
v-for="item in dialogObj.teacherTypeList"
:key="item.id"
:label="item.label"
:value="item.id">
</el-option> &ndash;&gt;
<el-option v-for="data in dialogObj.teacherTypeList" :key="data.type" :label="data.name"
:value="data.type"></el-option>
</el-select>
</el-form-item>-->
<el-form-item label="任务日期">
<el-date-picker
style="width: 140px;"
type="date"
v-model="searchFrom.task_date"
value-format="yyyy-MM-dd"
placeholder="选择日期">
</el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" plain @click="getUser">搜索</el-button>
</el-form-item>
<el-form-item v-if="$store.state.orderRefund">
<!--<el-button type="success" plain @click="add">新增教师</el-button>-->
<el-button type="success" plain @click="add">新增增长运营</el-button>
</el-form-item>
</el-form>
<el-tabs v-model="searchFrom.squad" type="card" style="background: white;padding-top: 10px" @tab-click="getUser">
<el-tab-pane v-if="phoneNumObj.teacher_type!='teacher_leader'" v-for="i in 10" :key="i" :label="'T'+i" :name="i.toString()"/>
<!-- <el-tab-pane v-if="phoneNumObj.teacher_type=='teacher_leader'" :key="phoneNumObj.squad" :label="'T'+phoneNumObj.squad" :name="phoneNumObj.squad.toString()"/> -->
</el-tabs>
<el-table
size="mini"
:data="userList"
height="calc(100vh - 335px)"
style="width: 100%">
<el-table-column
prop="name"
width="250"
label="老师">
<template slot-scope="scope">
<div style="display: flex;">
<a :href="scope.row.qr" target="_blank" class="clearfix">
<img class="avatar" :src="scope.row.qr" alt="二维码">
</a>
<div>
老师名:{{scope.row.name}}
<br>
微信号:{{scope.row.alias}}
<br>
类别:{{scope.row.type | teacherType}}
<br>
顾问:{{scope.row.adviser}}
<br>
开始时间:<span style="display: inline-block;width: 72px;vertical-align: text-top;line-height: 16px;">{{scope.row.teacher_start}}</span>
</div>
</div>
</template>
</el-table-column>
<el-table-column
prop="name"
label="添加好友">
<template slot-scope="scope">
进班人数:{{scope.row.into_class_num}}<br>
加老师处理数:{{scope.row.add_teacher_exec_num}}<br>
加老师成功数:{{scope.row.add_teacher_success_num}}<br>
成功率:<el-progress
style="display: inline-block;width: calc(90% - 50px)"
:text-inside="true"
:stroke-width="18"
:color="Number(scope.row.add_teacher_success_rate)>70 ? '#67C23A' : '#f00'"
:percentage="Number(scope.row.add_teacher_success_rate)?Number(scope.row.add_teacher_success_rate):0">
</el-progress>
<br>
处理率:<el-progress
style="display: inline-block;width: calc(90% - 50px)"
:text-inside="true"
:stroke-width="18"
:color="Number(scope.row.add_teacher_exec_rate)===100 ? '#67C23A' : '#f00'"
:percentage="Number(scope.row.add_teacher_exec_rate)?Number(scope.row.add_teacher_exec_rate):0">
</el-progress>
</template>
</el-table-column>
<el-table-column
prop="name"
label="召回率">
<template slot-scope="scope">
需召回人数:{{scope.row.need_recall_num}}<br>
已沟通人数:{{scope.row.recall_desc_exec_num}}<br>
用户回复数:{{scope.row.recall_desc_reply_num}}<br>
达标率:<el-progress
style="display: inline-block;width: calc(90% - 50px)"
:text-inside="true"
:stroke-width="18"
:color="Number(scope.row.recall_watch_rate)===100 ? '#67C23A' : '#dd001b'"
:percentage="Number(scope.row.recall_watch_rate)?Number(scope.row.recall_watch_rate):0">
</el-progress>
<br>
处理率:<el-progress
style="display: inline-block;width: calc(90% - 50px)"
:text-inside="true"
:stroke-width="18"
:color="Number(scope.row.recall_exec_rate)===100 ? '#67C23A' : '#f00'"
:percentage="Number(scope.row.recall_exec_rate)?Number(scope.row.recall_exec_rate):0">
</el-progress>
</template>
</el-table-column>
<el-table-column
prop="name"
label="意向标记">
<template slot-scope="scope">
意向用户数:{{scope.row.intention_num}}<br>
完课沟通用户数{{scope.row.over_desc_exec_num}}<br>
往期活跃用户沟通数:{{scope.row.past_desc_exec_num}}<br>
标记率:<el-progress
style="display: inline-block;width: calc(90% - 50px)"
:text-inside="true"
:stroke-width="18"
color="#67C23A"
:percentage="Number(scope.row.over_intention_rate)?Number(scope.row.over_intention_rate):0">
</el-progress>
<br>
处理率:<el-progress
style="display: inline-block;width: calc(90% - 50px)"
:text-inside="true"
:stroke-width="18"
:color="Number(scope.row.over_exec_rate)===100 ? '#67C23A' : '#f00'"
:percentage="Number(scope.row.over_exec_rate)?Number(scope.row.over_exec_rate):0">
</el-progress>
</template>
</el-table-column>
<el-table-column
prop="intention_num"
width="100"
label="意向用户数">
</el-table-column>
<el-table-column
prop="performance"
width="100"
label="当月业绩">
</el-table-column>
<el-table-column width="320" label="操作">
<template slot-scope="scope">
<el-button size="mini" plain type="primary" @click="goToTeacherDetail(scope.row)">查看详情</el-button>
<el-button size="mini" plain type="warning" @click="edit(scope.row)" v-if="!$store.state.readonly">编辑</el-button>
<el-button size="mini" plain type="success" @click="transferToggle(scope.row)" v-if="!$store.state.readonly">移交</el-button>
<el-button size="mini" plain type="danger" @click="delTeacher(scope.row)" v-if="$store.state.deletePermission && !$store.state.readonly">删除</el-button>
</template>
</el-table-column>
</el-table>
<div v-if="res" class="total-tab">
<div>总计</div>
<div>
<div>
成功率:<el-progress
style="display: inline-block;width: calc(90% - 50px)"
:text-inside="true"
:stroke-width="16"
:color="Number(res.add_teacher_success_rate)>70 ? '#67C23A' : '#f00'"
:percentage="Number(res.add_teacher_success_rate)?Number(res.add_teacher_success_rate):0">
</el-progress>
<br>
处理率:<el-progress
style="display: inline-block;width: calc(90% - 50px)"
:text-inside="true"
:stroke-width="16"
:color="Number(res.add_teacher_exec_rate)===100 ? '#67C23A' : '#f00'"
:percentage="Number(res.add_teacher_exec_rate)?Number(res.add_teacher_exec_rate):0">
</el-progress>
</div>
</div>
<div>
<div>
达标率:<el-progress
style="display: inline-block;width: calc(90% - 50px)"
:text-inside="true"
:stroke-width="16"
:color="Number(res.recall_watch_rate)===100 ? '#67C23A' : '#ff0000'"
:percentage="Number(res.recall_watch_rate)?Number(res.recall_watch_rate):0">
</el-progress>
<br>
处理率:<el-progress
style="display: inline-block;;width: calc(90% - 50px)"
:text-inside="true"
:stroke-width="16"
:color="Number(res.recall_exec_rate)===100 ? '#67C23A' : '#f00'"
:percentage="Number(res.recall_exec_rate)?Number(res.recall_exec_rate):0">
</el-progress>
</div>
</div>
<div>
<div>
标记率:<el-progress
style="display: inline-block;width: calc(90% - 50px)"
:text-inside="true"
:stroke-width="16"
color="#67C23A"
:percentage="Number(res.over_intention_rate)?Number(res.over_intention_rate):0">
</el-progress>
<br>
处理率:<el-progress
style="display: inline-block;width: calc(90% - 50px)"
:text-inside="true"
:stroke-width="16"
:color="Number(res.over_exec_rate)===100 ? '#67C23A' : '#f00'"
:percentage="Number(res.over_exec_rate)?Number(res.over_exec_rate):0">
</el-progress>
</div>
</div>
<div>
{{res.intention_num}}
</div>
<div>
{{res.total_money}}
</div>
<div></div>
</div>
<page :total="total" :limit="limit" @pageChange="onPageChange" @sizeChange="onSizeChange"/>
<dialog-com :dialogObj="dialogObj" @changeShow="changeShow" @reflash="getUser"/>
<el-dialog width="90%" top="5vh" :visible.sync="dialogDetail.show">
<div v-if="dialogDetail.show">
<teacher-detail :parentDetail="dialogDetail"></teacher-detail>
</div>
</el-dialog>
<el-dialog width="500px" :visible.sync="transfer.show" title="移交">
<el-form ref="transferForm" :rules="transfer.form.rules" :model="transfer.form" label-width="100px">
<el-form-item label="当前设备:" prop="teacher_name">
{{transfer.form.teacher_name}}
</el-form-item>
<el-form-item label="当前顾问:" prop="staff_current_name">
{{transfer.form.staff_current_name}}
</el-form-item>
<el-form-item label="移交顾问:" prop="staff_id">
<el-select v-model="transfer.form.staff_id" filterable placeholder="请选择" :clearable="false" @change="transferStaffName">
<el-option
v-for="(data,index) in transfer.staff"
:key="index"
:label="data.name"
:value="data.id">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="移交时间:" prop="transfer_at">
<div style="display: flex;">
<el-date-picker
v-model="transfer.form.transfer_at" :clearable="false" value-format="yyyy-MM-dd HH:mm:ss"
type="datetime" placeholder="选择时间"></el-date-picker>
</div>
</el-form-item>
<el-form-item label="移交原因:" prop="reason">
<el-select v-model="transfer.form.reason" filterable placeholder="请选择" :clearable="false" @change="transferReasonName">
<el-option
v-for="(data,index) in transfer.reasonList"
:key="index"
:label="data.name"
:value="data.id">
</el-option>
</el-select>
</el-form-item>
</el-form>
<div slot="footer">
<el-button @click="transferToggle">取消</el-button>
<el-button type="primary" @click="transferSave">确定</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import {getTeacherListApi,delTeacherApi,getStaffListApi,postTransferTeacherApi,getTeacherTypeListApi} from "../../service/api";
import {TEACHERTYPE} from "../../util/wordbook";
import page from '../framework/page'
import teacherDetail from '../teacherDetail/index'
import dialogCom from './dialog'
// import Dialog from "../class/dialog";
let teacherTypeSource = {}
export default {
name: "growth",
data(){
let nowDate = this.formatTime(new Date());
return {
transfer: {
show: false,
form: {
reason: '',
reason_name: '',
teacher_name: '',
teacher_id: '',
staff_current_name: '', // 当前顾问名
staff_name: '', // 移交顾问name
staff_id: '', // 移交顾问id
transfer_at: '',
rules: {
staff_id: [{required: true, message: '请选择', trigger: 'change'}],
transfer_at: [{required: true, message: '请选择', trigger: 'change'}],
reason: [{required: true, message: '请选择', trigger: 'change'}],
},
},
staff: [0],
reasonList: [{
id: 0,
name: '人员入职',
},{
id: 1,
name: '人员离职',
},{
id: 2,
name: '请假',
},{
id: 3,
name: '其它',
},]
},
searchFrom:{
name:'',
alias:"",
status:'0',
task_date:nowDate,
squad:"1",
type: '3,4', // 3、4 增长运营 tmk
},
dialogObj:{
typeAdd: '3,4', // 与searchFrom.type一致
type:0,
show:false,
id:''
},
dialogDetail:{
show:false,
id:''
},
userList:[],
total:0,
nowPage:1,
limit: 20,
res:null,
dialogDetailObj:{
show:false,
title:'班级列表',
id: ''
},
teacherTypeOption: [{
id: 0,
label: '老师'
}, {
id: 1,
label: '新星妈妈'
}],
phoneNumObj:{}
}
},
watch:{
'dialogDetail.show'(value){
if(!value){
this.getUser()
}
}
},
components:{
// Dialog,
page,
dialogCom,
teacherDetail
},
filters:{
teacherType(value){
return teacherTypeSource[value]
}
},
mounted(){
// console.log(s)
let data = localStorage.getItem("phoneNum");
console.log(data)
// debugger
if(data){
data = JSON.parse(data)
this.phoneNumObj=data;
}
if(data&&data.teacher_type!='teacher_leader'){
this.$router.push('/teacher/'+ data.id);
}else{
this.getUser()
}
getTeacherTypeListApi().then(res=>{
this.dialogObj.teacherTypeList = res
let obj = {}
res.forEach((item,index)=>{
obj[item.type]=item.name
})
teacherTypeSource = obj
console.log(obj)
});
},
methods:{
onPageChange(val){
this.nowPage = val;
this.getUser()
},
formatTime(date){
let year = date.getFullYear();
let Month = date.getMonth()+1;
if(Month < 10){
Month = `0${Month}`
}
let Day = date.getDate();
if(Day<10)Day = `0${Day}`;
return `${year}-${Month}-${Day}`;
},
onSizeChange(val){
this.limit = val
this.nowPage = 1;
this.getUser()
},
getUser(){
let json = {
limit: this.limit,
page: this.nowPage
}
if (this.searchFrom.type || this.searchFrom.type === 0) {
json.type = this.searchFrom.type
}
if (this.searchFrom.status){
json.status = this.searchFrom.status
}
if (this.searchFrom.name) {
json.name = this.searchFrom.name
}
if (this.searchFrom.alias) {
json.alias = this.searchFrom.alias
}
if (this.searchFrom.task_date){
json.task_date = this.searchFrom.task_date
}
let data = localStorage.getItem("phoneNum");
if(data){
data = JSON.parse(data)
}
if(data&&data.teacher_type=='teacher_leader'){
json.squad = data.squad
}else{
json.squad = this.searchFrom.squad
}
getTeacherListApi(json).then(res=>{
this.userList = res.list;
this.total = res.total;
this.res=res;
})
},
transferStaffName(data) {
this.transfer.form.staff_name = this.transfer.staff.find(x => x.id == data).name;
},
transferReasonName(data) {
this.transfer.form.reason_name = this.transfer.reasonList.find(x => x.id == data).name;
},
transferToggle(data) {
this.transfer.show = !this.transfer.show;
if (this.transfer.show){
if (this.transfer.staff[0] === 0) {
let json = { limit: 1000, page: 1, status: 0 }; // status 0 在职
getStaffListApi(json).then(res => {
this.transfer.staff = res.list;
});
}
this.$nextTick(()=>{
this.$refs['transferForm'].resetFields();
this.transfer.form.teacher_name = data.name;
this.transfer.form.teacher_id = data.id;
this.transfer.form.staff_current_name = data.adviser;
})
} else {
this.$nextTick(()=>{
this.$refs['transferForm'].resetFields();
})
}
},
transferSave() {
this.$refs['transferForm'].validate((valid) => {
if (valid) {
this.$confirm(`确定将
<span style="color: red;">${this.transfer.form.teacher_name}</span> 移交给
<span style="color: red;">${this.transfer.form.staff_name}</span> ?<br>
移交开始时间 ${this.transfer.form.transfer_at} <br>
移交原因 ${this.transfer.form.reason_name}`, '提示', {
dangerouslyUseHTMLString: true,
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
var json = {
teacher_id: this.transfer.form.teacher_id,
staff_id: this.transfer.form.staff_id,
transfer_at: this.transfer.form.transfer_at,
reason: this.transfer.form.reason,
};
postTransferTeacherApi(json).then(res => {
this.$message({type: 'success', message: '移交成功!'});
this.transferToggle();
this.getUser();
})
}).catch(() => {
this.$message({
type: 'info',
message: '已取消移交'
});
});
} else {
console.log('error submit!!');
return false;
}
});
},
edit(data){
this.dialogObj.id = data.id;
this.dialogObj.type = 2;
this.dialogObj.show = true
},
add(){
this.dialogObj.type = 0;
this.dialogObj.show = true
},
detail(data){
this.dialogObj.id = data.id;
this.dialogObj.type = 1;
this.dialogObj.show = true
},
delTeacher(data){
this.$confirm('此操作将删除该账号?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
delTeacherApi(data.id).then(res=>{
this.$message({
type: 'success',
message: '删除成功!'
});
this.getUser()
});
});
},
changeShow(data){
this.dialogObj.show=data
},
classDetail(row){
this.dialogDetailObj = {
show:true,
title:row.name + '班级详情',
id: row.id
}
},
goToTeacherDetail(row){
// this.$router.push('/teacher/'+ row.id);
this.dialogDetail.id = row.id;
this.dialogDetail.show = true
}
}
}
</script>
<style scoped lang="less">
@import "../../util/public";
.user{
/*height: 100%;*/
overflow: auto;
padding: 20px 0;
.btn-content{
text-align: center;
}
}
/deep/.el-progress-bar__outer{
background: #cccccc;
}
.total-tab{
display: table;
background: #dfedff;
width: 100%;
vertical-align: middle;
font-size: 12px;
&>div{
display: table-cell;
vertical-align: middle;
padding: 10px;
}
&>div:nth-child(1){
width: 230px;
min-width: 230px;
text-align: center;
}
&>div:nth-child(5){
min-width: 80px;
width: 80px;
}
&>div:nth-child(7){
min-width: 320px + 12px;
width: 320px + 12px;
}
&>div:nth-child(2),
&>div:nth-child(3),
&>div:nth-child(4){
min-width: 60px;
}
}
.avatar{
width: 70px;
margin-right: 5px;
height: 70px;
float: left;
}
.shortcut {
width: 50px;
}
</style>
......@@ -13,18 +13,18 @@
<el-option label="不带班" value="1"></el-option>
</el-select>
</el-form-item>
<el-form-item label="教师类型">
<!--<el-form-item label="教师类型">
<el-select v-model="searchFrom.type" style="width: 95px" placeholder="请选择" @change="getUser" clearable>
<!-- <el-option
&lt;!&ndash; <el-option
v-for="item in dialogObj.teacherTypeList"
:key="item.id"
:label="item.label"
:value="item.id">
</el-option> -->
</el-option> &ndash;&gt;
<el-option v-for="data in dialogObj.teacherTypeList" :key="data.type" :label="data.name"
:value="data.type"></el-option>
</el-select>
</el-form-item>
</el-form-item>-->
<el-form-item label="任务日期">
<el-date-picker
style="width: 140px;"
......@@ -289,7 +289,7 @@
import page from '../framework/page'
import teacherDetail from '../teacherDetail/index'
import dialogCom from './dialog'
import Dialog from "../class/dialog";
// import Dialog from "../class/dialog";
let teacherTypeSource = {}
export default {
name: "index",
......@@ -334,7 +334,13 @@
status:'0',
task_date:nowDate,
squad:"1",
type:"",
type:0,
},
dialogObj:{
typeAdd: 0, // 与searchFrom.type一致
type:0,
show:false,
id:''
},
dialogDetail:{
show:false,
......@@ -344,11 +350,6 @@
total:0,
nowPage:1,
limit: 20,
dialogObj:{
type:0,
show:false,
id:''
},
res:null,
dialogDetailObj:{
show:false,
......@@ -373,7 +374,7 @@
}
},
components:{
Dialog,
// Dialog,
page,
dialogCom,
teacherDetail
......
<template>
<div class="user">
<el-form ref="searchFrom" :model="searchFrom" size="mini" label-width="68px" inline>
<el-form-item label="昵称">
<el-input v-model="searchFrom.name" style="width: 90px"></el-input>
</el-form-item>
<el-form-item label="手机号">
<el-input v-model="searchFrom.alias" style="width: 110px"></el-input>
</el-form-item>
<el-form-item label="老师状态" clearable>
<el-select v-model="searchFrom.status" @change="getUser" style="width: 88px" clearable>
<el-option label="带班" value="0"></el-option>
<el-option label="不带班" value="1"></el-option>
</el-select>
</el-form-item>
<!--<el-form-item label="教师类型">
<el-select v-model="searchFrom.type" style="width: 95px" placeholder="请选择" @change="getUser" clearable>
&lt;!&ndash; <el-option
v-for="item in dialogObj.teacherTypeList"
:key="item.id"
:label="item.label"
:value="item.id">
</el-option> &ndash;&gt;
<el-option v-for="data in dialogObj.teacherTypeList" :key="data.type" :label="data.name"
:value="data.type"></el-option>
</el-select>
</el-form-item>-->
<el-form-item label="任务日期">
<el-date-picker
style="width: 140px;"
type="date"
v-model="searchFrom.task_date"
value-format="yyyy-MM-dd"
placeholder="选择日期">
</el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" plain @click="getUser">搜索</el-button>
</el-form-item>
<el-form-item v-if="$store.state.orderRefund">
<el-button type="success" plain @click="add">新增用户服务</el-button>
</el-form-item>
</el-form>
<el-tabs v-model="searchFrom.squad" type="card" style="background: white;padding-top: 10px" @tab-click="getUser">
<el-tab-pane v-if="phoneNumObj.teacher_type!='teacher_leader'" v-for="i in 10" :key="i" :label="'T'+i" :name="i.toString()"/>
<!-- <el-tab-pane v-if="phoneNumObj.teacher_type=='teacher_leader'" :key="phoneNumObj.squad" :label="'T'+phoneNumObj.squad" :name="phoneNumObj.squad.toString()"/> -->
</el-tabs>
<el-table
size="mini"
:data="userList"
height="calc(100vh - 335px)"
style="width: 100%">
<el-table-column
prop="name"
width="250"
label="老师">
<template slot-scope="scope">
<div style="display: flex;">
<a :href="scope.row.qr" target="_blank" class="clearfix">
<img class="avatar" :src="scope.row.qr" alt="二维码">
</a>
<div>
老师名:{{scope.row.name}}
<br>
微信号:{{scope.row.alias}}
<br>
类别:{{scope.row.type | teacherType}}
<br>
顾问:{{scope.row.adviser}}
<br>
开始时间:<span style="display: inline-block;width: 72px;vertical-align: text-top;line-height: 16px;">{{scope.row.teacher_start}}</span>
</div>
</div>
</template>
</el-table-column>
<el-table-column
prop="name"
label="添加好友">
<template slot-scope="scope">
进班人数:{{scope.row.into_class_num}}<br>
加老师处理数:{{scope.row.add_teacher_exec_num}}<br>
加老师成功数:{{scope.row.add_teacher_success_num}}<br>
成功率:<el-progress
style="display: inline-block;width: calc(90% - 50px)"
:text-inside="true"
:stroke-width="18"
:color="Number(scope.row.add_teacher_success_rate)>70 ? '#67C23A' : '#f00'"
:percentage="Number(scope.row.add_teacher_success_rate)?Number(scope.row.add_teacher_success_rate):0">
</el-progress>
<br>
处理率:<el-progress
style="display: inline-block;width: calc(90% - 50px)"
:text-inside="true"
:stroke-width="18"
:color="Number(scope.row.add_teacher_exec_rate)===100 ? '#67C23A' : '#f00'"
:percentage="Number(scope.row.add_teacher_exec_rate)?Number(scope.row.add_teacher_exec_rate):0">
</el-progress>
</template>
</el-table-column>
<el-table-column
prop="name"
label="召回率">
<template slot-scope="scope">
需召回人数:{{scope.row.need_recall_num}}<br>
已沟通人数:{{scope.row.recall_desc_exec_num}}<br>
用户回复数:{{scope.row.recall_desc_reply_num}}<br>
达标率:<el-progress
style="display: inline-block;width: calc(90% - 50px)"
:text-inside="true"
:stroke-width="18"
:color="Number(scope.row.recall_watch_rate)===100 ? '#67C23A' : '#dd001b'"
:percentage="Number(scope.row.recall_watch_rate)?Number(scope.row.recall_watch_rate):0">
</el-progress>
<br>
处理率:<el-progress
style="display: inline-block;width: calc(90% - 50px)"
:text-inside="true"
:stroke-width="18"
:color="Number(scope.row.recall_exec_rate)===100 ? '#67C23A' : '#f00'"
:percentage="Number(scope.row.recall_exec_rate)?Number(scope.row.recall_exec_rate):0">
</el-progress>
</template>
</el-table-column>
<el-table-column
prop="name"
label="意向标记">
<template slot-scope="scope">
意向用户数:{{scope.row.intention_num}}<br>
完课沟通用户数{{scope.row.over_desc_exec_num}}<br>
往期活跃用户沟通数:{{scope.row.past_desc_exec_num}}<br>
标记率:<el-progress
style="display: inline-block;width: calc(90% - 50px)"
:text-inside="true"
:stroke-width="18"
color="#67C23A"
:percentage="Number(scope.row.over_intention_rate)?Number(scope.row.over_intention_rate):0">
</el-progress>
<br>
处理率:<el-progress
style="display: inline-block;width: calc(90% - 50px)"
:text-inside="true"
:stroke-width="18"
:color="Number(scope.row.over_exec_rate)===100 ? '#67C23A' : '#f00'"
:percentage="Number(scope.row.over_exec_rate)?Number(scope.row.over_exec_rate):0">
</el-progress>
</template>
</el-table-column>
<el-table-column
prop="intention_num"
width="100"
label="意向用户数">
</el-table-column>
<el-table-column
prop="performance"
width="100"
label="当月业绩">
</el-table-column>
<el-table-column width="320" label="操作">
<template slot-scope="scope">
<el-button size="mini" plain type="primary" @click="goToTeacherDetail(scope.row)">查看详情</el-button>
<el-button size="mini" plain type="warning" @click="edit(scope.row)" v-if="!$store.state.readonly">编辑</el-button>
<el-button size="mini" plain type="success" @click="transferToggle(scope.row)" v-if="!$store.state.readonly">移交</el-button>
<el-button size="mini" plain type="danger" @click="delTeacher(scope.row)" v-if="$store.state.deletePermission && !$store.state.readonly">删除</el-button>
</template>
</el-table-column>
</el-table>
<div v-if="res" class="total-tab">
<div>总计</div>
<div>
<div>
成功率:<el-progress
style="display: inline-block;width: calc(90% - 50px)"
:text-inside="true"
:stroke-width="16"
:color="Number(res.add_teacher_success_rate)>70 ? '#67C23A' : '#f00'"
:percentage="Number(res.add_teacher_success_rate)?Number(res.add_teacher_success_rate):0">
</el-progress>
<br>
处理率:<el-progress
style="display: inline-block;width: calc(90% - 50px)"
:text-inside="true"
:stroke-width="16"
:color="Number(res.add_teacher_exec_rate)===100 ? '#67C23A' : '#f00'"
:percentage="Number(res.add_teacher_exec_rate)?Number(res.add_teacher_exec_rate):0">
</el-progress>
</div>
</div>
<div>
<div>
达标率:<el-progress
style="display: inline-block;width: calc(90% - 50px)"
:text-inside="true"
:stroke-width="16"
:color="Number(res.recall_watch_rate)===100 ? '#67C23A' : '#ff0000'"
:percentage="Number(res.recall_watch_rate)?Number(res.recall_watch_rate):0">
</el-progress>
<br>
处理率:<el-progress
style="display: inline-block;;width: calc(90% - 50px)"
:text-inside="true"
:stroke-width="16"
:color="Number(res.recall_exec_rate)===100 ? '#67C23A' : '#f00'"
:percentage="Number(res.recall_exec_rate)?Number(res.recall_exec_rate):0">
</el-progress>
</div>
</div>
<div>
<div>
标记率:<el-progress
style="display: inline-block;width: calc(90% - 50px)"
:text-inside="true"
:stroke-width="16"
color="#67C23A"
:percentage="Number(res.over_intention_rate)?Number(res.over_intention_rate):0">
</el-progress>
<br>
处理率:<el-progress
style="display: inline-block;width: calc(90% - 50px)"
:text-inside="true"
:stroke-width="16"
:color="Number(res.over_exec_rate)===100 ? '#67C23A' : '#f00'"
:percentage="Number(res.over_exec_rate)?Number(res.over_exec_rate):0">
</el-progress>
</div>
</div>
<div>
{{res.intention_num}}
</div>
<div>
{{res.total_money}}
</div>
<div></div>
</div>
<page :total="total" :limit="limit" @pageChange="onPageChange" @sizeChange="onSizeChange"/>
<dialog-com :dialogObj="dialogObj" @changeShow="changeShow" @reflash="getUser"/>
<el-dialog width="90%" top="5vh" :visible.sync="dialogDetail.show">
<div v-if="dialogDetail.show">
<teacher-detail :parentDetail="dialogDetail"></teacher-detail>
</div>
</el-dialog>
<el-dialog width="500px" :visible.sync="transfer.show" title="移交">
<el-form ref="transferForm" :rules="transfer.form.rules" :model="transfer.form" label-width="100px">
<el-form-item label="当前设备:" prop="teacher_name">
{{transfer.form.teacher_name}}
</el-form-item>
<el-form-item label="当前顾问:" prop="staff_current_name">
{{transfer.form.staff_current_name}}
</el-form-item>
<el-form-item label="移交顾问:" prop="staff_id">
<el-select v-model="transfer.form.staff_id" filterable placeholder="请选择" :clearable="false" @change="transferStaffName">
<el-option
v-for="(data,index) in transfer.staff"
:key="index"
:label="data.name"
:value="data.id">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="移交时间:" prop="transfer_at">
<div style="display: flex;">
<el-date-picker
v-model="transfer.form.transfer_at" :clearable="false" value-format="yyyy-MM-dd HH:mm:ss"
type="datetime" placeholder="选择时间"></el-date-picker>
</div>
</el-form-item>
<el-form-item label="移交原因:" prop="reason">
<el-select v-model="transfer.form.reason" filterable placeholder="请选择" :clearable="false" @change="transferReasonName">
<el-option
v-for="(data,index) in transfer.reasonList"
:key="index"
:label="data.name"
:value="data.id">
</el-option>
</el-select>
</el-form-item>
</el-form>
<div slot="footer">
<el-button @click="transferToggle">取消</el-button>
<el-button type="primary" @click="transferSave">确定</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import {getTeacherListApi,delTeacherApi,getStaffListApi,postTransferTeacherApi,getTeacherTypeListApi} from "../../service/api";
import {TEACHERTYPE} from "../../util/wordbook";
import page from '../framework/page'
import teacherDetail from '../teacherDetail/index'
import dialogCom from './dialog'
// import Dialog from "../class/dialog";
let teacherTypeSource = {}
export default {
name: "growth",
data(){
let nowDate = this.formatTime(new Date());
return {
transfer: {
show: false,
form: {
reason: '',
reason_name: '',
teacher_name: '',
teacher_id: '',
staff_current_name: '', // 当前顾问名
staff_name: '', // 移交顾问name
staff_id: '', // 移交顾问id
transfer_at: '',
rules: {
staff_id: [{required: true, message: '请选择', trigger: 'change'}],
transfer_at: [{required: true, message: '请选择', trigger: 'change'}],
reason: [{required: true, message: '请选择', trigger: 'change'}],
},
},
staff: [0],
reasonList: [{
id: 0,
name: '人员入职',
},{
id: 1,
name: '人员离职',
},{
id: 2,
name: '请假',
},{
id: 3,
name: '其它',
},]
},
searchFrom:{
name:'',
alias:"",
status:'0',
task_date:nowDate,
squad:"1",
type:2,
},
dialogObj:{
typeAdd: 2, // 用户服务 与searchFrom.type一致
type:0,
show:false,
id:''
},
dialogDetail:{
show:false,
id:''
},
userList:[],
total:0,
nowPage:1,
limit: 20,
res:null,
dialogDetailObj:{
show:false,
title:'班级列表',
id: ''
},
teacherTypeOption: [{
id: 0,
label: '老师'
}, {
id: 1,
label: '新星妈妈'
}],
phoneNumObj:{}
}
},
watch:{
'dialogDetail.show'(value){
if(!value){
this.getUser()
}
}
},
components:{
// Dialog,
page,
dialogCom,
teacherDetail
},
filters:{
teacherType(value){
return teacherTypeSource[value]
}
},
mounted(){
// console.log(s)
let data = localStorage.getItem("phoneNum");
console.log(data)
// debugger
if(data){
data = JSON.parse(data)
this.phoneNumObj=data;
}
if(data&&data.teacher_type!='teacher_leader'){
this.$router.push('/teacher/'+ data.id);
}else{
this.getUser()
}
getTeacherTypeListApi().then(res=>{
this.dialogObj.teacherTypeList = res
let obj = {}
res.forEach((item,index)=>{
obj[item.type]=item.name
})
teacherTypeSource = obj
console.log(obj)
});
},
methods:{
onPageChange(val){
this.nowPage = val;
this.getUser()
},
formatTime(date){
let year = date.getFullYear();
let Month = date.getMonth()+1;
if(Month < 10){
Month = `0${Month}`
}
let Day = date.getDate();
if(Day<10)Day = `0${Day}`;
return `${year}-${Month}-${Day}`;
},
onSizeChange(val){
this.limit = val
this.nowPage = 1;
this.getUser()
},
getUser(){
let json = {
limit: this.limit,
page: this.nowPage
}
if (this.searchFrom.type || this.searchFrom.type === 0) {
json.type = this.searchFrom.type
}
if (this.searchFrom.status){
json.status = this.searchFrom.status
}
if (this.searchFrom.name) {
json.name = this.searchFrom.name
}
if (this.searchFrom.alias) {
json.alias = this.searchFrom.alias
}
if (this.searchFrom.task_date){
json.task_date = this.searchFrom.task_date
}
let data = localStorage.getItem("phoneNum");
if(data){
data = JSON.parse(data)
}
if(data&&data.teacher_type=='teacher_leader'){
json.squad = data.squad
}else{
json.squad = this.searchFrom.squad
}
getTeacherListApi(json).then(res=>{
this.userList = res.list;
this.total = res.total;
this.res=res;
})
},
transferStaffName(data) {
this.transfer.form.staff_name = this.transfer.staff.find(x => x.id == data).name;
},
transferReasonName(data) {
this.transfer.form.reason_name = this.transfer.reasonList.find(x => x.id == data).name;
},
transferToggle(data) {
this.transfer.show = !this.transfer.show;
if (this.transfer.show){
if (this.transfer.staff[0] === 0) {
let json = { limit: 1000, page: 1, status: 0 }; // status 0 在职
getStaffListApi(json).then(res => {
this.transfer.staff = res.list;
});
}
this.$nextTick(()=>{
this.$refs['transferForm'].resetFields();
this.transfer.form.teacher_name = data.name;
this.transfer.form.teacher_id = data.id;
this.transfer.form.staff_current_name = data.adviser;
})
} else {
this.$nextTick(()=>{
this.$refs['transferForm'].resetFields();
})
}
},
transferSave() {
this.$refs['transferForm'].validate((valid) => {
if (valid) {
this.$confirm(`确定将
<span style="color: red;">${this.transfer.form.teacher_name}</span> 移交给
<span style="color: red;">${this.transfer.form.staff_name}</span> ?<br>
移交开始时间 ${this.transfer.form.transfer_at} <br>
移交原因 ${this.transfer.form.reason_name}`, '提示', {
dangerouslyUseHTMLString: true,
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
var json = {
teacher_id: this.transfer.form.teacher_id,
staff_id: this.transfer.form.staff_id,
transfer_at: this.transfer.form.transfer_at,
reason: this.transfer.form.reason,
};
postTransferTeacherApi(json).then(res => {
this.$message({type: 'success', message: '移交成功!'});
this.transferToggle();
this.getUser();
})
}).catch(() => {
this.$message({
type: 'info',
message: '已取消移交'
});
});
} else {
console.log('error submit!!');
return false;
}
});
},
edit(data){
this.dialogObj.id = data.id;
this.dialogObj.type = 2;
this.dialogObj.show = true
},
add(){
this.dialogObj.type = 0;
this.dialogObj.show = true
},
detail(data){
this.dialogObj.id = data.id;
this.dialogObj.type = 1;
this.dialogObj.show = true
},
delTeacher(data){
this.$confirm('此操作将删除该账号?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
delTeacherApi(data.id).then(res=>{
this.$message({
type: 'success',
message: '删除成功!'
});
this.getUser()
});
});
},
changeShow(data){
this.dialogObj.show=data
},
classDetail(row){
this.dialogDetailObj = {
show:true,
title:row.name + '班级详情',
id: row.id
}
},
goToTeacherDetail(row){
// this.$router.push('/teacher/'+ row.id);
this.dialogDetail.id = row.id;
this.dialogDetail.show = true
}
}
}
</script>
<style scoped lang="less">
@import "../../util/public";
.user{
/*height: 100%;*/
overflow: auto;
padding: 20px 0;
.btn-content{
text-align: center;
}
}
/deep/.el-progress-bar__outer{
background: #cccccc;
}
.total-tab{
display: table;
background: #dfedff;
width: 100%;
vertical-align: middle;
font-size: 12px;
&>div{
display: table-cell;
vertical-align: middle;
padding: 10px;
}
&>div:nth-child(1){
width: 230px;
min-width: 230px;
text-align: center;
}
&>div:nth-child(5){
min-width: 80px;
width: 80px;
}
&>div:nth-child(7){
min-width: 320px + 12px;
width: 320px + 12px;
}
&>div:nth-child(2),
&>div:nth-child(3),
&>div:nth-child(4){
min-width: 60px;
}
}
.avatar{
width: 70px;
margin-right: 5px;
height: 70px;
float: left;
}
.shortcut {
width: 50px;
}
</style>
......@@ -102,7 +102,7 @@ export default [{
value: '销售管理',
icon: 'icon-laoshi',
list: [{
value: '教师列表',
value: '教师列表', // 老师用
routerName: 'teacher',
path: '/teacher',
cover: '3-1',
......@@ -111,6 +111,26 @@ export default [{
name: 'teacher',
component: e => require(['@/components/teacher'], e),
}
}, {
value: '增长运营列表', // 增长运营、TMK用
routerName: 'growth',
path: '/growth',
cover: '3-6',
router: {
path: '/growth',
name: 'growth',
component: e => require(['@/components/teacher/growth'], e),
}
}, {
value: '用户服务列表', // 用户服务用
routerName: 'userservice',
path: '/userservice',
cover: '3-7',
router: {
path: '/userservice',
name: 'userservice',
component: e => require(['@/components/teacher/userservice'], e),
}
}, {
value: '月课订单列表',
routerName: 'monthOrder',
......
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