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

<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>