|
|
|
@ -0,0 +1,439 @@
|
|
|
|
|
<template>
|
|
|
|
|
<div class="JNPF-common-layout">
|
|
|
|
|
<div class="JNPF-common-layout-center">
|
|
|
|
|
<el-row class="JNPF-common-search-box" :gutter="16">
|
|
|
|
|
<el-form @submit.native.prevent>
|
|
|
|
|
<el-col :span="6">
|
|
|
|
|
<el-form-item label="*商户">
|
|
|
|
|
<el-select v-model="query.companyId" placeholder="请选择要查询的商户" @change="handleSelectChange">
|
|
|
|
|
<el-option v-for="item in companyOptions" :key="item.id" :label="item.enterpriseName" :value="item.id">
|
|
|
|
|
</el-option>
|
|
|
|
|
</el-select>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</el-col>
|
|
|
|
|
<el-col :span="6">
|
|
|
|
|
<el-form-item label="创建日期">
|
|
|
|
|
<el-date-picker v-model="dateRange" type="daterange" align="right" unlink-panels range-separator="至"
|
|
|
|
|
start-placeholder="开始日期" end-placeholder="结束日期" :picker-options="pickerOptions">
|
|
|
|
|
</el-date-picker>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</el-col>
|
|
|
|
|
<el-col :span="6">
|
|
|
|
|
<el-form-item>
|
|
|
|
|
<el-button type="primary" icon="el-icon-search" @click="search()">查询</el-button>
|
|
|
|
|
<el-button icon="el-icon-refresh-right" @click="reset()">重置</el-button>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</el-col>
|
|
|
|
|
</el-form>
|
|
|
|
|
</el-row>
|
|
|
|
|
<div class="JNPF-common-layout-main JNPF-flex-main">
|
|
|
|
|
<el-row class="JNPF-common-search-box" :gutter="16">
|
|
|
|
|
<h2>回收订单统计</h2>
|
|
|
|
|
<div ref="chart" style="width: 800px; height: 600px;"></div>
|
|
|
|
|
</el-row>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script>
|
|
|
|
|
import request from "@/utils/request";
|
|
|
|
|
import { mapGetters } from "vuex";
|
|
|
|
|
import { getDataInterfaceRes } from "@/api/systemData/dataInterface";
|
|
|
|
|
import * as echarts from 'echarts'
|
|
|
|
|
|
|
|
|
|
export default {
|
|
|
|
|
name: 'BarChart',
|
|
|
|
|
components: {
|
|
|
|
|
},
|
|
|
|
|
data() {
|
|
|
|
|
return {
|
|
|
|
|
chart: null,
|
|
|
|
|
chartData: [],
|
|
|
|
|
dateRange: {},
|
|
|
|
|
pickerOptions: {
|
|
|
|
|
},
|
|
|
|
|
pickerOptions: {
|
|
|
|
|
shortcuts: [{
|
|
|
|
|
text: '最近一周',
|
|
|
|
|
onClick(picker) {
|
|
|
|
|
const end = new Date();
|
|
|
|
|
const start = new Date();
|
|
|
|
|
start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
|
|
|
|
|
picker.$emit('pick', [start, end]);
|
|
|
|
|
}
|
|
|
|
|
}, {
|
|
|
|
|
text: '最近一个月',
|
|
|
|
|
onClick(picker) {
|
|
|
|
|
const end = new Date();
|
|
|
|
|
const start = new Date();
|
|
|
|
|
start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
|
|
|
|
|
picker.$emit('pick', [start, end]);
|
|
|
|
|
}
|
|
|
|
|
}, {
|
|
|
|
|
text: '最近三个月',
|
|
|
|
|
onClick(picker) {
|
|
|
|
|
const end = new Date();
|
|
|
|
|
const start = new Date();
|
|
|
|
|
start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
|
|
|
|
|
picker.$emit('pick', [start, end]);
|
|
|
|
|
}
|
|
|
|
|
}]
|
|
|
|
|
},
|
|
|
|
|
keyword: "",
|
|
|
|
|
expandsTree: true,
|
|
|
|
|
refreshTree: true,
|
|
|
|
|
toFormDetailVisible: false,
|
|
|
|
|
expandObj: {},
|
|
|
|
|
columnOptions: [],
|
|
|
|
|
mergeList: [],
|
|
|
|
|
exportList: [],
|
|
|
|
|
showAll: false,
|
|
|
|
|
companyOptions: [],
|
|
|
|
|
stationOptions: [],
|
|
|
|
|
deviceOptions: [],
|
|
|
|
|
query: {
|
|
|
|
|
companyId: undefined,
|
|
|
|
|
creatStartTime: undefined,
|
|
|
|
|
creatEndTime: undefined
|
|
|
|
|
},
|
|
|
|
|
treeProps: {
|
|
|
|
|
children: "children",
|
|
|
|
|
label: "fullName",
|
|
|
|
|
value: "id",
|
|
|
|
|
isLeaf: "isLeaf"
|
|
|
|
|
},
|
|
|
|
|
list: [],
|
|
|
|
|
listLoading: true,
|
|
|
|
|
total: 0,
|
|
|
|
|
queryData: {},
|
|
|
|
|
listQuery: {
|
|
|
|
|
currentPage: 1,
|
|
|
|
|
pageSize: 20,
|
|
|
|
|
sort: "desc",
|
|
|
|
|
sidx: ""
|
|
|
|
|
},
|
|
|
|
|
flowVisible: false,
|
|
|
|
|
flowListVisible: false,
|
|
|
|
|
flowList: [],
|
|
|
|
|
adjustStatusOptions: [],
|
|
|
|
|
adjustStatusProps: { label: "fullName", value: "enCode" },
|
|
|
|
|
interfaceRes: {}
|
|
|
|
|
};
|
|
|
|
|
},
|
|
|
|
|
watch: {
|
|
|
|
|
dateRange: {
|
|
|
|
|
handler(newVal) {
|
|
|
|
|
this.query.creatStartTime = newVal[0];
|
|
|
|
|
this.query.creatEndTime = newVal[1];
|
|
|
|
|
},
|
|
|
|
|
immediate: true,
|
|
|
|
|
deep: true
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
computed: {
|
|
|
|
|
...mapGetters(["userInfo"]),
|
|
|
|
|
menuId() {
|
|
|
|
|
return this.$route.meta.modelId || "";
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
created() {
|
|
|
|
|
this.setDefaultDateRange();
|
|
|
|
|
this.fetchCompanies();
|
|
|
|
|
this.initSearchDataAndListData();
|
|
|
|
|
this.queryData = JSON.parse(JSON.stringify(this.query));
|
|
|
|
|
},
|
|
|
|
|
methods: {
|
|
|
|
|
setDefaultDateRange() {
|
|
|
|
|
const endDate = new Date();
|
|
|
|
|
const startDate = new Date(endDate);
|
|
|
|
|
startDate.setMonth(startDate.getMonth() - 1);
|
|
|
|
|
this.dateRange = [startDate, endDate];
|
|
|
|
|
},
|
|
|
|
|
initChart() {
|
|
|
|
|
const categories = this.chartData.map(item => item.stationName);
|
|
|
|
|
const seriesData = this.chartData.map(item => ({
|
|
|
|
|
price: parseFloat(item.price),
|
|
|
|
|
orderNums: parseInt(item.orderNums),
|
|
|
|
|
orderAcceptanceRate: parseFloat(item.orderAcceptanceRate.slice(0, -1)) / 100,
|
|
|
|
|
}));
|
|
|
|
|
|
|
|
|
|
const option = {
|
|
|
|
|
tooltip: {
|
|
|
|
|
trigger: 'axis',
|
|
|
|
|
axisPointer: {
|
|
|
|
|
type: 'shadow'
|
|
|
|
|
},
|
|
|
|
|
formatter: function (params) {
|
|
|
|
|
let tooltipContent = '';
|
|
|
|
|
params.forEach(function (item, index) {
|
|
|
|
|
if (index > 0) {
|
|
|
|
|
tooltipContent += '<br/>';
|
|
|
|
|
}
|
|
|
|
|
let unit = '';
|
|
|
|
|
if (item.seriesName === '下单总金额') {
|
|
|
|
|
unit = '元';
|
|
|
|
|
} else if (item.seriesName === '下单量') {
|
|
|
|
|
unit = '个';
|
|
|
|
|
} else {
|
|
|
|
|
unit = '%';
|
|
|
|
|
}
|
|
|
|
|
tooltipContent += `${item.seriesName}: ${item.value.toFixed(2)}${unit}`;
|
|
|
|
|
});
|
|
|
|
|
return tooltipContent;
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
xAxis: {
|
|
|
|
|
type: 'category',
|
|
|
|
|
data: categories
|
|
|
|
|
},
|
|
|
|
|
yAxis: {
|
|
|
|
|
type: 'value',
|
|
|
|
|
name: "下单量",
|
|
|
|
|
},
|
|
|
|
|
series: [
|
|
|
|
|
{
|
|
|
|
|
name: '下单总金额',
|
|
|
|
|
type: 'bar',
|
|
|
|
|
data: seriesData.map(item => item.price),
|
|
|
|
|
label: {
|
|
|
|
|
show: true,
|
|
|
|
|
position: 'top',
|
|
|
|
|
formatter: function (params) {
|
|
|
|
|
return params.value.toFixed(2) + '元';
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
itemStyle: {
|
|
|
|
|
color: '#7CFC00',
|
|
|
|
|
},
|
|
|
|
|
emphasis: {
|
|
|
|
|
focus: 'series',
|
|
|
|
|
label: {
|
|
|
|
|
show: true,
|
|
|
|
|
},
|
|
|
|
|
itemStyle: {
|
|
|
|
|
borderColor: '#7CFC00',
|
|
|
|
|
borderWidth: 2,
|
|
|
|
|
color: '#7CFC00'
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: '下单量',
|
|
|
|
|
type: 'bar',
|
|
|
|
|
data: seriesData.map(item => item.orderNums),
|
|
|
|
|
label: {
|
|
|
|
|
show: true,
|
|
|
|
|
position: 'top',
|
|
|
|
|
formatter: function (params) {
|
|
|
|
|
return params.value + '个';
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
itemStyle: {
|
|
|
|
|
color: '#8A2BE2',
|
|
|
|
|
},
|
|
|
|
|
emphasis: {
|
|
|
|
|
focus: 'series',
|
|
|
|
|
label: {
|
|
|
|
|
show: true,
|
|
|
|
|
},
|
|
|
|
|
itemStyle: {
|
|
|
|
|
borderColor: '#8A2BE2',
|
|
|
|
|
borderWidth: 2,
|
|
|
|
|
color: '#8A2BE2'
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: '接单率',
|
|
|
|
|
type: 'bar',
|
|
|
|
|
data: seriesData.map(item => item.orderAcceptanceRate),
|
|
|
|
|
label: {
|
|
|
|
|
show: true,
|
|
|
|
|
position: 'top',
|
|
|
|
|
formatter: function (params) {
|
|
|
|
|
return params.value + "%";
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
itemStyle: {
|
|
|
|
|
color: '#ADFF2F',
|
|
|
|
|
},
|
|
|
|
|
emphasis: {
|
|
|
|
|
focus: 'series',
|
|
|
|
|
label: {
|
|
|
|
|
show: true,
|
|
|
|
|
},
|
|
|
|
|
itemStyle: {
|
|
|
|
|
borderColor: '#ADFF2F',
|
|
|
|
|
borderWidth: 2,
|
|
|
|
|
color: '#ADFF2F'
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
],
|
|
|
|
|
};
|
|
|
|
|
this.chart = echarts.init(this.$refs.chart);
|
|
|
|
|
this.chart.setOption(option);
|
|
|
|
|
},
|
|
|
|
|
fetchCompanies() {
|
|
|
|
|
request({
|
|
|
|
|
url: `/api/scm/RecycleDevice/getCompanyList`,
|
|
|
|
|
method: "post"
|
|
|
|
|
}).then(res => {
|
|
|
|
|
this.companyOptions = res.data;
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
handleSelectChange(value) {
|
|
|
|
|
this.query.stationIds = [];
|
|
|
|
|
},
|
|
|
|
|
toggleTreeExpand(expands) {
|
|
|
|
|
this.refreshTree = false;
|
|
|
|
|
this.expandsTree = expands;
|
|
|
|
|
this.$nextTick(() => {
|
|
|
|
|
this.refreshTree = true;
|
|
|
|
|
this.$nextTick(() => {
|
|
|
|
|
this.$refs.treeBox.setCurrentKey(null);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
filterNode(value, data) {
|
|
|
|
|
if (!value) return true;
|
|
|
|
|
return data[this.treeProps.label].indexOf(value) !== -1;
|
|
|
|
|
},
|
|
|
|
|
loadNode(node, resolve) {
|
|
|
|
|
const nodeData = node.data;
|
|
|
|
|
const config = {
|
|
|
|
|
treeInterfaceId: "",
|
|
|
|
|
treeTemplateJson: []
|
|
|
|
|
};
|
|
|
|
|
if (config.treeInterfaceId) {
|
|
|
|
|
//这里是为了拿到参数中关联的字段的值,后端自行拿
|
|
|
|
|
if (config.treeTemplateJson && config.treeTemplateJson.length) {
|
|
|
|
|
for (let i = 0; i < config.treeTemplateJson.length; i++) {
|
|
|
|
|
const element = config.treeTemplateJson[i];
|
|
|
|
|
element.defaultValue = nodeData[element.relationField] || "";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//参数
|
|
|
|
|
let query = {
|
|
|
|
|
paramList: config.treeTemplateJson || []
|
|
|
|
|
};
|
|
|
|
|
//接口
|
|
|
|
|
getDataInterfaceRes(config.treeInterfaceId, query).then(res => {
|
|
|
|
|
let data = res.data;
|
|
|
|
|
if (Array.isArray(data)) {
|
|
|
|
|
resolve(data);
|
|
|
|
|
} else {
|
|
|
|
|
resolve([]);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
arraySpanMethod({ column }) {
|
|
|
|
|
for (let i = 0; i < this.mergeList.length; i++) {
|
|
|
|
|
if (column.property == this.mergeList[i].prop) {
|
|
|
|
|
return [this.mergeList[i].rowspan, this.mergeList[i].colspan];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
getMergeList(list) {
|
|
|
|
|
let newList = JSON.parse(JSON.stringify(list));
|
|
|
|
|
newList.forEach(item => {
|
|
|
|
|
if (item.children && item.children.length) {
|
|
|
|
|
let child = {
|
|
|
|
|
prop: item.prop + "-child-first"
|
|
|
|
|
};
|
|
|
|
|
item.children.unshift(child);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
newList.forEach(item => {
|
|
|
|
|
if (item.children && item.children.length) {
|
|
|
|
|
item.children.forEach((child, index) => {
|
|
|
|
|
if (index == 0) {
|
|
|
|
|
this.mergeList.push({
|
|
|
|
|
prop: child.prop,
|
|
|
|
|
rowspan: 1,
|
|
|
|
|
colspan: item.children.length
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
this.mergeList.push({
|
|
|
|
|
prop: child.prop,
|
|
|
|
|
rowspan: 0,
|
|
|
|
|
colspan: 0
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
this.mergeList.push({
|
|
|
|
|
prop: item.prop,
|
|
|
|
|
rowspan: 1,
|
|
|
|
|
colspan: 1
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
sortChange({ column, prop, order }) {
|
|
|
|
|
this.listQuery.sort = order == "ascending" ? "asc" : "desc";
|
|
|
|
|
this.listQuery.sidx = !order ? "" : prop;
|
|
|
|
|
this.initData();
|
|
|
|
|
},
|
|
|
|
|
async initSearchDataAndListData() {
|
|
|
|
|
await this.initSearchData();
|
|
|
|
|
this.initData();
|
|
|
|
|
},
|
|
|
|
|
//初始化查询的默认数据
|
|
|
|
|
async initSearchData() { },
|
|
|
|
|
initData() {
|
|
|
|
|
this.listLoading = true;
|
|
|
|
|
let _query = {
|
|
|
|
|
companyId: this.query.companyId,
|
|
|
|
|
creatStartTime: this.query.creatStartTime,
|
|
|
|
|
creatEndTime: this.query.creatEndTime,
|
|
|
|
|
};
|
|
|
|
|
request({
|
|
|
|
|
url: `/api/scm/RecycleOrder/compute`,
|
|
|
|
|
method: "post",
|
|
|
|
|
data: _query
|
|
|
|
|
}).then(res => {
|
|
|
|
|
this.list = res.data.map(o => ({
|
|
|
|
|
...o,
|
|
|
|
|
...this.expandObj
|
|
|
|
|
}));
|
|
|
|
|
if (res.data.length == 0) {
|
|
|
|
|
this.$message.error('当前图表无数据');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
this.chartData = res.data;
|
|
|
|
|
this.initChart();
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
search() {
|
|
|
|
|
if (this.query.companyId == null) {
|
|
|
|
|
this.$message.error('请选择需要查询的商户');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (this.query.creatStartTime == null || this.query.creatEndTime == null) {
|
|
|
|
|
this.$message.error('请选择需要查询的时间范围');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
this.listQuery.currentPage = 1;
|
|
|
|
|
this.listQuery.pageSize = 20;
|
|
|
|
|
this.listQuery.sort = "desc";
|
|
|
|
|
this.listQuery.sidx = "";
|
|
|
|
|
this.initData();
|
|
|
|
|
},
|
|
|
|
|
refresh(isrRefresh) {
|
|
|
|
|
if (isrRefresh) this.reset();
|
|
|
|
|
},
|
|
|
|
|
reset() {
|
|
|
|
|
this.query = JSON.parse(JSON.stringify(this.queryData));
|
|
|
|
|
this.dateRange = [];
|
|
|
|
|
this.search();
|
|
|
|
|
},
|
|
|
|
|
colseFlow(isrRefresh) {
|
|
|
|
|
this.flowVisible = false;
|
|
|
|
|
if (isrRefresh) this.reset();
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
</script>
|