xw_admin/src/views/cost/shipmentStatistics/index.vue

284 lines
7.6 KiB
Vue

<template>
<el-container class="mainBox mainBoxHeaderNoBorder">
<el-main class="nopadding">
<el-scrollbar>
<div class="searchMain">
<scSearch ref="scSearch" :searchList="searchList" @fetchSelectData="getSelectData">
<div class="searchItem">
<label class="name">时间粒度</label>
<el-select :size="size" class="input" placeholder="请选择时间粒度" v-model="reqParams.date_type">
<el-option v-for="(item,index) in setMap.dataTypeList" :key="index" :label="item.label" :value="item.date_type"></el-option>
</el-select>
</div>
<div class="searchItem">
<label class="name">时间范围</label>
<el-date-picker :size="size" class="input" :type="reqParams.date_type=='day'?'daterange':reqParams.date_type=='month'?'monthrange':reqParams.date_type=='year'?'yearrange':'datetimerange'" v-model="reqParams.dateSelect" value-format="YYYY-MM-DD"
start-placeholder="开始时间"
end-placeholder="结束时间">
</el-date-picker>
</div>
</scSearch>
<div class="searchItem searchBtn">
<el-button :size="size" type="primary" icon="el-icon-search" @click="upSearch">查询</el-button>
<el-button :size="size" type="info" icon="el-icon-RefreshRight" @click="reset">重置</el-button>
</div>
<div class="exportBtn">
<scExport :size="size" @exportData="exportData" @updateShow="exportChangeShow" :show="exportShow" type="20">
<el-button :size="size" v-auth="'costSummaryDownload'" icon="sc-icon-Download" :disabled="exportShow" @click="exportData">下载</el-button>
</scExport>
</div>
</div>
<div class="mainMiddle" v-loading="loading" element-loading-text="努力加载中...">
<div class="echartsView">
<scEcharts ref="c1" height="300px" :option="option"></scEcharts>
</div>
<div class="tableView">
<feesTable :info="feesData.tableList"></feesTable>
</div>
</div>
</el-scrollbar>
</el-main>
</el-container>
</template>
<script>
import scEcharts from '@/components/scEcharts';
import feesTable from './components/table'
export default {
name:"cost",
components: {
scEcharts,
feesTable
},
data() {
return {
size:'small',
loading:false,
dialog: {
save: false,
show: false,
},
setMap:{
dataTypeList:[
{date_type:'hour',label:'按时'},
{date_type:'day',label:'按天'},
{date_type:'month',label:'按月'},
{date_type:'year',label:'按年'},
],
},
option:{},
feesData:{
tableList:{}
},
selection: [],
exportShow:false,
searchList:[
{name:'成本类型',type:'select',code:['type_name'], data:[], placeholder:"请选择费用类型",show:true},
{name:'成本类别',type:'select',code:['category_name'], data:[], placeholder:"请选择费用类别",show:true},
],
params: {},
reqParams:{
page:1,
pageSize:30,
date_type:'month',
dateSelect:[],
start:'',
end:'',
}
}
},
watch:{
'reqParams.dateSelect':function (val){
if(val){
this.reqParams.start = val[0];
this.reqParams.end = val[1];
}else{
this.reqParams.start = "";
this.reqParams.end = "";
}
}
},
computed:{
},
created(){
},
mounted() {
this.getData();
},
methods: {
async getSelectData(item) {
let {data, params} = item;
this.params = params;
let searchParams = this.$TOOL.objCopy(params);
searchParams.field = ""
if (typeof data.code === 'string') {
searchParams.field = data.code;
} else {
searchParams.field = data.code[0];
}
if (data.type == 'select') {
const res = await this.$API.finance.cost.field.post(searchParams);
if (res.code == 200) {
if (res.data && res.data.length > 0) {
res.data.forEach(item => {
item.label = item[data.code];
item.value = item.id;
})
}
this.searchList.forEach(item => {
if (item.code == data.code) {
item.data = res.data;
}
})
}
}
},
async getData() {
this.loading = true;
const res = await this.$API.finance.cost.summary.post(this.reqParams);
this.loading = false;
if(res.code == 200){
res.data.tableList.data = this.setTableList(res.data.tableList.data);
this.feesData = res.data;
let option = {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
},
formatter: function (params) {
const filteredParams = params.filter(param => param.value !== 0);
let totalData = 0;
filteredParams.map(em=> {
totalData += em.value
})
const formattedParams = filteredParams.map(param => {
const percentage = (param.value/totalData*100).toFixed(2);
const seriesColor = param.color;
return `<span style="display: flex;justify-content: space-between"><span><span style="display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;background-color:${seriesColor};"></span>${param.seriesName} </span><div style="display: flex;justify-content: space-between;margin-left: 15px"><span style="font-weight: 500;display: inline-block;text-align: right;">¥ ${param.value}</span><span style="display: inline-block;margin-left: 10px; width: 50px;text-align: left;font-weight: 500;">${percentage}%</span></div></span>`;
}).join('');
return params[0].name + '<br/>总金额:¥ '+ totalData.toFixed(2) + '<br/>' + formattedParams;
}
},
toolbox:{
show:true,
feature: {
magicType: { type: ['line', 'bar'] },
}
},
grid:{
bottom:40,
left:10,
},
legend:{
show:true,
bottom:10
},
xAxis: {
boundaryGap: false,
type: 'category',
data: this.feesData.dateRange
},
yAxis: [{
type: 'value',
show:true,
axisLabel:{
margin:this.feesData.dateRange.length<13? 56:20
},
name: '',
axisTick:{
show:false
},
splitLine: {
show: false
}
}],
series: this.setList(this.feesData.summaryList),
};
this.option = option;
}
},
setList(data){
let newData = data[0].cost_item.map(item => ({
name: item,
data: [],
type:'bar',
symbol: 'none',
stack:'fees',
smooth: true,
}));
if(data && data.length>0){
data.forEach(item => {
item.cost_amount.forEach((amount, index) => {
newData[index].data.push(amount);
});
});
}
return newData
},
setTableList(data){
let newData = data.columns.map(column => [column]);
if(data.rows && data.rows.length>0){
data.rows.forEach((row, rowIndex) => {
data.columns.forEach((columnName, columnIndex) => {
newData[columnIndex][1 + rowIndex] = row[columnIndex]==0?'-':'¥'+row[columnIndex];
});
});
}
return newData
},
//表格选择后回调事件
selectionChange(selection){
this.selection = selection;
},
// 下载导出
exportChangeShow(params){
if(params.type == 20){
this.exportShow = params.status==0?true:false
}
},
async exportData() {
if(this.exportShow) return
const res = await this.$API.finance.cost.summaryExport.post(this.reqParams);
if(res.code == 200){
this.$message.success('开始导出');
}
},
upSearch(){
this.reqParams = {...this.reqParams,...this.params};
this.getData();
},
reset(){
this.reqParams = {
page:1,
pageSize:30,
date_type:'month',
dateSelect:[],
start:'',
end:''
};
this.$refs.scSearch.reload();
this.getData();
},
}
}
</script>
<style lang="scss" scoped>
.logoCell{
display: flex;
align-items: center;
height: 20px;
margin: 0 auto;
}
.mainMiddle{
min-height: 600px;
}
</style>