Browse Source

首页还原

dev-V1.0.6
parent
commit
b3290f1791
  1. 7
      zdxt-web-client/zdxt-admin-plus-ui/.env.development-wmy-cust
  2. 2
      zdxt-web-client/zdxt-admin-plus-ui/src/assets/styles/sidebar.scss
  3. 61
      zdxt-web-client/zdxt-admin-plus-ui/src/layout/components/Navbar.vue
  4. 2
      zdxt-web-client/zdxt-admin-plus-ui/src/layout/components/TagsView/index.vue
  5. 4
      zdxt-web-client/zdxt-admin-plus-ui/src/layout/index.vue
  6. 6
      zdxt-web-client/zdxt-admin-plus-ui/src/router/index.ts
  7. 2
      zdxt-web-client/zdxt-admin-plus-ui/src/store/modules/permission.ts
  8. 3
      zdxt-web-client/zdxt-admin-plus-ui/src/store/modules/user.ts
  9. 105
      zdxt-web-client/zdxt-admin-plus-ui/src/views/supervision/statistical/city-direct/index.vue
  10. 107
      zdxt-web-client/zdxt-admin-plus-ui/src/views/supervision/statistical/district-direct/index.vue

7
zdxt-web-client/zdxt-admin-plus-ui/.env.development-wmy-cust

@ -1,8 +1,8 @@
# VITE_APP_PROXY_TARGET = 'http://139.186.148.21:8080'
# VITE_APP_PROXY_TARGET = 'http://10.132.108.3:85/efcode20-sup-web/prod-api'
VITE_APP_PROXY_TARGET = 'http://172.16.21.213:8080'
# VITE_APP_PROXY_TARGET = 'http://172.16.21.213:8080'
# VITE_APP_PROXY_TARGET = 'http://172.16.21.93:8080'
# VITE_PROXY_TARGET = 'http://172.16.20.72:8080'
VITE_APP_PROXY_TARGET = 'http://172.16.20.72:8080'
# 页面标题
VITE_APP_TITLE = 执法监督码•执法监督
VITE_APP_LOGO_TITLE = 执法监督码•执法监督
@ -11,7 +11,8 @@ VITE_APP_LOGO_TITLE = 执法监督码•执法监督
VITE_APP_ENV = 'development'
# 开发环境
VITE_APP_BASE_API = '/dev-api'
# VITE_APP_BASE_API = '/dev-api'
VITE_APP_BASE_API = '/efcode20-sup-web/prod-api'
# 应用访问路径 例如使用前缀 /admin/
VITE_APP_CONTEXT_PATH = '/efcode20-sup-web/'

2
zdxt-web-client/zdxt-admin-plus-ui/src/assets/styles/sidebar.scss

@ -20,7 +20,7 @@
height: calc(100% - 50px);
position: fixed;
font-size: 0;
top: 50px;
top: 80px;
bottom: 0;
left: 0;
z-index: 1001;

61
zdxt-web-client/zdxt-admin-plus-ui/src/layout/components/Navbar.vue

