[add] 标协会员-会员统计

This commit is contained in:
lideqin
2024-03-07 18:02:21 +08:00
parent 523ab9ee5e
commit 0f95b52c0d
4 changed files with 422 additions and 162 deletions
+6
View File
@@ -154,6 +154,10 @@ const getStardsMemberProjectById = (params) => getAction('/member/tbMemberProjec
const memberDrawTicket = (params) => getAction('/member/tbMemberProjectSubitem/ticketCollection', params) const memberDrawTicket = (params) => getAction('/member/tbMemberProjectSubitem/ticketCollection', params)
// 标协会员单位信息-复制 // 标协会员单位信息-复制
const memberCopy = (params) => getAction('', params) const memberCopy = (params) => getAction('', params)
// 标协会员-会员统计-曲线图数据获取
const memberStatisticsLineData = (params) => getAction('', params)
// 标协会员-会员统计-饼状图数据获取
const memberStatisticsPieData = (params) => getAction('', params)
// 工作组成员维护-调账 // 工作组成员维护-调账
const workingGroupEditAccount = (param) => getAction('/project/payWorkingGroupSubitem/editAccount', param) const workingGroupEditAccount = (param) => getAction('/project/payWorkingGroupSubitem/editAccount', param)
@@ -242,6 +246,8 @@ export {
getStardsMemberProjectById, getStardsMemberProjectById,
memberDrawTicket, memberDrawTicket,
memberCopy, memberCopy,
memberStatisticsLineData,
memberStatisticsPieData,
workingGroupEditAccount, workingGroupEditAccount,
getAllDraftProjects, getAllDraftProjects,
@@ -380,8 +380,8 @@ export default {
}) })
}, },
onDateChange (value, dateString) { onDateChange (value, dateString) {
this.queryParam.estimatedArrivalStartDate = dateString[0] this.queryParam.estimatedArrivalDate_begin = dateString[0]
this.queryParam.estimatedArrivalEndDate = dateString[1] this.queryParam.estimatedArrivalDate_end = dateString[1]
}, },
// 提票 // 提票
handleDrawTicket (record) { handleDrawTicket (record) {
@@ -1,16 +1,93 @@
<template> <template>
<a-card :bordered="false"> <div style="min-width: 1100px" class="analysis-container">
<div class="echarts-box" id="membershipFeesTotalEcharts"></div> <div class="container">
</a-card> <div class="title">历年缴费会费总数</div>
<div class="echarts-box" id="membershipFeesTotalEcharts"></div>
</div>
<div class="container">
<div class="title">单位分类统计</div>
<div class="echarts-box" id="memberPieEcharts"></div>
</div>
<!-- 点击饼图展示相应的单位数据 -->
<stards-member-statistics-modal ref="stardsMemberStatisticsModal"></stards-member-statistics-modal>
</div>
</template> </template>
<script> <script>
import * as echarts from 'echarts/core' import * as echarts from 'echarts/core'
import {
TitleComponent,
TooltipComponent,
GridComponent,
LegendComponent,
} from 'echarts/components'
import { LineChart } from 'echarts/charts'
import { PieChart } from 'echarts/charts'
import { UniversalTransition } from 'echarts/features'
import { CanvasRenderer } from 'echarts/renderers'
import {
memberStatisticsLineData,
memberStatisticsPieData
} from '@/api/incomePaymentsApi'
import { formatMoney } from '@/utils/formatMoney'
import StardsMemberStatisticsModal from './modules/StardsMemberStatisticsModal'
echarts.use([
TitleComponent,
TooltipComponent,
GridComponent,
LineChart,
CanvasRenderer,
UniversalTransition,
LegendComponent,
PieChart
])
export default { export default {
name: 'StardsMemberStatistics', name: 'StardsMemberStatistics',
components: { StardsMemberStatisticsModal },
data () {
return {
lineData: [
{ year: '2022', data: 100 },
{ year: '2023', data: 800 },
{ year: '2024', data: 400 },
], // 曲线图数据
pieData: [
{ name: '团体会员', value: 8 },
{ name: '理事单位', value: 90 },
{ name: '副理事长单位', value: 70 },
] // 饼图数据
}
},
mounted() {
// this.getLineEchartsData()
// this.getPieEchartsData()
this.initLineEcharts()
this.initPieEcharts()
},
methods: { methods: {
initEcharts () { formatMoney,
// 获取曲线图数据
getLineEchartsData () {
memberStatisticsLineData().then(res => {
if (res.success) {
this.lineData = res.result
this.initLineEcharts()
}
})
},
// 获取饼图数据
getPieEchartsData () {
memberStatisticsPieData().then(res => {
if (res.success) {
this.pieData = res.result
this.initPieEcharts()
}
})
},
initLineEcharts () {
let chartDom = document.getElementById('membershipFeesTotalEcharts') let chartDom = document.getElementById('membershipFeesTotalEcharts')
let myChart = echarts.init(chartDom) let myChart = echarts.init(chartDom)
let option let option
@@ -21,30 +98,26 @@ export default {
trigger: 'axis', trigger: 'axis',
formatter: params => { formatter: params => {
// 获取xAxis data中的数据 // 获取xAxis data中的数据
let dataStr = '' let dataStr = `<div>
params.forEach(item => { <div style="margin: 0 8px;">
dataStr += `<div> <span style="display:inline-block;margin-right:5px;width:10px;height:10px;background-color:#fff;border: 2px solid #1BCDC6;border-radius: 50%"></span>
<div style="margin: 0 8px;"> <span style="color: #666">会费总数</span>
<span style="display:inline-block;margin-right:5px;width:10px;height:10px;background-color:#fff;border: 2px solid ${item.color};border-radius: 50%"></span> <span style="float:right;color:#333;margin-left:20px;">${this.formatMoney(params[0].data)}</span>
<span style="color: #666">${item.seriesName}</span> </div>
<span style="float:right;color:#333;margin-left:20px;">${this.formatMoney(item.data)}</span> </div>`
</div>
</div>`
})
return dataStr return dataStr
} }
}, },
legend: { legend: {
data: ['预估收入金额', '确认收入金额', '开票金额', '到账金额'], data: ['会费总数'],
right: '2%' right: '2%'
}, },
grid: { // grid: {
left: '2.4%', // left: '2.4%',
right: '0%', // right: '0%',
bottom: '3%', // bottom: '3%',
containLabel: true // containLabel: true
}, // },
toolbox: {},
xAxis: { xAxis: {
axisLine: { axisLine: {
show: true, show: true,
@@ -62,7 +135,7 @@ export default {
axisTick: { axisTick: {
show: false show: false
}, },
data: xData data: this.lineData.map(item => item.year)
}, },
yAxis: { yAxis: {
axisLine: { axisLine: {
@@ -87,160 +160,122 @@ export default {
}, },
}, },
series: [ series: [
// {
// name: '年度待确收金额',
// type: 'line',
// showSymbol: false,
// symbol: 'circle',
// symbolSize: 8,
// data: this.echartsData.allMoney,
// itemStyle: {
// emphasis: {
// color: '#fff',//拐点颜色
// borderColor: '#1BCDC6',//拐点边框颜色
// borderWidth: 2//拐点边框大小
// }
// },
// areaStyle: {
// opacity: 0.2,
// color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
// {
// offset: 0,
// color: '#1BCDC6'
// },
// {
// offset: 1,
// color: '#ffffff'
// }
// ])
// },
// },
{ {
name: '预估收入金额', data: this.lineData.map(item => item.data),
type: 'line', type: 'line',
showSymbol: false, smooth: true
symbol: 'circle', }
symbolSize: 8, ]
data: this.echartsData.estimatedArrivalMoney, }
option && myChart.setOption(option)
window.addEventListener('resize', () => {
myChart.resize()
})
},
initPieEcharts() {
let color = ['#069F99', '#88C87E', '#6D7FD0', '#FA9D81', '#A5B3FF']
let echartsData = this.pieData
// echartsData = this.initPoint(echartsData, color)
let chartDom = document.getElementById('memberPieEcharts')
let myChart = echarts.init(chartDom)
let option = {
tooltip: {
show: true,
trigger: 'item',
formatter: (param) => {
return `<div>
<span style="display:inline-block;margin-right:4px;border-radius:10px;width:10px;height:10px;background-color:${param.color};"></span>
<span style="color: #999">${param.name}</span>
<span style="color: #333">${param.value}</span>
</div>`
}
},
legend: {
left:'15%',
bottom: '2%',
right: '2%',
padding: [0, 50, 0, 50],
itemGap:50
},
labelLine: {
lineStyle: {
color: '#999'
}
},
series: [
{
color: color,
type: 'pie',
radius: ['30%', '60%'],
itemStyle: { itemStyle: {
normal: {lineStyle:{type: 'dashed'}}, borderColor: '#fff',
emphasis: { borderWidth: 2
color: '#fff',//拐点颜色 },
borderColor: '#1BCDC6',//拐点边框颜色 label: {
borderWidth: 2//拐点边框大小 show: true,
formatter: '{pre|}{d}%',
rich: {
pre: {
width: 4,
height: 4,
borderRadius: [4, 4, 4, 4]
}
} }
}, },
areaStyle: { labelLine: {
opacity: 0.2, show: true
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: '#1BCDC6'
},
{
offset: 1,
color: '#ffffff'
}
])
}, },
}, data: echartsData
{
name: '确认收入金额',
type: 'line',
showSymbol: false,
symbol: 'circle',
symbolSize: 8,
data: this.echartsData.confirmAmount,
itemStyle: {
emphasis: {
color: '#fff',//拐点颜色
borderColor: '#EBAB91',//拐点边框颜色
borderWidth: 2//拐点边框大小
}
},
areaStyle: {
opacity: 0.2,
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: '#EBAB91'
},
{
offset: 1,
color: '#ffffff'
}
])
},
},
{
name: '开票金额',
type: 'line',
showSymbol: false,
symbol: 'circle',
symbolSize: 8,
data: this.echartsData.billMoney,
itemStyle: {
emphasis: {
color: '#fff',//拐点颜色
borderColor: '#9CB7F2',//拐点边框颜色
borderWidth: 2//拐点边框大小
}
},
areaStyle: {
opacity: 0.2,
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: '#9CB7F2'
},
{
offset: 1,
color: '#ffffff'
}
])
},
},
{
name: '到账金额',
type: 'line',
showSymbol: false,
symbol: 'circle',
symbolSize: 8,
data: this.echartsData.comeAllMoney,
itemStyle: {
emphasis: {
color: '#fff',//拐点颜色
borderColor: '#B6F1AC',//拐点边框颜色
borderWidth: 2//拐点边框大小
}
},
areaStyle: {
opacity: 0.2,
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: '#B6F1AC'
},
{
offset: 1,
color: '#ffffff'
}
])
},
} }
] ]
} }
option && myChart.setOption(option) option && myChart.setOption(option)
this.echartsInstace = myChart
window.addEventListener('resize', () => { window.addEventListener('resize', () => {
myChart.resize() myChart.resize()
}) })
} myChart.on('click', this.chartClickFunc)
},
// 饼图的点击事件
chartClickFunc(params) {
console.log(params)
// 获取当前点击的饼状图的名字
// let queryData = {
// name: params.data.name, // 名字
// type: params.dataIndex + 1, // 序号
// departCode: this.queryParam.departCode, // 部门code
// }
// this.$refs.stardsMemberStatisticsModal.show(queryData)
},
} }
} }
</script> </script>
<style scoped> <style scoped lang="less">
.analysis-container{
display: flex;
gap: 10px;
}
.container {
position: relative;
padding: 20px;
box-sizing: border-box;
width: 100%;
background: #FFFFFF;
}
.echarts-box {
min-width: 550px;
width: 100%;
height: 400px;
}
.title {
text-align: left;
font-weight: 500;
color: #333;
font-size: 20px;
}
</style> </style>
@@ -0,0 +1,219 @@
<template>
<j-modal
:title="unitName + title"
:width="width"
:visible="visible"
:confirmLoading="confirmLoading"
switchFullscreen
:footer="null"
@ok="handleOk"
@cancel="handleCancel"
cancelText="关闭">
<a-spin :spinning="confirmLoading">
<!-- <div class="table-operator">-->
<!-- <a-button type="primary" icon="export" @click="handleExportXls(seriesName + '应收账款')">导出</a-button>-->
<!-- </div>-->
<a-table
ref="table"
size="middle"
bordered
rowKey="projectId"
:columns="columns"
:scroll="{x: 1500}"
:dataSource="dataSource"
:pagination="ipagination"
:loading="loading"
@change="handleTableChange"
:class="dataSource.length === 0 ? 'show-scroll' : ''"
class="j-table-force-nowrap main-table">
<!-- 项目名称-->
<template slot="projectName" slot-scope="text">
<a-tooltip>
<!-- primary-color" @click="openDetailModal(record)-->
<template slot="title">{{ text }}</template>
<div class="table-text">{{ text }}</div>
</a-tooltip>
</template>
<template slot="text" slot-scope="text">
<a-tooltip>
<template slot="title">{{ text }}</template>
<div class="table-text">{{ text }}</div>
</a-tooltip>
</template>
<template slot="allMoney" slot-scope="text">
<a-tooltip>
<template slot="title">{{ formatMoney(text) }}</template>
<div class="table-text">{{ formatMoney(text) }}</div>
</a-tooltip>
</template>
<!-- 是否打包-->
<template slot="pack" slot-scope="text, record">
<status-slot :statu-obj="record" :status-no="text" :status-type="true"></status-slot>
</template>
<template slot="footer" v-if="dataSource.length > 0">
<a-table
size="middle"
ref="footTable"
:rowKey="record => record.id"
:columns="columnsFooter"
:scroll="{x: 1500}"
:dataSource="footerDataSource"
:showHeader="false"
:pagination="false"
class="j-table-force-nowrap footer-table">
<!-- 项目名称-->
<template slot="projectName" slot-scope="text">
<!-- primary-color @click="openDetailModal(record)"-->
<a-tooltip>
<template slot="title">{{ text }}</template>
<div class="table-text " >{{ text }}</div>
</a-tooltip>
</template>
<template slot="text" slot-scope="text">
<a-tooltip>
<template slot="title">{{ text }}</template>
<div class="table-text">{{ text }}</div>
</a-tooltip>
</template>
<template slot="allMoney" slot-scope="text">
<a-tooltip>
<template slot="title">{{ formatMoney(text) }}</template>
<div class="table-text">{{ formatMoney(text) }}</div>
</a-tooltip>
</template>
</a-table>
</template>
</a-table>
</a-spin>
</j-modal>
</template>
<script>
import {getAction} from '@/api/manage'
const defaultSorter = {
column: 'createTime',
order: 'desc'
}
export default {
name: 'StardsMemberStatisticsModal',
data () {
return {
unitName: '', // 单位名称
title: '详情',
width: 1000,
visible: false,
confirmLoading: false,
columns: [],
dataSource: [],
ipagination: {
current: 1,
pageSize: 10,
pageSizeOptions: ['10', '20', '30', '50', '100'],
showTotal: (total, range) => {
return range[0] + '-' + range[1] + ' 共' + total + '条'
},
showQuickJumper: true,
showSizeChanger: true,
total: 0
},
loading: false,
/* 排序参数 */
isorter: {
column: 'createTime',
order: 'desc',
},
url: {
list: ''
}
}
},
methods: {
show (param) {
this.loadData(param)
this.visible = true
},
loadData(arg) {
if (!this.url.list) {
this.$message.error('请设置url.list属性!')
return
}
//加载数据 若传入参数1则加载第一页的内容
if (arg === 1) {
this.ipagination.current = 1
}
let params = this.getQueryParams()//查询条件
this.loading = true
getAction(this.url.list, params).then((res) => {
if (res.success) {
this.dataSource = res.result.pageList.records
// let obj = {
// id: '1',
// title: '总计',
// allMoney: res.result.sumOfMoney || '0.00' + '',
// comeAllMoney: res.result.sumOfReallyMoney || '0.00' + '',
// billMoney: res.result.sumOfBillMoney || '0.00' + '',
// confirmAmount: res.result.sumOfConfirmAmount || '0.00' + ''
// }
// this.footerDataSource = [obj]
if (res.result.pageList.total) {
this.ipagination.total = res.result.pageList.total
} else {
this.ipagination.total = 0
}
}
if (this.dataSource.length > 0) {
this.$nextTick(() => {
this.setScroll()
})
}
if (res.code === 510) {
this.$message.warning(res.message)
}
this.loading = false
}).finally(() => {
this.loading = false
})
},
handleTableChange(pagination, filters, sorter) {
//分页、排序、筛选变化时触发
//筛选
if (Object.keys(sorter).length > 0) {
this.isorter.column = sorter.field
if (sorter.order) {
// 如果当前有列选中筛选条件
this.isorter.order = 'ascend' == sorter.order ? 'asc' : 'desc'
} else {
// 没有筛选值则 isorter 重置为初始值
this.isorter.column = defaultSorter.column
this.isorter.order = defaultSorter.order
}
} else {
this.isorter.column = defaultSorter.column
this.isorter.order = defaultSorter.order
}
this.ipagination = pagination
this.loadData()
},
}
}
</script>
<style scoped>
</style>