Browse Source

监督端首页迁移

dev-V1.0.6
wangmingyong@163.com 3 months ago
parent
commit
9297b00f22
  1. 53
      zdxt-web-client/zdxt-admin-plus-ui/src/router/index.ts
  2. 6
      zdxt-web-client/zdxt-admin-plus-ui/src/views/home/index.vue
  3. 11
      zdxt-web-client/zdxt-admin-plus-ui/src/views/supervision/statistical/city-direct/index.vue
  4. 80
      zdxt-web-client/zdxt-admin-plus-ui/src/views/supervision/statistical/components/TopSixMetrics.vue
  5. 439
      zdxt-web-client/zdxt-admin-plus-ui/src/views/supervision/statistical/home/index copy.vue
  6. 1378
      zdxt-web-client/zdxt-admin-plus-ui/src/views/supervision/statistical/home/index.vue
  7. 45
      zdxt-web-client/zdxt-admin-plus-ui/src/views/supervision/statistical/styles/analysis-layout.css
  8. 2
      zdxt-web-client/zdxt-admin-plus-ui/src/views/supervision/statistical/utils/chartOptions.ts

53
zdxt-web-client/zdxt-admin-plus-ui/src/router/index.ts

@ -70,7 +70,8 @@ export const constantRoutes: RouteRecordRaw[] = [
children: [
{
path: '/home',
component: () => import('@/views/home/index.vue'),
// component: () => import('@/views/home/index.vue'),
component: () => import('@/views/supervision/statistical/home/index.vue'),
name: 'Home',
meta: { title: '首页', icon: 'dashboard', affix: true }
}
@ -314,31 +315,31 @@ export const constantRoutes: RouteRecordRaw[] = [
}
]
},
// {
// path: '/enforcement-code/statistical',
// component: Layout,
// hidden: true,
// children: [
// {
// path: 'home',
// component: () => import('@/views/supervision/statistical/home/index.vue'),
// name: 'StatisticalHome',
// meta: { title: '首页统计分析', fullscreen: true }
// },
// {
// path: 'city-direct',
// component: () => import('@/views/supervision/statistical/city-direct/index.vue'),
// name: 'StatisticalCityDirect',
// meta: { title: '市直综合分析', fullscreen: true }
// },
// {
// path: 'district-direct',
// component: () => import('@/views/supervision/statistical/district-direct/index.vue'),
// name: 'StatisticalDistrictDirect',
// meta: { title: '各区综合分析', fullscreen: true }
// }
// ]
// }
{
path: '/enforcement-code/statistical',
component: Layout,
hidden: true,
children: [
{
path: 'home',
component: () => import('@/views/supervision/statistical/home/index.vue'),
name: 'StatisticalHome',
meta: { title: '首页统计分析', fullscreen: true }
},
{
path: 'city-direct',
component: () => import('@/views/supervision/statistical/city-direct/index.vue'),
name: 'StatisticalCityDirect',
meta: { title: '市直综合分析', fullscreen: true }
},
{
path: 'district-direct',
component: () => import('@/views/supervision/statistical/district-direct/index.vue'),
name: 'StatisticalDistrictDirect',
meta: { title: '各区综合分析', fullscreen: true }
}
]
}
];
// 动态路由,基于用户权限动态去加载

6
zdxt-web-client/zdxt-admin-plus-ui/src/views/home/index.vue

