qb 4 months ago
parent
commit
bad4fd69b0
  1. 12
      src/api/wel/index.js
  2. 1
      src/views/aftersales/aftersalesWorkOrder.vue
  3. 12
      src/views/aftersales/aftersalesWorkOrderInfo.vue
  4. 491
      src/views/desk/DataBoard.vue

12
src/api/wel/index.js

@ -168,3 +168,15 @@ export const postSignforData = data => {
data,
});
};
/**
* 异常数据
* @param {Object} data
* @returns
*/
export const $_aftersalesData = params => {
return request({
url: '/api/logpm-report/warehouseIndex/aftersalesData',
method: 'get',
params,
});
};

1
src/views/aftersales/aftersalesWorkOrder.vue

@ -2848,6 +2848,7 @@ const exportReport = () => {
ids: details.selectionList.length
? details.selectionList.map(item => item.id).join(',')
: undefined,
...details.query,
};
switch (TabPermissions.value) {

12
src/views/aftersales/aftersalesWorkOrderInfo.vue

@ -1186,6 +1186,13 @@ const Completionpermissions = computed(() => {
}
return false;
});
const processedText=(inputtxt)=>{
if (inputtxt.endsWith('\n') && !inputtxt.endsWith('\n ')) {
return inputtxt.slice(0, -1);
}
return inputtxt;
}
const onLoad = async () => {
pageState.value = true; //
if (await localStorage.getItem('my_data')) {
@ -1271,12 +1278,12 @@ const onLoad = async () => {
// res.data.data.personResponsibleVOS.forEach(item => {
// sum = Number(item.responsibilityRatio) + sum;
// });
FangAddList.value = res.data.data.personResponsibleVOS.map(res => {
FangAddList.value = res.data.data.personResponsibleVOS.map(res => {
return {
businessName: res.businessId, //ID
personResponsibleName: res.personResponsibleName, //
responsibilityRatio: res.responsibilityRatio, //
description: res.description, //
description: processedText(res.description), //
tripartite: res.tripartite, //
};
});
@ -1390,6 +1397,7 @@ const onLoad = async () => {
Paymentmethod.value = res.data.data;
});
};
onMounted(() => {
watch(
() => $route.path, //

491
src/views/desk/DataBoard.vue

@ -772,14 +772,14 @@
<div class="align_center">
<div
:class="{ button: true, active: abnormal_status === 'day' }"
@click="() => (abnormal_status = 'day')"
:class="{ button: true, active: abnormal_status === 'dayData' }"
@click="() => (abnormal_status = 'dayData')"
>
当天
</div>
<div
:class="{ button: true, active: abnormal_status === 'month' }"
@click="() => (abnormal_status = 'month')"
:class="{ button: true, active: abnormal_status === 'monthData' }"
@click="() => (abnormal_status = 'monthData')"
>
当月
</div>
@ -793,7 +793,17 @@
<span>发起数</span>
</div>
<div class="mt10">
<span class="data mr5px">{{ abnormal_Info.sendNum }}</span>
<span
class="data mr5px underline"
@click="
() =>
handleShowAbnormalData('异常数据', abnormal_status, {
tip: '发起数',
prop: 'totalNum',
})
"
>{{ abnormal_Info.sendNum }}</span
>
<span class=""></span>
</div>
</div>
@ -804,18 +814,38 @@
<span>待处理</span>
</div>
<div class="mt10">
<span class="data mr5px">{{ abnormal_Info.noDealNum }}</span>
<span
class="data mr5px underline"
@click="
() =>
handleShowAbnormalData('异常数据', abnormal_status, {
tip: '待处理',
prop: 'unCompleteNum',
})
"
>{{ abnormal_Info.noDealNum }}</span
>
<span class=""></span>
</div>
</div>
<div class="abnormal_item red">
<div class="align_center">
<img class="dataIcon mr5px" src="@/static/icon_money_day.png" alt="" />
<span>异常率</span>
<img class="dataIcon mr5px " src="@/static/icon_money_day.png" alt="" />
<span>处理</span>
</div>
<div class="mt10">
<span class="data mr5px">{{ abnormal_Info.abnormalRate }}</span>
<span
class="data mr5px underline"
@click="
() =>
handleShowAbnormalData('异常数据-异常率-%', abnormal_status, {
tip: '处理率',
prop: 'processingRate',
},'bar')
"
>{{ abnormal_Info.abnormalRate }}</span
>
<span class="">%</span>
</div>
</div>
@ -1034,14 +1064,14 @@
</div>
</div>
<div class="text_center">
<div class="text_center" v-if="signforData_status !== 'daySignData'">
<div
class="data_box blue mb10"
@click="
handleShowSignDetail('签收数据 - 签收率 - %', signforData_status, {
tip: '签收率',
prop: 'signScale',
})
},'bar')
"
>
<div class="data mr5px underline">
@ -1076,8 +1106,8 @@
<div
class="data_box purple mb10"
@click="
handleShowSignDetail('签收数据 - 文员签收率 - %', signforData_status, {
tip: '文员签收',
handleShowSignDetail('签收数据 - 文员签收数 - 件', signforData_status, {
tip: '文员签收',
prop: 'clerkSignforScale',
})
"
@ -1085,10 +1115,10 @@
<div class="data mr5px underline">
{{ signforData.clerkSignforScale || 0 }}
</div>
<div class="">%</div>
<div class=""></div>
</div>
<div class="">
<span>文员签收</span>
<span>文员签收</span>
</div>
</div>
@ -1119,7 +1149,7 @@
handleShowSignDetail('签收数据 - 签收超时率 - %', signforData_status, {
tip: '签收超时率',
prop: 'clerkOverTimeScale',
})
},'bar')
"
>
<div class="data mr5px">
@ -1317,14 +1347,14 @@
</div>
</div>
<div class="text_center">
<div class="text_center" v-if="billSignforData_status !== 'dayBillLadingSignData'">
<div
class="data_box blue mb10"
@click="
handleShowSignDetail('自提签收数据 - 签收率 - %', billSignforData_status, {
tip: '签收率',
prop: 'signScale',
})
},'bar')
"
>
<div class="data mr5px underline">
@ -1359,7 +1389,7 @@
<div
class="data_box purple mb10"
@click="
handleShowSignDetail('自提签收数据 - 文员签收率 - %', billSignforData_status, {
handleShowSignDetail('自提签收数据 - 文员签收数 - 件', billSignforData_status, {
tip: '文员签收率',
prop: 'clerkSignforScale',
})
@ -1368,10 +1398,10 @@
<div class="data mr5px underline">
{{ billSignforData.clerkSignforScale ? billSignforData.clerkSignforScale : 0 }}
</div>
<div class="">%</div>
<div class=""></div>
</div>
<div class="">
<span>文员签收</span>
<span>文员签收</span>
</div>
</div>
@ -1402,7 +1432,7 @@
handleShowSignDetail('自提签收数据 - 超时签收任务 - %', billSignforData_status, {
tip: '超时签收任务',
prop: 'clerkOverTimeScale',
})
},'bar')
"
>
<div class="data mr5px underline">
@ -1492,6 +1522,7 @@ import {
postAllocationDataByWarehouseId,
postHandOrderDataByWarehouseId,
postTrunklineCarsDataByWarehouseId,
$_aftersalesData,
} from '@/api/wel/index';
import { exportExcelByDom } from '@/utils/export';
import * as echarts from 'echarts';
@ -1569,14 +1600,28 @@ const details = reactive({
},
/** 异常卸车数据 */
unloadAbnormalDataInfo: {
abnormalDayRate: '0',
abnormalMonthRate: '0',
noDealDayNum: 0,
noDealMonthNum: 0,
sendDayNum: 0,
sendMonthNum: 0,
unloadDayNum: 0,
unloadMonthNum: 0,
dayData: {
abnormalDayRate: 0,
abnormalMonthRate: 0,
noDealDayNum: 0,
noDealMonthNum: 0,
sendDayNum: 0,
sendMonthNum: 0,
unloadDayNum: 0,
unloadMonthNum: 0,
data: [],
},
monthData: {
abnormalDayRate: 0,
abnormalMonthRate: 0,
noDealDayNum: 0,
noDealMonthNum: 0,
sendDayNum: 0,
sendMonthNum: 0,
unloadDayNum: 0,
unloadMonthNum: 0,
data: [],
},
},
/** 配送数据 */
deliveryDataInfo: {},
@ -1657,7 +1702,7 @@ const delivery_status = ref<
>('tradeMatching');
/** 异常数据状态 */
const abnormal_status = ref<'day' | 'month'>('day');
const abnormal_status = ref<'dayData' | 'monthData'>('dayData');
/** 签收数据状态 */
const signforData_status = ref<'daySignData' | 'monthSignData'>('daySignData');
@ -1756,15 +1801,51 @@ const initTrunklineCarsData = async () => {
details.loadingObj.trunklineCarsData = false;
}
};
function accumulateData(targetInfo, dataArray, isMonthly) {
console.log('targetInfo :>> ', targetInfo);
for (let i = 0; i < dataArray.length; i++) {
const item = dataArray[i];
if (isMonthly) {
targetInfo.sendMonthNum += item.totalNum; //
targetInfo.noDealMonthNum += item.unCompleteNum; //
targetInfo.abnormalMonthRate += item.completeNum; //
} else {
targetInfo.sendDayNum += item.totalNum; //
targetInfo.noDealDayNum += item.unCompleteNum; //
targetInfo.abnormalDayRate += item.completeNum; //
}
}
}
/** 卸车异常数据 */
/**异常数据 */
const initUnloadAbnormalData = async () => {
try {
details.loadingObj.unloadAbnormalData = true;
const res = await postUnloadAbnormalData({});
const res = await $_aftersalesData({});
console.log('resw:>> ', res);
const { code, data } = res.data;
if (code !== 200) return;
details.unloadAbnormalDataInfo = data || {};
console.log(data, '异常数据');
details.unloadAbnormalDataInfo.dayData.data = data.dayData;
details.unloadAbnormalDataInfo.monthData.data = data.monthData;
// dayData
await accumulateData(details.unloadAbnormalDataInfo.dayData, data.dayData, false);
// monthData
await accumulateData(details.unloadAbnormalDataInfo.monthData, data.monthData, true);
//
details.unloadAbnormalDataInfo.dayData.abnormalMonthRate =
(details.unloadAbnormalDataInfo.dayData.abnormalMonthRate /
details.unloadAbnormalDataInfo.dayData.sendMonthNum) *
100 || 0;
details.unloadAbnormalDataInfo.monthData.abnormalDayRate =
(details.unloadAbnormalDataInfo.monthData.abnormalDayRate /
details.unloadAbnormalDataInfo.monthData.sendDayNum) *
100 || 0;
// details.unloadAbnormalDataInfo.dayData.data[0].noDealNum=10
// details.unloadAbnormalDataInfo.dayData.data[2].noDealNum=15
} catch (error) {
console.log('error :>> ', error);
} finally {
@ -2043,16 +2124,16 @@ handleRefresh();
/** 异常数据 */
const abnormal_Info = computed(() => {
const _obj =
abnormal_status.value === 'day'
abnormal_status.value === 'dayData'
? {
sendNum: details.unloadAbnormalDataInfo.sendDayNum,
noDealNum: details.unloadAbnormalDataInfo.noDealDayNum,
abnormalRate: details.unloadAbnormalDataInfo.abnormalDayRate,
sendNum: details.unloadAbnormalDataInfo.dayData.sendDayNum,
noDealNum: details.unloadAbnormalDataInfo.dayData.noDealDayNum,
abnormalRate: details.unloadAbnormalDataInfo.dayData.abnormalDayRate,
}
: {
sendNum: details.unloadAbnormalDataInfo.sendMonthNum,
noDealNum: details.unloadAbnormalDataInfo.noDealMonthNum,
abnormalRate: details.unloadAbnormalDataInfo.abnormalMonthRate,
sendNum: details.unloadAbnormalDataInfo.monthData.sendMonthNum,
noDealNum: details.unloadAbnormalDataInfo.monthData.noDealMonthNum,
abnormalRate: details.unloadAbnormalDataInfo.monthData.abnormalMonthRate,
};
return _obj;
@ -2075,6 +2156,7 @@ const delivery_bill_info = computed(() => {
/** 签收数据 */
const signforData = computed<any>(() => {
const _obj: any = details.signforDataInfo[signforData_status.value] || {};
console.log('_obj :>> ', _obj);
_obj.signScaleNum ? _obj.signScaleNum : (_obj.signScaleNum = _obj.signScale || 0);
_obj.clerkSignforScaleNum
@ -2120,109 +2202,275 @@ const billSignforData = computed<any>(() => {
type OptionObjType = { prop: string; tip: string };
//
const colors = ['#008CBA', '#808080']; //
// /** */
// const getProportion = (value: number, total: number) => {
// if (total === 0) return '0%';
// if (!isNumber(value)) return '0%';
// return computeNumber(Number(value), '/', total).next('*', 100).result.toFixed(2) + '%';
// };
/** 获取百分比 */
const getProportion = (value: number, total: number) => {
if (total === 0) return '0%';
const getProportion = (value: number) => {
if (!isNumber(value)) return '0%';
return computeNumber(Number(value), '/', total).next('*', 100).result.toFixed(2) + '%';
return (value * 100).toFixed(2) + '%';
};
/** 显示图表 */
const handleShowEcharts = (data: any[], title: string, optionObj: OptionObjType) => {
if (getObjType(data) !== 'array') return;
const _arr = [];
let _total = 0;
// /** */
// const handleShowEcharts = (data: any[], title: string, optionObj: OptionObjType) => {
// console.log('data :>> ', data);
// console.log('title :>> ', title);
// console.log('optionObj :>> ', optionObj);
// if (getObjType(data) !== 'array') return;
// const _arr = [];
// let _total = 0;
// for (let i = 0; i < data.length; i++) {
// const value = data[i];
// value[optionObj.prop] = isNumber(value[optionObj.prop]) ? Number(value[optionObj.prop]) : 0;
// _total = computeNumber(_total, '+', value[optionObj.prop]).result;
// }
// for (let i = 0; i < data.length; i++) {
// const value = data[i];
// let isContinue = false;
// for (let j = 0; j < _arr.length; j++) {
// const item = _arr[j];
// if (item.value > value[optionObj.prop]) continue;
// _arr.splice(j, 0, {
// name: value.warehouseName + ' - ' + getProportion(value[optionObj.prop], _total),
// value: value[optionObj.prop],
// });
// isContinue = true;
// break;
// }
// if (isContinue) continue;
// _arr.push({
// name: value.warehouseName + ' - ' + getProportion(value[optionObj.prop], _total),
// value: value[optionObj.prop],
// });
// }
// nextTick(() => {
// // Echarts
// const chartDom = document.getElementById('echartBox');
// const myChart = echarts.init(chartDom);
// const option = {
// title: {
// text: title,
// // subtext: 'Fake Data',
// left: 'right',
// },
// tooltip: {
// trigger: 'item',
// },
// legend: {
// orient: 'vertical',
// left: 'left',
// },
// series: [
// {
// name: optionObj.tip,
// // --
// type: 'bar',
// // radius: '50%',
// //
// data: _arr,
// //
// emphasis: {
// itemStyle: {
// shadowBlur: 10,
// shadowOffsetX: 0,
// shadowColor: 'rgba(0, 0, 0, 0.5)',
// },
// label: {
// show: true,
// fontSize: 20,
// fontWeight: 'bold',
// },
// },
// //
// radius: ['30%', '70%'],
// // avoidLabelOverlap: false,
// //
// // padAngle: 2,
// //
// // minShowLabelAngle: 5,
// //
// left: '20%',
// },
// ],
// };
// option && myChart.setOption(option);
// });
// };
//
const handleShowEcharts = (data: any[], title: string, optionObj: OptionObjType, chartType: string = 'pie') => {
console.log('data :>> ', data);
console.log('title :>> ', title);
console.log('optionObj :>> ', optionObj);
if (getObjType(data) !== 'array') return; //
const _arr = []; //
let _total = 0; //
//
for (let i = 0; i < data.length; i++) {
const value = data[i];
value[optionObj.prop] = isNumber(value[optionObj.prop]) ? Number(value[optionObj.prop]) : 0;
_total = computeNumber(_total, '+', value[optionObj.prop]).result;
const value = data[i]; //
value[optionObj.prop] = isNumber(value[optionObj.prop]) ? Number(value[optionObj.prop]) : 0; // 0
_total = computeNumber(_total, '+', value[optionObj.prop]).result; //
}
//
for (let i = 0; i < data.length; i++) {
const value = data[i];
let isContinue = false;
const value = data[i]; //
let isContinue = false; //
// _arr
for (let j = 0; j < _arr.length; j++) {
const item = _arr[j];
if (item.value > value[optionObj.prop]) continue;
const item = _arr[j]; // _arr
if (item.value > value[optionObj.prop]) continue; // _arr
_arr.splice(j, 0, {
name: value.warehouseName + ' - ' + getProportion(value[optionObj.prop], _total),
value: value[optionObj.prop],
_arr.splice(j, 0, { //
name: value.warehouseName, //
value: value[optionObj.prop], //
});
isContinue = true;
break;
isContinue = true; // true
break; //
}
if (isContinue) continue;
if (isContinue) continue; //
_arr.push({
name: value.warehouseName + ' - ' + getProportion(value[optionObj.prop], _total),
value: value[optionObj.prop],
_arr.push({ //
name: value.warehouseName, //
value: value[optionObj.prop], //
});
}
nextTick(() => {
// Echarts
nextTick(() => { // DOM
//
const chartDom = document.getElementById('echartBox');
const myChart = echarts.init(chartDom);
if (!chartDom) return; //
const myChart = echarts.init(chartDom); // ECharts
const option = {
title: {
text: title,
// subtext: 'Fake Data',
left: 'right',
text: title, //
left: 'right', //
},
tooltip: {
trigger: 'item',
trigger: 'item', //
formatter: (params) => {
if (chartType === 'pie') {
return `${params.name}: ${params.value} (${params.percent}%)`; //
} else {
return `${params.name}: ${getProportion(params.value)}`; //
}
},
},
legend: {
orient: 'vertical',
left: 'left',
orient: 'vertical', //
left: 'left', //
},
series: [
{
name: optionObj.tip,
// --
type: 'pie',
// radius: '50%',
//
data: _arr,
//
emphasis: {
...(chartType === 'bar' && { //
xAxis: {
type: 'category', // x
data: _arr.map(item => item.name), // x
axisLabel: {
interval: 0, //
rotate: 45, //
},
},
yAxis: {
type: 'value', // y
axisLabel: {
formatter: (value) => {
return getProportion(value); // y
}
},
},
series: [
{
name: optionObj.tip, //
type: 'bar', //
data: _arr.map(item => ({ //
name: item.name, //
value: item.value, //
})),
itemStyle: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)',
color: (params) => {
//
return colors[params.dataIndex % 2];
}
},
label: {
show: true,
fontSize: 20,
fontWeight: 'bold',
emphasis: {
itemStyle: {
shadowBlur: 10, //
shadowOffsetX: 0, //
shadowColor: 'rgba(0, 0, 0, 0.5)', //
},
label: {
show: true, //
fontSize: 20, //
fontWeight: 'bold', //
formatter: (params) => {
return getProportion(params.value); //
}
},
},
barGap: '30%', //
barWidth: '40%', //
left: '20%', //
},
//
radius: ['30%', '70%'],
// avoidLabelOverlap: false,
//
// padAngle: 2,
//
// minShowLabelAngle: 5,
//
left: '20%',
},
],
],
}),
...(chartType === 'pie' && { //
series: [
{
name: optionObj.tip, //
type: 'pie', //
data: _arr.map((item) => ({ //
name: item.name + ' - ' + getProportion(item.value / _total), //
value: item.value, //
})),
emphasis: {
itemStyle: {
shadowBlur: 10, //
shadowOffsetX: 0, //
shadowColor: 'rgba(0, 0, 0, 0.5)', //
},
label: {
show: true, //
fontSize: 20, //
fontWeight: 'bold', //
},
},
radius: ['30%', '70%'], //
left: '20%', //
},
],
}),
};
option && myChart.setOption(option);
option && myChart.setOption(option); // option
});
};
/** 请求详情 */
const handleDetails = async (type, title, optionObj: OptionObjType) => {
details.popUpShow.isShow = true;
@ -2251,7 +2499,6 @@ const handleDetails = async (type, title, optionObj: OptionObjType) => {
case 'trunklineCarsDataColumn':
res = await postTrunklineCarsDataByWarehouseId({});
break;
default:
break;
}
@ -2286,15 +2533,33 @@ const handleShowDeliveryDetail = (
handleShowEcharts(data, title, optionObj);
};
/** 显示售后异常数据 */
const handleShowAbnormalData = (title, type: 'dayData' | 'monthData', optionObj: any = {},chartType) => {
details.popUpShow.isShow = true;
details.title = title;
console.log(optionObj, 'optionObj');
console.log(type, 'type');
console.log(title, 'title');
if (getObjType(details.unloadAbnormalDataInfo[type]) !== 'object') return;
const { data } = details.unloadAbnormalDataInfo[type];
handleShowEcharts(data, title, optionObj,chartType);
};
/** 显示签收详情 */
const handleShowSignDetail = (
title,
type: 'daySignData' | 'monthSignData' | 'dayBillLadingSignData' | 'monthBillLadingSignData',
optionObj: any = {}
optionObj: any = {},
chartType
) => {
details.popUpShow.isShow = true;
details.title = title;
console.log(type, 'typeaaa');
console.log(title, 'titleaaa');
console.log(optionObj, 'optionObjaaa');
console.log(details.signforDataInfo[type], 'details.signforDataInfo[type]');
if (getObjType(details.signforDataInfo[type]) !== 'object') return;
@ -2302,7 +2567,7 @@ const handleShowSignDetail = (
console.log('data :>> ', data);
handleShowEcharts(data, title, optionObj);
handleShowEcharts(data, title, optionObj,chartType);
};
/** 导出 */

Loading…
Cancel
Save