You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
400 lines
14 KiB
400 lines
14 KiB
<template>
|
|
<div class="main-content12 expense-wrap">
|
|
<div class="flex-common">
|
|
<div class="flex-between mb24">
|
|
<div class=" flex gap12">
|
|
<b>{{ name }} 月详情</b>
|
|
<div class="flex gap12" v-if="id">
|
|
<span @click="sort(index)" :class="sortIndex === index ? ['ver-anchor-point','ver-anchor-point-active'] : ['ver-anchor-point']" v-for="(item, index) in serviceRanking" :key="item">{{ item }}</span>
|
|
</div>
|
|
</div>
|
|
<CustomDropdown ref="dropdownRef" :placeholder="date" width="280px">
|
|
<DateSelect slot="normal" view="month" v-model="date" :onlyMonth="true" @change="handleDateChange"/>
|
|
</CustomDropdown>
|
|
</div>
|
|
<el-form>
|
|
<!-- show-summary -->
|
|
<GuipTable :tableData="monthList" :key="tableKey" ref="multipleTable" autoColumn="true" :loading="tableLoading" style="flex:1"
|
|
:show-summary="true" :summary-method="getSummaries" @sort-change="sortChange">
|
|
<el-table-column prop="date" label="日期" v-if="!id"></el-table-column>
|
|
|
|
<template v-else>
|
|
<el-table-column type="index" label="排行" width="80px"></el-table-column>
|
|
|
|
<el-table-column prop="date2" label="服务排行" v-if="rankFlag === 'chktype'">
|
|
<template slot-scope="scope">
|
|
<div class="flex">
|
|
{{ nameList[scope.row.id] }}
|
|
</div>
|
|
</template>
|
|
</el-table-column>
|
|
|
|
<el-table-column prop="date1" label="站点排行" v-else>
|
|
<template slot-scope="scope">
|
|
<div class="flex">
|
|
{{ nameList[scope.row.id] }}
|
|
</div>
|
|
</template>
|
|
</el-table-column>
|
|
</template>
|
|
|
|
<el-table-column prop="1" label="利润" :sortable="sortIndex === '1' ? 'custom' : false">
|
|
<template slot-scope="scope">
|
|
<div class="flex">
|
|
{{ scope.row.profit ? scope.row.profit : '-' }}
|
|
</div>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column prop="2" label="收入" :sortable="sortIndex === '2' ? 'custom' : false">
|
|
<template slot-scope="scope">
|
|
<div class="flex">
|
|
{{ scope.row.income ? scope.row.income : '-' }}
|
|
</div>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column prop="3" label="支出" :sortable="sortIndex === '3' ? 'custom' : false">
|
|
<template slot-scope="scope">
|
|
<div class="flex">
|
|
{{ scope.row.cost ? scope.row.cost : '-' }}
|
|
</div>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column prop="4" label="单量" :sortable="sortIndex === '4' ? 'custom' : false">
|
|
<template slot-scope="scope">
|
|
<div class="flex">
|
|
{{ scope.row.check_num ? scope.row.check_num : '-' }}
|
|
</div>
|
|
</template>
|
|
</el-table-column>
|
|
|
|
<el-table-column v-for="(col, index) in payList" :key="index" :label="col.name+'收/支/单量'">
|
|
<template slot-scope="scope">
|
|
<div class="flex" v-if="scope.row.pay_type[col.id]">
|
|
{{ scope.row.pay_type[col.id].income }}/
|
|
{{ scope.row.pay_type[col.id].cost }}/
|
|
{{ scope.row.pay_type[col.id].check_num }}
|
|
</div>
|
|
<div v-else>-</div>
|
|
</template>
|
|
</el-table-column>
|
|
|
|
</GuipTable>
|
|
</el-form>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
<script>
|
|
import GuipTable from '@/components/GuipTable.vue';
|
|
import DateSelect from "@/components/super/DateSelect.vue";
|
|
import CustomDropdown from "@/components/CustomDropdown.vue";
|
|
|
|
export default {
|
|
components: {
|
|
CustomDropdown, DateSelect,
|
|
GuipTable,
|
|
},
|
|
props: {
|
|
rankFlag: {
|
|
type: String,
|
|
default: ''
|
|
},
|
|
},
|
|
data() {
|
|
return {
|
|
date:'',
|
|
uid:0,
|
|
chktype:0,
|
|
|
|
id: 0,
|
|
|
|
name:'',
|
|
monthList:[],
|
|
monthTotal:[],
|
|
payList:[],
|
|
nameList:[],
|
|
|
|
tableLoading:false,
|
|
tableKey: '',
|
|
|
|
sortIndex:'1',
|
|
sortOrder:'asc',
|
|
serviceRanking:{
|
|
'1':'利润排行',
|
|
'2':'收入排行',
|
|
'3':'支出排行',
|
|
'4':'检测量排行',
|
|
},
|
|
sortField: {
|
|
'1':'profit',
|
|
'2':'income',
|
|
'3':'cost',
|
|
'4':'check_num',
|
|
},
|
|
}
|
|
},
|
|
mounted() {
|
|
if(!this.$route.query.date) {
|
|
this.$message.error('非法请求');
|
|
this.$router.push('/agent/expenseStatistics')
|
|
}
|
|
this.date = this.$route.query.date
|
|
|
|
if(this.$route.query.id) this.id = this.$route.query.id
|
|
if(this.$route.query.uid) this.uid = this.$route.query.uid
|
|
if(this.$route.query.chktype) this.chktype = this.$route.query.chktype
|
|
|
|
this.getStats()
|
|
},
|
|
methods: {
|
|
getDate(dateStr) {
|
|
const date = new Date(dateStr);
|
|
const year = date.getFullYear(); // 2025
|
|
const month = date.getMonth() + 1; // 3 (表示3月)
|
|
|
|
return `${year}-${month}`
|
|
},
|
|
handleDateChange(date) {
|
|
this.date = this.getDate(date)
|
|
localStorage.setItem('date', JSON.stringify(date))
|
|
|
|
this.$refs.dropdownRef.closeDropdown();
|
|
this.getStats()
|
|
},
|
|
sort(index){
|
|
this.sortIndex = index
|
|
this.sortList()
|
|
},
|
|
sortChange({prop, order}){
|
|
this.sortIndex = prop
|
|
this.sortOrder = 'asc'
|
|
if (order === 'descending') this.sortOrder = 'desc'
|
|
this.sortList()
|
|
},
|
|
sortList(){
|
|
const field = this.sortField[this.sortIndex]
|
|
return this.monthList.sort((a, b) => {
|
|
const valA = a[field];
|
|
const valB = b[field];
|
|
|
|
// 处理字符串和数字类型的比较
|
|
if (typeof valA === 'string') {
|
|
return this.sortOrder === 'asc'
|
|
? valA.localeCompare(valB)
|
|
: valB.localeCompare(valA);
|
|
} else {
|
|
return this.sortOrder === 'asc'
|
|
? valA - valB
|
|
: valB - valA;
|
|
}
|
|
});
|
|
},
|
|
getStats(){
|
|
this.monthList=[]
|
|
this.monthTotal=[]
|
|
this.payList=[]
|
|
this.nameList=[]
|
|
this.tableKey = Math.random();
|
|
if(this.id){
|
|
if(this.rankFlag == 'chktype') {
|
|
this.getChktypeStatsRank()
|
|
return true
|
|
}
|
|
this.getSiteStatsRank()
|
|
return true
|
|
}
|
|
|
|
this.getDayStats();
|
|
},
|
|
getSummaries() {
|
|
const sums = [];
|
|
|
|
let index = -1
|
|
if(this.id) sums[++index] = '-'
|
|
sums[++index] = `小计`
|
|
sums[++index] = this.monthTotal.profit
|
|
sums[++index] = this.monthTotal.income
|
|
sums[++index] = this.monthTotal.cost
|
|
sums[++index] = this.monthTotal.check_num
|
|
this.payList.forEach(column =>{
|
|
sums[++index] = this.monthTotal.pay_type[column.id].income + '/' + this.monthTotal.pay_type[column.id].cost + '/' + this.monthTotal.pay_type[column.id].check_num
|
|
})
|
|
return sums;
|
|
},
|
|
getDayStats() {
|
|
this.tableLoading = true
|
|
try {
|
|
this.$http('POST', '/agentnew/ajax_get_day_stats', {
|
|
date: this.date,
|
|
uid: this.uid,
|
|
type: this.chktype,
|
|
}).then(response => {
|
|
this.$nextTick(() => {
|
|
this.name = response.data.name
|
|
this.monthList = response.data.list
|
|
this.payList = response.data.pay_list
|
|
this.monthTotal = response.data.total
|
|
})
|
|
}).catch(error => {
|
|
console.error(error, 'error')
|
|
})
|
|
} catch (error) {
|
|
console.error('数据加载失败:', error)
|
|
} finally {
|
|
this.tableLoading = false
|
|
}
|
|
},
|
|
getSiteStatsRank() {
|
|
this.tableLoading = true
|
|
try {
|
|
this.$http('POST', '/agentnew/ajax_get_site_stats_rank', {
|
|
date: this.date,
|
|
type: this.id,
|
|
}).then(response => {
|
|
this.tableLoading = false
|
|
this.$nextTick(() => {
|
|
this.name = response.data.name
|
|
this.monthList = response.data.list
|
|
this.monthTotal = response.data.total
|
|
this.nameList = response.data.name_list
|
|
this.sortList()
|
|
})
|
|
}).catch(error => {
|
|
console.error(error, 'error')
|
|
})
|
|
} catch (error) {
|
|
console.error('数据加载失败:', error)
|
|
} finally {
|
|
this.tableLoading = false
|
|
}
|
|
},
|
|
getChktypeStatsRank() {
|
|
this.tableLoading = true
|
|
try {
|
|
this.$http('POST', '/agentnew/ajax_get_chktype_stats_rank', {
|
|
date: this.date,
|
|
uid: this.id,
|
|
}).then(response => {
|
|
this.tableLoading = false
|
|
this.$nextTick(() => {
|
|
this.name = response.data.name
|
|
this.monthList = response.data.list
|
|
this.monthTotal = response.data.total
|
|
this.nameList = response.data.name_list
|
|
this.sortList()
|
|
})
|
|
}).catch(error => {
|
|
console.error(error, 'error')
|
|
})
|
|
} catch (error) {
|
|
console.error('数据加载失败:', error)
|
|
} finally {
|
|
this.tableLoading = false
|
|
}
|
|
},
|
|
}
|
|
}
|
|
|
|
</script>
|
|
<style lang="scss" scoped>
|
|
.el-form-item{
|
|
margin-bottom: 0 !important;
|
|
}
|
|
.expense-wrap{
|
|
|
|
.ver-anchor-point {
|
|
height: 28px;
|
|
display: flex;
|
|
align-items: center;
|
|
padding: 4px 12px;
|
|
white-space: nowrap;
|
|
transition: all .3s;
|
|
border-radius: 14px;
|
|
background: #FFFFFF;
|
|
box-sizing: border-box;
|
|
border: 1px solid #DFE2E6;
|
|
letter-spacing: 0.08em;
|
|
color: #8A9099;
|
|
cursor: pointer;
|
|
}
|
|
.ver-anchor-point:hover {
|
|
border-color: transparent;
|
|
transition: all .3s;
|
|
color: #006AFF;
|
|
background: #F2F3F5;
|
|
}
|
|
.ver-anchor-point-active{
|
|
color: #006AFF;
|
|
}
|
|
.pagetitle {
|
|
text-align: left;
|
|
font-size: 16px;
|
|
font-weight: bold;
|
|
line-height: normal;
|
|
letter-spacing: 0.08em;
|
|
color: #1E2226;
|
|
margin-top: 8px;
|
|
}
|
|
.monthTotal-wrap{
|
|
display: grid;
|
|
grid-gap: 12px;
|
|
grid-template-columns: repeat(auto-fit, 287px);
|
|
}
|
|
|
|
.loss-tip{
|
|
width: 50px;
|
|
height: 24px;
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
box-sizing: border-box;
|
|
border-radius: 4px;
|
|
background: #FFF1F0;
|
|
box-sizing: border-box;
|
|
border: 1px solid #FFA39E;
|
|
font-size: 14px;
|
|
font-weight: normal;
|
|
line-height: 20px;
|
|
text-align: center;
|
|
letter-spacing: 0.08em;
|
|
color: #FF4D4F;
|
|
}
|
|
.total-item{
|
|
padding: 14px 16px;
|
|
font-size: 12px;
|
|
letter-spacing: 0.03em;
|
|
color: #23242B;
|
|
box-sizing: border-box;
|
|
border-radius: 4px;
|
|
background: #F2F7FF;
|
|
.price{
|
|
text-align: left;
|
|
font-size: 12px;
|
|
font-weight: normal;
|
|
line-height: 15px;
|
|
letter-spacing: 0.08em;
|
|
color: #1E2226;
|
|
margin: 14px 0;
|
|
b{
|
|
font-size: 22px;
|
|
line-height: 20px;
|
|
letter-spacing: normal;
|
|
}
|
|
}
|
|
.total-bottom{
|
|
align-items: flex-start;
|
|
}
|
|
}
|
|
.loss{
|
|
background: #FFF1F0;
|
|
.top-left b{
|
|
color: #FF4D4F;
|
|
}
|
|
}
|
|
.gain{
|
|
background: #EFFFE0;
|
|
.top-left b{
|
|
color: #00C261;
|
|
}
|
|
}
|
|
}
|
|
</style>
|