@ -548,7 +548,7 @@ async function loadAdminTrend() {
let { times, ins, ent } = res ? normalizeTimeSeries(unwrapData(res)) : { times: [] as string[], ins: [] as number[], ent: [] as number[] };
if (!times.length) {
times = ['2024-08', '2024-10', '2024-12', '2025-02', '2025-04', '2025-06', '2025-08', '2025-10', '2025-12', '2026-02', '2026-04', '2026-06', '2026-08'];
ins = [2800, 3200, 3800, 3500, 4200, 4800, 5200, 5800, 6400, 6000, 6800, 7200, 7600];
ins = ['2800', '3200', '3800', '3500', '4200', '4800', '5200', '5800', '6400', '6000', '6800', '7200', '7600'];
ent = [1200, 1500, 1800, 1600, 2200, 2500, 2800, 3100, 3400, 3200, 3600, 3900, 4100];
}
await nextTick();
@ -557,7 +557,7 @@ async function loadAdminTrend() {
adminTrendChart = echarts.init(adminTrendRef.value);
}
adminTrendChart.setOption(
buildTrendLineOption(times, ins, ent, '行政执法数量', '被检查企业数量', '行政执法数量(宗)', '被执法企业数量(家)'),
buildTrendLineOption(times, ins.map(Number), ent.map(Number), '行政执法数量', '被检查企业数量', '行政执法数量(宗)', '被执法企业数量(家)'),
true
);
adminTrendChart.resize();
@ -578,7 +578,7 @@ async function loadNonTrend() {
nonTrendChart = echarts.init(nonTrendRef.value);
}
nonTrendChart.setOption(
buildTrendLineOption(times, ins, ent, '非行政执法数量', '被检查企业数量', '行政执法数量(宗)', '被检查企业数量(家)'),
buildTrendLineOption(times, ins.map(Number), ent.map(Number), '非行政执法数量', '被检查企业数量', '非行政执法数量(宗)', '被检查企业数量(家)'),
true
);
nonTrendChart.resize();

11
zdxt-web-client/zdxt-admin-plus-ui/src/views/supervision/statistical/city-direct/index.vue

@ -19,19 +19,21 @@
</dl>
</div>
<div class="select_item">
<label class="select_time">时间筛选</label>
<label class="select_time">时间筛选<a></a></label>
<el-date-picker
v-model="dateRange"
type="daterange"
range-separator="至"
value-format="YYYY-MM-DD"
clearable
popper-class="analysis-date-picker"
@change="refreshAll"
/>
<span>综合数据</span>
</div>
</div>
<div class="link_btn">
<div class="link_btn" style="text-align: right;">
<a href="javascript:void(0)" style="display: none;">各市直执法部门综合分析</a>
<router-link to="/enforcement-code/statistical/district-direct">各区执法综合分析</router-link>
</div>
@ -339,7 +341,10 @@ async function loadEntCSort() {
);
if (!res) return;
await nextTick();
rankComplaintChart = renderRankChart(rankComplaintRef.value, rankComplaintChart, normalizeRankList(unwrapData(res)), 'bureau_dept_name', '排行')!;
const data = normalizeRankList(unwrapData(res));
// rankComplaint uses 'complaint_departments' field, others use 'bureau_dept_name'
const nameKey = isCityWide.value ? 'complaint_departments' as const : 'bureau_dept_name' as const;
rankComplaintChart = renderRankChart(rankComplaintRef.value, rankComplaintChart, data, nameKey, '被投诉单位次数')!;
}
async function loadAutoRate() {

80
zdxt-web-client/zdxt-admin-plus-ui/src/views/supervision/statistical/components/TopSixMetrics.vue

@ -9,8 +9,18 @@
<div class="percent-tag"><label>本月</label><span class="data-change">{{ m.singleLaw?.thisMonth ?? '-' }}</span></div>
</div>
</div>
<div class="percent-tag"><label>同比</label><span class="data-change">{{ fmt(m.singleLaw?.yoy) }}</span></div>
<div class="percent-tag"><label>环比</label><span class="data-change">{{ fmt(m.singleLaw?.mom) }}</span></div>
<div class="percent-tag">
<label>同比</label>
<span class="data-rise" :style="{ display: isRise(m.singleLaw?.yoy) ? '' : 'none' }"><i class="fa fa-long-arrow-up"></i></span>
<span class="data-fall" :style="{ display: isFall(m.singleLaw?.yoy) ? '' : 'none' }"><i class="fa fa-long-arrow-down"></i></span>
<span class="data-change">{{ fmt(m.singleLaw?.yoy) }}</span>
</div>
<div class="percent-tag">
<label>环比</label>
<span class="data-rise" :style="{ display: isRise(m.singleLaw?.mom) ? '' : 'none' }"><i class="fa fa-long-arrow-up"></i></span>
<span class="data-fall" :style="{ display: isFall(m.singleLaw?.mom) ? '' : 'none' }"><i class="fa fa-long-arrow-down"></i></span>
<span class="data-change">{{ fmt(m.singleLaw?.mom) }}</span>
</div>
</div>
<div class="data_item">
<div class="cont-title">联合执法数量</div>
@ -21,8 +31,18 @@
<div class="percent-tag"><label>本月</label><span class="data-change">{{ m.unionLaw?.thisMonth ?? '-' }}</span></div>
</div>
</div>
<div class="percent-tag"><label>同比</label><span class="data-change">{{ fmt(m.unionLaw?.yoy) }}</span></div>
<div class="percent-tag"><label>环比</label><span class="data-change">{{ fmt(m.unionLaw?.mom) }}</span></div>
<div class="percent-tag">
<label>同比</label>
<span class="data-rise" :style="{ display: isRise(m.unionLaw?.yoy) ? '' : 'none' }"><i class="fa fa-long-arrow-up"></i></span>
<span class="data-fall" :style="{ display: isFall(m.unionLaw?.yoy) ? '' : 'none' }"><i class="fa fa-long-arrow-down"></i></span>
<span class="data-change">{{ fmt(m.unionLaw?.yoy) }}</span>
</div>
<div class="percent-tag">
<label>环比</label>
<span class="data-rise" :style="{ display: isRise(m.unionLaw?.mom) ? '' : 'none' }"><i class="fa fa-long-arrow-up"></i></span>
<span class="data-fall" :style="{ display: isFall(m.unionLaw?.mom) ? '' : 'none' }"><i class="fa fa-long-arrow-down"></i></span>
<span class="data-change">{{ fmt(m.unionLaw?.mom) }}</span>
</div>
</div>
<div class="data_item">
<div class="cont-title">被执法企业数量</div>
@ -33,8 +53,18 @@
<div class="percent-tag"><label>本月</label><span class="data-change">{{ m.enfEnt?.thisMonth ?? '-' }}</span></div>
</div>
</div>
<div class="percent-tag"><label>同比</label><span class="data-change">{{ fmt(m.enfEnt?.yoy) }}</span></div>
<div class="percent-tag"><label>环比</label><span class="data-change">{{ fmt(m.enfEnt?.mom) }}</span></div>
<div class="percent-tag">
<label>同比</label>
<span class="data-rise" :style="{ display: isRise(m.enfEnt?.yoy) ? '' : 'none' }"><i class="fa fa-long-arrow-up"></i></span>
<span class="data-fall" :style="{ display: isFall(m.enfEnt?.yoy) ? '' : 'none' }"><i class="fa fa-long-arrow-down"></i></span>
<span class="data-change">{{ fmt(m.enfEnt?.yoy) }}</span>
</div>
<div class="percent-tag">
<label>环比</label>
<span class="data-rise" :style="{ display: isRise(m.enfEnt?.mom) ? '' : 'none' }"><i class="fa fa-long-arrow-up"></i></span>
<span class="data-fall" :style="{ display: isFall(m.enfEnt?.mom) ? '' : 'none' }"><i class="fa fa-long-arrow-down"></i></span>
<span class="data-change">{{ fmt(m.enfEnt?.mom) }}</span>
</div>
</div>
<div class="data_item">
<div class="cont-title">入企压减率</div>
@ -56,8 +86,18 @@
<div class="percent-tag"><label>本月</label><span class="data-change">{{ m.entComplaint?.thisMonth ?? '-' }}</span></div>
</div>
</div>
<div class="percent-tag"><label>同比</label><span class="data-change">{{ fmt(m.entComplaint?.yoy) }}</span></div>
<div class="percent-tag"><label>环比</label><span class="data-change">{{ fmt(m.entComplaint?.mom) }}</span></div>
<div class="percent-tag">
<label>同比</label>
<span class="data-rise" :style="{ display: isRise(m.entComplaint?.yoy) ? '' : 'none' }"><i class="fa fa-long-arrow-up"></i></span>
<span class="data-fall" :style="{ display: isFall(m.entComplaint?.yoy) ? '' : 'none' }"><i class="fa fa-long-arrow-down"></i></span>
<span class="data-change">{{ fmt(m.entComplaint?.yoy) }}</span>
</div>
<div class="percent-tag">
<label>环比</label>
<span class="data-rise" :style="{ display: isRise(m.entComplaint?.mom) ? '' : 'none' }"><i class="fa fa-long-arrow-up"></i></span>
<span class="data-fall" :style="{ display: isFall(m.entComplaint?.mom) ? '' : 'none' }"><i class="fa fa-long-arrow-down"></i></span>
<span class="data-change">{{ fmt(m.entComplaint?.mom) }}</span>
</div>
</div>
<div class="data_item">
<div class="cont-title">企业数量</div>
@ -68,8 +108,18 @@
<div class="percent-tag"><label>本月</label><span class="data-change">{{ m.ent?.thisMonth ?? '-' }}</span></div>
</div>
</div>
<div class="percent-tag"><label>同比</label><span class="data-change">{{ fmt(m.ent?.yoy) }}</span></div>
<div class="percent-tag"><label>环比</label><span class="data-change">{{ fmt(m.ent?.mom) }}</span></div>
<div class="percent-tag">
<label>同比</label>
<span class="data-rise" :style="{ display: isRise(m.ent?.yoy) ? '' : 'none' }"><i class="fa fa-long-arrow-up"></i></span>
<span class="data-fall" :style="{ display: isFall(m.ent?.yoy) ? '' : 'none' }"><i class="fa fa-long-arrow-down"></i></span>
<span class="data-change">{{ fmt(m.ent?.yoy) }}</span>
</div>
<div class="percent-tag">
<label>环比</label>
<span class="data-rise" :style="{ display: isRise(m.ent?.mom) ? '' : 'none' }"><i class="fa fa-long-arrow-up"></i></span>
<span class="data-fall" :style="{ display: isFall(m.ent?.mom) ? '' : 'none' }"><i class="fa fa-long-arrow-down"></i></span>
<span class="data-change">{{ fmt(m.ent?.mom) }}</span>
</div>
</div>
</div>
</template>
@ -84,4 +134,14 @@ function fmt(val?: string | number) {
if (val === undefined || val === null || val === '-') return '-%';
return formatPercent(val);
}
function isRise(val?: string | number) {
if (val === undefined || val === null || val === '-') return false;
return parseFloat(String(val)) >= 0;
}
function isFall(val?: string | number) {
if (val === undefined || val === null || val === '-') return false;
return parseFloat(String(val)) < 0;
}
</script>

439
zdxt-web-client/zdxt-admin-plus-ui/src/views/supervision/statistical/home/index copy.vue

@ -0,0 +1,439 @@
<template>
<div class="statistical-home">
<div class="wrap_all">
<!-- 左侧:行政执法 -->
<div class="wrap_left">
<div class="cont_left">
<h1 class="block_tit">行政执法</h1>
<div class="count_admin_wrap">
<div class="count_admin">
<label><img src="/statistical/images/icon_jc2.png" alt="单独执法" />单独执法</label>
<div class="count_admin_num">
<b>{{ coordination.singleNum }}</b>
<span class="number_percent">{{ coordination.singlePer }}<i>%</i></span>
</div>
<div class="percent_box">
<div class="percent-tag">
<span class="data-rise"><i class="fa fa-long-arrow-up"></i></span>
<span class="data-change">{{ coordination.singleYoy }}%</span>
<label>同比</label>
</div>
<div class="percent-tag">
<span class="data-fall"><i class="fa fa-long-arrow-down"></i></span>
<span class="data-change">{{ coordination.singleRr }}%</span>
<label>环比</label>
</div>
</div>
</div>
<div class="count_admin">
<label><img src="/statistical/images/icon_jc.png" alt="联合执法" />联合执法</label>
<div class="count_admin_num">
<b>{{ coordination.unionNum }}</b>
<span class="number_percent">{{ coordination.unionPer }}<i>%</i></span>
</div>
<div class="percent_box">
<div class="percent-tag">
<span class="data-rise"><i class="fa fa-long-arrow-up"></i></span>
<span class="data-change">{{ coordination.unionYoy }}%</span>
<label>同比</label>
</div>
<div class="percent-tag">
<span class="data-fall"><i class="fa fa-long-arrow-down"></i></span>
<span class="data-change">{{ coordination.unionRr }}%</span>
<label>环比</label>
</div>
</div>
</div>
<div class="count_admin">
<label><img src="/statistical/images/icon_qy.png" alt="被执法企业" />被执法企业</label>
<div class="count_admin_num"><b>{{ enterprise.num }}</b></div>
<div class="percent_box">
<div class="percent-tag">
<span class="data-rise"><i class="fa fa-long-arrow-up"></i></span>
<span class="data-change">{{ enterprise.yoy }}%</span>
<label>同比</label>
</div>
<div class="percent-tag">
<span class="data-fall"><i class="fa fa-long-arrow-down"></i></span>
<span class="data-change">{{ enterprise.rr }}%</span>
<label>环比</label>
</div>
</div>
</div>
<div class="count_admin">
<label><img src="/statistical/images/icon_yj.png" alt="入企压减率" />入企压减率</label>
<div class="count_admin_num"><b>{{ coordination.cutNum }}</b></div>
<div class="percent_box">
<div class="percent-tag yjlv">
<span class="number_percent">{{ coordination.cutPer }}<i>%</i></span>
</div>
</div>
</div>
</div>
<div ref="adminPieRef" class="chartbox_right" style="margin-top: -10%"></div>
</div>
</div>
<!-- 右侧:非行政执法 -->
<div class="wrap_right">
<div class="cont_left">
<h1 class="block_tit">非行政执法</h1>
<div class="count_wrap">
<div v-for="(item, index) in nonTypeList" :key="item.dict_label" class="count_item">
<label>
<img :src="`/statistical/images/icon_24_r${index + 1}.png`" :alt="item.dict_label" />
{{ item.dict_label }}
</label>
<span class="number_count">{{ item.num }}</span>
</div>
</div>
<div ref="nonPieRef" class="chartbox_right"></div>
</div>
</div>
<!-- 中间:地图 -->
<div class="wrap_cent">
<div class="select_set">
<div class="select_item">
<span>深圳市</span>
<span class="time_wrap">
<el-date-picker
v-model="dateRange"
type="daterange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
value-format="YYYY-MM-DD"
:disabled-date="disabledDate"
clearable
@change="onDateChange"
/>
</span>
</div>
</div>
<div class="link_btn" style="text-align: right">
<router-link v-if="showLeftLink" to="/enforcement-code/statistical/city-direct">{{ leftLinkText }}</router-link>
<router-link to="/enforcement-code/statistical/district-direct"><span>{{ rightLinkText }}</span></router-link>
</div>
<div class="count_box">
<div class="count_item admin">
<div class="count_tit"><label>行政执法</label></div>
<div class="count_num">
<div class="count_num_all">{{ coordination.allNum }}</div>
<div class="count_num_sub">
<span>(市直:<b>{{ sJcNum }}</b></span>
<span>各区:<b>{{ qJcNum }}</b>)</span>
</div>
</div>
</div>
<div class="count_item non_admin">
<div class="count_tit"><label>非行政执法</label></div>
<div class="count_num">
<div class="count_num_all">{{ njcAll }}</div>
<div class="count_num_sub">
<span>(市直:<b>{{ sNjcNum }}</b></span>
<span>各区:<b>{{ qNjcNum }}</b>)</span>
</div>
</div>
</div>
</div>
<div class="map_box">
<img class="szmap" src="/statistical/images/szmap_3d.png" alt="深圳地图" width="1920" height="1080" border="0" />
<div class="label_wrap">
<DistrictPopup
v-for="config in districtConfigs"
:key="config.key"
:config="config"
:data="districtDataMap[config.name]"
:expanded="expandedDistrictIdx === config.idx"
@toggle="onDistrictToggle"
/>
</div>
</div>
</div>
<!-- 底部:趋势图 -->
<div class="wrap_bottom">
<div class="cont_left">
<h3>涉企执法趋势</h3>
<div class="tab_tit">
<a :class="{ active: trendTab === 0 }" @click="switchTrendTab(0)">行政执法</a>
<a :class="{ active: trendTab === 1 }" @click="switchTrendTab(1)">非行政执法</a>
</div>
<div class="tab_chart">
<div v-show="trendTab === 0" ref="adminTrendRef" class="chartbox" style="position: absolute"></div>
<div v-show="trendTab === 1" ref="nonTrendRef" class="chartbox" style="position: absolute"></div>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { computed, nextTick, onMounted, onUnmounted, reactive, ref } from 'vue';
import * as echarts from 'echarts';
import DistrictPopup from './components/DistrictPopup.vue';
import {
analysisEnterprises,
analysisEnterprisesCoordination,
analysisEnterprisesNonAll,
analysisNonRegistrationType,
analysisRegistrationType,
analysisTime,
areaRegistration,
nonAnalysisTime
} from '@/api/supervision/statistical/statisticalPanel';
import type { AreaRegistrationData, DictStatItem } from '@/api/supervision/statistical/types';
import {
normalizeAreaRegistration,
normalizeCoordination,
normalizeDictStatList,
normalizeEnterpriseStat,
normalizeTimeSeries,
toNum,
unwrapData
} from '@/api/supervision/statistical/adapters';
import { buildAdminPieOption, buildNonAdminPieOption, buildTrendLineOption } from '../utils/chartOptions';
import { DISTRICT_CONFIGS, DISTRICT_LIST } from '../utils/districtConfig';
async function safeLoad<T>(fn: () => Promise<T>): Promise<T | null> {
try {
return await fn();
} catch (e) {
console.warn('[统计首页] 接口加载失败', e);
return null;
}
}
const districtConfigs = DISTRICT_CONFIGS;
const dateRange = ref<[string, string] | null>(null);
const trendTab = ref(0);
const expandedDistrictIdx = ref<number | null>(null);
const coordination = reactive({
roleFlag: 1,
roleDept: '',
allNum: 0,
nonNum: 0,
unionNum: 0,
unionYoy: '0.0',
unionRr: '0.0',
unionPer: '0.0',
singleNum: 0,
singleYoy: '0.0',
singleRr: '0.0',
singlePer: '0.0',
cutNum: 0,
cutPer: '0.0'
});
const enterprise = reactive({ num: 0, yoy: '0.0', rr: '0.0' });
const nonTypeList = ref<DictStatItem[]>([]);
const njcAll = ref(0);
const qJcNum = ref(0);
const qNjcNum = ref(0);
const districtDataMap = ref<Record<string, AreaRegistrationData>>({});
const adminPieRef = ref<HTMLElement>();
const nonPieRef = ref<HTMLElement>();
const adminTrendRef = ref<HTMLElement>();
const nonTrendRef = ref<HTMLElement>();
let adminPieChart: echarts.ECharts | null = null;
let nonPieChart: echarts.ECharts | null = null;
let adminTrendChart: echarts.ECharts | null = null;
let nonTrendChart: echarts.ECharts | null = null;
const showLeftLink = computed(() => coordination.roleFlag === 1);
const leftLinkText = computed(() => '各市直执法单位综合分析');
const rightLinkText = computed(() => {
if ([9, 4, 3].includes(coordination.roleFlag)) {
return `${coordination.roleDept}综合分析`;
}
return '各区综合分析';
});
const sJcNum = computed(() => ([9, 4, 3].includes(coordination.roleFlag) ? '-' : coordination.allNum - qJcNum.value));
const sNjcNum = computed(() => ([9, 4, 3].includes(coordination.roleFlag) ? '-' : njcAll.value - qNjcNum.value));
function disabledDate(time: Date) {
const min = new Date('2019-04-14').getTime();
const max = new Date('2099-06-16').getTime();
return time.getTime() < min || time.getTime() > max;
}
function getTimeParams() {
if (!dateRange.value) return { beginTime: undefined, endTime: undefined };
return { beginTime: dateRange.value[0], endTime: dateRange.value[1] };
}
async function loadCoordination() {
const res = await safeLoad(() => analysisEnterprisesCoordination(getTimeParams()));
if (!res) return;
const data = normalizeCoordination(unwrapData(res));
Object.assign(coordination, data);
njcAll.value = data.nonNum;
}
async function loadEnterprise() {
const res = await safeLoad(() => analysisEnterprises(getTimeParams()));
if (!res) return;
Object.assign(enterprise, normalizeEnterpriseStat(unwrapData(res)));
}
async function loadNjcAll() {
const res = await safeLoad(() => analysisEnterprisesNonAll(getTimeParams()));
if (!res) return;
njcAll.value = toNum(unwrapData(res));
}
async function loadAdminType() {
const res = await safeLoad(() => analysisRegistrationType(getTimeParams()));
if (!res) return;
const list = normalizeDictStatList(unwrapData(res));
const chartData = list.filter((item) => item.dict_label).map((item) => ({ value: item.num, name: item.dict_label }));
await nextTick();
if (adminPieRef.value && chartData.length) {
adminPieChart ??= echarts.init(adminPieRef.value);
adminPieChart.setOption(buildAdminPieOption(chartData), true);
}
}
async function loadNonType() {
const res = await safeLoad(() => analysisNonRegistrationType(getTimeParams()));
if (!res) return;
const list = normalizeDictStatList(unwrapData(res));
nonTypeList.value = list;
const chartData = list.filter((item) => item.dict_label).map((item) => ({ value: item.num, name: item.dict_label }));
await nextTick();
if (nonPieRef.value && chartData.length) {
nonPieChart ??= echarts.init(nonPieRef.value);
nonPieChart.setOption(buildNonAdminPieOption(chartData), true);
}
}
async function loadAdminTrend() {
const res = await safeLoad(() => analysisTime(getTimeParams()));
if (!res) return;
const { times, ins, ent } = normalizeTimeSeries(unwrapData(res));
await nextTick();
if (adminTrendRef.value && times.length) {
adminTrendChart ??= echarts.init(adminTrendRef.value);
adminTrendChart.setOption(
buildTrendLineOption(times, ins.map(Number), ent.map(Number), '行政执法数量', '被检查企业数量', '行政执法数量(宗)'),
true
);
}
}
async function loadNonTrend() {
const res = await safeLoad(() => nonAnalysisTime(getTimeParams()));
if (!res) return;
const { times, ins, ent } = normalizeTimeSeries(unwrapData(res));
await nextTick();
if (nonTrendRef.value && times.length) {
nonTrendChart ??= echarts.init(nonTrendRef.value);
nonTrendChart.setOption(
buildTrendLineOption(times, ins.map(Number), ent.map(Number), '非行政执法数量', '被检查企业数量', '行政执法数量(宗)'),
true
);
}
}
async function loadAreaData() {
const params = getTimeParams();
let jcSum = 0;
let njcSum = 0;
const dataMap: Record<string, AreaRegistrationData> = {};
const results = await Promise.allSettled(
DISTRICT_LIST.map((area) => areaRegistration({ ...params, deptId: area }))
);
results.forEach((result, index) => {
if (result.status !== 'fulfilled') return;
const data = normalizeAreaRegistration(unwrapData(result.value));
const area = data.area || DISTRICT_LIST[index];
dataMap[area] = data;
jcSum += data.allNum;
njcSum += data.njcNum;
});
districtDataMap.value = dataMap;
qJcNum.value = jcSum;
qNjcNum.value = njcSum;
}
async function refreshAll() {
await Promise.allSettled([
loadCoordination(),
loadEnterprise(),
loadNjcAll(),
loadAdminType(),
loadNonType(),
loadAdminTrend(),
loadNonTrend(),
loadAreaData()
]);
}
function onDateChange() {
refreshAll();
}
function onDistrictToggle(idx: number) {
expandedDistrictIdx.value = expandedDistrictIdx.value === idx ? null : idx;
}
function switchTrendTab(tab: number) {
trendTab.value = tab;
nextTick(() => {
if (tab === 0) adminTrendChart?.resize();
else nonTrendChart?.resize();
});
}
function handleResize() {
adminPieChart?.resize();
nonPieChart?.resize();
adminTrendChart?.resize();
nonTrendChart?.resize();
}
onMounted(() => {
refreshAll();
window.addEventListener('resize', handleResize);
});
onUnmounted(() => {
window.removeEventListener('resize', handleResize);
adminPieChart?.dispose();
nonPieChart?.dispose();
adminTrendChart?.dispose();
nonTrendChart?.dispose();
});
</script>
<style scoped>
@import '/statistical/styles/home.css';
@import '/statistical/font-awesome-bak/css/font-awesome.min.css';
.statistical-home {
width: 100%;
min-height: calc(100vh - 50px);
overflow: auto;
background: #0b1d4b;
}
.statistical-home :deep(.el-date-editor) {
--el-input-bg-color: rgba(0, 30, 80, 0.6);
--el-input-border-color: rgba(58, 174, 251, 0.4);
--el-input-text-color: rgba(255, 255, 255, 0.85);
--el-input-placeholder-color: rgba(255, 255, 255, 0.45);
}
.statistical-home :deep(.el-range-separator) {
color: rgba(255, 255, 255, 0.6);
}
</style>

1378
zdxt-web-client/zdxt-admin-plus-ui/src/views/supervision/statistical/home/index.vue

File diff suppressed because it is too large

45
zdxt-web-client/zdxt-admin-plus-ui/src/views/supervision/statistical/styles/analysis-layout.css

@ -29,3 +29,48 @@
.statistical-analysis .el-date-editor {
margin-left: 8px;
}
/* select_time 标签样式 */
.select_time {
position: relative;
display: inline-block;
margin: 0 5px 0 0;
padding: 0 25px 0 10px;
height: 28px;
line-height: 28px;
color: #315EFB;
font-weight: 500;
background: rgba(59, 145, 253, 0.12);
text-align: center;
border-radius: 6px;
cursor: pointer;
}
.select_time > a {
display: inline-block;
position: absolute;
right: 0;
width: 18px;
height: 100%;
}
.select_time > a::after {
position: absolute;
right: 0;
width: 18px;
height: 18px;
content: "\f105";
color: #678dfe;
font-family: "FontAwesome";
font-size: 1.25rem;
}
/* FontAwesome 图标修复 */
.statistical-analysis .fa {
font-family: "FontAwesome";
}
/* 日期选择器弹窗暗色适配 */
.analysis-date-picker {
background: #fff !important;
}

2
zdxt-web-client/zdxt-admin-plus-ui/src/views/supervision/statistical/utils/chartOptions.ts

@ -110,7 +110,7 @@ export function buildNonAdminPieOption(data: { value: number; name: string }[]):
export function buildTrendLineOption(
times: string[],
ins: number[],
ins: number[] ,
ent: number[],
insName: string,
entName: string,

Loading…
Cancel
Save