408 lines
13 KiB
Vue
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>
|