Browse Source

收支统计渲染

zq-0828-newMenu
pengda 1 month ago
parent
commit
1f0dfd0b00
  1. 6
      src/components/super/DateSelect.vue
  2. 13
      src/router/index.js
  3. 408
      src/views/agent/expenseStatistics.vue
  4. 306
      src/views/agent/statisticalDetails.vue

6
src/components/super/DateSelect.vue

@ -11,7 +11,7 @@
</div> </div>
<div class="controls"> <div class="controls">
<button v-if="!onlyYear" @click="toggleView('month')" :class="{ active: view !== 'year' }">月度</button> <button v-if="!onlyYear" @click="toggleView('month')" :class="{ active: view !== 'year' }">月度</button>
<button @click="toggleView('year')" :class="{ active: view === 'year' }">年度</button> <button v-if="!onlyMonth" @click="toggleView('year')" :class="{ active: view === 'year' }">年度</button>
</div> </div>
</div> </div>
@ -62,6 +62,10 @@
onlyYear:{ onlyYear:{
type:Boolean, type:Boolean,
default:false default:false
},
onlyMonth:{
type:Boolean,
default:false
} }
}, },
data() { data() {

13
src/router/index.js

@ -10,7 +10,7 @@ const whiteSecondSider = [
const blackSliderList = [ const blackSliderList = [
'/franchise', '/agreement', '/customizeDoc', '/agent/siteAdd', '/agent/siteServiceList', '/agent/siteTemplate','/agent/siteAddFinally','/agent/siteServiceAdd', '/agent/supplyList', '/franchise', '/agreement', '/customizeDoc', '/agent/siteAdd', '/agent/siteServiceList', '/agent/siteTemplate','/agent/siteAddFinally','/agent/siteServiceAdd', '/agent/supplyList',
'/agent/domainList','/agent/siteAddChooseService' '/agent/domainList','/agent/siteAddChooseService'
, '/agent/noticeList' , '/agent/noticeList' , '/agent/statisticalDetails', '/agent/siteRank', '/agent/serviceRank'
]; ];
// 一级路由 // 一级路由
let first_child_router = [] let first_child_router = []
@ -326,7 +326,6 @@ const routes = [{
name: '收支统计', name: '收支统计',
component: () => import( /* webpackChunkName: "expenseStatistics" */ '../views/agent/expenseStatistics.vue'), component: () => import( /* webpackChunkName: "expenseStatistics" */ '../views/agent/expenseStatistics.vue'),
meta: { meta: {
title:'各站点统计列表',
hideBreadcrumb: true // 一级页面不显示面包屑 hideBreadcrumb: true // 一级页面不显示面包屑
} }
}, },
@ -342,16 +341,22 @@ const routes = [{
path: '/agent/siteRank', path: '/agent/siteRank',
name: '站点排行', name: '站点排行',
component: () => import( /* webpackChunkName: "statisticalDetails" */ '../views/agent/statisticalDetails.vue'), component: () => import( /* webpackChunkName: "statisticalDetails" */ '../views/agent/statisticalDetails.vue'),
props: {
rankFlag: 'site'
},
meta: { meta: {
breadcrumbParent: '各站点统计列表' // 手动指定父级 breadcrumbParent: '收支统计' // 手动指定父级
} }
}, },
{ {
path: '/agent/serviceRank', path: '/agent/serviceRank',
name: '服务排行', name: '服务排行',
component: () => import( /* webpackChunkName: "statisticalDetails" */ '../views/agent/statisticalDetails.vue'), component: () => import( /* webpackChunkName: "statisticalDetails" */ '../views/agent/statisticalDetails.vue'),
props: {
rankFlag: 'chktype'
},
meta: { meta: {
breadcrumbParent: '各站点统计列表' // 手动指定父级 breadcrumbParent: '收支统计' // 手动指定父级
} }
}, },

408
src/views/agent/expenseStatistics.vue

@ -5,127 +5,138 @@
<div class="flex-between"> <div class="flex-between">
<el-tabs v-model="totalType" @tab-click="handleClick"> <el-tabs v-model="totalType" @tab-click="handleClick">
<el-tab-pane label="月统计列表" name="1"></el-tab-pane> <el-tab-pane label="月统计列表" name="1"></el-tab-pane>
<el-tab-pane label="各站点统计列表" name="2"></el-tab-pane> <el-tab-pane v-if="siteNum>1" label="各站点统计列表" name="2"></el-tab-pane>
<el-tab-pane label="各服务统计列表" name="3"></el-tab-pane> <el-tab-pane label="各服务统计列表" name="3"></el-tab-pane>
</el-tabs> </el-tabs>
<div class="flex"> <div class="flex">
<GuipSelect label="服务类型" v-if="totalType == '3'" :options="[{label:'asd',value:'9'}]"></GuipSelect> <!-- <GuipSelect label="服务类型" v-if="totalType == '3'" :options="[{label:'asd',value:'9'}]"></GuipSelect>-->
<GuipSelect label="时间" :options="[{label:'asd',value:'9'}]"></GuipSelect> <!-- <GuipSelect label="时间" :options="[{label:'asd',value:'9'}]"></GuipSelect>-->
<CustomDropdown ref="dropdownRef" :placeholder="date" width="280px">
<DateSelect slot="normal" view="month" :onlyMonth="true" @change="handleDateChange"/>
</CustomDropdown>
</div> </div>
</div> </div>
<div v-if="totalType == '1'" class="mt24 monthTotal-wrap flex"> <div v-if="totalType == '1' && Object.keys(monthTotal).length>0" class="mt24 monthTotal-wrap flex">
<div class="total-item loss"> <div class="total-item" :class="monthTotal.profit<0?'loss':''">
<div class="flex-between total-top"> <div class="flex-between total-top">
<div class="top-left"> <div class="top-left">
<img src="" alt=""> <img src="" alt="">
<b>月利润</b> <b>月利润</b>
</div> </div>
<span class="loss-tip">亏损</span> <span v-if="monthTotal.profit<0" class="loss-tip">亏损</span>
</div> </div>
<div class="price"> <div class="price">
<b>8900</b> <b>{{monthTotal.profit}}</b>
</div> </div>
<div class="gap24 flex-between total-bottom"> <div class="gap24 flex-between total-bottom">
<div class="left column gap8"> <div class="left column gap8">
<span>淘宝200.89</span> <template v-for="(col, index) in payList">
<span>微信200.89</span> <span v-if="index % 2 === 1" :key="index">{{ col.name }}{{ monthTotal.pay_type[col.id].profit }}</span>
<span>淘宝200.89</span> </template>
</div> </div>
<div class="right column gap8"> <div class="right column gap8">
<span>淘宝200.89</span> <template v-for="(col, index) in payList">
<span>支付宝200.89</span> <span v-if="index % 2 === 0" :key="index">{{ col.name }}{{ monthTotal.pay_type[col.id].profit }}</span>
</template>
</div> </div>
</div> </div>
</div> </div>
<div class="total-item"> <div class="total-item">
<div class="flex-between total-top"> <div class="flex-between total-top">
<div class="top-left"> <div class="top-left">
<img src="" alt=""> <img src="" alt="">
<b>利润</b> <b>收入</b>
</div> </div>
<span class="loss-tip">亏损</span> <span class="loss-tip-empty"></span>
</div> </div>
<div class="price"> <div class="price">
<b>8900</b> <b>{{this.monthTotal.income}}</b>
</div> </div>
<div class="gap24 flex-between total-bottom"> <div class="gap24 flex-between total-bottom">
<div class="left column gap8"> <div class="left column gap8">
<span>淘宝200.89</span> <template v-for="(col, index) in payList">
<span>微信200.89</span> <span v-if="index % 2 === 1" :key="index">{{ col.name }}{{ monthTotal.pay_type[col.id].income }}</span>
<span>淘宝200.89</span> </template>
</div> </div>
<div class="right column gap8"> <div class="right column gap8">
<span>淘宝200.89</span> <template v-for="(col, index) in payList">
<span>支付宝200.89</span> <span v-if="index % 2 === 0" :key="index">{{ col.name }}{{ monthTotal.pay_type[col.id].income }}</span>
</template>
</div> </div>
</div> </div>
</div> </div>
<div class="total-item"> <div class="total-item">
<div class="flex-between total-top"> <div class="flex-between total-top">
<div class="top-left"> <div class="top-left">
<img src="" alt=""> <img src="" alt="">
<b>利润</b> <b>支出</b>
</div> </div>
<span class="loss-tip">亏损</span> <span class="loss-tip-empty"></span>
</div> </div>
<div class="price"> <div class="price">
<b>8900</b> <b>{{this.monthTotal.cost}}</b>
</div> </div>
<div class="gap24 flex-between total-bottom"> <div class="gap24 flex-between total-bottom">
<div class="left column gap8"> <div class="left column gap8">
<span>淘宝200.89</span> <template v-for="(col, index) in payList">
<span>微信200.89</span> <span v-if="index % 2 === 1" :key="index">{{ col.name }}{{ monthTotal.pay_type[col.id].cost }}</span>
<span>淘宝200.89</span> </template>
</div> </div>
<div class="right column gap8"> <div class="right column gap8">
<span>淘宝200.89</span> <template v-for="(col, index) in payList">
<span>支付宝200.89</span> <span v-if="index % 2 === 0" :key="index">{{ col.name }}{{ monthTotal.pay_type[col.id].cost }}</span>
</template>
</div> </div>
</div> </div>
</div> </div>
<div class="total-item"> <div class="total-item">
<div class="flex-between total-top"> <div class="flex-between total-top">
<div class="top-left"> <div class="top-left">
<img src="" alt=""> <img src="" alt="">
<b>利润</b> <b>单量</b>
</div> </div>
<span class="loss-tip">亏损</span> <span class="loss-tip-empty"></span>
</div> </div>
<div class="price"> <div class="price">
<b>8900</b> <b>{{this.monthTotal.check_num}}</b>
</div> </div>
<div class="gap24 flex-between total-bottom"> <div class="gap24 flex-between total-bottom">
<div class="left column gap8"> <div class="left column gap8">
<span>淘宝200.89</span> <template v-for="(col, index) in payList">
<span>微信200.89</span> <span v-if="index % 2 === 1" :key="index">{{ col.name }}{{ monthTotal.pay_type[col.id].check_num }}</span>
<span>淘宝200.89</span> </template>
</div> </div>
<div class="right column gap8"> <div class="right column gap8">
<span>淘宝200.89</span> <template v-for="(col, index) in payList">
<span>支付宝200.89</span> <span v-if="index % 2 === 0" :key="index">{{ col.name }}{{ monthTotal.pay_type[col.id].check_num }}</span>
</template>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<el-form class="mt24"> <el-form class="mt24">
<GuipTable :tableData="monthTotalList" ref="multipleTable" autoColumn="true" :loading="tableLoading" style="flex:1" <GuipTable :tableData="monthList" :key="tableKey" ref="multipleTable" autoColumn="true" :loading="tableLoading" style="flex:1"
:show-summary="totalType === '1'" :show-summary="totalType === '1'"
:summary-method="totalType === '1' ? getSummaries : null"> :summary-method="totalType === '1' ? getSummaries : null">
<el-table-column prop="date" label="日期" min-width="130px" v-if="totalType == '1'"></el-table-column> <el-table-column prop="date" label="日期" min-width="130px" v-if="totalType == '1'"></el-table-column>
<el-table-column prop="date1" label="站点名称" min-width="130px" v-if="totalType == '2'"></el-table-column> <el-table-column prop="date1" label="站点名称" min-width="130px" v-if="totalType == '2'">
<el-table-column prop="date2" label="服务名称" min-width="130px" v-if="totalType == '3'"></el-table-column> <template slot-scope="scope">
<div class="flex">
{{ nameList[scope.row.id] }}
</div>
</template>
</el-table-column>
<el-table-column prop="date2" label="服务名称" min-width="130px" v-if="totalType == '3'">
<template slot-scope="scope">
<div class="flex">
{{ nameList[scope.row.id] }}
</div>
</template>
</el-table-column>
<el-table-column prop="profit" label="利润" min-width="110px"> <el-table-column prop="profit" label="利润" min-width="110px">
<template slot-scope="scope"> <template slot-scope="scope">
<div class="flex"> <div class="flex">
{{ scope.row.profit }} {{ scope.row.profit ? scope.row.profit : '-' }}
</div> </div>
</template> </template>
</el-table-column> </el-table-column>
@ -139,43 +150,48 @@
<el-table-column prop="expenditure" label="支出" min-width="110px"> <el-table-column prop="expenditure" label="支出" min-width="110px">
<template slot-scope="scope"> <template slot-scope="scope">
<div class="flex"> <div class="flex">
{{ scope.row.expenditure ? scope.row.expenditure : '-' }} {{ scope.row.cost ? scope.row.cost : '-' }}
</div> </div>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="orderVolume" label="单量" min-width="110px"> <el-table-column prop="orderVolume" label="单量" min-width="110px">
<template slot-scope="scope"> <template slot-scope="scope">
<div class="flex"> <div class="flex">
{{ scope.row.orderVolume ? scope.row.orderVolume : '-' }} {{ scope.row.check_num ? scope.row.check_num : '-' }}
</div> </div>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="profit1" label="淘宝收/支/单量" min-width="160px">
<el-table-column v-for="(col, index) in payList" :key="index" :label="col.name+'收/支/单量'" min-width="160px">
<template slot-scope="scope"> <template slot-scope="scope">
<div class="flex"> <div class="flex" v-if="scope.row.pay_type[col.id]">
{{ scope.row.profit ? scope.row.profit : '-' }} {{ scope.row.pay_type[col.id].income }}/
{{ scope.row.pay_type[col.id].cost }}/
{{ scope.row.pay_type[col.id].check_num }}
</div> </div>
<div v-else>-</div>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column v-if="totalType == '3'" <el-table-column v-if="totalType == '3'"
key="top" prop="top" label="站点排行(利润)" width="250"> key="top1" prop="top1" label="站点排行(利润)" width="250">
<template v-slot="{ row }"> <template slot-scope="scope">
<span v-if="true" slot="reference" class="flex"> <span v-if="topList[scope.row.id]" slot="reference" class="flex">
NO.1 万方本科版 NO.1 {{topList[scope.row.id]}}
<svg-icon :size="14" @click="handleClick2(row.id,1,0)" <svg-icon :size="14" @click="handleClicksiteRank(scope.row.id)"
:path="require('@/assets/super/list-detail.svg')" :color="'#8A9099'" :path="require('@/assets/super/list-detail.svg')" :color="'#8A9099'"
:hoverColor="'#006AFF'" /> :hoverColor="'#006AFF'" />
</span> </span>
<span v-else slot="reference">暂无排行</span> <span v-else slot="reference">暂无排行</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column v-if="totalType == '2'" <el-table-column v-if="totalType == '2'"
key="top" prop="top" label="服务排行(利润)" width="250"> key="top2" prop="top2" label="服务排行(利润)" width="250">
<template v-slot="{ row }"> <template slot-scope="scope">
<span v-if="true" slot="reference" class="flex"> <span v-if="topList[scope.row.id]" slot="reference" class="flex">
NO.1 万方本科版 NO.1 {{topList[scope.row.id]}}
<svg-icon :size="14" @click="handleClick2(row.id,1,0)" <svg-icon :size="14" @click="handleClickserviceRank(scope.row.id)"
:path="require('@/assets/super/list-detail.svg')" :color="'#8A9099'" :path="require('@/assets/super/list-detail.svg')" :color="'#8A9099'"
:hoverColor="'#006AFF'" /> :hoverColor="'#006AFF'" />
</span> </span>
@ -185,7 +201,7 @@
<el-table-column label="操作" fixed="right" v-if="totalType != '1'"> <el-table-column label="操作" fixed="right" v-if="totalType != '1'">
<template slot-scope="scope"> <template slot-scope="scope">
<GuipButton type="text" class="mr-16" @click="handleClick2(scope.row.id,0,1)">详情</GuipButton> <GuipButton type="text" class="mr-16" @click="handleClickDetail(scope.row.id)">详情</GuipButton>
</template> </template>
</el-table-column> </el-table-column>
</GuipTable> </GuipTable>
@ -195,15 +211,18 @@
</template> </template>
<script> <script>
import GuipButton from '@/components/GuipButton.vue'; import GuipButton from '@/components/GuipButton.vue';
import GuipSelect from '@/components/GuipSelect.vue'; // import GuipSelect from '@/components/GuipSelect.vue';
import GuipTable from '@/components/GuipTable.vue'; import GuipTable from '@/components/GuipTable.vue';
import SvgIcon from '@/components/SvgIcon.vue'; import SvgIcon from '@/components/SvgIcon.vue';
import DateSelect from "@/components/super/DateSelect.vue";
import CustomDropdown from "@/components/CustomDropdown.vue";
export default { export default {
components: { components: {
CustomDropdown, DateSelect,
GuipTable, GuipTable,
GuipButton, GuipButton,
GuipSelect, // GuipSelect,
SvgIcon SvgIcon
}, },
props: { props: {
@ -215,131 +234,158 @@ export default {
data() { data() {
return { return {
totalType:'1', totalType:'1',
date: this.getNow(),
tableLoading:false, tableLoading:false,
monthTotalList:[ siteNum: 1,
{ tableKey: '',
date:'2025-08-26', monthList:[],
profit:19, monthTotal:[],
income:29, payList:[],
}, nameList:[],
{ topList:[],
profit:-87.9,
date:'2025-08-26',
income:7.9,
expenditure:40,
},
{
profit:619.46,
date:'2025-08-26',
income:79
},
],
top_list:[]
} }
}, },
mounted() { mounted() {
const {total_type} = this.$route.query const {total_type, date} = this.$route.query
this.$nextTick(()=>{ this.$nextTick(()=>{
this.totalType = this.total_type; this.totalType = this.total_type;
if(total_type)this.totalType = total_type; if(total_type)this.totalType = total_type;
if(date) this.date = date;
this.getSiteNum()
this.handleClick()
}) })
console.log(this.total_type,total_type,'total_type===');
// this.getExpenseList()
}, },
methods: { methods: {
handleClick2(id,rankFlag,detailFlag){ getNow() {
this.$router.push(`/agent/serviceRank?totalType=${this.totalType}&rankFlag=${rankFlag}&detailFlag=${detailFlag}`) const now = new Date();
const year = now.getFullYear();
const month = now.getMonth() + 1;
return `${year}-${month}`
}, },
handleClick(tab, event){ getDate(dateStr) {
console.log(tab, event,'=====tab, event'); const date = new Date(dateStr);
this.getExpenseList() 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.handleClick()
},
handleClickDetail(id){
if(this.totalType == 2) this.$router.push(`/agent/statisticalDetails?uid=${id}&total_type=${this.totalType}&date=${this.date}`)
if(this.totalType == 3) this.$router.push(`/agent/statisticalDetails?chktype=${id}&total_type=${this.totalType}&date=${this.date}`)
},
handleClicksiteRank(id){
this.$router.push(`/agent/siteRank?id=${id}&total_type=${this.totalType}&date=`+this.date)
},
handleClickserviceRank(id){
this.$router.push(`/agent/serviceRank?id=${id}&total_type=${this.totalType}&date=`+this.date)
},
handleClick(){
this.monthList = []
this.payList = []
this.monthTotal = []
this.nameList = []
this.topList = []
this.tableKey = Math.random();
if(this.totalType == 1) this.getDayStats()
if(this.totalType == 2) this.getSiteStats()
if(this.totalType == 3) this.getChktypeStats()
}, },
getSummaries(param) { getSummaries() {
if(this.totalType != '1')return [] if(this.totalType != '1') return []
const { columns, data } = param;
const sums = []; const sums = [];
let obj = {
1:'profit',
2:'income',
3:'expenditure',
4:'orderVolume'
}
console.log(obj,'==');
columns.forEach((column, index) => {
// console.log(data,column, index,'====');
// const values = data.map(item => {
// item[column.property] = Number(item[column.property]) || 0
// return {...item}
// });
// console.log(values,'values===');
// for(let i = 1;i<4;i++){
// const incomeSum = this.getColumnReduce(data,obj[i]);
// sums[i] = incomeSum;
// console.log(sums[i],'sums[i]====sums[i]');
// }
const numericColumns = ['profit', 'income', 'expenditure', 'orderVolume']; let index = 0
if (numericColumns.includes(column.property)) { sums[index] = `小计`
const values = data.map(item => Number(item[column.property]) || 0); sums[++index] = this.monthTotal.profit
if (!values.every(value => isNaN(value))) { sums[++index] = this.monthTotal.income
sums[index] = values.reduce((prev, curr) => { sums[++index] = this.monthTotal.cost
const value = Number(curr); sums[++index] = this.monthTotal.check_num
return !isNaN(value) ? prev + value : prev; this.payList.forEach(column =>{
}, 0); sums[++index] = this.monthTotal.pay_type[column.id].income + '/' + this.monthTotal.pay_type[column.id].cost + '/' + this.monthTotal.pay_type[column.id].check_num
// })
if (['profit', 'income', 'expenditure'].includes(column.property)) {
sums[index] = sums[index].toFixed(2) + ' 元';
}
} else {
sums[index] = 'N/A';
}
} else {
sums[index] = 'N/A';
}
if (index === 0) {
sums[index] = `2025年8月利润小计`;
}
//
// if (!data[0]?.hasOwnProperty(column.property) ||
// data.some(item => item[column.property] === null || item[column.property] === '')) {
// sums[index] = 'N/A';
// return;
// }
//
// sums[index] = values.reduce((prev, curr) => prev + curr, 0);
});
return sums; return sums;
}, },
getColumnReduce(data,key){ getSiteNum() {
const incomeSum = data.reduce((sum, item) => sum + Number(item[key]), 0); try {
return incomeSum.toFixed(2) this.$http('POST', '/agentnew/ajax_get_agent_sitenum', {date: this.date}).then(response => {
this.$nextTick(() => {
this.siteNum = response.data
})
}).catch(error => {
console.error(error, 'error')
})
} catch (error) {
console.error('数据加载失败:', error)
}
}, },
getExpenseList() { getDayStats() {
// this.tableLoading = true
try {
// this.tableLoading = true this.$http('POST', '/agentnew/ajax_get_day_stats', {date: this.date}).then(response => {
// try { this.$nextTick(() => {
// const requestParams = { this.monthList = response.data.list
// date:'2025-08', this.payList = response.data.pay_list
// totalType:this.totalType this.monthTotal = response.data.total
// } })
// this.$http('POST', '/agentnew/ajax_get_check_order_list', requestParams).then(response => { }).catch(error => {
// this.tableLoading = false console.error(error, 'error')
// console.log(response,'===='); })
// // this.$nextTick(() => { } catch (error) {
// // this.monthTotalList = response.data.list console.error('数据加载失败:', error)
// // }) } finally {
// }).catch(error => { this.tableLoading = false
// console.error(error, 'error') }
// }) },
// } catch (error) { getSiteStats() {
// console.error(':', error) this.tableLoading = true
// } finally { try {
// this.tableLoading = false this.$http('POST', '/agentnew/ajax_get_site_stats', {date: this.date}).then(response => {
// } this.tableLoading = false
this.$nextTick(() => {
this.monthList = response.data.list
this.payList = response.data.pay_list
this.monthTotal = response.data.total
this.nameList = response.data.name_list
this.topList = response.data.top_list
})
}).catch(error => {
console.error(error, 'error')
})
} catch (error) {
console.error('数据加载失败:', error)
} finally {
this.tableLoading = false
}
},
getChktypeStats() {
this.tableLoading = true
try {
this.$http('POST', '/agentnew/ajax_get_chktype_stats', {date: this.date}).then(response => {
this.tableLoading = false
this.$nextTick(() => {
this.monthList = response.data.list
this.payList = response.data.pay_list
this.monthTotal = response.data.total
this.nameList = response.data.name_list
this.topList = response.data.top_list
})
}).catch(error => {
console.error(error, 'error')
})
} catch (error) {
console.error('数据加载失败:', error)
} finally {
this.tableLoading = false
}
}, },
} }
} }
@ -389,6 +435,11 @@ export default {
letter-spacing: 0.08em; letter-spacing: 0.08em;
color: #FF4D4F; color: #FF4D4F;
} }
.loss-tip-empty{
width: 50px;
height: 24px;
display: flex;
}
.total-item{ .total-item{
padding: 14px 16px; padding: 14px 16px;
font-size: 12px; font-size: 12px;
@ -397,6 +448,7 @@ export default {
box-sizing: border-box; box-sizing: border-box;
border-radius: 4px; border-radius: 4px;
background: #F2F7FF; background: #F2F7FF;
min-height: 153px;
.price{ .price{
text-align: left; text-align: left;
font-size: 12px; font-size: 12px;

306
src/views/agent/statisticalDetails.vue

@ -1,124 +1,295 @@
<template> <template>
<div class="main-content12 expense-wrap"> <div class="main-content12 expense-wrap">
<div class="flex-common"> <div class="flex-common">
<el-form> <div class="flex-between mb24">
<div class="flex-between mb24"> <div class=" flex gap12">
<div class=" flex gap12"> <b>{{ name }} 月详情</b>
<b>{{ }}turnitin中文站月详情</b> <div class="flex gap12" v-if="id">
<div class="flex gap12"> <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>
<span :class="['ver-anchor-point',]" v-for="item in serviceRanking" :key="item">{{ item }}</span>
</div>
</div> </div>
<GuipSelect label="时间" :options="[{label:'asd',value:'9'}]"></GuipSelect>
</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 --> <!-- show-summary -->
<GuipTable :tableData="monthTotalList" ref="multipleTable" autoColumn="true" :loading="tableLoading" style="flex:1"> <GuipTable :tableData="monthList" :key="tableKey" ref="multipleTable" autoColumn="true" :loading="tableLoading" style="flex:1"
<el-table-column prop="sort" label="排行" min-width="130px" v-if="rankFlag == 1"></el-table-column> :show-summary="true" :summary-method="getSummaries" @sort-change="sortChange">
<el-table-column prop="date" label="日期" min-width="130px" v-if="detailFlag ==1"></el-table-column> <el-table-column prop="date" label="日期" v-if="!id"></el-table-column>
<el-table-column prop="date" label="站点排行" min-width="130px" v-if="totalType == '3' && detailFlag != 1"></el-table-column>
<el-table-column prop="date" label="服务排行" min-width="130px" v-if="totalType == '2' && detailFlag != 1"></el-table-column> <template v-else>
<el-table-column prop="profit" label="利润" min-width="110px"> <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"> <template slot-scope="scope">
<div class="flex"> <div class="flex">
{{ scope.row.profit }} {{ scope.row.profit ? scope.row.profit : '-' }}
</div> </div>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="income" label="收入" min-width="110px"> <el-table-column prop="2" label="收入" :sortable="sortIndex === '2' ? 'custom' : false">
<template slot-scope="scope"> <template slot-scope="scope">
<div class="flex"> <div class="flex">
{{ scope.row.profit ? scope.row.profit : '-' }} {{ scope.row.income ? scope.row.income : '-' }}
</div> </div>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="expenditure" label="支出" min-width="110px"> <el-table-column prop="3" label="支出" :sortable="sortIndex === '3' ? 'custom' : false">
<template slot-scope="scope"> <template slot-scope="scope">
<div class="flex"> <div class="flex">
{{ scope.row.profit ? scope.row.profit : '-' }} {{ scope.row.cost ? scope.row.cost : '-' }}
</div> </div>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="orderVolume" label="单量" min-width="110px"> <el-table-column prop="4" label="单量" :sortable="sortIndex === '4' ? 'custom' : false">
<template slot-scope="scope"> <template slot-scope="scope">
<div class="flex"> <div class="flex">
{{ scope.row.profit ? scope.row.profit : '-' }} {{ scope.row.check_num ? scope.row.check_num : '-' }}
</div> </div>
</template> </template>
</el-table-column> </el-table-column>
<!-- 这个可能进行循环渲染 -->
<el-table-column prop="profit" label="淘宝收/支/单量" v-if="detailFlag" min-width="160px"> <el-table-column v-for="(col, index) in payList" :key="index" :label="col.name+'收/支/单量'">
<template slot-scope="scope"> <template slot-scope="scope">
<div class="flex"> <div class="flex" v-if="scope.row.pay_type[col.id]">
{{ scope.row.profit ? scope.row.profit : '-' }} {{ scope.row.pay_type[col.id].income }}/
{{ scope.row.pay_type[col.id].cost }}/
{{ scope.row.pay_type[col.id].check_num }}
</div> </div>
<div v-else>-</div>
</template> </template>
</el-table-column> </el-table-column>
</GuipTable> </GuipTable>
</el-form> </el-form>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import GuipSelect from '@/components/GuipSelect.vue';
import GuipTable from '@/components/GuipTable.vue'; import GuipTable from '@/components/GuipTable.vue';
import DateSelect from "@/components/super/DateSelect.vue";
import CustomDropdown from "@/components/CustomDropdown.vue";
export default { export default {
components: { components: {
CustomDropdown, DateSelect,
GuipTable, GuipTable,
GuipSelect, },
props: {
rankFlag: {
type: String,
default: ''
},
}, },
data() { data() {
return { return {
totalType:'1', date:'',
detailFlag:true,// uid:0,
rankFlag:false,// chktype:0,
id: 0,
name:'',
monthList:[],
monthTotal:[],
payList:[],
nameList:[],
tableLoading:false, tableLoading:false,
monthTotalList:[ tableKey: '',
{'sort':1,'profit':20,income:304,expenditure:280,orderVolume:47},
{'sort':2,'profit':30,income:127,expenditure:89,orderVolume:36}, sortIndex:'1',
], sortOrder:'asc',
serviceRanking:{ serviceRanking:{
'1':'利润排行', '1':'利润排行',
'2':'收入排行', '2':'收入排行',
'3':'支出排行', '3':'支出排行',
'4':'检测量排行', '4':'检测量排行',
} },
sortField: {
'1':'profit',
'2':'income',
'3':'cost',
'4':'check_num',
},
} }
}, },
mounted() { mounted() {
const {totalType,detailFlag,rankFlag} = this.$route.query if(!this.$route.query.date) {
this.totalType = totalType; this.$message.error('非法请求');
this.detailFlag = detailFlag; this.$router.push('/agent/expenseStatistics')
this.rankFlag = rankFlag; }
this.getDetailList() 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: { methods: {
getDetailList() { getDate(dateStr) {
console.log('调用了---'); const date = new Date(dateStr);
// this.tableLoading = true const year = date.getFullYear(); // 2025
// try { const month = date.getMonth() + 1; // 3 (3)
// const requestParams = {
// date:'2025-08', return `${year}-${month}`
// totalType:this.totalType },
// } handleDateChange(date) {
// this.$http('POST', '/agentnew/ajax_get_check_order_list', requestParams).then(response => { this.date = this.getDate(date)
// this.tableLoading = false localStorage.setItem('date', JSON.stringify(date))
// console.log(response,'====');
// // this.$nextTick(() => { this.$refs.dropdownRef.closeDropdown();
// // if (this.intervalId && response.data.maxid && this.orderListPrevMaxId && response.data.maxid > this.orderListPrevMaxId) { this.getStats()
// // console.log(''); },
// // this.playSound(); sort(index){
// // } this.sortIndex = index
// // this.monthTotalList = response.data.list this.sortList()
// // }) },
// }).catch(error => { sortChange({prop, order}){
// console.error(error, 'error') this.sortIndex = prop
// }) this.sortOrder = 'asc'
// } catch (error) { if (order === 'descending') this.sortOrder = 'desc'
// console.error(':', error) this.sortList()
// } finally { },
// this.tableLoading = false 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
}
}, },
} }
} }
@ -151,6 +322,9 @@ export default {
color: #006AFF; color: #006AFF;
background: #F2F3F5; background: #F2F3F5;
} }
.ver-anchor-point-active{
color: #006AFF;
}
.pagetitle { .pagetitle {
text-align: left; text-align: left;
font-size: 16px; font-size: 16px;

Loading…
Cancel
Save