Files
supplier-dispatch-h5/src/views/kpi/kpiIndex.vue

1465 lines
45 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="wrap">
<div v-if="isMobile" class="headWrap">
<div class="title">KPI.数据看板</div>
<div class="titleName">{{ current }}-{{indexData && indexData.supplierName}}</div>
</div>
<div v-else class="webHeadWrap" :style="'justify-content:'+(isZd==1 ? 'space-between':'center')">
<div class="empty" v-if="isZd==1"></div>
<div class="title">KPI.数据看板<span v-if="isZd!=1">--{{ current }}</span></div>
<!-- 只有中道账号才显示搜索框 -->
<div class="searchWrap" v-if="isZd==1">
<span class="month">{{ current }}</span>
<el-select
v-model="supplierId"
filterable
remote
reserve-keyword
placeholder="请输入后选择"
:remote-method="remoteMethod"
@change="getData"
:loading="selectLoading">
<el-option
v-for="item in selectOption"
:key="item.id"
:label="item.name"
:value="item.id">
</el-option>
</el-select>
<i class="el-icon-search" @click="searchHandle"></i>
</div>
</div>
<van-tabs v-model="active" sticky @click="onClick">
<van-tab v-for="(item,index) in tabArr" :key="index" :title="item.name"></van-tab>
</van-tabs>
<div v-loading="loadingData" :class="{'contentWrap':true,'webcontentWrap':!isMobile}" v-if="active===0">
<div :class="{'reciceOrder':true,'webCom':!isMobile}">
<div :class="{'title':true,'webTitle':!isMobile}">接单指标</div>
<div class="reciceOrderIWrap">
<div class="left common">
<div class="num">{{ indexData && indexData.receiveOrderCount }}</div>
<div class="itemTitle">承接案件量</div>
</div>
<div class="center common" @click="clickJumpHandle(5)">
<div class="num">{{ indexData && indexData.refuseOrderRate }}%</div>
<div class="itemTitle">拒单率 ></div>
</div>
<div class="right common" @click="clickJumpHandle(6)">
<div class="num">{{ indexData && indexData.timeoutOrderRate }}%</div>
<div class="itemTitle">超时率 ></div>
</div>
</div>
</div>
<div :class="{'reciceOrder':true,'webCom':!isMobile,'evaluate':isMobile}">
<div class="title">客户评价</div>
<div class="reciceOrderIWrap" v-if="indexData">
<circle-char :data="indexData && indexData.complainOrderRate" :title-text="'投诉率'" :bg-color="'#9485ED'"
:is-store="false" @clickComplain="clickJumpHandle(7)"></circle-char>
<circle-char :data="indexData && indexData.customerSatisfaction" :title-text="'客户满意度'"
:bg-color="'#5DDECF'"></circle-char>
<circle-char :data="indexData && indexData.urgeRate" :title-text="'催促率'"
:bg-color="'#FFADAD'"></circle-char>
</div>
</div>
<div :class="{'reciceOrder':true,'webCom':!isMobile,'appUse':isMobile}">
<div class="title">APP使用</div>
<div class="reciceOrderIWrap" v-if="indexData">
<circle-char :data="indexData && indexData.appRate" :title-text="'使用率'" :bg-color="'#3AA1FF'"
:is-store="false"
@clickUse="clickJumpHandle(8)"></circle-char>
<circle-char :data="indexData && indexData.threeMinutesContactRate" :title-text="'3联系客户率'"
:bg-color="'#5D7FD7'"></circle-char>
<circle-char :data="indexData && indexData.polymerizationSuccessRate" :title-text="'总聚合成功率'"
:bg-color="'#4ECB73'"></circle-char>
</div>
</div>
<div :class="{'reciceOrder':true,'webCom':!isMobile}">
<div :class="{'title':true,'webTitle':!isMobile}">时效</div>
<div class="reciceOrderIWrap">
<div class="left common">
<div class="num">{{ indexData && indexData.receiving }}</div>
<div class="itemTitle">接单时效()</div>
</div>
<div class="line"></div>
<div class="center common">
<div class="num">{{ indexData && indexData.polymerizationSuccessArriving }}</div>
<div class="itemTitle">集合成功到达时效</div>
</div>
<div class="line"></div>
<div class="right common">
<div class="num">{{ indexData && indexData.arriving }}</div>
<div class="itemTitle">到达时效</div>
</div>
</div>
</div>
<div :class="{'reciceOrder':true,'webCom':!isMobile,'store':isMobile}">
<div class="title">综合打分</div>
<div class="storeWrap" v-if="indexData">
<circle-char :data="indexData && indexData.score" :bg-color="'#00D273'" :is-store="true"></circle-char>
</div>
</div>
<div v-if="isMobile" style="padding: 20px"></div>
</div>
<div v-loading="loadingData" class="contentWrap monthTotal" v-if="active===1">
<div :class="{'tabWrap':true,'webTabWrap':!isMobile}">
<div v-for="(item,index) in list" :class="activeIndex===index ? 'active' : ''" :key="index"
@click="changeTab(index)">{{ item.name }}
</div>
</div>
<div :class="{'chartWrapWeb':!isMobile,'comChart':true}">
<template v-if="isMobile">
<div v-if="active===1" id="chartWrap" style="width: 100%;height:300px"></div>
<div v-if="isMobile && activeIndex==3" class="selectWrap">
<el-select v-model="value" @change="changeHandle">
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</div>
</template>
<template v-else>
<div v-if="[0,1,2].includes(activeIndex)">
<div id="chartWrap" style="width: 100%;height:300px"></div>
</div>
<div v-else style="width: 100%;display: flex;justify-content: space-between">
<div id="chartWrap" style="width: 47%;height:300px"></div>
<div class="webSwitch">
<el-switch
@change="switchHandle"
class="swithContainer"
v-model="swithVal"
active-text="拖车"
inactive-color="#409EFF"
inactive-text="小修">
</el-switch>
<div id="chartWrap1" style="width: 100%;height:300px"></div>
</div>
</div>
</template>
</div>
<div :class="{'webTab':!isMobile,}">
<noFit-table :is-mobile='isMobile' :table-data="detailList" :label-list="labelList"></noFit-table>
</div>
</div>
<div v-loading="loadingData" class="contentWrap monthTotal" v-if="[2,3,4].includes(active)">
<div :class="{'tabWrap':true,'webTabWrap':!isMobile,'mobileTab':isMobile}">
<div v-for="(item,index) in (active===3 ? driverList : list)" :class="activeIndex===index ? 'active' : ''"
:key="index"
@click="changeTab(index)">{{ item.name }}
</div>
</div>
<div :class="{'comTab':true}">
<noFit-table :is-mobile='isMobile' :table-data="detailList" :label-list="labelList"></noFit-table>
</div>
</div>
<div v-loading="loadingData" class="contentWrap monthTotal" v-if="[5,6,7,8,9].includes(active)">
<div :class="{'comTab':true,'detailTable':isMobile}">
<noFit-table :is-mobile='isMobile' :table-data="detailList" :label-list="labelList"
:loading="loading"></noFit-table>
</div>
<el-pagination
v-if="active !== 9"
small
:current-page.sync="pageNum"
:page-size.sync="pageSize"
@current-change="getKpiData"
@size-change="getKpiData"
layout="prev, pager, next"
:total="total">
</el-pagination>
</div>
</div>
</template>
<script>
import * as echarts from 'echarts';
import dayjs from "dayjs";
import {
getKpiDetailsData,
getStatisticsKpiByMonth,
getStatisticsKpi,
getDriverStatisticsKpi,
getSupplierId
} from "@/api/kpi.js"
import {myMixins} from "@/utils/myMixins"
import CircleChar from "@/views/kpi/components/circleChar.vue";
import NoFitTable from "@/views/kpi/components/noFit-table.vue";
export default {
name: "kpiIndex",
components: {CircleChar, NoFitTable},
computed: {},
mixins: [myMixins],
data() {
return {
active: 0,
activeIndex: 0,
tabArr: [
{name: '总览'}, {name: '月/总'}, {name: '日/总'}, {name: '月/师傅'}, {name: '日/师傅'}, {name: '拒单明细'},
{name: '超时明细'}, {name: '投诉明细'}, {name: '不使用APP案件明细'}, {name: '车辆在线情况'}
],
list: [{name: '接单指标'}, {name: '客户评价'}, {name: 'APP使用'}, {name: ' 时效 '}],
driverList: [{name: '接单情况'}, {name: '服务评价'}, {name: 'APP使用情况'}, {name: '时效 '}],
startMonthTime: '',
startTime: '',
endTime: '',
indexData: {},
detailList: [],
labelList: [],
loading: false,
loadingData: false,
v1: [],
v2: [],
v3: [],
v4: [],
v5: [],
v6: [],
xAxisArr: [],
isMobile: false,
isZd: '',
current: dayjs(new Date()).format('M'),
value: '1',
options: [
{value: '1', label: '师傅接单时效'},
{value: '2', label: '到达时效'},
],
pageNum: 1,
pageSize: 10,
total: 0,
swithVal: true,
supplierId:'',//1128,
selectLoading: false,
selectOption: [],
}
},
async mounted() {
await this.checkMobile();
await this.initDate();
await this.getData();
},
created() {
this.checkMobile();
const urlParams = new URLSearchParams(window.location.search);
this.isZd = urlParams?.get('isZd') || ''
},
async activated() {
},
methods: {
async remoteMethod(query) {
if (query !== '') {
this.selectLoading = true;
try {
const result = await getSupplierId(query);
this.selectOption = result.data || []
} catch (error) {
console.error('Error fetching data:', error);
this.selectOption = [];
} finally {
this.selectLoading = false;
}
} else {
this.selectOption = [];
}
},
async searchHandle() {//web端服务商搜索操作
console.log("搜索按钮")
},
async changeHandle() {
await this.getData();
await this.drawLine();
},
async switchHandle() {
await this.getData();
await this.drawLine1();
},
async getData() {
try {
this.loadingData = true
this.indexData = {}
this.v1 = []
this.v2 = []
this.v3 = []
this.v4 = []
this.v5 = []
this.v6 = []
this.xAxisArr = []
await this.getKpiData()
this.loadingData = false
} finally {
this.loadingData = false
}
},
async clickJumpHandle(type) {
this.loading = true
this.active = type;
await this.onClick();
},
onClick() {
this.activeIndex = 0;
this.detailList = [];
this.labelList = [];
this.getData();
if (this.active === 1) {
setTimeout(() => {
this.drawLine()
if (!this.isMobile && this.activeIndex === 3) {
this.drawLine1()
}
}, 500)
}
},
drawLine() { // 基于准备好的dom初始化echarts实例
// console.log("执行图表加载")
let myChart = echarts.init(document.getElementById('chartWrap'))
let option;
//接单指标
let series1 = [{
name: '派遣案件量',
type: 'bar',
data: this.v1,
yAxisIndex: 0,
smooth: true,
barWidth: this.isMobile ? 35 : 60,
label: {
show: true, // 显示标签
position: 'top', // 标签位置在柱形顶部
}
},
{
name: '拒单率',
type: 'line',
smooth: true,
data: this.v2,
yAxisIndex: 1,
label: {
show: true,
position: 'top',
formatter: '{c}%'
},
},
{
name: '超时率',
type: "line",
data: this.v3,
yAxisIndex: 1,
smooth: true,
label: {
show: true,
position: 'top',
formatter: '{c}%'
},
},
{
name: '客户取消率',
type: "line",
data: this.v4,
yAxisIndex: 1,
smooth: true,
label: {
show: true,
position: 'top',
formatter: '{c}%'
},
},
]
let series2 = [{
name: '客户评价率',
type: 'bar',
data: this.v1,
yAxisIndex: 0,
smooth: true,
barWidth: this.isMobile ? 35 : 60,
label: {
show: true, // 显示标签
position: 'top', // 标签位置在柱形顶部
}
},
{
name: '投诉率',
type: "line",
data: this.v3,
yAxisIndex: 1,
smooth: true,
label: {
show: true,
position: 'top',
formatter: '{c}%'
},
},
{
name: '客户满意度',
type: 'line',
smooth: true,
data: this.v2,
yAxisIndex: 1,
label: {
show: true,
position: 'top',
formatter: '{c}%'
},
},
]
let series3 = [
{
name: 'APP使用率',
type: 'line',
data: this.v1,
yAxisIndex: 0,
smooth: true,
label: {
show: true, // 显示标签
position: 'top', // 标签位置在柱形顶部
formatter: '{c}%'
}
},
{
name: '3联系客户率',
type: 'line',
smooth: true,
data: this.v2,
yAxisIndex: 0,
label: {
show: true,
position: 'top',
formatter: '{c}%'
},
},
{
name: '平安成功率',
type: "line",
data: this.v3,
yAxisIndex: 0,
smooth: true,
label: {
show: true,
position: 'top',
formatter: '{c}%'
},
},
{
name: '中华成功率',
type: "line",
data: this.v4,
yAxisIndex: 0,
smooth: true,
label: {
show: true,
position: 'top',
formatter: '{c}%'
},
},
{
name: '中道成功率',
type: "line",
data: this.v5,
yAxisIndex: 0,
smooth: true,
label: {
show: true,
position: 'top',
formatter: '{c}%'
},
},
{
name: '总成功率',
type: "line",
data: this.v6,
yAxisIndex: 0,
smooth: true,
label: {
show: true,
position: 'top',
formatter: '{c}%'
},
},
]
let series4 = [{
name: '接单时效(分)',
type: 'bar',
data: this.v1,
yAxisIndex: 1,
smooth: true,
barWidth: this.isMobile ? 35 : 60,
label: {
show: true, // 显示标签
position: 'top', // 标签位置在柱形顶部
}
},
{
name: '3分钟接单率',
type: 'line',
smooth: true,
data: this.v2,
yAxisIndex: 0,
label: {
show: true,
position: 'top',
formatter: '{c}%'
},
},
]
let series5 = [{
name: '到达时效(分)',
type: 'bar',
data: this.v1,
yAxisIndex: 1,
smooth: true,
barWidth: this.isMobile ? 25 : 10,
label: {
show: true, // 显示标签
position: 'top', // 标签位置在柱形顶部
}
},
{
name: '聚合成功到达时效',
type: 'bar',
data: this.v2,
yAxisIndex: 1,
smooth: true,
barWidth: this.isMobile ? 25 : 50,
label: {
show: true, // 显示标签
position: 'top', // 标签位置在柱形顶部
}
},
{
name: '40分钟到达率',
type: 'line',
smooth: true,
data: this.v3,
yAxisIndex: 0,
label: {
show: true,
position: 'top',
formatter: '{c}%'
},
},
]
let yAxis1 = [
{type: 'value'},
{
type: 'value',
axisLabel: {
formatter: '{value}%'
}
},
]
let yAxis2 = [
{
type: 'value',
axisLabel: {
formatter: '{value}%'
}
},
{
type: 'value',
axisLabel: {
formatter: '{value}%'
}
},
]
let yAxis3 = [
{
type: 'value',
axisLabel: {
formatter: '{value}%'
}
},
]
let yAxis4 = [
{
type: 'value',
axisLabel: {
formatter: '{value}%'
}
},
{type: 'value'},
]
let yAxis5 = [
{
type: 'value',
axisLabel: {
formatter: '{value}%'
}
},
{type: 'value'},
]
let series = []
let yAxis = []
if (this.active === 1) {
if (this.activeIndex === 0) {
series = series1
yAxis = yAxis1
} else if (this.activeIndex === 1) {
series = series2
yAxis = yAxis2
} else if (this.activeIndex === 2) {
series = series3
yAxis = yAxis3
} else if (this.activeIndex === 3) {
if (this.value == 1) {
series = series4
yAxis = yAxis4
} else {
series = series5
yAxis = yAxis5
}
}
}
option = {
title: {
text: this.isMobile ? this.getTitle(this.activeIndex) : '师傅接单时效',
textStyle: {
fontSize: 12
},
},
legend: {
textStyle: {
fontSize: this.isMobile ? 8 : ''
},
right: '1%',
itemWidth: this.isMobile ? 10 : 18, // 设置图例图标的宽度,从而调整图标大小
itemHeight: this.isMobile ? 6 : 10,
width: (this.active == 1 && this.activeIndex == 2) ? '60%' : '100%',
},
xAxis: {
type: 'category',
data: this.xAxisArr,
},
grid: {
left: '1%',
right: '1%',
bottom: '6%',
containLabel: true
},
yAxis: yAxis,
series: series,
};
option && myChart.setOption(option, true);
},
drawLine1() {
let myChart = echarts.init(document.getElementById('chartWrap1'))
let option;
option = {
title: {
text: '到达时效',
textStyle: {
fontSize: 12
},
},
legend: {
right: '1%',
itemWidth: 18, // 设置图例图标的宽度,从而调整图标大小
itemHeight: 10,
},
xAxis: {
type: 'category',
data: this.xAxisArr,
},
grid: {
left: '1%',
right: '1%',
bottom: '6%',
containLabel: true
},
yAxis: [
{
type: 'value',
axisLabel: {
formatter: '{value}%'
}
},
{type: 'value'},
],
series: [{
name: '到达时效(分)',
type: 'bar',
data: this.v3,
yAxisIndex: 1,
smooth: true,
barWidth: 50,
label: {
show: true, // 显示标签
position: 'top', // 标签位置在柱形顶部
}
},
{
name: '聚合成功到达时效',
type: 'bar',
data: this.v4,
yAxisIndex: 1,
smooth: true,
barWidth: 50,
label: {
show: true, // 显示标签
position: 'top', // 标签位置在柱形顶部
}
},
{
name: '40分钟到达率',
type: 'line',
smooth: true,
data: this.v5,
yAxisIndex: 0,
label: {
show: true,
position: 'top',
formatter: '{c}%'
},
},
]
};
option && myChart.setOption(option, true);
},
async getKpiData() {
try {
this.loading = true
if (this.active === 0) {
let res = await getStatisticsKpiByMonth({
startTime: this.startTime,
endTime: this.endTime,
statisticsType: 1,
supplierId: this.supplierId,
});
this.indexData = res.data;
} else if ([1, 2].includes(this.active)) {
let res = await getStatisticsKpi({
startTime: this.active === 1 ? this.startMonthTime : this.startTime,
endTime: this.endTime,
statisticsType: this.active === 1 ? 1 : 2,
supplierId: this.supplierId,
})
this.detailList = res.data?.map(item => {
let formatVal = dayjs(item.statisticsDate).format('DD');
let formatVal1 = dayjs(item.statisticsDate).format('MM');
return {...item, date: formatVal, month: formatVal1};
});
this.loading = false
this.detailList?.map(item => {
this.xAxisArr.unshift(item.month)
})
await this.twoTabHanldeData()
} else if ([3, 4].includes(this.active)) {
let res = await getDriverStatisticsKpi({
startTime: this.startTime ,
endTime: this.endTime,
statisticsType: this.active === 3 ? 1 : 2,
driverId: 68517,
})
this.detailList = res.data
this.loading = false;
await this.twoTabHanldeData();
} else if ([5, 6, 7, 8, 9].includes(this.active)) {
this.detailList = []
this.labelList = []
let result = await getKpiDetailsData({
startTime: this.startTime,
endTime: this.endTime,
searchType: this.setType(this.active),
pageNum: this.pageNum,
pageSize: this.pageSize
});
this.total = result.total
this.detailList = result.data?.map(item => {
let formatVal = dayjs(item.createTime).format('DD');
return {...item, date: formatVal};
});
this.loading = false
if (this.active === 5) {//拒单明细
this.labelList = [
{label: '案件编号', prop: 'orderCode'},
{label: '服务内容', prop: 'serviceName'},
{label: '拒单师傅车号', prop: 'plateNumber'},
{label: '拒单师傅名称', prop: 'driverName'},
{label: '手机号', prop: 'driverPhone'},
{label: '上游接单来源', prop: 'workSource'},
{label: '中道派单时间', prop: 'dispatchTime'},
{label: '拒绝原因', prop: 'reason'},
]
} else if (this.active === 6) {//超时明细
this.labelList = [
{label: '案件编号', prop: 'orderCode'},
{label: '服务内容', prop: 'serviceName'},
{label: '超时师傅车号', prop: 'plateNumber'},
{label: '超时师傅名称', prop: 'driverName'},
{label: '手机号', prop: 'driverPhone'},
{label: '上游接单来源', prop: 'workSource'},
{label: '中道派单时间', prop: 'dispatchTime'},
]
} else if (this.active === 7) {//投诉明细
this.labelList = [
{label: '案件编号', prop: 'orderCode'},
{label: '服务内容', prop: 'serviceName'},
{label: '接单车号', prop: 'plateNumber'},
{label: '接单师傅', prop: 'driverName'},
{label: '手机号', prop: 'driverPhone'},
{label: '客户投诉内容', prop: 'reason'},
]
} else if (this.active === 8) {//不使用App案件明细
// console.log("不使用App案件明细")
this.labelList = [
{label: '案件编号', prop: 'orderCode'},
{label: '服务内容', prop: 'serviceName'},
{label: '接单师傅手机号', prop: 'driverName'},
]
} else if (this.active === 9) {//车辆在线情况
this.labelList = [
{label: '日期', prop: 'date'},
{label: '在线车辆数量', prop: 'vehicleCount'},
]
}
}
} finally {
this.loading = false
}
},
checkMobile() {
const userAgent = navigator.userAgent || navigator.vendor || window.opera;
this.isMobile = /android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test(userAgent);
},
// 初始化获取当月日期
initDate() {
this.startTime = dayjs(new Date()).format('YYYY-MM') + '-01 00:00:00'
this.endTime = dayjs(new Date()).format('YYYY-MM') + '-' + this.getDayLen()+' 23:59:59'
this.startMonthTime=this.getStartTimeFromEndTime(this.endTime)
console.log(this.startTime,this.endTime,this.startMonthTime)
},
// 获取当月天数
getDayLen() {
let date;
let year;
let month;
let d;
date = new Date();
year = date.getFullYear();
month = date.getMonth() + 1;
d = new Date(year, month, 0);
return d.getDate();
},
//获取近五个月的开始时间
getStartTimeFromEndTime(endTimeStr) {
const endTime = new Date(endTimeStr);
endTime.setMonth(endTime.getMonth() - 5); // 减去5个月
const year = endTime.getFullYear();
let month = String(endTime.getMonth() + 1).padStart(2, '0'); // 月份+1并确保为两位数
let day = '01'; // 因为我们要的是那个月的第一天
const startTimeStr = `${year}-${month}-${day} `+'00:00:00';
return startTimeStr;
},
async changeTab(index) {
try {
this.loadingData = true
this.activeIndex = index
this.labelList = []
this.v1 = []
this.v2 = []
this.v3 = []
this.v4 = []
this.v5 = []
this.v6 = []
await this.twoTabHanldeData()
this.loadingData = false
if (this.active === 1) {
await this.drawLine()
if (!this.isMobile && this.activeIndex === 3) {
this.drawLine1()
}
}
} finally {
this.loadingData = false
}
},
// 二级tab切可不调接口需再次处理数据,1,2,3,4
twoTabHanldeData() {
if (this.active === 1) {
if (this.activeIndex === 0) {//接单指标
this.detailList?.map(item => {
this.v1.unshift(item.dispatchOrderCount)
this.v2.unshift(item.refuseOrderRate)
this.v3.unshift(item.timeoutOrderRate)
this.v4.unshift(item.cancelrate)
})
this.labelList = [
{label: '月', prop: 'month'},
{label: '派遣量', prop: 'dispatchOrderCount'},
{label: '承接量', prop: 'receiveOrderCount'},
{label: '完成量', prop: 'finishOrderCount'},
{label: '拒单量', prop: 'refuseOrderCount'},
{label: '拒单率(%', prop: 'refuseOrderRate'},
{label: '超时接单量', prop: 'timeoutOrderCount'},
{label: '超时率(%', prop: 'timeoutOrderRate'},
{label: '取消率(%', prop: 'cancelrate'},
]
} else if (this.activeIndex === 1) {
this.detailList?.map(item => {
this.v1.unshift(item.customerEvaluateRate)
this.v2.unshift(item.customerSatisfaction)
this.v3.unshift(item.complainOrderRate)
})
this.labelList = [
{label: '月', prop: 'month'},
{label: '投诉量', prop: 'complainOrderCount'},
{label: '投诉率(%', prop: 'complainOrderRate'},
{label: '客户满意度', prop: 'customerSatisfaction'},
{label: '客户评价率(%', prop: 'customerEvaluateRate'},
]
} else if (this.activeIndex === 2) {
this.detailList?.map(item => {
this.v1.unshift(item.appRate)
this.v2.unshift(item.threeMinutesContactRate)
this.v3.unshift(item.pinganPolymerizationSuccessRate)
this.v4.unshift(item.zhonghuaPolymerizationSuccessRate)
this.v5.unshift(item.zdPolymerizationSuccessRate)
this.v6.unshift(item.polymerizationSuccessRate)
})
this.labelList = [
{label: '月', prop: 'month'},
{label: '使用率(%', prop: 'appRate'},
{label: '3联系客户率%', prop: 'threeMinutesContactRate'},
{label: '平安聚合成功率(%', prop: 'pinganPolymerizationSuccessRate'},
{label: '中华聚合成功率(%', prop: 'zhonghuaPolymerizationSuccessRate'},
{label: '中道聚合成功率(%', prop: 'zdPolymerizationSuccessRate'},
{label: '总聚合成功率(%', prop: 'polymerizationSuccessRate'},
]
} else if (this.activeIndex === 3) {
if (this.isMobile) {
if (this.value == 1) {
this.detailList?.map(item => {
this.v1.unshift(item.receiving)
this.v2.unshift(item.threeMinutesReceivingRate)
})
} else {
this.detailList?.map(item => {
this.v1.unshift(item.arriving)
this.v2.unshift(item.polymerizationSuccessArriving)
this.v3.unshift(item.fortyMinutesArrivalRate)
})
}
} else {
this.detailList?.map(item => {
this.v1.unshift(item.receiving)
this.v2.unshift(item.threeMinutesReceivingRate)
})
if (this.swithVal) {
this.detailList?.map(item => {
this.v3.unshift(item.trailArriving)
this.v4.unshift(item.trailPolymerizationSuccessArriving)
this.v5.unshift(item.trailFortyMinutesArrivalRate)
})
} else {
this.detailList?.map(item => {
this.v3.unshift(item.minorArriving)
this.v4.unshift(item.minorPolymerizationSuccessArriving)
this.v5.unshift(item.minorFortyMinutesArrivalRate)
})
}
}
this.labelList = [
{label: '月', prop: 'month'},
{label: '接单时效(分)', prop: 'receiving'},
{label: '3接单率%', prop: 'threeMinutesReceivingRate'},
{label: '到达时效(分)', prop: 'arriving'},
{label: '40到达率%', prop: 'fortyMinutesArrivalRate'},
{label: '聚合成功到达时效', prop: 'polymerizationSuccessArriving'},
]
}
} else if (this.active === 2) {
if (this.activeIndex === 0) {//接单指标
this.labelList = [
{label: '日', prop: 'date'},
{label: '派遣案件量', prop: 'dispatchOrderCount'},
{label: '承接案件量', prop: 'receiveOrderCount'},
{label: '完成量', prop: 'finishOrderCount'},
{label: '拒单量', prop: 'refuseOrderCount'},
{label: '拒单率(%', prop: 'refuseOrderRate'},
{label: '超时接单量', prop: 'timeoutOrderCount'},
{label: '超时率(%', prop: 'timeoutOrderRate'},
{label: '客户取消率(%', prop: 'cancelrate'},
]
} else if (this.activeIndex === 1) {
this.labelList = [
{label: '日', prop: 'date'},
{label: '投诉量', prop: 'complainOrderCount'},
{label: '投诉率(%', prop: 'complainOrderRate'},
{label: '客户评价率(%', prop: 'customerEvaluateRate'},
{label: '催促率(%', prop: 'urgeRate'},
]
} else if (this.activeIndex === 2) {
this.labelList = [
{label: '日', prop: 'date'},
{label: '使用率(%', prop: 'appRate'},
{label: '3联系客户率%', prop: 'threeMinutesContactRate'},
{label: '平安聚合成功率(%', prop: 'pinganPolymerizationSuccessRate'},
{label: '中华聚合成功率(%', prop: 'zhonghuaPolymerizationSuccessRate'},
{label: '中道聚合成功率(%', prop: 'zdPolymerizationSuccessRate'},
{label: '总聚合成功率(%', prop: 'polymerizationSuccessRate'},
]
} else if (this.activeIndex === 3) {
this.labelList = [
{label: '日', prop: 'date'},
{label: '接单时效(分)', prop: 'receiving'},
{label: '3接单率%', prop: 'threeMinutesReceivingRate'},
{label: '小修到达时效(分)', prop: 'minorArriving'},
{label: '拖车到达时效(分)', prop: 'trailArriving'},
{label: '困境到达时效(分)', prop: 'dilemmaArriving'},
{label: '到达时效(分)', prop: 'arriving'},
{label: '40到达率%', prop: 'fortyMinutesArrivalRate'},
{label: '小修聚合成功到达时效(分)', prop: 'minorPolymerizationSuccessArriving'},
{label: '拖车聚合成功到达时效(分)', prop: 'trailPolymerizationSuccessArriving'},
{label: '聚合成功到达时效', prop: 'polymerizationSuccessArriving'},
]
}
} else if (this.active === 3) {
if (this.activeIndex === 0) {
this.labelList = [
{label: '师傅姓名', prop: 'driverName'},
{label: '承接案件量', prop: 'receiveOrderCount'},
{label: '拒单量', prop: 'refuseOrderCount'},
{label: '拒单率(%', prop: 'refuseOrderRate'},
{label: '超时接单量', prop: 'timeoutOrderCount'},
{label: '超时率(%', prop: 'timeoutOrderRate'},
]
} else if (this.activeIndex === 1) {
this.labelList = [
{label: '师傅姓名', prop: 'driverName'},
{label: '承接案件量', prop: 'receiveOrderCount'},
{label: '投诉量', prop: 'complainOrderCount'},
{label: '投诉率(%', prop: 'complainOrderRate'},
{label: '客户满意度', prop: 'customerSatisfaction'},
{label: '客户评价率(%', prop: 'customerEvaluateRate'},
{label: '催促率(%', prop: 'urgeRate'},
]
} else if (this.activeIndex === 2) {
this.labelList = [
{label: '师傅姓名', prop: 'driverName'},
{label: '承接案件量', prop: 'receiveOrderCount'},
{label: 'App使用率%', prop: 'appRate'},
{label: '3联系客户率%', prop: 'threeMinutesContactRate'},
{label: '平安聚合成功率(%', prop: 'pinganPolymerizationSuccessRate'},
{label: '中华聚合成功率(%', prop: 'zhonghuaPolymerizationSuccessRate'},
{label: '中道聚合成功率(%', prop: 'zdPolymerizationSuccessRate'},
{label: '总聚合成功率(%', prop: 'polymerizationSuccessRate'},
{label: '日均在线时长', prop: 'onlineDuration'},
]
} else if (this.activeIndex === 3) {
this.labelList = [
{label: '师傅姓名', prop: 'driverName'},
{label: '接单时效(分)', prop: 'receiving'},
{label: '3接单率%', prop: 'threeMinutesReceivingRate'},
{label: '到达时效(分)', prop: 'arriving'},
{label: '40到达率%', prop: 'fortyMinutesArrivalRate'},
{label: '聚合成功到达时效', prop: 'polymerizationSuccessArriving'},
]
}
} else if (this.active === 4) {
if (this.activeIndex === 0) {//接单指标
this.labelList = [
{label: '日', prop: 'date'},
{label: '派遣案件量', prop: 'dispatchOrderCount'},
{label: '承接案件量', prop: 'receiveOrderCount'},
{label: '完成量', prop: 'finishOrderCount'},
{label: '拒单量', prop: 'refuseOrderCount'},
{label: '拒单率(%', prop: 'refuseOrderRate'},
{label: '超时接单量', prop: 'timeoutOrderCount'},
{label: '超时率(%', prop: 'timeoutOrderRate'},
{label: '客户取消率(%', prop: 'cancelrate'},
]
} else if (this.activeIndex === 1) {
this.labelList = [
{label: '日', prop: 'date'},
{label: '投诉量', prop: 'complainOrderCount'},
{label: '投诉率(%', prop: 'complainOrderRate'},
{label: '客户满意度', prop: 'customerSatisfaction'},
{label: '客户评价率(%', prop: 'customerEvaluateRate'},
{label: '催促率(%', prop: 'urgeRate'},
]
} else if (this.activeIndex === 2) {
this.labelList = [
{label: '日', prop: 'date'},
{label: '使用率(%', prop: 'appRate'},
{label: '3联系客户率%', prop: 'threeMinutesContactRate'},
{label: '平安聚合成功率(%', prop: 'pinganPolymerizationSuccessRate'},
{label: '中华聚合成功率(%', prop: 'zhonghuaPolymerizationSuccessRate'},
{label: '中道聚合成功率(%', prop: 'zdPolymerizationSuccessRate'},
{label: '总聚合成功率(%', prop: 'polymerizationSuccessRate'},
{label: '日均在线时长', prop: 'onlineDuration'},
]
} else if (this.activeIndex === 3) {
this.labelList = [
{label: '日', prop: 'date'},
{label: '接单时效(分)', prop: 'receiving'},
{label: '3接单率%', prop: 'threeMinutesReceivingRate'},
{label: '到达时效(分)', prop: 'arriving'},
{label: '40到达率%', prop: 'fortyMinutesArrivalRate'},
{label: '聚合成功到达时效', prop: 'polymerizationSuccessArriving'},
]
}
}
},
setType(type) {
switch (type) {
case 5:
return 1;
case 6:
return 2;
case 7:
return 3;
case 8:
return 4;
case 9:
return 5;
}
},
getTitle(type) {
switch (type) {
case 0:
return '接单时效';
case 1:
return '客户评价';
case 2:
return 'APP使用';
case 3:
return '时效';
}
},
}
,
}
</script>
<style scoped lang="scss">
@import "@/styles/mixin.scss";
@import "@/styles/common.scss";
@import "@/styles/mixin.scss";
.wrap {
@include wh(100%, 100%);
}
.headWrap {
@include wh(100%, 56px);
background: #3E62B9;
@include flexTwoCenter;
flex-direction: column;
.title {
font-size: 20px;
color: #FFFFFF;
}
.titleName {
font-family: PingFangSC, PingFang SC;
@include fontWeightSize(14px, 500);
color: #BDDAFF;
}
}
.webHeadWrap {
@include flexCenter;
@include wh(100%, 50px);
background: #3E62B9;
box-sizing: border-box;
padding: 0 20px;
.empty {
@include wh(250px, 100%);
}
.title {
font-size: 20px;
color: #FFFFFF;
}
.searchWrap {
display: flex;
align-items: center;
position: relative;
.month {
display: inline-block;
width: 45px;
height: 30px;
line-height: 30px;
text-align: center;
border-radius: 20px 0px 0px 20px;
border: 1px solid #4C81F5;
font-size: 14px;
color: #FFFFFF;
}
.el-icon-search {
font-size: 15px;
color: #4C81F5;
position: absolute;
right: 15px;
}
::v-deep .el-input--suffix .el-input__inner {
height: 32px;
background: #EFF2F8;
}
::v-deep .el-input__inner {
border-radius: 0px 20px 20px 0px;
}
}
}
::v-deep .van-tabs {
background: white;
}
::v-deep .van-tabs__nav--line.van-tabs__nav--complete {
background: #5D7FD7;
padding: 0;
height: 36px;
}
::v-deep .van-tab--active {
background: #FFFFFF;
border-radius: 7px 7px 0px 0px;
@include sizeWeightCol(13px, 500, #5D7FD7 !important);
}
::v-deep .van-tabs__line {
display: none;
}
::v-deep .van-tab {
border-right: 1px solid #6B97D0;
@include sizeWeightCol(13px, 500, #ACC1DB);
}
::v-deep .van-col {
padding: 6px 10px;
background: #E5E6EB;
border-right: 1px solid #ccc;
border-bottom: 1px solid #ccc;;
}
.contentWrap {
@include wh(100%, calc(100% - 120px));
overflow-y: auto;
background: #EFF2F8;
.reciceOrder {
@include whBg(375px, 146px, #FFFFFF);
@include sizing4Padding(19px, 25px, 38px, 19px);
margin-bottom: 10px;
.storeWrap {
width: 100%;
text-align: center;
}
.title {
@include sizeWeightCol(14px, bold, #040415);
margin-bottom: 14px;
}
.reciceOrderIWrap {
@include flexColAround;
.common {
@include flexColCen;
}
}
.num {
@include sizeWeightCol(24px, bold, #040415);
margin-bottom: 10px;
}
.itemTitle {
@include flexCenter;
font-size: 12px;
color: rgba(4, 4, 21, 0.45);
}
.img {
@include whMarLe(8px, 10px, 4px);
}
.line {
border-right: 2px solid #EAE9EC;
}
}
.evaluate, .appUse, .store {
height: 179px;
.title {
margin-bottom: 0 !important;
}
}
.webCom {
@include whBg(420px, 200px, #FFFFFF);
float: left;
margin: 10px;
.webTitle {
margin-bottom: 40px !important;
}
}
}
.webcontentWrap {
@include wh(100%, calc(100% - 86px));
}
.tabWrap {
@include wh(100%, 22px);
@include flexColAround;
margin: 10px 0;
div {
padding: 2px 8px;
border-radius: 7px;
font-size: 12px;
@include bgFontColor(#3E3C3C, #F4F4F4);
}
.active {
position: relative;
opacity: 1;
@include bgFontColor(#ffffff, #F1B289);
}
.active:after {
content: '';
display: block;
@include wh(18px, 2px);
background: #FFFFFF;
position: absolute;
margin-top: 3px;
left: 50%;
opacity: 1;
transform: translateX(-50%);
width: 0;
height: 0;
border: 4px solid;
//border-color: #F1B289 transparent transparent transparent;
border-color: transparent transparent transparent transparent;
}
}
.webTabWrap {
width: 40% !important;
.active:after {
margin-top: 5px;
}
}
.monthTotal {
background: #FFFFFF;
padding-left: 6px;
//height: auto !important;
.leftMonth {
.leftItem {
font-weight: bold;
border-right: 1px solid #cccccc;
border-left: 1px solid #cccccc;
text-align: center;
padding: 8px 10px;
}
.leftItem:nth-child(odd) {
border-top: 1px solid #cccccc;
border-bottom: 1px solid #cccccc;
background-color: #f2f2f2; /* 奇数*/
}
}
.content {
flex-grow: 1; /* 占据剩余空间 */
overflow-x: auto; /* 当内容超出宽度时启用水平滚动 */
}
}
.comTab {
width: 100%;
height: 95%;
}
::v-deep .el-table {
height: 100%;
}
::v-deep .el-table--scrollable-x .el-table__body-wrapper {
height: 95% !important;
}
.chartWrapWeb, .webTab {
height: calc(100% - 200px);
width: 100%;
box-sizing: border-box;
padding: 0 40px;
}
.comChart {
position: relative;
.selectWrap {
position: absolute;
top: 0;
z-index: 1111;
left: 38px;
}
::v-deep .el-input__inner {
padding: 2px;
width: 98px;
height: 24px;
font-size: 12px;
}
::v-deep .el-input__inner {
right: 2px;
}
::v-deep .el-input__icon {
line-height: 0;
}
}
.el-pagination {
text-align: center;
}
.webSwitch {
width: 47%;
position: relative;
.swithContainer {
position: absolute;
z-index: 111;
left: 60px;
}
}
::v-deep .el-switch__core {
font-size: 12px;
width: 30px !important;
height: 16px;
}
::v-deep .el-switch__core::after {
width: 14px;
height: 14px;
margin-top: -1px;
}
::v-deep .el-switch.is-checked .el-switch__core::after {
margin-left: -15px;
}
::v-deep .el-switch__label * {
font-size: 12px;
}
</style>