Files
UNION_HUTB/target/classes/views/platform/member/inquire/DataBoard.html
T
2026-09-09 09:14:28 +08:00

481 lines
18 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!--#
layout("/layouts/platform.html"){
#-->
<style>
.top-col {
background-color: white;
position: relative;
box-sizing: border-box;
padding: 20px;
width: calc((100% - (20px * 3)) / 4);
}
.top-col:not(:last-child), .center-col:not(:last-child) {
margin-right: 20px;
}
.col-title {
color: rgba(0, 0, 0, .45);
font-size: 14px;
margin-bottom: 10px;
}
.top-col-member-number {
font-size: 30px;
color: rgba(0, 0, 0, .85);
}
.top-col-chart {
height: 80px;
width: 100%;
position: relative;
}
.center-col {
background-color: white;
position: relative;
box-sizing: border-box;
padding: 20px;
width: calc((100% - (20px * 1)) / 2);
}
.idx {
display: flex;
justify-content: center;
align-items: center;
color: rgba(0, 0, 0, .85);
width: 20px;
height: 20px;
border-radius: 50%;
background-color: #f0f0f0;
font-size: 12px;
}
.idx-rank {
color: white !important;
background-color: #314659 !important;
}
.el-table__body-wrapper::-webkit-scrollbar {
display: none; /* Chrome Safari */
}
.el-table__body-wrapper {
scrollbar-width: none; /* firefox */
-ms-overflow-style: none; /* IE 10+ */
overflow-x: hidden;
overflow-y: auto;
}
</style>
<div id="app" v-cloak>
<guava>
<el-row style="background-color: #f0f2f5" type="flex">
<el-col class="top-col" v-loading="loading.memberNumber">
<div class="col-title">会员数</div>
<div class="top-col-member-number">{{memberNumberData.memberNum}}<span
style="font-size: 14px">&ensp;</span></div>
<div style="color: rgba(0,0,0,.85);margin-top: 20px;font-size: 14px;display: flex;align-items: center;justify-content:flex-end;">
年同比 {{memberNumberData.ratio}}&ensp;
<svg aria-hidden="true" data-icon="caret-up" fill="currentColor" focusable="false"
height="1em"
style="color: #67C23A"
v-if="memberNumberData.diff>=0"
viewBox="0 0 1024 1024" width="1em">
<path d="M858.9 689L530.5 308.2c-9.4-10.9-27.5-10.9-37 0L165.1 689c-12.2 14.2-1.2 35 18.5 35h656.8c19.7 0 30.7-20.8 18.5-35z"></path>
</svg>
<svg aria-hidden="true" data-icon="caret-up" fill="currentColor" focusable="false"
height="1em"
style="color: #F56C6C"
v-else
viewBox="0 0 1024 1024" width="1em">
<path d="M840.4 300H183.6c-19.7 0-30.7 20.8-18.5 35l328.4 380.8c9.4 10.9 27.5 10.9 37 0L858.9 335c12.2-14.2 1.2-35-18.5-35z"></path>
</svg>
</div>
</el-col>
<el-col class="top-col" v-loading="loading.growthTrend">
<div class="col-title">增长趋势</div>
<div class="top-col-chart" id="growthTrendChart"></div>
</el-col>
<el-col class="top-col" v-loading="loading.memberPercentage">
<div class="col-title">会员占比</div>
<div class="top-col-chart" id="memberPercentageChart"
style="position: absolute;height: 120px;right: -10%;bottom: 20px"></div>
</el-col>
<el-col class="top-col" v-loading="loading.growthTrend">
<div class="col-title">男女占比</div>
<div class="top-col-chart" id="memberSexPercentageChart"
style="position: absolute;height: 120px;right: -10%;bottom: 20px"></div>
</el-col>
</el-row>
<el-row style="background-color: #f0f2f5;margin-top: 20px" type="flex">
<el-col class="center-col" v-loading="loading.unionMember">
<div class="col-title">工会会员数</div>
<div id="unionMemberChart" style="width: 100%;height: 100px"></div>
<el-table :data="unionMember" :header-cell-style="{background:'#FAFAFA'}"
height="calc(100vh - 160px - 300px)"
row-key="id" style="width: 100%;margin-top: 20px">
<el-table-column label="序号" width="100px">
<template scope="{$index}">
<div class="idx idx-rank" v-if="$index<3">{{$index+1}}</div>
<div class="idx" v-else>{{$index+1}}</div>
</template>
</el-table-column>
<el-table-column align="center" header-align="center" label="院级工会" prop="unioncode"
show-overflow-tooltip sortable>
<template scope="{row}">
{{row.unionname}} {{isDisPlayCode?''+row.unioncode+'':null}}
</template>
</el-table-column>
<el-table-column align="center" header-align="center" label="会员人数" prop="value"
show-overflow-tooltip
sortable
width="120px"></el-table-column>
</el-table>
</el-col>
<el-col class="center-col">
<div class="col-title">在职状态</div>
<div id="userStateMemberChart"
style="width: 100%;height:calc(50% - 35px);box-sizing: border-box;padding: 30px 10px"
v-loading="loading.userStateMember"></div>
<div class="col-title">人员类型</div>
<div id="personTypeMemberChart"
style="width: 100%;height:calc(50% - 35px);box-sizing: border-box;padding: 30px 10px"
v-loading="loading.personTypeMember"></div>
</el-col>
</el-row>
</guava>
</div>
<script>
const chart = {
growthTrendChart: undefined,
memberPercentageChart: undefined,
memberSexPercentageChart: undefined,
unionMemberChart: undefined,
personTypeMemberChart: undefined,
userStateMemberChart: undefined,
}
const vue = new Vue({
el: '#app',
mixins: [],
data() {
return {
loading: {
memberNumber: false,
growthTrend: false,
memberPercentage: false,
memberSexPercentage: false,
unionMember: false,
personTypeMember: false,
userStateMember: false,
},
memberNumberData: {
memberNum: '--',
lastYearMemberNum: '--',
ratio: '0.0%',
diff: 0,
},
memberPercentage: '--',
unionMember: [],
}
},
components: {},
methods: {
/**
* 会员数
* @returns {Promise<void>}
*/
async getMemberNumber() {
this.loading.memberNumber = true
const resp = await $.get(loc() + '/memberNumber')
if (resp.code === 0) {
const {data: {memberNum, lastYearMemberNum}} = resp
const diff = memberNum - lastYearMemberNum
const ratio = (lastYearMemberNum ? (Math.abs(diff) / lastYearMemberNum * 100) : diff / 1 * 10).toFixed(2) + " %"
this.memberNumberData = {memberNum, lastYearMemberNum, diff, ratio}
this.loading.memberNumber = false
} else {
this.notifyWarning(resp.msg)
}
},
/**
* 增长趋势
* @returns {Promise<void>}
*/
async getGrowthTrend() {
this.loading.growthTrend = true
const resp = await $.get(loc() + '/growthTrend')
this.loading.growthTrend = false
if (resp.code === 0) {
const {data} = resp
const labels = data.map(v => v.label)
const values = data.map(v => v.value)
if (chart.growthTrendChart) {
chart.growthTrendChart.changeData(values)
return
}
chart.growthTrendChart = new G2Plot.TinyArea('growthTrendChart', {
autoFit: true,
data: values,
smooth: true,
showContent: true,
areaStyle: {
fill: '#d6e3fd',
},
tooltip: {
customContent: function (i, data) {
if (labels[i]) {
return labels[i] + '-' + data[0]?.data?.y + '人';
}
return ''
},
},
});
chart.growthTrendChart.render();
} else {
this.notifyWarning(resp.msg)
}
},
/**
* 会员占比
* @returns {Promise<void>}
*/
async getMemberPercentage() {
this.loading.memberPercentage = true
const resp = await $.get(loc() + '/memberPercentage')
this.loading.memberPercentage = false
if (resp.code === 0) {
const {data} = resp
this.memberPercentage = data.toFixed(2)
if (chart.memberPercentageChart) {
chart.memberPercentageChart.changeData(data)
return
}
chart.memberPercentageChart = new G2Plot.Liquid('memberPercentageChart', {
outline: {
border: 4,
distance: 8,
},
wave: {
length: 128,
},
autoFit: true,
percent: data,
statistic: {
content: {
style: {
fontSize: 16
}
}
}
});
chart.memberPercentageChart.render();
} else {
this.notifyWarning(resp.msg)
}
},
/**
* 男女占比
* @returns {Promise<void>}
*/
async getMemberSexPercentage() {
this.loading.memberSexPercentage = true
const resp = await $.get(loc() + '/memberSexPercentage')
this.loading.memberSexPercentage = false
if (resp.code === 0) {
const {data} = resp
if (chart.memberSexPercentageChart) {
chart.memberSexPercentageChart.changeData(data)
return
}
chart.memberSexPercentageChart = new G2Plot.Pie('memberSexPercentageChart', {
data,
angleField: 'value',
colorField: 'type',
legend: false,
label: {
formatter: () => '',
},
interactions: [{type: 'element-active'}], color: ['#409EFF', '#F56C6C'],
});
chart.memberSexPercentageChart.render();
} else {
this.notifyWarning(resp.msg)
}
},
/**
* 各工会会员数
* @returns {Promise<void>}
*/
async getUnionMember() {
this.loading.unionMember = true
const resp = await $.get(loc() + '/unionMember')
this.loading.unionMember = false
if (resp.code === 0) {
const {chartData, tableData} = resp.data
this.unionMember = tableData
const labels = chartData.map(v => v.unionname)
const values = chartData.map(v => v.value)
if (chart.unionMemberChart) {
chart.unionMemberChart.changeData(values)
return
}
chart.unionMemberChart = new G2Plot.TinyArea('unionMemberChart', {
autoFit: true,
data: values,
smooth: true,
tooltip: {
customContent: function (i, data) {
if (labels[i]) {
return labels[i] + '- ' + data[0]?.data?.y + '人';
}
return ''
},
},
})
chart.unionMemberChart.render();
} else {
this.notifyWarning(resp.msg)
}
},
/**
* 根据人员类型查找会员数
* @returns {Promise<void>}
*/
async getPersonTypeMember() {
this.loading.personTypeMember = true
const resp = await $.get(loc() + '/personTypeMember')
this.loading.personTypeMember = false
if (resp.code === 0) {
const {data} = resp
if (chart.personTypeMemberChart) {
chart.personTypeMemberChart.changeData(data)
return
}
chart.personTypeMemberChart = new G2Plot.Column('personTypeMemberChart', {
data,
autoFit: true,
xField: 'label',
yField: 'value',
label: {
// 可手动配置 label 数据标签位置
position: 'middle', // 'top', 'bottom', 'middle',
// 配置样式
style: {
fill: '#FFFFFF',
opacity: 0.6,
},
},
xAxis: {
label: {
autoHide: true,
autoRotate: false,
},
},
meta: {
label: {
alias: '类型',
},
value: {
alias: '会员数',
},
},
});
chart.personTypeMemberChart.render()
} else {
this.notifyWarning(resp.msg)
}
},
/**
* 根据在职状态查找会员数
* @returns {Promise<void>}
*/
async getUserStateMember() {
this.loading.userStateMember = true
const resp = await $.get(loc() + '/userStateMember')
this.loading.userStateMember = false
if (resp.code === 0) {
const {data} = resp
if (chart.userStateMemberChart) {
chart.userStateMemberChart.changeData(data)
return
}
chart.userStateMemberChart = new G2Plot.Radar('userStateMemberChart', {
data,
xField: 'label',
yField: 'value',
appendPadding: [0, 10, 0, 10],
meta: {
value: {
alias: '会员数量',
min: 0,
nice: true,
formatter: (v) => parseInt(v),
},
},
xAxis: {
tickLine: null,
},
yAxis: {
label: false,
grid: {
alternateColor: 'rgba(0, 0, 0, 0.04)',
},
},
// 开启辅助点
point: {
size: 2,
},
area: {},
});
chart.userStateMemberChart.render();
} else {
this.notifyWarning(resp.msg)
}
},
initData() {
this.getMemberNumber()
this.getGrowthTrend()
this.getMemberPercentage()
this.getMemberSexPercentage()
this.getUnionMember()
this.getPersonTypeMember()
this.getUserStateMember()
},
},
mounted() {
this.initData()
}
})
</script>
<!--#
}
#-->