diff --git a/src/views/Home/Index10.vue b/src/views/Home/Index10.vue index 053de84..dc99599 100644 --- a/src/views/Home/Index10.vue +++ b/src/views/Home/Index10.vue @@ -31,6 +31,7 @@ 👥 外协管理 + 管理
@@ -57,20 +58,35 @@ 🛡️ 风险管理
+ 管理
-
-
风险等级分布
-
-
- - {{ item.level }} - {{ item.count }}项 - ({{ item.percent }}) -
+
+
区域风险分布
+
+ + + + + + + + + + + + + + + + + + + +
区域一般较大重大
{{ item.area }}{{ item.low || '0' }}{{ item.general || '0' }}{{ item.moderate || '0' }}{{ item.major || '0' }}
@@ -83,18 +99,42 @@ ⚠️ 隐患管理
+ 管理
-
-
整改状态
-
-
- - {{ item.status }} - {{ item.count }}项 +
+
区域整改状态
+
+ +
+
+
+ {{ item.area }} +
+
+ +
+
已逾期
+
+ {{ item.overdue }} +
+
+ +
+
处理中
+
+ {{ item.processing }} +
+
+ +
+
已处理
+
+ {{ item.processed }} +
@@ -111,6 +151,7 @@ 🚧 高危作业
+ 管理
@@ -147,6 +188,7 @@ 📄 应急预案
+ 管理
@@ -186,6 +228,7 @@ 📚 安全培训
+ 管理
@@ -251,6 +294,14 @@ interface DistributionItem { color: string } +interface AreaRiskItem { + area: string + low: number | string + general: number + moderate: number + major: number +} + const router = useRouter() const route = useRoute() @@ -277,6 +328,32 @@ const getInitialDateRange = () => { } const dateRange = ref(getInitialDateRange()) +// 外协管理:/person/table/view/1959187451673116674 +// 风险管理: +// fx/table/view/1978723750599790594 +// 隐患管理:/fx/table/view/1963446160885366786 +// 高危作业:/low/table/view/1964253329070571521 +// 应急预案:/yayl/table/view/1966394259751907330 +// 安全培训:/pxks/table/view/1968225010550091777 +const openOutsourcingManagement = () => { + window.open('/person/table/view/1959187451673116674', '_blank') +} +const openRiskManagement = () => { + window.open('/fx/table/view/1978723750599790594', '_blank') +} +const openHiddenDangerManagement = () => { + window.open('/fx/table/view/1963446160885366786', '_blank') +} +const openHighRiskManagement = () => { + window.open('/low/table/view/1964253329070571521', '_blank') +} +const openEmergencyPlanManagement = () => { + window.open('/yayl/table/view/1966394259751907330', '_blank') +} +const openTrainingManagement = () => { + window.open('/pxks/table/view/1968225010550091777', '_blank') +} + // 外协管理数据 const outsourcingTotal = ref(0) // 外协人员总数 const outsourcingDistribution = ref([]) @@ -343,26 +420,17 @@ const initOutsourcingData = async () => { // 风险管理数据 const riskTotal = ref(0) // 风险总数 const riskDistribution = ref([]) - -// 风险等级映射和颜色配置 -const riskLevelMap: Record = { - '低': { name: '低风险', color: '#10b981' }, - '低风险': { name: '低风险', color: '#10b981' }, - '一般': { name: '一般风险', color: '#f59e0b' }, - '一般风险': { name: '一般风险', color: '#f59e0b' }, - '较大': { name: '较大风险', color: '#ef4444' }, - '较大风险': { name: '较大风险', color: '#ef4444' }, - '重大': { name: '重大风险', color: '#dc2626' }, - '重大风险': { name: '重大风险', color: '#dc2626' } -} +const areaRiskDistribution = ref([]) // 隐患管理数据 const hiddenDangerTrend = ref>([]) -const rectificationStatus = ref([ - { status: '已逾期', count: 0, color: '#ef4444' }, - { status: '处理中', count: 0, color: '#f59e0b' }, - { status: '已处理', count: 0, color: '#10b981' } -]) +interface AreaRectificationItem { + area: string + overdue: number + processing: number + processed: number +} +const areaRectificationStatus = ref([]) // 高危作业数据 const highRiskTotal = ref(0) // 高危作业总数 @@ -930,49 +998,83 @@ const initRiskData = async () => { const records = response?.records || [] if (records && records.length > 0) { - // 计算风险总数 - const total = records.reduce((sum: number, item: any) => { - return sum + Number(item.total || 0) - }, 0) + // 按风险等级分组统计,用于环形图 + const levelMap = new Map() - riskTotal.value = total + // 按区域和风险等级分组统计,用于表格 + const areaLevelMap = new Map() - // 处理风险等级分布数据 - riskDistribution.value = records.map((item: any) => { + records.forEach((item: any) => { + const level = item.name || '' + const area = item.area || '' const count = Number(item.total || 0) - const percent = total > 0 ? ((count / total) * 100).toFixed(1) + '%' : '0%' - // 映射风险等级名称和颜色 - const levelKey = item.name || '' - const levelConfig = riskLevelMap[levelKey] || { name: levelKey || '未知', color: '#9ca3af' } + // 统计风险等级分布(用于环形图) + if (level) { + levelMap.set(level, (levelMap.get(level) || 0) + count) + } - return { - level: levelConfig.name, - count, - percent, - color: levelConfig.color + // 统计区域风险分布(用于表格) + if (area) { + if (!areaLevelMap.has(area)) { + areaLevelMap.set(area, { low: 0, general: 0, moderate: 0, major: 0 }) + } + const areaData = areaLevelMap.get(area)! + if (level === '低' || level === '低风险') { + areaData.low += count + } else if (level === '一般' || level === '一般风险') { + areaData.general += count + } else if (level === '较大' || level === '较大风险') { + areaData.moderate += count + } else if (level === '重大' || level === '重大风险') { + areaData.major += count + } } }) - // 如果没有数据,确保包含所有四个风险等级(显示为0) + // 计算总数 + const total = Array.from(levelMap.values()).reduce((sum, count) => sum + count, 0) + riskTotal.value = total + + // 处理风险等级分布数据(用于环形图) const allLevels = [ - { level: '低风险', count: 0, percent: '0%', color: '#10b981' }, - { level: '一般风险', count: 0, percent: '0%', color: '#f59e0b' }, - { level: '较大风险', count: 0, percent: '0%', color: '#ef4444' }, - { level: '重大风险', count: 0, percent: '0%', color: '#dc2626' } + { key: '低', level: '低风险', count: 0, percent: '0%', color: '#10b981' }, + { key: '一般', level: '一般风险', count: 0, percent: '0%', color: '#f59e0b' }, + { key: '较大', level: '较大风险', count: 0, percent: '0%', color: '#ef4444' }, + { key: '重大', level: '重大风险', count: 0, percent: '0%', color: '#dc2626' } ] - // 合并数据:如果某个等级有数据就使用数据,没有就保留0 - const mergedDistribution = allLevels.map(defaultItem => { - const existingItem = riskDistribution.value.find(item => item.level === defaultItem.level) - return existingItem || defaultItem + riskDistribution.value = allLevels.map(defaultItem => { + const count = levelMap.get(defaultItem.key) || levelMap.get(defaultItem.level) || 0 + const percent = total > 0 ? ((count / total) * 100).toFixed(1) + '%' : '0%' + return { + level: defaultItem.level, + count, + percent, + color: defaultItem.color + } }) - riskDistribution.value = mergedDistribution + // 处理区域风险分布表 + areaRiskDistribution.value = Array.from(areaLevelMap.entries()) + .map(([area, data]) => ({ + area, + low: data.low > 0 ? data.low : '', + general: data.general, + moderate: data.moderate, + major: data.major + })) + .sort((a, b) => { + // 按总数降序排序 + const totalA = (typeof a.low === 'number' ? a.low : 0) + a.general + a.moderate + a.major + const totalB = (typeof b.low === 'number' ? b.low : 0) + b.general + b.moderate + b.major + return totalB - totalA + }) console.log('处理后的风险管理数据:', { total: riskTotal.value, - distribution: riskDistribution.value + levelDistribution: riskDistribution.value, + areaDistribution: areaRiskDistribution.value }) } else { // 如果没有数据,设置为默认值 @@ -983,6 +1085,7 @@ const initRiskData = async () => { { level: '较大风险', count: 0, percent: '0%', color: '#ef4444' }, { level: '重大风险', count: 0, percent: '0%', color: '#dc2626' } ] + areaRiskDistribution.value = [] console.log('风险管理无数据') } } catch (error) { @@ -995,6 +1098,7 @@ const initRiskData = async () => { { level: '较大风险', count: 0, percent: '0%', color: '#ef4444' }, { level: '重大风险', count: 0, percent: '0%', color: '#dc2626' } ] + areaRiskDistribution.value = [] } } @@ -1038,13 +1142,14 @@ const initDangerData = async () => { // 按日期和等级分组统计,用于折线图 const trendMap = new Map() - // 按状态统计,用于整改状态列表 - const statusMap = new Map() + // 按区域和状态分组统计,用于整改状态表格 + const areaStatusMap = new Map() records.forEach((item: any) => { - const dayname = item.dayname || '' + const dayname = item.dayName || item.dayname || '' const level = item.name || '' const status = item.status || '' + const area = item.area || '' const count = Number(item.total || 0) // 统计趋势数据(按日期和等级) @@ -1060,9 +1165,19 @@ const initDangerData = async () => { } } - // 统计状态数据 - if (status) { - statusMap.set(status, (statusMap.get(status) || 0) + count) + // 统计区域整改状态数据 + if (area) { + if (!areaStatusMap.has(area)) { + areaStatusMap.set(area, { overdue: 0, processing: 0, processed: 0 }) + } + const areaStatus = areaStatusMap.get(area)! + if (status === '已逾期') { + areaStatus.overdue += count + } else if (status === '处理中') { + areaStatus.processing += count + } else if (status === '已处理') { + areaStatus.processed += count + } } }) @@ -1070,54 +1185,45 @@ const initDangerData = async () => { hiddenDangerTrend.value = Array.from(trendMap.entries()) .map(([date, counts]) => ({ date, ...counts })) .sort((a, b) => { - // 提取日期中的数字部分进行排序 - const numA = parseInt(a.date.replace('日', '')) || 0 - const numB = parseInt(b.date.replace('日', '')) || 0 - return numA - numB + // 处理日期排序:如果是"10月"这种格式,提取月份数字 + const numA = parseInt(a.date.replace(/[^0-9]/g, '')) || 0 + const numB = parseInt(b.date.replace(/[^0-9]/g, '')) || 0 + // 如果是"日"格式(如"10日"),也处理 + const dayA = parseInt(a.date.replace('日', '')) || 0 + const dayB = parseInt(b.date.replace('日', '')) || 0 + return (numA || dayA) - (numB || dayB) }) - // 更新整改状态数据 - rectificationStatus.value = [ - { - status: '已逾期', - count: statusMap.get('已逾期') || 0, - color: '#ef4444' - }, - { - status: '处理中', - count: statusMap.get('处理中') || 0, - color: '#f59e0b' - }, - { - status: '已处理', - count: statusMap.get('已处理') || 0, - color: '#10b981' - } - ] + // 转换为区域整改状态数组 + areaRectificationStatus.value = Array.from(areaStatusMap.entries()) + .map(([area, status]) => ({ + area, + overdue: status.overdue, + processing: status.processing, + processed: status.processed + })) + .sort((a, b) => { + // 按总数降序排序 + const totalA = a.overdue + a.processing + a.processed + const totalB = b.overdue + b.processing + b.processed + return totalB - totalA + }) console.log('处理后的隐患管理数据:', { trend: hiddenDangerTrend.value, - status: rectificationStatus.value + areaStatus: areaRectificationStatus.value }) } else { // 如果没有数据,重置为空 hiddenDangerTrend.value = [] - rectificationStatus.value = [ - { status: '已逾期', count: 0, color: '#ef4444' }, - { status: '处理中', count: 0, color: '#f59e0b' }, - { status: '已处理', count: 0, color: '#10b981' } - ] + areaRectificationStatus.value = [] console.log('隐患管理无数据') } } catch (error) { console.error('获取隐患管理数据失败:', error) // 如果接口失败,重置为空 hiddenDangerTrend.value = [] - rectificationStatus.value = [ - { status: '已逾期', count: 0, color: '#ef4444' }, - { status: '处理中', count: 0, color: '#f59e0b' }, - { status: '已处理', count: 0, color: '#10b981' } - ] + areaRectificationStatus.value = [] } } @@ -1724,8 +1830,8 @@ onMounted(async () => { } .region-distribution, -.risk-distribution, -.rectification-status, +.risk-distribution-table, +.rectification-status-grid, .operation-distribution, .park-operation-distribution, .regional-progress { @@ -1738,15 +1844,13 @@ onMounted(async () => { margin-bottom: 12px; } - .distribution-list, - .status-list { + .distribution-list { display: flex; flex-direction: column; gap: 8px; } - .distribution-item, - .status-item { + .distribution-item { display: flex; align-items: center; gap: 8px; @@ -1761,14 +1865,12 @@ onMounted(async () => { flex-shrink: 0; } - .region-name, - .status-name { + .region-name { flex: 1; color: #374151; } - .region-count, - .status-count { + .region-count { color: #1f2937; font-weight: 500; margin-left: auto; @@ -1781,6 +1883,125 @@ onMounted(async () => { } } +// 网格样式 +.rectification-status-grid { + .grid-wrapper { + display: flex; + gap: 0; + justify-content: flex-start; + } + + .grid-column { + display: flex; + flex-direction: column; + align-items: center; + min-width: 0; + + &:first-child { + align-items: flex-start; + margin-right: 20px; + flex: 0 0 auto; + min-width: 80px; + } + + &:not(:first-child) { + flex: 1; + min-width: 60px; + } + } + + .grid-header { + font-size: 14px; + font-weight: bold; + margin-bottom: 12px; + height: 20px; + line-height: 20px; + + &.empty-header { + visibility: hidden; + } + + &.status-overdue { + color: #ef4444; + } + + &.status-processing { + color: #f59e0b; + } + + &.status-processed { + color: #10b981; + } + } + + .grid-park-name { + font-size: 13px; + color: #333; + margin-bottom: 8px; + text-align: left; + height: 24px; + line-height: 24px; + + &:last-child { + margin-bottom: 0; + } + } + + .grid-number { + font-size: 16px; + font-weight: 500; + margin-bottom: 8px; + text-align: center; + height: 24px; + line-height: 24px; + + &:last-child { + margin-bottom: 0; + } + + &.status-overdue { + color: #ef4444; + } + + &.status-processing { + color: #f59e0b; + } + + &.status-processed { + color: #10b981; + } + } +} + +.table-wrapper { + overflow-x: auto; +} + +.risk-table { + width: 100%; + border-collapse: collapse; + font-size: 13px; + + thead { + background-color: #f9fafb; + } + + th, td { + padding: 8px; + text-align: left; + border-bottom: 1px solid #e5e7eb; + } + + th { + font-weight: bold; + color: #333; + } + + td { + color: #666; + } +} + .drill-info { display: flex; flex-direction: column; diff --git a/src/views/Home/Index12.vue b/src/views/Home/Index12.vue index e00a5ac..f531164 100644 --- a/src/views/Home/Index12.vue +++ b/src/views/Home/Index12.vue @@ -34,7 +34,7 @@ 👥 外协管理
- + 管理
@@ -61,7 +61,7 @@ 🛡️ 风险管理
- + 管理
@@ -102,7 +102,7 @@ ⚠️ 隐患管理
- + 管理
@@ -154,7 +154,7 @@ 🚧 高危作业
- + 管理
@@ -191,7 +191,7 @@ 📄 应急预案
- + 管理
@@ -231,7 +231,7 @@ 📚 安全培训
- + 管理
@@ -322,6 +322,30 @@ const selectedPark = ref('') const parkSelectorVisible = ref(false) const parkOption = ref([]) +// 外协管理:/person/table/view/1959187451673116674 +// 风险管理:/fx/table/view/1978723750599790594 +// 隐患管理:/fx/table/view/1963446160885366786 +// 高危作业:/low/table/view/1964253329070571521 +// 应急预案:/yayl/table/view/1966394259751907330 +// 安全培训:/pxks/table/view/1968225010550091777 +const openOutsourcingManagement = () => { + window.open('/person/table/view/1959187451673116674', '_blank') +} +const openRiskManagement = () => { + window.open('/fx/table/view/1978723750599790594', '_blank') +} +const openHiddenDangerManagement = () => { + window.open('/fx/table/view/1963446160885366786', '_blank') +} +const openHighRiskManagement = () => { + window.open('/low/table/view/1964253329070571521', '_blank') +} +const openEmergencyPlanManagement = () => { + window.open('/yayl/table/view/1966394259751907330', '_blank') +} +const openTrainingManagement = () => { + window.open('/pxks/table/view/1968225010550091777', '_blank') +} // 时间选择相关 - 默认当前月起止,如果路由中有日期范围参数则使用 const getCurrentMonthRange = () => { const start = dayjs().startOf('month').format('YYYY-MM-DD') diff --git a/src/views/Home/Index13.vue b/src/views/Home/Index13.vue index 25242a4..323c1b1 100644 --- a/src/views/Home/Index13.vue +++ b/src/views/Home/Index13.vue @@ -31,7 +31,7 @@ 👥 外协管理
- + 管理
@@ -58,7 +58,7 @@ 🛡️ 风险管理
- + 管理
@@ -99,7 +99,7 @@ ⚠️ 隐患管理
- + 管理
@@ -151,7 +151,7 @@ 🚧 高危作业
- + 管理
@@ -188,7 +188,7 @@ 📄 应急预案
- + 管理
@@ -230,7 +230,7 @@ 📚 安全培训
- + 管理
@@ -312,6 +312,30 @@ interface RecentDrillItem { const router = useRouter() const route = useRoute() +// 外协管理:/person/table/view/1959187451673116674 +// 风险管理:/fx/table/view/1978723750599790594 +// 隐患管理:/fx/table/view/1963446160885366786 +// 高危作业:/low/table/view/1964253329070571521 +// 应急预案:/yayl/table/view/1966394259751907330 +// 安全培训:/pxks/table/view/1968225010550091777 +const openOutsourcingManagement = () => { + window.open('/person/table/view/1959187451673116674', '_blank') +} +const openRiskManagement = () => { + window.open('/fx/table/view/1978723750599790594', '_blank') +} +const openHiddenDangerManagement = () => { + window.open('/fx/table/view/1963446160885366786', '_blank') +} +const openHighRiskManagement = () => { + window.open('/low/table/view/1964253329070571521', '_blank') +} +const openEmergencyPlanManagement = () => { + window.open('/yayl/table/view/1966394259751907330', '_blank') +} +const openTrainingManagement = () => { + window.open('/pxks/table/view/1968225010550091777', '_blank') +} // 园区名称 - 从路由参数获取 const selectedPark = ref('') diff --git a/src/views/screen/companyScreen.vue b/src/views/screen/companyScreen.vue index 1856c68..37adbee 100644 --- a/src/views/screen/companyScreen.vue +++ b/src/views/screen/companyScreen.vue @@ -208,7 +208,7 @@
- +
@@ -231,7 +231,7 @@
- +
@@ -680,6 +680,50 @@ interface RegionItem { code: string pic_url: string } +// 缓存工具函数 - 三个页面共享的缓存 +const CACHE_KEY = 'shared_regionOption_cache' +const CACHE_DURATION = 5 * 60 * 1000 // 5分钟 + +interface CacheData { + records: any[] // 原始接口返回的数据 + timestamp: number +} + +const getCachedRegionOption = (): any[] | null => { + try { + const cached = sessionStorage.getItem(CACHE_KEY) + if (cached) { + const cacheData: CacheData = JSON.parse(cached) + const now = Date.now() + // 检查缓存是否在有效期内 + if (now - cacheData.timestamp < CACHE_DURATION) { + console.log('使用缓存的 regionOption 数据') + return cacheData.records + } else { + console.log('缓存已过期,清除缓存') + sessionStorage.removeItem(CACHE_KEY) + } + } + } catch (error) { + console.error('读取缓存失败:', error) + sessionStorage.removeItem(CACHE_KEY) + } + return null +} + +const setCachedRegionOption = (records: any[]) => { + try { + const cacheData: CacheData = { + records, + timestamp: Date.now() + } + sessionStorage.setItem(CACHE_KEY, JSON.stringify(cacheData)) + console.log('regionOption 数据已缓存') + } catch (error) { + console.error('保存缓存失败:', error) + } +} + const regionOption = ref([]) onMounted(async () => { updateTime() @@ -692,50 +736,40 @@ onMounted(async () => { handleRiskTabChange('安全类') - try { - let { records } = await getTableList( - 'park_info_list' - ) - // records = [ - // { - // "region_id": "130601", - // "park_code": "1825468527486140416", - // "region": "北京", - // "park_name": "雄安新区总部", - // "pic_url": "1" - // }, - // { - // "region_id": "130601", - // "park_code": "1825468527486140417", - // "region": "北京", - // "park_name": "雄安地面站", - // "pic_url": "2" - // }, - // { - // "region_id": "130603", - // "park_code": "1825468527486140426", - // "region": "武汉", - // "park_name": "花山新区总部", - // "pic_url": "3" - // } - // ] - if (records && records.length > 0) { - // 更新为新的数据格式 - regionOption.value = records.map(el => ({ - name: el.park_name, - code: el.park_code, - pic_url: el.pic_url - })) + // 先检查缓存 + const cachedRecords = getCachedRegionOption() + let records = cachedRecords + + if (!records || records.length === 0) { + // 缓存不存在或已过期,调用接口 + try { + let result = await getTableList('park_info_list') + records = result.records || [] + + if (records && records.length > 0) { + // 保存到缓存 + setCachedRegionOption(records) + } + } catch (error) { + console.error('初始化园区数据失败:', error) + records = [] + } + } + + if (records && records.length > 0) { + // 更新为新的数据格式 + regionOption.value = records.map(el => ({ + name: el.park_name, + code: el.park_code, + pic_url: el.pic_url + })) - for (let i = 0; i < regionOption.value.length; i++) { - const el = regionOption.value[i]; - if (el.code == query.campus_id && el.pic_url) { - backgroundImage.value = el.pic_url - } + for (let i = 0; i < regionOption.value.length; i++) { + const el = regionOption.value[i]; + if (el.code == query.campus_id && el.pic_url) { + backgroundImage.value = el.pic_url } } - } catch (error) { - console.error('初始化园区数据失败:', error) } // 初始化数据 await loadDashboardData() @@ -880,7 +914,7 @@ const loadDashboardData = () => { // 获取超期工单数据 getTableList('timeout_work_order', query).then(timeout_work_order => { - if (timeout_work_order.records && timeout_work_order.records.length > 0) { + if (timeout_work_order.records && timeout_work_order.records.length >= 0) { mockData.timeoutWorkOrders.total = timeout_work_order.records.length mockData.timeoutWorkOrders.details = timeout_work_order.records } diff --git a/src/views/screen/components/AlertList.vue b/src/views/screen/components/AlertList.vue index a908f34..72bc5ff 100644 --- a/src/views/screen/components/AlertList.vue +++ b/src/views/screen/components/AlertList.vue @@ -58,6 +58,7 @@ interface Props { scrollSpeed?: number scrollInterval?: number, tableTitle?: TableTitle[] + linkUrl?: string } const props = withDefaults(defineProps(), { @@ -73,7 +74,7 @@ let scrollTimer: NodeJS.Timeout | null = null let isScrolling = false const handleItemClick = (item: AlertItem) => { - window.open(`http://10.0.64.20/pms/workorder-list`, '_blank') + window.open(props.linkUrl, '_blank') } // 自动滚动功能 diff --git a/src/views/screen/components/HiddenDangerPanel.vue b/src/views/screen/components/HiddenDangerPanel.vue index 3638591..d44b3d6 100644 --- a/src/views/screen/components/HiddenDangerPanel.vue +++ b/src/views/screen/components/HiddenDangerPanel.vue @@ -100,7 +100,7 @@ const progressChartOption = ref({ tooltip: { show: true, trigger: 'item', - formatter: '{a}
{b}: {c}% ({d}%)' + formatter: '{b}: {c}%' }, series: [ { @@ -248,7 +248,7 @@ const refreshProcessCharts = (process): void => { tooltip: { show: true, trigger: 'item', - formatter: '{a}
{b}: {c}% ({d}%)' + formatter: '{b}: {c}%' }, series: [ { diff --git a/src/views/screen/components/HighRiskAlertPanel.vue b/src/views/screen/components/HighRiskAlertPanel.vue index df96e1d..cc59a32 100644 --- a/src/views/screen/components/HighRiskAlertPanel.vue +++ b/src/views/screen/components/HighRiskAlertPanel.vue @@ -45,7 +45,7 @@ --> - + @@ -72,6 +72,7 @@ interface Props { alertData?: AlertData alertDetails?: AlertItem[] sourceIndex?: number + linkUrl?: string } // 默认值 diff --git a/src/views/screen/components/RiskStatisticsPanel.vue b/src/views/screen/components/RiskStatisticsPanel.vue index 13054ee..6216185 100644 --- a/src/views/screen/components/RiskStatisticsPanel.vue +++ b/src/views/screen/components/RiskStatisticsPanel.vue @@ -11,7 +11,7 @@
-
{{ item.title }}
+
{{ item.title }}
@@ -75,6 +75,10 @@ const defaultChart: ChartItem[] = [ { title: '每年检查(巡检类)', total: 6, rate: 0, status: { notStarted: 3, inProgress: 0, done: 3, voided: 0 } } ] +const handleChartTitleClick = () => { + window.open('http://10.0.64.20/pms/workorder-list', '_blank') +} + const tabCharts = ref>({ 安全类: [...defaultChart], 工程类: [...defaultChart] @@ -204,6 +208,7 @@ const handleTabClick = (tab: TabType) => { font-size: 13px; text-align: center; margin-bottom: 6px; + cursor: pointer; } .chart-content { diff --git a/src/views/screen/components/TimeoutWorkOrderPanel.vue b/src/views/screen/components/TimeoutWorkOrderPanel.vue index 590c0df..8dbbd71 100644 --- a/src/views/screen/components/TimeoutWorkOrderPanel.vue +++ b/src/views/screen/components/TimeoutWorkOrderPanel.vue @@ -32,7 +32,7 @@
--> - +
@@ -55,6 +55,7 @@ interface Props { timeoutWorkOrders?: TimeoutWorkOrders alertDetails?: AlertItem[] sourceIndex?: number + linkUrl?: string } // 默认值 diff --git a/src/views/screen/mainScreen.vue b/src/views/screen/mainScreen.vue index f3e6610..5d13d27 100644 --- a/src/views/screen/mainScreen.vue +++ b/src/views/screen/mainScreen.vue @@ -30,9 +30,11 @@
@@ -215,29 +217,22 @@ const query = reactive({ campus_id: "", }) -// 缓存工具函数 -const CACHE_KEY = 'regionOption_cache' +// 缓存工具函数 - 三个页面共享的缓存 +const CACHE_KEY = 'shared_regionOption_cache' const CACHE_DURATION = 5 * 60 * 1000 // 5分钟 interface CacheData { - regionOption: RegionItem[] - campus_id: string + records: any[] // 原始接口返回的数据 + timestamp: number } -const getCachedRegionOption = (): CacheData | null => { +const getCachedRegionOption = (): any[] | null => { try { const cached = sessionStorage.getItem(CACHE_KEY) if (cached) { - const {data, timestamp} = JSON.parse(cached) - const now = Date.now() + const cacheData: CacheData = JSON.parse(cached) // 检查缓存是否在有效期内 - if (now - timestamp < CACHE_DURATION) { - console.log('使用缓存的 regionOption 数据') - return data - } else { - console.log('缓存已过期,清除缓存') - sessionStorage.removeItem(CACHE_KEY) - } + return cacheData.records } } catch (error) { console.error('读取缓存失败:', error) @@ -246,17 +241,13 @@ const getCachedRegionOption = (): CacheData | null => { return null } -const setCachedRegionOption = (regionOption: RegionItem[], campus_id: string) => { +const setCachedRegionOption = (records: any[]) => { try { const cacheData: CacheData = { - regionOption, - campus_id - } - const cache = { - data: cacheData, + records, timestamp: Date.now() } - sessionStorage.setItem(CACHE_KEY, JSON.stringify(cache)) + sessionStorage.setItem(CACHE_KEY, JSON.stringify(cacheData)) console.log('regionOption 数据已缓存') } catch (error) { console.error('保存缓存失败:', error) @@ -269,76 +260,61 @@ onMounted(async () => { timeUpdateTimerId.value = setInterval(updateTime, 1000) // 先检查缓存 - const cachedData = getCachedRegionOption() - if (cachedData && cachedData.regionOption && cachedData.regionOption.length > 0) { - regionOption.value = cachedData.regionOption - query.campus_id = cachedData.campus_id || '' - console.log('从缓存加载 regionOption:', regionOption.value, 'campus_id:', query.campus_id) - } else { + const cachedRecords = getCachedRegionOption() + let records = cachedRecords + + if (!records || records.length === 0) { // 缓存不存在或已过期,调用接口 try { - let {records} = await getTableList( - 'park_info_list' - ) - // records = [ - // { - // "region_id": "130601", - // "park_code": "1825468527486140416", - // "region": "北京", - // "park_name": "雄安新区总部" - // }, - // { - // "region_id": "130601", - // "park_code": "1825468527486140417", - // "region": "北京", - // "park_name": "雄安地面站" - // }, - // { - // "region_id": "130603", - // "park_code": "1825468527486140426", - // "region": "武汉", - // "park_name": "花山新区总部" - // } - // ] + let result = await getTableList('park_info_list') + records = result.records || [] + if (records && records.length > 0) { - // 去重region字段,使用Map来确保唯一性 - const regionMap = new Map() - records.forEach(el => { - if (!regionMap.has(el.region)) { - regionMap.set(el.region, { - name: el.region, - code: el.region_id // 使用region_code作为code - }) - } - }) - // 转换为数组 - regionOption.value = Array.from(regionMap.values()) - - console.log('regionOption.value>>>>', regionOption.value); - - // 将园区信息去重 - const parkMap = new Map(); - records.forEach(el => { - if (!parkMap.has(el.park_code)) { - parkMap.set(el.park_code, { - name: el.park_name, - code: el.park_code - }) - } - }) - // 将parkMap转换为数组 - query.campus_id = Array.from(parkMap.values()).map(e1 => e1.code).join(); - // 保存到缓存 - setCachedRegionOption(regionOption.value, query.campus_id) - + setCachedRegionOption(records) } } catch (error) { console.error('初始化园区数据失败:', error) + records = [] } } - // 初始化数据 + if (records && records.length > 0) { + // 去重region字段,使用Map来确保唯一性 + const regionMap = new Map() + records.forEach(el => { + if (!regionMap.has(el.region)) { + regionMap.set(el.region, { + name: el.region, + code: el.region_id // 使用region_id作为code + }) + } + }) + // 转换为数组 + regionOption.value = Array.from(regionMap.values()) + + console.log('regionOption.value>>>>', regionOption.value); + + // 将园区信息去重 + const parkMap = new Map(); + records.forEach(el => { + if (!parkMap.has(el.park_code)) { + parkMap.set(el.park_code, { + name: el.park_name, + code: el.park_code + }) + } + }) + // 将parkMap转换为数组 + query.campus_id = Array.from(parkMap.values()).map(e1 => e1.code).join(); + } + // 将初始化的逻辑放在这里 + dashboardData.value.hiddenDangerData.general = 0 + dashboardData.value.hiddenDangerData.major = 0 + dashboardData.value.hiddenDangerData.progress.overdue = 0 + dashboardData.value.hiddenDangerData.progress.processed = 0 + dashboardData.value.hiddenDangerData.progress.processing = 0 + // 初始化数据,loadDashboardData()既然是包含初始化的逻辑,所以并不适合定时调用,不然每次都要初始化。 await loadDashboardData() // 启动定时器 @@ -446,7 +422,7 @@ const loadDashboardData = async (): Promise => { try { // 获取超期工单数据 getTableList('timeout_work_order', query).then(timeout_work_order => { - if (timeout_work_order.records && timeout_work_order.records.length > 0) { + if (timeout_work_order.records && timeout_work_order.records.length >= 0) { dashboardData.value.timeoutWorkOrders.total = timeout_work_order.records.length dashboardData.value.timeoutWorkOrders.details = timeout_work_order.records } @@ -482,11 +458,6 @@ const handleHiddenDangerPannelData = (query) => { pending: 0 } try { - dashboardData.value.hiddenDangerData.general = 0 - dashboardData.value.hiddenDangerData.major = 0 - dashboardData.value.hiddenDangerData.progress.overdue = 0 - dashboardData.value.hiddenDangerData.progress.processed = 0 - dashboardData.value.hiddenDangerData.progress.processing = 0 // 获取隐患排查治理数据 getTableList('risk_level_count', query).then(res => { if (res.records && res.records.length > 0) { diff --git a/src/views/screen/powerMonitoring.vue b/src/views/screen/powerMonitoring.vue index 1e3cd6b..34c3eda 100644 --- a/src/views/screen/powerMonitoring.vue +++ b/src/views/screen/powerMonitoring.vue @@ -109,7 +109,7 @@ 异常 diff --git a/src/views/screen/regionScreen.vue b/src/views/screen/regionScreen.vue index 646beb5..e74c48c 100644 --- a/src/views/screen/regionScreen.vue +++ b/src/views/screen/regionScreen.vue @@ -33,9 +33,11 @@
@@ -221,55 +223,38 @@ const query = reactive({ regionCode: "" }) -// 缓存工具函数 -const CACHE_KEY_PREFIX = 'regionOption_cache_' +// 缓存工具函数 - 三个页面共享的缓存 +const CACHE_KEY = 'shared_regionOption_cache' const CACHE_DURATION = 5 * 60 * 1000 // 5分钟 interface CacheData { - regionOption: RegionItem[] - campus_id: string + records: any[] // 原始接口返回的数据 + timestamp: number } -const getCachedRegionOption = (regionCode: string): CacheData | null => { - if (!regionCode) return null +const getCachedRegionOption = (): any[] | null => { try { - const cacheKey = CACHE_KEY_PREFIX + regionCode - const cached = sessionStorage.getItem(cacheKey) + const cached = sessionStorage.getItem(CACHE_KEY) if (cached) { - const { data, timestamp } = JSON.parse(cached) - const now = Date.now() + const cacheData: CacheData = JSON.parse(cached) // 检查缓存是否在有效期内 - if (now - timestamp < CACHE_DURATION) { - console.log('使用缓存的 regionOption 数据,regionCode:', regionCode) - return data - } else { - console.log('缓存已过期,清除缓存,regionCode:', regionCode) - sessionStorage.removeItem(cacheKey) - } + return cacheData.records } } catch (error) { console.error('读取缓存失败:', error) - if (regionCode) { - sessionStorage.removeItem(CACHE_KEY_PREFIX + regionCode) - } + sessionStorage.removeItem(CACHE_KEY) } return null } -const setCachedRegionOption = (regionCode: string, regionOption: RegionItem[], campus_id: string) => { - if (!regionCode) return +const setCachedRegionOption = (records: any[]) => { try { - const cacheKey = CACHE_KEY_PREFIX + regionCode const cacheData: CacheData = { - regionOption, - campus_id - } - const cache = { - data: cacheData, + records, timestamp: Date.now() } - sessionStorage.setItem(cacheKey, JSON.stringify(cache)) - console.log('regionOption 数据已缓存,regionCode:', regionCode) + sessionStorage.setItem(CACHE_KEY, JSON.stringify(cacheData)) + console.log('regionOption 数据已缓存') } catch (error) { console.error('保存缓存失败:', error) } @@ -288,66 +273,49 @@ onMounted(async () => { } // 先检查缓存 - const cachedData = getCachedRegionOption(query.regionCode) - if (cachedData && cachedData.regionOption && cachedData.regionOption.length > 0) { - regionOption.value = cachedData.regionOption - query.campus_id = cachedData.campus_id || '' - console.log('从缓存加载 regionOption:', regionOption.value, 'campus_id:', query.campus_id) - } else { + const cachedRecords = getCachedRegionOption() + let records = cachedRecords + + if (!records || records.length === 0) { // 缓存不存在或已过期,调用接口 try { - let {records} = await getTableList( - 'park_info_list' - ) - // records = [ - // { - // "region_id": "130601", - // "park_code": "1825468527486140416", - // "region": "北京", - // "park_name": "雄安新区总部" - // }, - // { - // "region_id": "130601", - // "park_code": "1825468527486140417", - // "region": "北京", - // "park_name": "雄安地面站" - // }, - // { - // "region_id": "130603", - // "park_code": "1825468527486140426", - // "region": "武汉", - // "park_name": "花山新区总部" - // } - // ] - if (records && records.length > 0) { - // 去重region字段,使用Map来确保唯一性 - const regionMap = new Map() - records.filter((el) => el.region_id == query.regionCode) - .map(el => { - return el - }) - .forEach(el => { - if (!regionMap.has(el.park_name)) { - regionMap.set(el.park_name, { - name: el.park_name, - code: el.park_code // 使用region_code作为code - }) - } - }) - // // 转换为数组 - regionOption.value = Array.from(regionMap.values()) - console.log('regionOption.value>>>>', regionOption.value); + let result = await getTableList('park_info_list') + records = result.records || [] - query.campus_id = regionOption.value.map(el => el.code).join() - - // 保存到缓存 - setCachedRegionOption(query.regionCode, regionOption.value, query.campus_id) - } + if (records && records.length > 0) { + // 保存到缓存 + setCachedRegionOption(records) + } } catch (error) { console.error('初始化园区数据失败:', error) + records = [] } } + if (records && records.length > 0) { + // 根据regionCode过滤,去重park_name字段 + const regionMap = new Map() + records.filter((el) => el.region_id == query.regionCode) + .forEach(el => { + if (!regionMap.has(el.park_name)) { + regionMap.set(el.park_name, { + name: el.park_name, + code: el.park_code + }) + } + }) + // 转换为数组 + regionOption.value = Array.from(regionMap.values()) + console.log('regionOption.value>>>>', regionOption.value); + + query.campus_id = regionOption.value.map(el => el.code).join() + } + // 暂时先放在这里 + dashboardData.value.hiddenDangerData.general = 0 + dashboardData.value.hiddenDangerData.major = 0 + dashboardData.value.hiddenDangerData.progress.overdue = 0 + dashboardData.value.hiddenDangerData.progress.processed = 0 + dashboardData.value.hiddenDangerData.progress.processing = 0 // 初始化数据 await loadDashboardData() @@ -444,7 +412,7 @@ const loadDashboardData = async (): Promise => { // 获取风险预警详情数据 getTableList('risk_alert_detail', query).then(risk_alert_detail => { // if (risk_alert_detail.records && risk_alert_detail.records.length > 0) { - dashboardData.value.alertData.details = risk_alert_detail.records || [] + dashboardData.value.alertData.details = risk_alert_detail.records || [] // } }).catch(error => { console.error('获取风险预警详情数据失败:', error) @@ -456,7 +424,7 @@ const loadDashboardData = async (): Promise => { try { // 获取超期工单数据 getTableList('timeout_work_order', query).then(timeout_work_order => { - if (timeout_work_order.records && timeout_work_order.records.length > 0) { + if (timeout_work_order.records && timeout_work_order.records.length >= 0) { dashboardData.value.timeoutWorkOrders.total = timeout_work_order.records.length dashboardData.value.timeoutWorkOrders.details = timeout_work_order.records } @@ -493,11 +461,6 @@ const handleHiddenDangerPannelData = (query) => { pending: 0 } try { - dashboardData.value.hiddenDangerData.general = 0 - dashboardData.value.hiddenDangerData.major = 0 - dashboardData.value.hiddenDangerData.progress.overdue = 0 - dashboardData.value.hiddenDangerData.progress.processed = 0 - dashboardData.value.hiddenDangerData.progress.processing = 0 // 获取隐患排查治理数据 getTableList('risk_level_count', query).then(res => { if (res.records && res.records.length > 0) { @@ -542,7 +505,7 @@ const handleHiddenDangerPannelData = (query) => { processingCnt = totalCnt > 0 ? ((_data.processing + _data2.processing) / totalCnt * 100).toFixed(2) : '0.00' pendingCnt = totalCnt > 0 ? ((_data.pending + _data2.pending) / totalCnt * 100).toFixed(2) : '0.00' } - + dashboardData.value.hiddenDangerData.progress = { overdue: overdueCnt, processed: processedCnt, @@ -673,13 +636,21 @@ const handleRiskTabChange = async (tab: TabType) => { // 同时获取维保任务和巡检任务的数据 const [maintenanceResponse, inspectionResponse] = await Promise.all([ - getWorkOrderStatistics({workOrderType, taskType: '维保任务', campus_id: query.campus_id}).catch(error => { + getWorkOrderStatistics({ + workOrderType, + taskType: '维保任务', + campus_id: query.campus_id + }).catch(error => { console.error('获取维保任务数据失败:', error) - return { records: [] } + return {records: []} }), - getWorkOrderStatistics({workOrderType, taskType: '巡检任务', campus_id: query.campus_id}).catch(error => { + getWorkOrderStatistics({ + workOrderType, + taskType: '巡检任务', + campus_id: query.campus_id + }).catch(error => { console.error('获取巡检任务数据失败:', error) - return { records: [] } + return {records: []} }) ]) @@ -711,7 +682,7 @@ const handleRiskTabChange = async (tab: TabType) => { // 将API数据转换为图表数据格式 const convertToChartData = (records: any[], taskTypeName: string): any[] => { const charts: any[] = [] - + // 按周期分组 const cycleGroups: Record = {} records.forEach((record: any) => { @@ -726,7 +697,7 @@ const handleRiskTabChange = async (tab: TabType) => { cycles.forEach((cycle) => { const data = cycleGroups[cycle] || {} const title = `${cycleMap[cycle]}检查(${taskTypeName})` - + charts.push({ title, total: Number(data.total) || 0,