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

1935 lines
65 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 }}-{{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">--中道救援</span><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
clearable
placeholder="请输入后选择"
:remote-method="remoteMethod"
@change="selectSupplierNameHanldle"
:loading="selectLoading">
<el-option
v-for="item in selectOption"
:key="item.id"
:label="item.name"
:value="item.id">
</el-option>
</el-select>
</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>
<div v-if="isMobile && !([0,1,2,3].includes(active))" class="tipArrow left">{{ leftArr }}</div>
<div v-if="isMobile && !([8,9].includes(active))" class="tipArrow right">>>></div>
</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" style="cursor: pointer">拒单率 ></div>
</div>
<div class="right common" @click="clickJumpHandle(6)">
<div class="num">{{ indexData && indexData.timeoutOrderRate }}%</div>
<div class="itemTitle" style="cursor: pointer">超时率 ></div>
</div>
</div>
</div>
<div :class="{'reciceOrder':true,'webCom':!isMobile,'evaluate':isMobile}">
<div class="title">客户评价</div>
<div class="reciceOrderIWrap" v-if="indexData">
<circle-char ref="Doughnut1" :data="indexData && indexData.complainOrderRate" :title-text="'投诉率'" :bg-color="'#9485ED'"
:is-store="false" @clickComplain="clickJumpHandle(7)"></circle-char>
<circle-char ref="Doughnut2" :data="indexData && indexData.customerSatisfaction" :title-text="'客户满意度'"
:bg-color="'#5DDECF'"></circle-char>
<circle-char ref="Doughnut3" :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 ref="Doughnut4" :data="indexData && indexData.appRate" :title-text="'使用率'" :bg-color="'#3AA1FF'"
:is-store="false"
@clickUse="clickJumpHandle(8)"></circle-char>
<circle-char ref="Doughnut5" :data="indexData && indexData.threeMinutesContactRate" :title-text="'3联系客户率'"
:bg-color="'#5D7FD7'"></circle-char>
<circle-char ref="Doughnut6" :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="scoreTitle">
<div>
<span class="title" style="margin-right: 15px">综合打分</span>
<el-button v-if="!isMobile && isBtn && supplierId" size="mini" type="primary" @click="applicateHandle">信息变更申请</el-button>
</div>
<i class="el-icon-question" @click.prevent="showScoreChart = !showScoreChart"></i>
</div>
<div class="storeWrap" v-if="indexData">
<circle-char v-if="showScoreChart" ref="Doughnut7" :data="indexData && indexData.score" :bg-color="'#00D273'" :is-store="true"></circle-char>
<div v-else class="detailScore">
<div class="left">
<div>
<span class="defen">接单得分:</span>
</div>
<div>
<span class="defen">接单时效得分:</span>
</div>
<div>
<span class="defen">接单时效得分:</span>
</div>
<div><span class="defen">聚合成功率得分:</span>
</div>
<div><span class="defen">APP使用率得分:</span>
</div>
<div><span class="defen">催促率得分:</span>
</div>
<div><span class="defen">投诉率得分:</span>
</div>
</div>
<div class="right">
<div>
<span>{{ indexData.orderScore }}</span>
</div>
<div>
<span>{{ indexData.orderAgeingScore }}</span>
</div>
<div>
<span>{{ indexData.arriveAgeingScore }}</span>
</div>
<div> <span>{{ indexData.polymerizationSuccessScore }}</span></div>
<div> <span>{{ indexData.appUseScore }}</span></div>
<div> <span>{{ indexData.urgeScore }}</span></div>
<div><span>{{ indexData.urgeScore }}</span></div>
</div>
</div>
</div>
</div>
<div :class="{'allDataChartWrap':true,'webComAllData':!isMobile,'store':isMobile}">
<div class="allDataChart" id="allDataChart" ></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" style="width: 100%">
<div id="chartWrap" style="width: 100%;height:300px"></div>
</div>
<div v-if="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 v-if="isMobile" :active='active' :is-mobile='isMobile' :table-data="etlDetailList" :label-list="etlLabelList"></noFit-table>
<noFit-table v-else :active='active' :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="searchDriverName" v-if="[3,4].includes(active)">
<el-select
v-model="driverName"
filterable
remote
clearable
reserve-keyword
placeholder="请输入后选择"
:remote-method="driverremoteMethod"
@change="getData"
:loading="driverselectLoading"
:style="isMobile ? 'width:100%' : 'width:50%'"
>
<el-option
v-for="item in driverselectOption"
:key="item.id"
:label="item.name"
:value="item.name">
</el-option>
</el-select>
</div>
<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 :active='active' :is-mobile='isMobile' :table-data="detailList" :label-list="labelList"></noFit-table>
</div>
<el-pagination
small
v-if="active !== 2"
:page-sizes="[20, 50, 100]"
:current-page.sync="pageNum"
:page-size.sync="pageSize"
@current-change="getKpiData"
@size-change="getKpiData"
layout="prev, pager, next,sizes"
:total="total">
</el-pagination>
</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 :active='active' :is-mobile='isMobile' :table-data="detailList" :label-list="labelList"
></noFit-table>
</div>
<!-- <el-pagination
small
:current-page.sync="pageNum"
:page-size.sync="pageSize"
@current-change="getKpiData"
@size-change="getKpiData"
layout="prev, pager, next"
:total="total">
</el-pagination>-->
<el-pagination
v-if="active !== 9"
small
:page-sizes="[20, 50, 100]"
:current-page.sync="pageNum"
:page-size.sync="pageSize"
@current-change="getKpiData"
@size-change="getKpiData"
layout="prev, pager, next,sizes"
:total="total">
</el-pagination>
</div>
</div>
</template>
<script>
import * as echarts from 'echarts';
import dayjs from "dayjs";
import {
getKpiDetailsData,
getStatisticsKpiByMonth,
getStatisticsKpi,
getDriverStatisticsKpi,
getSupplierId,
getDriverName,
getRecentSupplierKpi
} 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: '服务评价'}, {name: 'APP使用情况'}, {name: '时效 '}],
startMonthTime: '',
startTime: '',
endTime: '',
indexData: {},
detailList: [],
labelList: [],
etlDetailList: [],
etlLabelList: [],
loading: false,
loadingData: false,
v1: [],
v2: [],
v3: [],
v4: [],
v5: [],
v6: [],
xAxisArr: [],
isMobile: false,
isZd: '',
current: dayjs(new Date()).format('M'),
supplierName:'',
value: '1',
options: [
{value: '1', label: '师傅接单时效'},
{value: '2', label: '到达时效'},
],
pageNum: 1,
pageSize: 20,
total: 0,
swithVal: true,
supplierId:'',
selectLoading: false,
selectOption: [],
driverId:'',//68517
driverName:'',
driverselectLoading: false,
driverselectOption: [],
leftArr:'<<<',
showScoreChart:true,
continueMonthKpi:[],
isBtn:false,//是否有信息变更申请按钮权限
}
},
created() {
this.checkMobile();
const urlParams = new URLSearchParams(window.location.search);
this.isZd = urlParams?.get('isZd') || ''
this.supplierId = urlParams?.get('supplierId') || ''
this.isBtn= Number(urlParams?.get('isBtn'))
},
async mounted() {
await this.checkMobile();
await this.initDate();
await this.getData();
// await this.allDataChart()
},
methods: {
applicateHandle() {
if (window.parent) {
const hasListener = window.parent.dispatchEvent(new Event('checkCloseDialog'));
if (hasListener) {
window.parent.postMessage('closeDialog', '*');
} else {
window.history.back();
}
}
},
async selectSupplierNameHanldle(){
await this.getData()
setTimeout(()=>{
this.$refs.Doughnut1.initCircle()
this.$refs.Doughnut2.initCircle()
this.$refs.Doughnut3.initCircle()
this.$refs.Doughnut4.initCircle()
this.$refs.Doughnut5.initCircle()
this.$refs.Doughnut6.initCircle()
this.$refs.Doughnut7.initCircle()
},1500)
},
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 driverremoteMethod(query){
if (query !== '') {
this.driverselectLoading = true;
try {
const result = await getDriverName(query);
this.driverselectOption = result.data || []
} catch (error) {
this.driverselectOption = [];
} finally {
this.driverselectLoading = false;
}
} else {
this.driverselectOption = [];
}
},
async changeHandle() {
this.v1=[]
this.v2=[]
await this.twoTabHanldeData();
await this.drawLine();
},
async switchHandle() {
await this.getData();
await this.drawLine1();
},
async getData() {
try {
this.loadingData = true
this.indexData = {}
this.total=0
this.pageNum=1
this.v1 = []
this.v2 = []
this.v3 = []
this.v4 = []
this.v5 = []
this.v6 = []
this.xAxisArr = []
this.etlDetailList=[]
this.etlLabelList=[]
this.continueMonthKpi=[]
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.driverName=''
this.getData();
if (this.active === 1) {
setTimeout(() => {
this.drawLine()
if (!this.isMobile && this.activeIndex === 3) {
this.drawLine1()
}
}, 500)
}
},
drawLine() { // 基于准备好的dom初始化echarts实例
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: 'line',
data: this.v1,
smooth: true,
yAxisIndex: 0,
label: {
show: true, // 显示标签
position: 'top', // 标签位置在柱形顶部
formatter: '{c}%'
}
},
{
name: '投诉率',
type: "line",
data: this.v3,
smooth: true,
yAxisIndex: 0,
label: {
show: true,
position: 'top',
formatter: '{c}%'
},
},
{
name: '客户满意度',
type: 'line',
smooth: true,
data: this.v2,
yAxisIndex: 0,
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}%'
}
} ]
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: 45,
barGap: '0%', // 设置柱子之间的间隔
label: {
show: true, // 显示标签
position: 'top', // 标签位置在柱形顶部
}
},
{
name: '聚合成功到达时效',
type: 'bar',
data: this.v4,
yAxisIndex: 1,
smooth: true,
barWidth: 45,
barGap: '0%', // 设置柱子之间的间隔
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 allDataChart(){
let res = await getRecentSupplierKpi({
startTime: this.startTime,
endTime: this.endTime,
statisticsType: 1,
supplierId: this.supplierId,
driverId: this.driverId,
driverName:this.driverName,
});
console.log("res",res)
this.continueMonthKpi=res.data;
let v1=[]
let v2=[]
if( this.continueMonthKpi.length>0){
this.continueMonthKpi.forEach(item=>{
v1.push(item.dispatchOrderCount)
v2.push(item.orderScore)
})
}
let myChart = echarts.init(document.getElementById('allDataChart'))
let option = {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
crossStyle: {
color: '#999'
}
}
},
legend: { },
xAxis: [
{
type: 'category',
data: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'],
axisPointer: {
type: 'shadow'
}
}
],
yAxis: [
{
type: 'value',
axisLabel: {
formatter: '{value}',
rotate: 45,
margin: 2
}
},
{
type: 'value',
axisLabel: {
formatter: '{value}',
}
}
],
series: [
{
name: '案件量',
type: 'bar',
yAxisIndex: 0,
data:v1
},
{
name: '总分',
type: 'line',
yAxisIndex: 1,
data: v2
}
]
};
option && myChart.setOption(option, true);
},
async getKpiData() {
try {
this.loading = true
if (this.active === 0) {
await this.allDataChart()
let res = await getStatisticsKpiByMonth({
startTime: this.startTime,
endTime: this.endTime,
statisticsType: 1,
supplierId: this.supplierId,
});
if(!res.data){
return
}
this.indexData = res.data;
this.supplierName=res.data?.supplierName
this.indexData.refuseOrderRate=this.indexData.refuseOrderRate*100
if (this.indexData.refuseOrderRate % 1 !== 0) {
this.indexData.refuseOrderRate = this.indexData.refuseOrderRate.toFixed(2);
}
this.indexData.timeoutOrderRate=this.indexData.timeoutOrderRate*100
if (this.indexData.timeoutOrderRate % 1 !== 0) {
this.indexData.timeoutOrderRate = this.indexData.timeoutOrderRate.toFixed(2);
}
this.indexData.complainOrderRate=this.indexData.complainOrderRate*100
if (this.indexData.complainOrderRate % 1 !== 0) {
this.indexData.complainOrderRate = this.indexData.complainOrderRate.toFixed(2);
}
this.indexData.customerSatisfaction=this.indexData.customerSatisfaction*100
if (this.indexData.customerSatisfaction % 1 !== 0) {
this.indexData.customerSatisfaction = this.indexData.customerSatisfaction.toFixed(2);
}
this.indexData.threeMinutesContactRate=this.indexData.threeMinutesContactRate*100
if (this.indexData.threeMinutesContactRate % 1 !== 0) {
this.indexData.threeMinutesContactRate = this.indexData.threeMinutesContactRate.toFixed(2);
}
this.indexData.urgeRate=this.indexData.urgeRate*100
if (this.indexData.urgeRate % 1 !== 0) {
this.indexData.urgeRate = this.indexData.urgeRate.toFixed(2);
}
this.indexData.appRate=this.indexData.appRate*100
if (this.indexData.appRate % 1 !== 0) {
this.indexData.appRate = this.indexData.appRate.toFixed(2);
}
this.indexData.polymerizationSuccessRate=this.indexData.polymerizationSuccessRate*100
if (this.indexData.polymerizationSuccessRate % 1 !== 0) {
this.indexData.polymerizationSuccessRate = this.indexData.polymerizationSuccessRate.toFixed(2);
}
} 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 => {
item.refuseOrderRate=this.formatPercentage(item.refuseOrderRate) ;
item.timeoutOrderRate=this.formatPercentage(item.timeoutOrderRate) ;
item.cancelRate=this.formatPercentage(item.cancelRate) ;
item.urgeRate=this.formatPercentage(item.urgeRate) ;
item.complainOrderRate=this.formatPercentage(item.complainOrderRate) ;
item.customerEvaluateRate=this.formatPercentage(item.customerEvaluateRate) ;
item.appRate=this.formatPercentage(item.appRate) ;
item.threeMinutesContactRate=this.formatPercentage(item.threeMinutesContactRate) ;
item.pinganPolymerizationSuccessRate=this.formatPercentage(item.pinganPolymerizationSuccessRate) ;
item.zhonghuaPolymerizationSuccessRate=this.formatPercentage(item.zhonghuaPolymerizationSuccessRate) ;
item.zdPolymerizationSuccessRate=this.formatPercentage(item.zdPolymerizationSuccessRate) ;
item.polymerizationSuccessRate=this.formatPercentage(item.polymerizationSuccessRate) ;
item.threeMinutesReceivingRate=this.formatPercentage(item.threeMinutesReceivingRate) ;
item.fortyMinutesArrivalRate=this.formatPercentage(item.fortyMinutesArrivalRate) ;
item.customerSatisfaction=this.formatPercentage(item.customerSatisfaction) ;
item.trailFortyMinutesArrivalRate=this.formatPercentage(item.trailFortyMinutesArrivalRate) ;
item.minorFortyMinutesArrivalRate=this.formatPercentage(item.minorFortyMinutesArrivalRate) ;
let formatVal = dayjs(item.statisticsDate).format('DD');
let formatVal1 = dayjs(item.statisticsDate).format('M');
return {...item, date: formatVal, month: (formatVal1 == this.current) ? '本月' : (formatVal1 + '月')};
});
this.loading = false
this.detailList?.map(item => {
this.xAxisArr.push(item.month)
})
this.xAxisArr[this.xAxisArr.length - 1] = '本月'
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,
supplierId: this.supplierId,
driverId: this.driverId,
driverName:this.driverName,
pageNum: this.pageNum,
pageSize: this.pageSize
})
// this.detailList = res.data
this.total = res.total
this.detailList = res.data?.map(item => {
item.refuseOrderRate=this.formatPercentage(item.refuseOrderRate) ;
item.timeoutOrderRate=this.formatPercentage(item.timeoutOrderRate) ;
item.cancelRate=this.formatPercentage(item.cancelRate) ;
// item.urgeRate=this.formatPercentage(item.urgeRate) ;
item.complainOrderRate=this.formatPercentage(item.complainOrderRate) ;
item.customerEvaluateRate=this.formatPercentage(item.customerEvaluateRate) ;
item.appRate=this.formatPercentage(item.appRate) ;
item.threeMinutesContactRate=this.formatPercentage(item.threeMinutesContactRate) ;
item.pinganPolymerizationSuccessRate=this.formatPercentage(item.pinganPolymerizationSuccessRate) ;
item.zhonghuaPolymerizationSuccessRate=this.formatPercentage(item.zhonghuaPolymerizationSuccessRate) ;
item.zdPolymerizationSuccessRate=this.formatPercentage(item.zdPolymerizationSuccessRate) ;
item.polymerizationSuccessRate=this.formatPercentage(item.polymerizationSuccessRate) ;
item.threeMinutesReceivingRate=this.formatPercentage(item.threeMinutesReceivingRate) ;
item.fortyMinutesArrivalRate=this.formatPercentage(item.fortyMinutesArrivalRate) ;
item.customerSatisfaction=this.formatPercentage(item.customerSatisfaction) ;
let formatVal = dayjs(item.statisticsDate).format('DD');
return {...item, date: formatVal};
});
console.log("this.detailList",this.detailList)
this.loading = false;
if(this.active===4 && !this.driverName){
this.detailList=[]
this.total=0
}
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,
supplierId:this.supplierId
});
this.total = result.total
this.detailList = result.data?.map(item => {
let formatVal =item.createTime ? 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: 'complainCreateTime'},
{label: '投诉类型', prop: 'complainTypeString'},
]
} else if (this.active === 8) {//不使用App案件明细
this.labelList = [
{label: '案件编号', prop: 'orderCode'},
{label: '服务内容', prop: 'serviceName'},
{label: '接单师傅手机号', prop: 'driverPhone'},
{label: '工单创建时间', prop: 'orderCreateTime'},
{label: '事发地', prop: 'vehiclePointAddress'},
]
} else if (this.active === 9) {//车辆在线情况
this.labelList = [
{label: '日期', prop: 'date'},
{label: '0点在线车辆数量', prop: 'zeroClockVehicleCount'},
{label: '8点在线车辆数量', prop: 'eightClockVehicleCount'},
{label: '12点在线车辆数量', prop: 'twelveClockVehicleCount'},
{label: '16点在线车辆数量', prop: 'sixteenClockVehicleCount'},
{label: '20点在线车辆数量', prop: 'twentyClockVehicleCount'},
{label: '22点在线车辆数量', prop: 'twentyTwoClockVehicleCount'},
]
}
}
} finally {
this.loading = false
}
},
formatPercentage(value) {
let result = value * 100;
if (Number.isInteger(result)) {
return result.toString() + '%';
} else {
return result.toFixed(2) + '%';
}
},
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)
},
// 获取当月天数
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() {
this.etlDetailList=[]
this.etlLabelList=[]
if (this.active === 1) {
const columnObj = {} //创建标题数组中第一个对象
columnObj.label = 'KPI' //第一个标题名称
columnObj.prop = 'month' //第一个标题名称对应的字段
this.etlLabelList.push(columnObj)
if (this.activeIndex === 0) {//接单指标
this.etlDetailList=[{ 'month': '派遣量' },{ 'month': '承接量' },{ 'month': '完成量' },
{ 'month': '拒单量' },{ 'month': '拒单率(%)' },{ 'month': '超时接单量' },{ 'month': '超时率(%)' },{ 'month': '客户取消率(%)' }]
let props = 'prop' //自定义字段名称
this.detailList?.map((item,index) => {
this.v1.push(item.dispatchOrderCount)
this.v2.push(item.refuseOrderRate.replace('%', ''))
this.v3.push(item.timeoutOrderRate.replace('%', ''))
this.v4.push(item.cancelRate.replace('%', ''))
const columnObj = {}
columnObj.label = item.month // 每一列的标题的名称
columnObj.prop = props + index //自定义每一列标题字段名称
this.etlLabelList.push(columnObj)
let mappings = [ 'dispatchOrderCount', 'receiveOrderCount', 'finishOrderCount','refuseOrderCount',
'refuseOrderRate', 'timeoutOrderCount', 'timeoutOrderRate','cancelRate' ];
for (let i = 0; i < mappings.length; i++) {
this.$set(this.etlDetailList[i], columnObj.prop, item[mappings[i]]);
}
})
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.etlDetailList=[{ 'month': '投诉量' },{ 'month': '投诉率(%)' },{ 'month': '客户满意度(%)' }, { 'month': '客户评价率(%)' }]
let props = 'prop' //自定义字段名称
this.detailList?.map((item,index) => {
this.v1.push(item.customerEvaluateRate.replace('%', ''))
this.v2.push(item.customerSatisfaction.replace('%', ''))
this.v3.push(item.complainOrderRate.replace('%', ''))
const columnObj = {}
columnObj.label = item.month // 每一列的标题的名称
columnObj.prop = props + index //自定义每一列标题字段名称
this.etlLabelList.push(columnObj)
let mappings = [ 'complainOrderCount', 'complainOrderRate', 'customerSatisfaction','customerEvaluateRate' ];
for (let i = 0; i < mappings.length; i++) {
this.$set(this.etlDetailList[i], columnObj.prop, item[mappings[i]]);
}
})
this.labelList = [
{label: '月', prop: 'month'},
{label: '投诉量', prop: 'complainOrderCount'},
{label: '投诉率(%)', prop: 'complainOrderRate'},
{label: '客户满意度(%)', prop: 'customerSatisfaction'},
{label: '客户评价率(%)', prop: 'customerEvaluateRate'},
]
} else if (this.activeIndex === 2) {
this.etlDetailList=[{ 'month': '使用率(%)' },{ 'month': '3联系客户率(%)' },{ 'month': '平安聚合成功率(%)' }, { 'month': '中华聚合成功率(%)' }
,{ 'month': '中道聚合成功率(%' }, { 'month': '总聚合成功率(%)' }]
let props = 'prop' //自定义字段名称
this.detailList?.map((item,index) => {
this.v1.push(item.appRate.replace('%', ''))
this.v2.push(item.threeMinutesContactRate.replace('%', ''))
this.v3.push(item.pinganPolymerizationSuccessRate.replace('%', ''))
this.v4.push(item.zhonghuaPolymerizationSuccessRate.replace('%', ''))
this.v5.push(item.zdPolymerizationSuccessRate.replace('%', ''))
this.v6.push(item.polymerizationSuccessRate.replace('%', ''))
const columnObj = {}
columnObj.label = item.month // 每一列的标题的名称
columnObj.prop = props + index //自定义每一列标题字段名称
this.etlLabelList.push(columnObj)
let mappings = [ 'appRate', 'threeMinutesContactRate', 'pinganPolymerizationSuccessRate','zhonghuaPolymerizationSuccessRate','zdPolymerizationSuccessRate','polymerizationSuccessRate' ];
for (let i = 0; i < mappings.length; i++) {
this.$set(this.etlDetailList[i], columnObj.prop, item[mappings[i]]);
}
})
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) {
this.etlDetailList=[{ 'month': '接单时效(分)' },{ 'month': '3接单率(%)' },{ 'month': '到达时效(分)' }, { 'month': '40到达率(%)' },{'month':'聚合成功到达时效(分)'}]
let props = 'prop' //自定义字段名称
if (this.isMobile) {
if (this.value == 1) {
this.detailList?.map(item => {
this.v1.push(item.receiving)
this.v2.push(item.threeMinutesReceivingRate.replace('%', ''))
})
} else {
this.detailList?.map(item => {
this.v1.push(item.arriving)
this.v2.push(item.polymerizationSuccessArriving)
this.v3.push(item.fortyMinutesArrivalRate.replace('%', ''))
})
}
this.detailList?.map((item,index) => {
const columnObj = {}
columnObj.label = item.month // 每一列的标题的名称
columnObj.prop = props + index //自定义每一列标题字段名称
this.etlLabelList.push(columnObj)
let mappings = [ 'receiving', 'threeMinutesReceivingRate', 'arriving','fortyMinutesArrivalRate','polymerizationSuccessArriving'];
for (let i = 0; i < mappings.length; i++) {
this.$set(this.etlDetailList[i], columnObj.prop, item[mappings[i]]);
}
})
} else {
this.detailList?.map(item => {
this.v1.push(item.receiving)
this.v2.push(item.threeMinutesReceivingRate.replace('%', ''))
})
if (this.swithVal) {
this.detailList?.map(item => {
this.v3.push(item.trailArriving)
this.v4.push(item.trailPolymerizationSuccessArsriving)
this.v5.push(item.trailFortyMinutesArrivalRate ? item.trailFortyMinutesArrivalRate.replace('%', '') : item.trailFortyMinutesArrivalRate)
})
} else {
this.detailList?.map(item => {
this.v3.push(item.minorArriving)
this.v4.push(item.minorPolymerizationSuccessArriving)
this.v5.push(item.minorFortyMinutesArrivalRate ? item.minorFortyMinutesArrivalRate.replace('%', '') : 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: 'score'},
{label: '案件总量', prop: 'orderCount'},
{label: '累计得分', prop: 'cumulativeScore'},
{label: '两分钟内接单得分', prop: 'twoMinutesAcceptScore'},
{label: '1分钟内联系客户得分', prop: 'oneMinutesContactCustomerScore'},
{label: '联系成功得分', prop: 'contactSuccessScore'},
{label: '准时到达B点得分', prop: 'arriveBScore'},
{label: '准时到达C点得分', prop: 'arriveCScore'},
{label: '服务成功得分', prop: 'serviceSuccessScore'},
{label: '必传照片上传得分', prop: 'uploadPhotoScore'},
{label: '审核一次通过得分', prop: 'auditScore'},
{label: '平安案件无评价扣分', prop: 'pinganNoCommentDeduct'},
{label: '案件差评扣分', prop: 'orderNegativeDeduct'},
{label: '催促扣分', prop: 'urgeDeduct'},
{label: '有责车损扣分', prop: 'responsibleDeduct'},
{label: '有责投诉(非态度类)扣分', prop: 'complaintNoAttitudeDeduct'},
{label: '有责投诉(态度类)扣分', prop: 'complaintAttitudeDeduct'},
{label: '拒单扣分', prop: 'rejectDeduct'},
{label: '超时扣分', prop: 'timeoutDeduct'},
{label: '聚合成功得分', prop: 'polymerizationSuccessScore'},
{label: '聚合失败扣分', prop: 'polymerizationFailDeduct'},
{label: '每月培训得分', prop: 'trainingScore'},
{label: '新手入列得分', prop: 'listedScore'},
{label: '星级评分', prop: 'starRank'},
]
}if (this.activeIndex === 1) {
this.labelList = [
{label: '师傅姓名', prop: 'driverName'},
{label: '承接案件量', prop: 'receiveOrderCount'},
{label: '拒单量', prop: 'refuseOrderCount'},
{label: '拒单率(%)', prop: 'refuseOrderRate'},
{label: '超时接单量', prop: 'timeoutOrderCount'},
{label: '超时率(%)', prop: 'timeoutOrderRate'},
]
} else if (this.activeIndex === 2) {
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 === 3) {
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: '日均在线时长(h)', prop: 'onlineDuration'},
]
} else if (this.activeIndex === 4) {
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: 'driverName'},
{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: 'driverName'},
{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: 'driverName'},
{label: '使用率(%)', prop: 'appRate'},
{label: '3联系客户率(%)', prop: 'threeMinutesContactRate'},
{label: '平安聚合成功率(%)', prop: 'pinganPolymerizationSuccessRate'},
{label: '中华聚合成功率(%)', prop: 'zhonghuaPolymerizationSuccessRate'},
{label: '中道聚合成功率(%)', prop: 'zdPolymerizationSuccessRate'},
{label: '总聚合成功率(%)', prop: 'polymerizationSuccessRate'},
{label: '日均在线时长(h)', prop: 'onlineDuration'},
]
} else if (this.activeIndex === 3) {
this.labelList = [
{label: '日', prop: 'date'},
{label: '师傅姓名', prop: 'driverName'},
{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;
font-size: 12px;
}
::v-deep .el-input__inner {
border-radius: 0px 20px 20px 0px;
}
::v-deep .el-input__suffix {
top: 4px; /* 给清除按钮预留空间 */
}
}
}
::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);
border-bottom: none;
}
::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;;
}
::v-deep .el-pagination .el-select .el-input{
width: 80px;
margin:0
}
.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;
.scoreTitle{
@include flexBetCen;
i{
cursor: pointer;
font-size: 14px;
}
}
.storeWrap {
width: 100%;
text-align: center;
.detailScore{
display: flex;
justify-content:center;
}
/* .defen{
display: inline-block;
//width: 92px;
//text-align: right;
}*/
.left{
text-align: right;
padding-right: 5px;
}
.right{
display: flex;
justify-content: space-between;
flex-direction: column;
text-align: left;
}
}
.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;
}
}
.allDataChartWrap{
width: 375px;
height: 220px;
}
.allDataChart{
width: 100%;
height: 100%;
}
.webComAllData{
width: 400px;
height: 255px;
float: left;
margin: 10px;
}
.webCom {
@include whBg(420px, 200px, #FFFFFF);
float: left;
margin: 10px;
.webTitle {
margin-bottom: 40px !important;
}
}
}
.webcontentWrap {
@include wh(100%, calc(100% - 86px));
}
.tipArrow{
position: absolute;
top: 10px;
color: #FFFFFF;
font-size: 12px;
}
.left{
left: 0;
}
.right{
right: 0px;
}
.tabWrap {
@include wh(100%, 22px);
@include flexColAround;
margin: 10px 0;
div {
cursor: pointer;
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;
}
}
.webTabWrap {
width: 40% !important;
.active:after {
margin-top: 4px;
}
}
.monthTotal {
background: #FFFFFF;
padding-left: 6px;
.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; /* 当内容超出宽度时启用水平滚动 */
}
}
.searchDriverName{
width: 97%;
display: flex;
align-items: center;
span{
width: 20%;
}
::v-deep .el-input{
font-size: 12px;
}
::v-deep .el-input__inner{
height: 30px;
}
::v-deep .el-input__suffix {
top: 4px; /* 给清除按钮预留空间 */
}
}
.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>