Files
dvcp_v2_webapp/project/pingchang/apps/AppTwoNewOrganizationSta/staPane.vue
2022-10-21 17:37:41 +08:00

408 lines
13 KiB
Vue

<template>
<section class="staPane">
<ai-list isTabs>
<template #blank>
<ai-tree-menu title="组织目录" @search="v=>$refs.areaTree.filter(v)">
<el-tree ref="areaTree" lazy node-key="id" :load="getAreas"
:filter-node-method="handleTreeFilter"
:default-expanded-keys="[selectedAreaId]"
@node-click="handleSelectArea"
:props="{label:'name',isLeaf:'leaf'}"/>
</ai-tree-menu>
<el-scrollbar>
<div class="mainPane">
<el-row type="flex">
<div class="cardPane orgCountMap" v-for="v in orgCountMap" :key="v.key">
<b v-html="v.name"/>
<span v-html="v.desc"/>
<b class="count" v-html="v.v1"/>
</div>
</el-row>
<el-row type="flex">
<div class="cardPane">
<ai-title title="各类组织成员数量"/>
<div id="orgMemberCountMapChart"/>
</div>
<div class="cardPane">
<ai-title title="待建党组织关注度统计"/>
<div id="buildPartyCountMapChart"/>
</div>
</el-row>
<el-row type="flex" v-if="top.bizType==0">
<div class="cardPane">
<ai-title title="新经济组织类型分布"/>
<div id="companyCategoryCountMapChart"/>
</div>
<div class="cardPane">
<ai-title title="安全隐患类型占比"/>
<div id="dangerousTypeCountMapChart"/>
</div>
</el-row>
<el-row type="flex" v-if="top.bizType==1">
<div class="cardPane">
<ai-title title="新社会组织类型分布"/>
<div id="socialTypeCountMapChart"/>
</div>
<div class="cardPane">
<ai-title title="外资背景统计"/>
<div id="foreignCountMapChart"/>
</div>
</el-row>
</div>
</el-scrollbar>
</template>
</ai-list>
</section>
</template>
<script>
import {mapState} from "vuex";
import * as echarts from "echarts";
export default {
name: "staPane",
label: "两新组织统计",
props: {
instance: Function,
dict: Object,
permissions: Function,
},
inject: ['top'],
computed: {
...mapState(['user']),
typeName() {
return this.top.bizType == 0 ? '新经济' : '新社会'
},
orgCountMap() {
let init = [
{name: `${this.typeName}组织总量`, desc: `当前所有的${this.typeName}组织总数量`, key: "zzzl", v1: 0},
{name: "含有党群组织的数量", desc: `含有党群组织的${this.typeName}组织总数量`, key: "dqzzsl", v1: 0},
{name: "具备建立中共党组织条件的数量", desc: "具备条件但尚未建立党组织的数量", key: "jbjldzztjsl", v1: 0}
]
return init.map(e => ({
...e,
v1: Number(this.meta.orgCountMap?.[e.key]) || 0
}))
},
chartOps() {
let orgMemberCountMapData = this.dict.getDict('orgMemberTypes').map(e => [e.dictName, Number(this.meta?.orgMemberCountMap?.[e.dictValue] || 0)]),
buildPartyCountMapData = this.dict.getDict('twoNewOrgConcernDegree').map(e => [e.dictName, Number(this.meta?.buildPartyCountMap?.[e.dictValue] || 0)]),
companyCategoryCountMapData = this.dict.getDict('twoNewOrgCompanyCategory').map(e => [e.dictName, Number(this.meta?.companyCategoryCountMap?.[e.dictValue] || 0)]),
dangerousTypeCountMapData = this.dict.getDict('twoNewOrgDangerousType').slice(1).map(e => [e.dictName, Number(this.meta?.dangerousTypeCountMap?.[e.dictValue] || 0)]),
socialTypeCountMapData = this.dict.getDict('twoNewOrgSocialType').map(e => [e.dictName, Number(this.meta?.socialTypeCountMap?.[e.dictValue] || 0)]),
foreignCountMapData = this.dict.getDict('twoNewOrgIsForeign').map(e => [e.dictName, Number(this.meta?.foreignCountMap?.[e.dictValue] || 0)])
return {
orgMemberCountMap: {
tooltip: {},
grid: {
left: 82,
right: 40,
bottom: 80,
top: 30
},
xAxis: {
type: 'category', axisLine: {lineStyle: {color: '#D8DDE8'}}, axisTick: false,
axisLabel: {color: '#666', margin: 19}
},
yAxis: {
type: 'value', axisLine: false, min: 0, minInterval: 1,
axisLabel: {color: '#666', margin: 19},
splitLine: {lineStyle: {color: '#D8DDE8', type: 'dashed'}}
},
series: {
type: 'bar',
barWidth: 24,
itemStyle: {color: '#22AA99'},
emphasis: {itemStyle: {color: "#2266FF"}},
},
dataset: {
source: orgMemberCountMapData
}
},
buildPartyCountMap: {
tooltip: {},
grid: {
left: 82,
right: 40,
bottom: 80,
top: 30
},
xAxis: {
type: 'category', axisLine: {lineStyle: {color: '#D8DDE8'}}, axisTick: false,
axisLabel: {color: '#666', margin: 19}
},
yAxis: {
type: 'value', axisLine: false, min: 0, minInterval: 1,
axisLabel: {color: '#666', margin: 19},
splitLine: {lineStyle: {color: '#D8DDE8', type: 'dashed'}}
},
series: {
type: 'bar',
barWidth: 24,
itemStyle: {color: '#22AA99'},
emphasis: {itemStyle: {color: "#2266FF"}},
},
dataset: {
source: buildPartyCountMapData
}
},
companyCategoryCountMap: {
legend: {
orient: 'vertical', left: 220, y: 'center',
itemGap: 4, itemWidth: 8, itemHeight: 8,
formatter: name => {
let item = companyCategoryCountMapData.find(e => e?.[0] == name)
return ` {a|${name.replace(/(.{10}).*/g, '$1...')}} {b|${item?.[1]}}`
},
tooltip: {show: true},
textStyle: {
rich: {
a: {color: '#666', width: 130, fontSize: 14, lineHeight: 22},
b: {fontWeight: 'bold', align: 'right', color: '#333', fontSize: 14, width: 54, lineHeight: 22}
}
},
},
tooltip: {},
color: ['#02A499', '#F8B425', '#EC4461', '#D846E4', '#38A4F8'],
series: {
name: '重点青少年类型分布',
center: [100, '50%'], radius: 80,
type: 'pie', label: false,
itemStyle: {borderColor: '#fff', borderWidth: 2},
},
dataset: {
source: companyCategoryCountMapData
}
},
dangerousTypeCountMap: {
legend: {
orient: 'vertical', left: 220, y: 'center',
itemGap: 4, itemWidth: 8, itemHeight: 8,
formatter: name => {
let item = dangerousTypeCountMapData.find(e => e?.[0] == name)
return ` {a|${name.replace(/(.{10}).*/g, '$1...')}} {b|${item?.[1]}}`
},
tooltip: {show: true},
textStyle: {
rich: {
a: {color: '#666', width: 166, fontSize: 14, lineHeight: 22},
b: {fontWeight: 'bold', align: 'right', color: '#333', fontSize: 14, lineHeight: 22}
}
},
},
tooltip: {},
color: ['#02A499', '#F8B425', '#EC4461', '#D846E4', '#38A4F8'],
series: {
name: '重点青少年性别分布', type: 'pie',
center: [100, '50%'], radius: [40, 80], label: false,
itemStyle: {borderColor: '#fff', borderWidth: 2},
},
dataset: {
source: dangerousTypeCountMapData
}
},
socialTypeCountMap: {
legend: {
orient: 'vertical', left: 220, y: 'center',
itemGap: 4, itemWidth: 8, itemHeight: 8,
formatter: name => {
let item = socialTypeCountMapData.find(e => e?.[0] == name)
return ` {a|${name.replace(/(.{10}).*/g, '$1...')}} {b|${item?.[1]}}`
},
tooltip: {show: true},
textStyle: {
rich: {
a: {color: '#666', width: 130, fontSize: 14, lineHeight: 22},
b: {fontWeight: 'bold', align: 'right', color: '#333', fontSize: 14, width: 54, lineHeight: 22}
}
},
},
tooltip: {},
color: ['#02A499', '#F8B425', '#EC4461', '#D846E4', '#38A4F8'],
series: {
name: '重点青少年类型分布',
center: [100, '50%'], radius: 80,
type: 'pie', label: false,
itemStyle: {borderColor: '#fff', borderWidth: 2},
},
dataset: {
source: socialTypeCountMapData
}
},
foreignCountMap: {
legend: {
orient: 'vertical', left: 220, y: 'center',
itemGap: 4, itemWidth: 8, itemHeight: 8,
formatter: name => {
let item = foreignCountMapData.find(e => e?.[0] == name)
return ` {a|${name.replace(/(.{10}).*/g, '$1...')}} {b|${item?.[1]}}`
},
tooltip: {show: true},
textStyle: {
rich: {
a: {color: '#666', width: 166, fontSize: 14, lineHeight: 22},
b: {fontWeight: 'bold', align: 'right', color: '#333', fontSize: 14, lineHeight: 22}
}
},
},
tooltip: {},
color: ['#02A499', '#F8B425', '#EC4461', '#D846E4', '#38A4F8'],
series: {
name: '重点青少年性别分布', type: 'pie',
center: [100, '50%'], radius: [40, 80], label: false,
itemStyle: {borderColor: '#fff', borderWidth: 2},
},
dataset: {
source: foreignCountMapData
}
},
}
}
},
data() {
return {
selectedAreaId: "",
meta: {},
charts: {
orgMemberCountMap: null,
buildPartyCountMap: null,
companyCategoryCountMap: null,
dangerousTypeCountMap: null,
socialTypeCountMap: null,
foreignCountMap: null,
}
}
},
methods: {
getAreas(node, resolve) {
if (node.level == 0) {
let {areaName: name, areaId: id} = this.user.info
resolve([{name, id}])
} else {
let {id} = node?.data
this.instance.post("/admin/area/queryAreaByParentId", null, {
params: {id}
}).then(res => {
if (res?.data) {
resolve(res.data.map(e => ({...e, leaf: e.type == 5})))
}
})
}
},
handleTreeFilter(v, data) {
return data.name.indexOf(v) > -1
},
getStaData() {
let {bizType} = this.top
return this.instance.post("/app/apptwoneworganization/countByAreaIdAndBizType", null, {
params: {areaId: this.selectedAreaId, bizType}
}).then(res => {
if (res?.data) {
this.meta = res.data
}
})
},
handleSelectArea({id}) {
this.selectedAreaId = id
this.getStaData().then(() => this.getChartData())
},
initEcharts() {
Object.keys(this.charts).map(id => {
let ref = document.getElementById(id + "Chart")
if (ref) this.charts[id] = echarts.init(ref)
})
this.getChartData()
},
getChartData() {
Object.keys(this.charts).map(e => {
this.charts[e]?.setOption(this.chartOps?.[e])
})
}
},
created() {
this.dict.load("twoNewOrgCompanyCategory", 'twoNewOrgDangerousType',
'twoNewOrgConcernDegree', 'orgMemberTypes', 'twoNewOrgSocialType', 'twoNewOrgIsForeign')
this.selectedAreaId = JSON.parse(JSON.stringify(this.user.info.areaId))
},
mounted() {
this.initEcharts()
this.getStaData().then(() => this.getChartData())
}
}
</script>
<style lang="scss" scoped>
.staPane {
height: 100%;
::v-deep .ai-list__blank {
display: flex;
height: 100% !important;
gap: 16px;
.el-scrollbar {
flex: 1;
min-width: 0;
.el-scrollbar__wrap {
overflow-x: hidden;
}
}
.mainPane {
display: flex;
flex-direction: column;
gap: 16px;
& > .el-row {
width: 100%;
gap: 16px;
height: auto;
& > div {
flex: 1;
min-width: 0;
}
}
}
.cardPane {
background: #FFFFFF;
box-shadow: 0 0 4px 0 rgba(0, 0, 0, 0.05);
border-radius: 4px;
&.orgCountMap {
padding: 16px 24px;
box-sizing: border-box;
height: 120px;
font-size: 14px;
color: #888;
display: flex;
flex-direction: column;
gap: 8px;
b {
font-size: 16px;
color: #333333;
&.count {
font-size: 24px;
color: #2266FF;
}
}
}
}
}
#orgMemberCountMapChart, #buildPartyCountMapChart {
width: 100%;
height: 270px;
}
#companyCategoryCountMapChart, #dangerousTypeCountMapChart, #socialTypeCountMapChart, #foreignCountMapChart {
width: 100%;
height: 220px;
}
}
</style>