@ -1,14 +1,13 @@
<template>
<div class="dashboard-navbar">
<div class="navbar-left">
<div class="navbar-left"> <div class="system-title">
<!-- <span class="title-main">执法监督码</span>
<span class="title-dot">·</span>
<span class="title-sub">执法监督</span> -->
</div>
<div class="hamburger-btn" @click="toggleSideBar">
<i class="fa fa-bars"></i>
</div>
<div class="system-title">
<span class="title-main">执法监督码</span>
<span class="title-dot">·</span>
<span class="title-sub">执法监督</span>
</div>
</div>
<div class="navbar-right">
@ -27,25 +26,27 @@
</div>
</div>
<el-dropdown trigger="click" @command="handleCommand">
<div class="user-info">
<div class="user-avatar">
<img :src="userStore.avatar" alt="avatar" />
</div>
<div class="user-detail">
<div class="username">{{ userStore.nickname || 'admin' }}</div>
<div class="user-org">深圳市司法局</div>
<div class="user-org">{{ userStore.deptName || '' }}</div>
</div>
<el-dropdown trigger="click" @command="handleCommand">
<i class="fa fa-caret-down user-caret"></i>
</div>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item command="logout">退出登录</el-dropdown-item>
<el-dropdown-item command="profile">个人中心</el-dropdown-item>
<!-- <el-dropdown-item command="settings">布局设置</el-dropdown-item> -->
<el-dropdown-item divided command="logout">退出登录</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
</div>
</div>
</template>
<script setup lang="ts">
@ -80,7 +81,12 @@ const handleSystemCodeChange = async (systemCode: string) => {
};
const handleCommand = async (command: string) => {
if (command === 'logout') {
if (command === 'profile') {
router.push({ path: '/user/profile' });
} else if (command === 'settings') {
// Settings
router.push({ path: '/settings' });
} else if (command === 'logout') {
await ElMessageBox.confirm('确定注销并退出系统吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
@ -94,8 +100,9 @@ const handleCommand = async (command: string) => {
<style lang="scss" scoped>
.dashboard-navbar {
height: 50px;
background: linear-gradient(180deg, #0c3d8f 0%, #0a2e72 100%);
height: 80px;
background: #1367fe;
background-image: linear-gradient(to right, rgba(0, 0, 0, .2), rgba(255, 255, 255, .2));
display: flex;
align-items: center;
justify-content: space-between;
@ -135,6 +142,10 @@ const handleCommand = async (command: string) => {
display: flex;
align-items: baseline;
gap: 2px;
width: 320px;
height: 40px;
background: url('../../../public/img/logo-zfjd-st.png') no-repeat;
background-size: 100% 100%;
}
.title-main {
@ -182,10 +193,11 @@ const handleCommand = async (command: string) => {
cursor: pointer;
transition: all 0.25s ease;
position: relative;
margin-right: 12px;
&:hover {
background: rgba(255, 255, 255, 0.12);
background: linear-gradient(#0447c0, transparent);
height: 70px;
width: 80px;
.nav-icon .el-icon {
color: rgba(255, 255, 255, 0.9);
}
@ -196,9 +208,9 @@ const handleCommand = async (command: string) => {
}
&.is-active {
background: rgba(64, 160, 255, 0.25);
box-shadow: inset 0 -2px 0 #40a0ff;
background: linear-gradient(#0447c0, transparent);
height: 70px;
width: 80px;
.nav-icon .el-icon {
color: #fff;
}
@ -210,25 +222,26 @@ const handleCommand = async (command: string) => {
}
.nav-icon {
width: 24px;
height: 24px;
width: 30px;
height: 30px;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 1px;
.el-icon {
font-size: 16px;
font-size: 24px;
color: rgba(255, 255, 255, 0.75);
transition: color 0.25s;
}
}
.nav-label {
font-size: 12px;
color: rgba(255, 255, 255, 0.7);
font-size: 16px;
color: #fff;
white-space: nowrap;
transition: color 0.25s;
padding-top:8px;
}
.user-info {

2
zdxt-web-client/zdxt-admin-plus-ui/src/layout/components/TagsView/index.vue

@ -14,7 +14,7 @@
>
<svg-icon v-if="tagsIcon && tag.meta && tag.meta.icon && tag.meta.icon !== '#'" :icon-class="tag.meta.icon"/>
<span class="tags-view-item-title">{{ tag.title }}</span>
<span v-if="!isAffix(tag)" @click.prevent.stop="closeSelectedTag(tag)">
<span v-if="!isAffix(tag) && visitedViews.length > 1" @click.prevent.stop="closeSelectedTag(tag)">
<close class="el-icon-close" style="width: 1em; height: 1em; vertical-align: middle" />
</span>
</router-link>

4
zdxt-web-client/zdxt-admin-plus-ui/src/layout/index.vue

@ -144,7 +144,7 @@ const setLayout = () => {
}
.main-container {
padding-top: 50px;
padding-top: 80px;
box-sizing: border-box;
}
@ -213,7 +213,7 @@ const setLayout = () => {
}
.iframe-mode .dashboard-navbar {
background: linear-gradient(180deg, #0c3d8f 0%, #0a2e72 100%);
// background: linear-gradient(180deg, #0c3d8f 0%, #0a2e72 100%);
border-bottom: 1px solid rgba(64, 160, 255, 0.2);
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
}

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

@ -324,19 +324,19 @@ export const constantRoutes: RouteRecordRaw[] = [
path: 'home',
component: () => import('@/views/supervision/statistical/home/index.vue'),
name: 'StatisticalHome',
meta: { title: '首页统计分析', fullscreen: true }
meta: { title: '首页统计分析', fullscreen: true, breadcrumb: false }
},
{
path: 'city-direct',
component: () => import('@/views/supervision/statistical/city-direct/index.vue'),
name: 'StatisticalCityDirect',
meta: { title: '市直综合分析', fullscreen: true }
meta: { title: '市直综合分析', fullscreen: true, breadcrumb: false }
},
{
path: 'district-direct',
component: () => import('@/views/supervision/statistical/district-direct/index.vue'),
name: 'StatisticalDistrictDirect',
meta: { title: '各区综合分析', fullscreen: true }
meta: { title: '各区综合分析', fullscreen: true, breadcrumb: false }
}
]
}

2
zdxt-web-client/zdxt-admin-plus-ui/src/store/modules/permission.ts

@ -31,7 +31,7 @@ export const CATCH_ALL_ROUTE_NAME = 'CatchAll404';
//http://10.132.108.3:85/loginByUserId
export const systemCodeOptions: SystemCodeOption[] = [
{ label: '首页', value: 'planindex', icon: 'HomeFilled', fullscreenRoute: '/home' },
{ label: '执法监督码', value: 'supervisionCode', icon: 'Document', defaultRoute: '/statistics/administrative/enterprise-enforcement' },
{ label: '统计分析', value: 'supervisionCode', icon: 'Document', defaultRoute: '/statistics/administrative/enterprise-enforcement' },
{ label: '后台管理', value: 'authService', icon: 'Setting', defaultRoute: '/system-setting/menu' }
];

3
zdxt-web-client/zdxt-admin-plus-ui/src/store/modules/user.ts

@ -14,6 +14,7 @@ export const useUserStore = defineStore('user', () => {
const userId = ref<string | number>('');
const tenantId = ref<string>('');
const avatar = ref('');
const deptName = ref('');
const roles = ref<Array<string>>([]); // 用户角色编码集合 → 判断路由权限
const permissions = ref<Array<string>>([]); // 用户权限编码集合 → 判断按钮权限
const v1SystemCredential = ref<string>(sessionStorage.getItem('v1_system_credential') || '');
@ -60,6 +61,7 @@ export const useUserStore = defineStore('user', () => {
avatar.value = profile;
userId.value = user.userId;
tenantId.value = user.tenantId;
deptName.value = user.deptName || '';
return Promise.resolve();
}
return Promise.reject(err);
@ -92,6 +94,7 @@ export const useUserStore = defineStore('user', () => {
token,
nickname,
avatar,
deptName,
roles,
permissions,
v1SystemCredential,

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

@ -19,8 +19,9 @@
</dl>
</div>
<div class="select_item">
<label class="select_time">时间筛选<a></a></label>
<label class="select_time" :class="{ active: datePickerOpen }" @click="datePickerOpen = !datePickerOpen">时间筛选<a></a></label>
<el-date-picker
v-if="datePickerOpen"
v-model="dateRange"
type="daterange"
range-separator="至"
@ -193,73 +194,10 @@ const CASE_TYPE_ICONS: Record<string, string> = {
违规执法: 'icon_1001.png', 违法执法: 'icon_1002.png', 入企不扫码: 'icon_1004.png', 其他: 'icon_1003.png'
};
/* ======================== 开发调试用假数据 ======================== */
const MOCK_STATS: Partial<CollectStatisticsData> = {
singleLaw: { count: 542, yesterday: 12, thisMonth: 48, yoy: 3.25, mom: -1.5, completed: 0, unCompleted: 0 },
unionLaw: { count: 3, yesterday: 0, thisMonth: 1, yoy: -2.1, mom: 0.5, completed: 0, unCompleted: 0 },
enfEnt: { count: 485, yesterday: 15, thisMonth: 62, yoy: 5.8, mom: 2.3, completed: 0, unCompleted: 0 },
entEeduction: { count: 9, yesterday: 0, thisMonth: 1, yoy: -100, mom: 1.64, rate: '1.64%' },
entComplaint: { count: 128, yesterday: 3, thisMonth: 15, yoy: 12.5, mom: 3.8, completed: 96, unCompleted: 32 },
ent: { count: 69320, yesterday: 1, thisMonth: 18, yoy: 0, mom: 0, completed: 0, unCompleted: 0 },
lawCategoryTotal: 610,
lawCategory: [
{ 行政检查: 537 }, { 行政处罚: 11 }, { 行政许可: 0 }, { 行政强制: 0 },
{ 行政征收: 0 }, { 行政给付: 0 }, { 行政确认: 1 }, { 行政登记: 0 },
{ 行政裁决: 0 }, { 文书送达: 61 }
],
totalCaseType: 25,
caseType: [
{ 违规执法: 15 }, { 违法执法: 4 }, { 入企不扫码: 3 }, { 其他: 3 }
],
lawFieldTotal: 520,
lawField: [
{ 卫生健康: 128 }, { 应急管理: 89 }, { 生态环境: 67 }, { 市场监督管理资源: 145 }, { 规划和自然资源: 91 }
],
eva: { high: 85, mid: 28, low: 5, un: 10 }
};
const MOCK_ENF_ENT_SORT = [
{ enterprise_name: '深圳市某某科技有限公司', cnt: 48 },
{ enterprise_name: '某某集团股份有限公司', cnt: 35 },
{ enterprise_name: '深圳市某某医疗器械公司', cnt: 29 },
{ enterprise_name: '某某电子(深圳)有限公司', cnt: 25 },
{ enterprise_name: '深圳市某某食品有限公司', cnt: 22 },
{ enterprise_name: '某某环保科技深圳分公司', cnt: 18 },
{ enterprise_name: '深圳市某某化工有限公司', cnt: 15 },
{ enterprise_name: '某某光电股份有限公司', cnt: 12 },
{ enterprise_name: '深圳市某某物流有限公司', cnt: 10 },
{ enterprise_name: '某某商贸(深圳)有限公司', cnt: 8 }
];
const MOCK_ENFORCEMENT_SORT = [
{ bureau_dept_name: '市市场监督管理局', cnt: 185 },
{ bureau_dept_name: '市应急管理局', cnt: 142 },
{ bureau_dept_name: '市生态环境局', cnt: 98 },
{ bureau_dept_name: '市卫生健康委员会', cnt: 76 },
{ bureau_dept_name: '市交通运输局', cnt: 54 },
{ bureau_dept_name: '市住房和建设局', cnt: 43 },
{ bureau_dept_name: '市水务局', cnt: 32 },
{ bureau_dept_name: '市城市管理和综合执法局', cnt: 28 },
{ bureau_dept_name: '市商务局', cnt: 19 },
{ bureau_dept_name: '市发展和改革委员会', cnt: 12 }
];
const MOCK_ENT_C_SORT = [
{ bureau_dept_name: '市市场监督管理局', cnt: 32 },
{ bureau_dept_name: '市卫生健康委员会', cnt: 24 },
{ bureau_dept_name: '市应急管理局', cnt: 18 },
{ bureau_dept_name: '市生态环境局', cnt: 15 },
{ bureau_dept_name: '市交通运输局', cnt: 11 },
{ bureau_dept_name: '市住房和建设局', cnt: 8 },
{ bureau_dept_name: '市城市管理和综合执法局', cnt: 6 },
{ bureau_dept_name: '市水务局', cnt: 4 },
{ bureau_dept_name: '市商务局', cnt: 3 },
{ bureau_dept_name: '市人力资源和社会保障局', cnt: 2 }
];
const MOCK_AUTO_RATE = { autoCnt: 235, unAutoCnt: 375 };
/* ======================== 开发调试用假数据(已删除) ======================== */
const dateRange = ref<[string, string] | null>(null);
const datePickerOpen = ref(false);
const deptPanelOpen = ref(false);
const deptList = ref<(SysDeptVo & { deptId: string | number | null })[]>([]);
const selectedDeptId = ref<string | number | null>(null);
@ -384,7 +322,8 @@ function changeDept(id: string | number | null, name: string) {
async function loadStatistics() {
const res = await safeLoad(() => collectStatistics(getParams()));
stats.value = (res ? unwrapData(res) : MOCK_STATS) as Partial<CollectStatisticsData>;
if (!res) return;
stats.value = unwrapData(res) as Partial<CollectStatisticsData>;
}
function renderRankChart(
@ -394,8 +333,12 @@ function renderRankChart(
nameKey: 'enterprise_name' | 'bureau_dept_name',
seriesName: string
) {
if (!el || !data.length) return chart;
if (!el) return chart;
const instance = chart ?? echarts.init(el);
if (!data.length) {
instance.clear();
return instance;
}
const names = data.map((d) => d[nameKey] || '');
const values = data.map((d) => toNum(d.cnt));
instance.setOption(buildRankBarOption(names, values, seriesName), true);
@ -403,43 +346,39 @@ function renderRankChart(
}
async function loadEnfEntSort() {
const size = rankSizeEnt.value;
const res = await safeLoad(() => queryEnfEntSort({ ...getParams(), pageSize: size }));
const list = res ? unwrapData(res) : MOCK_ENF_ENT_SORT.slice(0, size);
const res = await safeLoad(() => queryEnfEntSort({ ...getParams(), pageSize: rankSizeEnt.value }));
const list = res ? unwrapData(res) : [];
await nextTick();
rankCompanyChart = renderRankChart(rankCompanyRef.value, rankCompanyChart, normalizeRankList(list), 'enterprise_name', '被执法企业次数')!;
}
async function loadEnforcementSort() {
const size = rankSizeInspect.value;
const res = await safeLoad(() =>
isCityWide.value
? queryEnforcementSort({ ...getParams(), pageSize: size })
: queryUnionSort({ ...getParams(), pageSize: size })
? queryEnforcementSort({ ...getParams(), pageSize: rankSizeInspect.value })
: queryUnionSort({ ...getParams(), pageSize: rankSizeInspect.value })
);
const list = res ? unwrapData(res) : MOCK_ENFORCEMENT_SORT.slice(0, size);
const list = res ? unwrapData(res) : [];
await nextTick();
rankInspectChart = renderRankChart(rankInspectRef.value, rankInspectChart, normalizeRankList(list), 'bureau_dept_name', '执法数量')!;
}
async function loadEntCSort() {
const size = rankSizeComplaint.value;
const res = await safeLoad(() =>
isCityWide.value
? queryEntCSort({ ...getParams(), pageSize: size })
: queryLawEntSort({ ...getParams(), pageSize: size })
? queryEntCSort({ ...getParams(), pageSize: rankSizeComplaint.value })
: queryLawEntSort({ ...getParams(), pageSize: rankSizeComplaint.value })
);
const list = res ? unwrapData(res) : MOCK_ENT_C_SORT.slice(0, size);
const list = res ? unwrapData(res) : [];
await nextTick();
const data = normalizeRankList(list);
// 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, '被投诉单位次数')!;
rankComplaintChart = renderRankChart(rankComplaintRef.value, rankComplaintChart, data, 'bureau_dept_name', '被投诉单位次数')!;
}
async function loadAutoRate() {
const res = await safeLoad(() => queryAutoRate(getParams()));
const data = (res ? unwrapData(res) : MOCK_AUTO_RATE) as Record<string, unknown>;
if (!res) return;
const data = unwrapData(res) as Record<string, unknown>;
await nextTick();
if (rankPieAutoRef.value) {
rankPieAutoChart ??= echarts.init(rankPieAutoRef.value);

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

@ -54,8 +54,8 @@
</div>
</div>
<div class="select_item">
<label class="select_time">时间筛选</label>
<el-date-picker v-model="dateRange" type="daterange" range-separator="" value-format="YYYY-MM-DD" clearable @change="refreshAll" />
<label class="select_time" :class="{ active: datePickerOpen }" @click="datePickerOpen = !datePickerOpen">时间筛选<a></a></label>
<el-date-picker v-if="datePickerOpen" v-model="dateRange" type="daterange" range-separator="" value-format="YYYY-MM-DD" clearable @change="refreshAll" />
<span>综合数据</span>
</div>
</div>
@ -195,6 +195,7 @@ const cssVars = computed(() => {
});
const dateRange = ref<[string, string] | null>(null);
const datePickerOpen = ref(false);
const deptPanelOpen = ref(false);
const detailPanelOpen = ref(false);
const detailTab = ref(0);
@ -212,83 +213,7 @@ const rankSizeEnt = ref(10);
const rankSizeInspect = ref(10);
const rankSizeComplaint = ref(10);
/* ======================== 开发调试用假数据 ======================== */
const MOCK_STATS: Partial<CollectStatisticsData> = {
singleLaw: { count: 1285, yesterday: 35, thisMonth: 142, yoy: 4.2, mom: 1.8, completed: 0, unCompleted: 0 },
unionLaw: { count: 86, yesterday: 2, thisMonth: 12, yoy: -1.5, mom: 3.1, completed: 0, unCompleted: 0 },
enfEnt: { count: 928, yesterday: 41, thisMonth: 168, yoy: 6.3, mom: 2.5, completed: 0, unCompleted: 0 },
entEeduction: { count: 142, yesterday: 5, thisMonth: 18, yoy: -3.5, mom: 0.8, rate: '2.36%' },
entComplaint: { count: 85, yesterday: 2, thisMonth: 10, yoy: 8.2, mom: 4.1, completed: 62, unCompleted: 23 },
ent: { count: 48560, yesterday: 8, thisMonth: 22, yoy: 0.5, mom: 0.2, completed: 0, unCompleted: 0 },
lawCategoryTotal: 1438,
lawCategory: [
{ 行政检查: 1220 }, { 行政处罚: 125 }, { 行政许可: 42 }, { 行政强制: 32 },
{ 行政征收: 5 }, { 行政给付: 8 }, { 行政确认: 6 }, { 行政登记: 0 },
{ 行政裁决: 0 }, { 文书送达: 0 }
],
totalCaseType: 35,
caseType: [
{ 违规执法: 21 }, { 违法执法: 6 }, { 入企不扫码: 4 }, { 其他: 4 }
],
lawFieldTotal: 1285,
lawField: [
{ 卫生健康: 320 }, { 应急管理: 215 }, { 生态环境: 168 }, { 市场监督管理资源: 380 }, { 规划和自然资源: 202 }
],
eva: { high: 62, mid: 17, low: 3, un: 3 },
law_comp: { count: 85, mom: 4.1, yoy: 8.2, completed: 62 },
district: {
福田: { singleLaw: 420, unionLaw: 30, enfEnt: 380, entEeduction: 5, compAddress: 25, entAddress: 4800 },
罗湖: { singleLaw: 260, unionLaw: 20, enfEnt: 220, entEeduction: 3, compAddress: 18, entAddress: 3200 },
南山: { singleLaw: 320, unionLaw: 25, enfEnt: 300, entEeduction: 4, compAddress: 22, entAddress: 5000 },
盐田: { singleLaw: 60, unionLaw: 8, enfEnt: 45, entEeduction: 1, compAddress: 6, entAddress: 300 },
宝安: { singleLaw: 580, unionLaw: 45, enfEnt: 520, entEeduction: 8, compAddress: 35, entAddress: 18500 },
龙岗: { singleLaw: 510, unionLaw: 35, enfEnt: 440, entEeduction: 7, compAddress: 28, entAddress: 16500 },
龙华: { singleLaw: 150, unionLaw: 15, enfEnt: 130, entEeduction: 2, compAddress: 12, entAddress: 2500 },
坪山: { singleLaw: 80, unionLaw: 10, enfEnt: 75, entEeduction: 1, compAddress: 7, entAddress: 4500 },
光明: { singleLaw: 110, unionLaw: 12, enfEnt: 95, entEeduction: 2, compAddress: 9, entAddress: 16500 },
大鹏新: { singleLaw: 40, unionLaw: 5, enfEnt: 35, entEeduction: 0, compAddress: 3, entAddress: 17500 },
深汕: { singleLaw: 25, unionLaw: 3, enfEnt: 20, entEeduction: 0, compAddress: 2, entAddress: 200 }
}
};
const MOCK_ENF_ENT_SORT = [
{ enterprise_name: '深圳市某某科技有限公司', cnt: 56 },
{ enterprise_name: '某某电子(深圳)有限公司', cnt: 42 },
{ enterprise_name: '深圳市某某食品有限公司', cnt: 38 },
{ enterprise_name: '某某集团股份有限公司', cnt: 31 },
{ enterprise_name: '某某环保科技深圳分公司', cnt: 27 },
{ enterprise_name: '深圳市某某医疗器械公司', cnt: 24 },
{ enterprise_name: '某某光电股份有限公司', cnt: 19 },
{ enterprise_name: '深圳市某某化工有限公司', cnt: 16 },
{ enterprise_name: '深圳市某某物流有限公司', cnt: 13 },
{ enterprise_name: '某某商贸(深圳)有限公司', cnt: 9 }
];
const MOCK_ENFORCEMENT_SORT = [
{ bureau_dept_name: '福田区市场监督管理局', cnt: 152 },
{ bureau_dept_name: '宝安区应急管理局', cnt: 138 },
{ bureau_dept_name: '龙岗区生态环境局', cnt: 115 },
{ bureau_dept_name: '南山区市场监督管理局', cnt: 98 },
{ bureau_dept_name: '罗湖区卫生健康局', cnt: 82 },
{ bureau_dept_name: '龙华区应急管理局', cnt: 68 },
{ bureau_dept_name: '光明区市场监督管理局', cnt: 54 },
{ bureau_dept_name: '坪山区应急管理局', cnt: 43 },
{ bureau_dept_name: '盐田区卫生健康局', cnt: 32 },
{ bureau_dept_name: '大鹏新区应急管理局', cnt: 18 }
];
const MOCK_ENT_C_SORT = [
{ bureau_dept_name: '福田区市场监督管理局', cnt: 28 },
{ bureau_dept_name: '宝安区市场监督管理局', cnt: 24 },
{ bureau_dept_name: '南山区卫生健康局', cnt: 18 },
{ bureau_dept_name: '龙岗区应急管理局', cnt: 15 },
{ bureau_dept_name: '罗湖区市场监督管理局', cnt: 12 },
{ bureau_dept_name: '龙华区应急管理局', cnt: 9 },
{ bureau_dept_name: '盐田区卫生健康局', cnt: 7 },
{ bureau_dept_name: '光明区市场监督管理局', cnt: 5 },
{ bureau_dept_name: '坪山区应急管理局', cnt: 4 },
{ bureau_dept_name: '大鹏新区卫生健康局', cnt: 2 }
];
/* ======================== 开发调试用假数据(已删除) ======================== */
const districtBarRef = ref<HTMLElement>();
const complaintHandlingRef = ref<HTMLElement>();
@ -374,7 +299,8 @@ function initChart(key: string, el?: HTMLElement) {
async function loadStatistics() {
const res = await safeLoad(() => collectStatistics(getParams()));
const data = (res ? unwrapData(res) : MOCK_STATS) as Partial<CollectStatisticsData>;
if (!res) return;
const data = (unwrapData(res) ?? {}) as Partial<CollectStatisticsData>;
stats.value = data;
if (data.law_comp) {
@ -443,33 +369,34 @@ function renderRank(
nameKey: 'enterprise_name' | 'bureau_dept_name',
title: string
) {
if (!el || !data.length) return;
if (!el) return;
const chart = initChart(key, el);
if (!data.length) {
chart?.clear();
return;
}
const names = data.map((d) => d[nameKey] || '');
const values = data.map((d) => toNum(d.cnt));
chart?.setOption(buildRankBarOption(names, values, title), true);
}
async function loadEnfEntSort() {
const size = rankSizeEnt.value;
const res = await safeLoad(() => queryEnfEntSort({ ...getParams(), pageSize: size }));
const list = res ? unwrapData(res) : MOCK_ENF_ENT_SORT.slice(0, size);
const res = await safeLoad(() => queryEnfEntSort({ ...getParams(), pageSize: rankSizeEnt.value }));
const list = res ? unwrapData(res) : [];
await nextTick();
renderRank(rankCompanyRef.value, 'rankCompany', normalizeRankList(list), 'enterprise_name', '被执法企业次数');
}
async function loadEnforcementSort() {
const size = rankSizeInspect.value;
const res = await safeLoad(() => queryEnforcementSort({ ...getParams(), pageSize: size }));
const list = res ? unwrapData(res) : MOCK_ENFORCEMENT_SORT.slice(0, size);
const res = await safeLoad(() => queryEnforcementSort({ ...getParams(), pageSize: rankSizeInspect.value }));
const list = res ? unwrapData(res) : [];
await nextTick();
renderRank(rankInspectRef.value, 'rankInspect', normalizeRankList(list), 'bureau_dept_name', '执法数量');
}
async function loadEntCSort() {
const size = rankSizeComplaint.value;
const res = await safeLoad(() => queryEntCSort({ ...getParams(), pageSize: size }));
const list = res ? unwrapData(res) : MOCK_ENT_C_SORT.slice(0, size);
const res = await safeLoad(() => queryEntCSort({ ...getParams(), pageSize: rankSizeComplaint.value }));
const list = res ? unwrapData(res) : [];
await nextTick();
renderRank(rankComplaintRef.value, 'rankComplaint', normalizeRankList(list), 'bureau_dept_name', '投诉次数');
}

Loading…
Cancel
Save