Merge branch 'dev' of http://120.46.213.136:9528/isoftstone/lc_frontend into dev
This commit is contained in:
@@ -31,6 +31,7 @@
|
|||||||
<span class="card-icon">👥</span>
|
<span class="card-icon">👥</span>
|
||||||
外协管理
|
外协管理
|
||||||
</div>
|
</div>
|
||||||
|
<el-button type="text" class="manage-btn" @click="openOutsourcingManagement">管理</el-button>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<div class="donut-chart-wrapper">
|
<div class="donut-chart-wrapper">
|
||||||
@@ -57,20 +58,35 @@
|
|||||||
<span class="card-icon">🛡️</span>
|
<span class="card-icon">🛡️</span>
|
||||||
风险管理
|
风险管理
|
||||||
</div>
|
</div>
|
||||||
|
<el-button type="text" class="manage-btn" @click="openRiskManagement">管理</el-button>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<div class="donut-chart-wrapper">
|
<div class="donut-chart-wrapper">
|
||||||
<Echart :options="riskChartOption" width="100%" height="200px" />
|
<Echart :options="riskChartOption" width="100%" height="200px" />
|
||||||
</div>
|
</div>
|
||||||
<div class="risk-distribution">
|
<div class="risk-distribution-table">
|
||||||
<div class="distribution-title">风险等级分布</div>
|
<div class="distribution-title">区域风险分布</div>
|
||||||
<div class="distribution-list">
|
<div class="table-wrapper">
|
||||||
<div class="distribution-item" v-for="item in riskDistribution" :key="item.level">
|
<table class="risk-table">
|
||||||
<span class="dot" :style="{ backgroundColor: item.color }"></span>
|
<thead>
|
||||||
<span class="region-name">{{ item.level }}</span>
|
<tr>
|
||||||
<span class="region-count">{{ item.count }}项</span>
|
<th>区域</th>
|
||||||
<span class="region-percent">({{ item.percent }})</span>
|
<th>低</th>
|
||||||
</div>
|
<th>一般</th>
|
||||||
|
<th>较大</th>
|
||||||
|
<th>重大</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr v-for="item in areaRiskDistribution" :key="item.area">
|
||||||
|
<td>{{ item.area }}</td>
|
||||||
|
<td>{{ item.low || '0' }}</td>
|
||||||
|
<td>{{ item.general || '0' }}</td>
|
||||||
|
<td>{{ item.moderate || '0' }}</td>
|
||||||
|
<td>{{ item.major || '0' }}</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -83,18 +99,42 @@
|
|||||||
<span class="card-icon warning">⚠️</span>
|
<span class="card-icon warning">⚠️</span>
|
||||||
隐患管理
|
隐患管理
|
||||||
</div>
|
</div>
|
||||||
|
<el-button type="text" class="manage-btn" @click="openHiddenDangerManagement">管理</el-button>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<div class="line-chart-wrapper">
|
<div class="line-chart-wrapper">
|
||||||
<Echart :options="hiddenDangerChartOption" width="100%" height="180px" />
|
<Echart :options="hiddenDangerChartOption" width="100%" height="180px" />
|
||||||
</div>
|
</div>
|
||||||
<div class="rectification-status">
|
<div class="rectification-status-grid">
|
||||||
<div class="distribution-title">整改状态</div>
|
<div class="distribution-title">区域整改状态</div>
|
||||||
<div class="status-list">
|
<div class="grid-wrapper">
|
||||||
<div class="status-item" v-for="item in rectificationStatus" :key="item.status">
|
<!-- 第一列:区域名称 -->
|
||||||
<span class="dot" :style="{ backgroundColor: item.color }"></span>
|
<div class="grid-column">
|
||||||
<span class="status-name">{{ item.status }}</span>
|
<div class="grid-header empty-header"></div>
|
||||||
<span class="status-count">{{ item.count }}项</span>
|
<div class="grid-park-name" v-for="item in areaRectificationStatus" :key="'area-' + item.area">
|
||||||
|
{{ item.area }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- 已逾期列 -->
|
||||||
|
<div class="grid-column">
|
||||||
|
<div class="grid-header status-overdue">已逾期</div>
|
||||||
|
<div class="grid-number status-overdue" v-for="item in areaRectificationStatus" :key="'overdue-' + item.area">
|
||||||
|
{{ item.overdue }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- 处理中列 -->
|
||||||
|
<div class="grid-column">
|
||||||
|
<div class="grid-header status-processing">处理中</div>
|
||||||
|
<div class="grid-number status-processing" v-for="item in areaRectificationStatus" :key="'processing-' + item.area">
|
||||||
|
{{ item.processing }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- 已处理列 -->
|
||||||
|
<div class="grid-column">
|
||||||
|
<div class="grid-header status-processed">已处理</div>
|
||||||
|
<div class="grid-number status-processed" v-for="item in areaRectificationStatus" :key="'processed-' + item.area">
|
||||||
|
{{ item.processed }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -111,6 +151,7 @@
|
|||||||
<span class="card-icon">🚧</span>
|
<span class="card-icon">🚧</span>
|
||||||
高危作业
|
高危作业
|
||||||
</div>
|
</div>
|
||||||
|
<el-button type="text" class="manage-btn" @click="openHighRiskManagement">管理</el-button>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<div class="high-risk-top">
|
<div class="high-risk-top">
|
||||||
@@ -147,6 +188,7 @@
|
|||||||
<span class="card-icon">📄</span>
|
<span class="card-icon">📄</span>
|
||||||
应急预案
|
应急预案
|
||||||
</div>
|
</div>
|
||||||
|
<el-button type="text" class="manage-btn" @click="openEmergencyPlanManagement">管理</el-button>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<div class="emergency-plan-top">
|
<div class="emergency-plan-top">
|
||||||
@@ -186,6 +228,7 @@
|
|||||||
<span class="card-icon">📚</span>
|
<span class="card-icon">📚</span>
|
||||||
安全培训
|
安全培训
|
||||||
</div>
|
</div>
|
||||||
|
<el-button type="text" class="manage-btn" @click="openTrainingManagement">管理</el-button>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<div class="bar-chart-wrapper">
|
<div class="bar-chart-wrapper">
|
||||||
@@ -251,6 +294,14 @@ interface DistributionItem {
|
|||||||
color: string
|
color: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface AreaRiskItem {
|
||||||
|
area: string
|
||||||
|
low: number | string
|
||||||
|
general: number
|
||||||
|
moderate: number
|
||||||
|
major: number
|
||||||
|
}
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
|
|
||||||
@@ -277,6 +328,32 @@ const getInitialDateRange = () => {
|
|||||||
}
|
}
|
||||||
const dateRange = ref(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<number>(0) // 外协人员总数
|
const outsourcingTotal = ref<number>(0) // 外协人员总数
|
||||||
const outsourcingDistribution = ref<DistributionItem[]>([])
|
const outsourcingDistribution = ref<DistributionItem[]>([])
|
||||||
@@ -343,26 +420,17 @@ const initOutsourcingData = async () => {
|
|||||||
// 风险管理数据
|
// 风险管理数据
|
||||||
const riskTotal = ref<number>(0) // 风险总数
|
const riskTotal = ref<number>(0) // 风险总数
|
||||||
const riskDistribution = ref<DistributionItem[]>([])
|
const riskDistribution = ref<DistributionItem[]>([])
|
||||||
|
const areaRiskDistribution = ref<AreaRiskItem[]>([])
|
||||||
// 风险等级映射和颜色配置
|
|
||||||
const riskLevelMap: Record<string, { name: string; color: string }> = {
|
|
||||||
'低': { 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 hiddenDangerTrend = ref<Array<{ date: string; general: number; major: number }>>([])
|
const hiddenDangerTrend = ref<Array<{ date: string; general: number; major: number }>>([])
|
||||||
const rectificationStatus = ref<DistributionItem[]>([
|
interface AreaRectificationItem {
|
||||||
{ status: '已逾期', count: 0, color: '#ef4444' },
|
area: string
|
||||||
{ status: '处理中', count: 0, color: '#f59e0b' },
|
overdue: number
|
||||||
{ status: '已处理', count: 0, color: '#10b981' }
|
processing: number
|
||||||
])
|
processed: number
|
||||||
|
}
|
||||||
|
const areaRectificationStatus = ref<AreaRectificationItem[]>([])
|
||||||
|
|
||||||
// 高危作业数据
|
// 高危作业数据
|
||||||
const highRiskTotal = ref<number>(0) // 高危作业总数
|
const highRiskTotal = ref<number>(0) // 高危作业总数
|
||||||
@@ -930,49 +998,83 @@ const initRiskData = async () => {
|
|||||||
const records = response?.records || []
|
const records = response?.records || []
|
||||||
|
|
||||||
if (records && records.length > 0) {
|
if (records && records.length > 0) {
|
||||||
// 计算风险总数
|
// 按风险等级分组统计,用于环形图
|
||||||
const total = records.reduce((sum: number, item: any) => {
|
const levelMap = new Map<string, number>()
|
||||||
return sum + Number(item.total || 0)
|
|
||||||
}, 0)
|
|
||||||
|
|
||||||
riskTotal.value = total
|
// 按区域和风险等级分组统计,用于表格
|
||||||
|
const areaLevelMap = new Map<string, { low: number; general: number; moderate: number; major: number }>()
|
||||||
|
|
||||||
// 处理风险等级分布数据
|
records.forEach((item: any) => {
|
||||||
riskDistribution.value = records.map((item: any) => {
|
const level = item.name || ''
|
||||||
|
const area = item.area || ''
|
||||||
const count = Number(item.total || 0)
|
const count = Number(item.total || 0)
|
||||||
const percent = total > 0 ? ((count / total) * 100).toFixed(1) + '%' : '0%'
|
|
||||||
|
|
||||||
// 映射风险等级名称和颜色
|
// 统计风险等级分布(用于环形图)
|
||||||
const levelKey = item.name || ''
|
if (level) {
|
||||||
const levelConfig = riskLevelMap[levelKey] || { name: levelKey || '未知', color: '#9ca3af' }
|
levelMap.set(level, (levelMap.get(level) || 0) + count)
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
// 统计区域风险分布(用于表格)
|
||||||
level: levelConfig.name,
|
if (area) {
|
||||||
count,
|
if (!areaLevelMap.has(area)) {
|
||||||
percent,
|
areaLevelMap.set(area, { low: 0, general: 0, moderate: 0, major: 0 })
|
||||||
color: levelConfig.color
|
}
|
||||||
|
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 = [
|
const allLevels = [
|
||||||
{ level: '低风险', count: 0, percent: '0%', color: '#10b981' },
|
{ key: '低', level: '低风险', count: 0, percent: '0%', color: '#10b981' },
|
||||||
{ level: '一般风险', count: 0, percent: '0%', color: '#f59e0b' },
|
{ key: '一般', level: '一般风险', count: 0, percent: '0%', color: '#f59e0b' },
|
||||||
{ level: '较大风险', count: 0, percent: '0%', color: '#ef4444' },
|
{ key: '较大', level: '较大风险', count: 0, percent: '0%', color: '#ef4444' },
|
||||||
{ level: '重大风险', count: 0, percent: '0%', color: '#dc2626' }
|
{ key: '重大', level: '重大风险', count: 0, percent: '0%', color: '#dc2626' }
|
||||||
]
|
]
|
||||||
|
|
||||||
// 合并数据:如果某个等级有数据就使用数据,没有就保留0
|
riskDistribution.value = allLevels.map(defaultItem => {
|
||||||
const mergedDistribution = allLevels.map(defaultItem => {
|
const count = levelMap.get(defaultItem.key) || levelMap.get(defaultItem.level) || 0
|
||||||
const existingItem = riskDistribution.value.find(item => item.level === defaultItem.level)
|
const percent = total > 0 ? ((count / total) * 100).toFixed(1) + '%' : '0%'
|
||||||
return existingItem || defaultItem
|
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('处理后的风险管理数据:', {
|
console.log('处理后的风险管理数据:', {
|
||||||
total: riskTotal.value,
|
total: riskTotal.value,
|
||||||
distribution: riskDistribution.value
|
levelDistribution: riskDistribution.value,
|
||||||
|
areaDistribution: areaRiskDistribution.value
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
// 如果没有数据,设置为默认值
|
// 如果没有数据,设置为默认值
|
||||||
@@ -983,6 +1085,7 @@ const initRiskData = async () => {
|
|||||||
{ level: '较大风险', count: 0, percent: '0%', color: '#ef4444' },
|
{ level: '较大风险', count: 0, percent: '0%', color: '#ef4444' },
|
||||||
{ level: '重大风险', count: 0, percent: '0%', color: '#dc2626' }
|
{ level: '重大风险', count: 0, percent: '0%', color: '#dc2626' }
|
||||||
]
|
]
|
||||||
|
areaRiskDistribution.value = []
|
||||||
console.log('风险管理无数据')
|
console.log('风险管理无数据')
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -995,6 +1098,7 @@ const initRiskData = async () => {
|
|||||||
{ level: '较大风险', count: 0, percent: '0%', color: '#ef4444' },
|
{ level: '较大风险', count: 0, percent: '0%', color: '#ef4444' },
|
||||||
{ level: '重大风险', count: 0, percent: '0%', color: '#dc2626' }
|
{ level: '重大风险', count: 0, percent: '0%', color: '#dc2626' }
|
||||||
]
|
]
|
||||||
|
areaRiskDistribution.value = []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1038,13 +1142,14 @@ const initDangerData = async () => {
|
|||||||
// 按日期和等级分组统计,用于折线图
|
// 按日期和等级分组统计,用于折线图
|
||||||
const trendMap = new Map<string, { general: number; major: number }>()
|
const trendMap = new Map<string, { general: number; major: number }>()
|
||||||
|
|
||||||
// 按状态统计,用于整改状态列表
|
// 按区域和状态分组统计,用于整改状态表格
|
||||||
const statusMap = new Map<string, number>()
|
const areaStatusMap = new Map<string, { overdue: number; processing: number; processed: number }>()
|
||||||
|
|
||||||
records.forEach((item: any) => {
|
records.forEach((item: any) => {
|
||||||
const dayname = item.dayname || ''
|
const dayname = item.dayName || item.dayname || ''
|
||||||
const level = item.name || ''
|
const level = item.name || ''
|
||||||
const status = item.status || ''
|
const status = item.status || ''
|
||||||
|
const area = item.area || ''
|
||||||
const count = Number(item.total || 0)
|
const count = Number(item.total || 0)
|
||||||
|
|
||||||
// 统计趋势数据(按日期和等级)
|
// 统计趋势数据(按日期和等级)
|
||||||
@@ -1060,9 +1165,19 @@ const initDangerData = async () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 统计状态数据
|
// 统计区域整改状态数据
|
||||||
if (status) {
|
if (area) {
|
||||||
statusMap.set(status, (statusMap.get(status) || 0) + count)
|
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())
|
hiddenDangerTrend.value = Array.from(trendMap.entries())
|
||||||
.map(([date, counts]) => ({ date, ...counts }))
|
.map(([date, counts]) => ({ date, ...counts }))
|
||||||
.sort((a, b) => {
|
.sort((a, b) => {
|
||||||
// 提取日期中的数字部分进行排序
|
// 处理日期排序:如果是"10月"这种格式,提取月份数字
|
||||||
const numA = parseInt(a.date.replace('日', '')) || 0
|
const numA = parseInt(a.date.replace(/[^0-9]/g, '')) || 0
|
||||||
const numB = parseInt(b.date.replace('日', '')) || 0
|
const numB = parseInt(b.date.replace(/[^0-9]/g, '')) || 0
|
||||||
return numA - numB
|
// 如果是"日"格式(如"10日"),也处理
|
||||||
|
const dayA = parseInt(a.date.replace('日', '')) || 0
|
||||||
|
const dayB = parseInt(b.date.replace('日', '')) || 0
|
||||||
|
return (numA || dayA) - (numB || dayB)
|
||||||
})
|
})
|
||||||
|
|
||||||
// 更新整改状态数据
|
// 转换为区域整改状态数组
|
||||||
rectificationStatus.value = [
|
areaRectificationStatus.value = Array.from(areaStatusMap.entries())
|
||||||
{
|
.map(([area, status]) => ({
|
||||||
status: '已逾期',
|
area,
|
||||||
count: statusMap.get('已逾期') || 0,
|
overdue: status.overdue,
|
||||||
color: '#ef4444'
|
processing: status.processing,
|
||||||
},
|
processed: status.processed
|
||||||
{
|
}))
|
||||||
status: '处理中',
|
.sort((a, b) => {
|
||||||
count: statusMap.get('处理中') || 0,
|
// 按总数降序排序
|
||||||
color: '#f59e0b'
|
const totalA = a.overdue + a.processing + a.processed
|
||||||
},
|
const totalB = b.overdue + b.processing + b.processed
|
||||||
{
|
return totalB - totalA
|
||||||
status: '已处理',
|
})
|
||||||
count: statusMap.get('已处理') || 0,
|
|
||||||
color: '#10b981'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
console.log('处理后的隐患管理数据:', {
|
console.log('处理后的隐患管理数据:', {
|
||||||
trend: hiddenDangerTrend.value,
|
trend: hiddenDangerTrend.value,
|
||||||
status: rectificationStatus.value
|
areaStatus: areaRectificationStatus.value
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
// 如果没有数据,重置为空
|
// 如果没有数据,重置为空
|
||||||
hiddenDangerTrend.value = []
|
hiddenDangerTrend.value = []
|
||||||
rectificationStatus.value = [
|
areaRectificationStatus.value = []
|
||||||
{ status: '已逾期', count: 0, color: '#ef4444' },
|
|
||||||
{ status: '处理中', count: 0, color: '#f59e0b' },
|
|
||||||
{ status: '已处理', count: 0, color: '#10b981' }
|
|
||||||
]
|
|
||||||
console.log('隐患管理无数据')
|
console.log('隐患管理无数据')
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('获取隐患管理数据失败:', error)
|
console.error('获取隐患管理数据失败:', error)
|
||||||
// 如果接口失败,重置为空
|
// 如果接口失败,重置为空
|
||||||
hiddenDangerTrend.value = []
|
hiddenDangerTrend.value = []
|
||||||
rectificationStatus.value = [
|
areaRectificationStatus.value = []
|
||||||
{ status: '已逾期', count: 0, color: '#ef4444' },
|
|
||||||
{ status: '处理中', count: 0, color: '#f59e0b' },
|
|
||||||
{ status: '已处理', count: 0, color: '#10b981' }
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1724,8 +1830,8 @@ onMounted(async () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.region-distribution,
|
.region-distribution,
|
||||||
.risk-distribution,
|
.risk-distribution-table,
|
||||||
.rectification-status,
|
.rectification-status-grid,
|
||||||
.operation-distribution,
|
.operation-distribution,
|
||||||
.park-operation-distribution,
|
.park-operation-distribution,
|
||||||
.regional-progress {
|
.regional-progress {
|
||||||
@@ -1738,15 +1844,13 @@ onMounted(async () => {
|
|||||||
margin-bottom: 12px;
|
margin-bottom: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.distribution-list,
|
.distribution-list {
|
||||||
.status-list {
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.distribution-item,
|
.distribution-item {
|
||||||
.status-item {
|
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
@@ -1761,14 +1865,12 @@ onMounted(async () => {
|
|||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.region-name,
|
.region-name {
|
||||||
.status-name {
|
|
||||||
flex: 1;
|
flex: 1;
|
||||||
color: #374151;
|
color: #374151;
|
||||||
}
|
}
|
||||||
|
|
||||||
.region-count,
|
.region-count {
|
||||||
.status-count {
|
|
||||||
color: #1f2937;
|
color: #1f2937;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
margin-left: auto;
|
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 {
|
.drill-info {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|||||||
@@ -34,7 +34,7 @@
|
|||||||
<span class="card-icon">👥</span>
|
<span class="card-icon">👥</span>
|
||||||
外协管理
|
外协管理
|
||||||
</div>
|
</div>
|
||||||
<!-- <el-button type="text" class="manage-btn">管理</el-button> -->
|
<el-button type="text" class="manage-btn" @click="openOutsourcingManagement">管理</el-button>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<div class="donut-chart-wrapper">
|
<div class="donut-chart-wrapper">
|
||||||
@@ -61,7 +61,7 @@
|
|||||||
<span class="card-icon">🛡️</span>
|
<span class="card-icon">🛡️</span>
|
||||||
风险管理
|
风险管理
|
||||||
</div>
|
</div>
|
||||||
<!-- <el-button type="text" class="manage-btn">管理</el-button> -->
|
<el-button type="text" class="manage-btn" @click="openRiskManagement">管理</el-button>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<div class="donut-chart-wrapper">
|
<div class="donut-chart-wrapper">
|
||||||
@@ -102,7 +102,7 @@
|
|||||||
<span class="card-icon warning">⚠️</span>
|
<span class="card-icon warning">⚠️</span>
|
||||||
隐患管理
|
隐患管理
|
||||||
</div>
|
</div>
|
||||||
<!-- <el-button type="text" class="manage-btn">管理</el-button> -->
|
<el-button type="text" class="manage-btn" @click="openHiddenDangerManagement">管理</el-button>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<div class="line-chart-wrapper">
|
<div class="line-chart-wrapper">
|
||||||
@@ -154,7 +154,7 @@
|
|||||||
<span class="card-icon">🚧</span>
|
<span class="card-icon">🚧</span>
|
||||||
高危作业
|
高危作业
|
||||||
</div>
|
</div>
|
||||||
<!-- <el-button type="text" class="manage-btn">管理</el-button> -->
|
<el-button type="text" class="manage-btn" @click="openHighRiskManagement">管理</el-button>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<div class="high-risk-top">
|
<div class="high-risk-top">
|
||||||
@@ -191,7 +191,7 @@
|
|||||||
<span class="card-icon">📄</span>
|
<span class="card-icon">📄</span>
|
||||||
应急预案
|
应急预案
|
||||||
</div>
|
</div>
|
||||||
<!-- <el-button type="text" class="manage-btn">管理</el-button> -->
|
<el-button type="text" class="manage-btn" @click="openEmergencyPlanManagement">管理</el-button>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<div class="emergency-plan-top">
|
<div class="emergency-plan-top">
|
||||||
@@ -231,7 +231,7 @@
|
|||||||
<span class="card-icon">📚</span>
|
<span class="card-icon">📚</span>
|
||||||
安全培训
|
安全培训
|
||||||
</div>
|
</div>
|
||||||
<!-- <el-button type="text" class="manage-btn">管理</el-button> -->
|
<el-button type="text" class="manage-btn" @click="openTrainingManagement">管理</el-button>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<div class="bar-chart-wrapper">
|
<div class="bar-chart-wrapper">
|
||||||
@@ -322,6 +322,30 @@ const selectedPark = ref<string>('')
|
|||||||
const parkSelectorVisible = ref<boolean>(false)
|
const parkSelectorVisible = ref<boolean>(false)
|
||||||
const parkOption = ref<ParkItem[]>([])
|
const parkOption = ref<ParkItem[]>([])
|
||||||
|
|
||||||
|
// 外协管理:/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 getCurrentMonthRange = () => {
|
||||||
const start = dayjs().startOf('month').format('YYYY-MM-DD')
|
const start = dayjs().startOf('month').format('YYYY-MM-DD')
|
||||||
|
|||||||
@@ -31,7 +31,7 @@
|
|||||||
<span class="card-icon">👥</span>
|
<span class="card-icon">👥</span>
|
||||||
外协管理
|
外协管理
|
||||||
</div>
|
</div>
|
||||||
<!-- <el-button type="text" class="manage-btn">管理</el-button> -->
|
<el-button type="text" class="manage-btn" @click="openOutsourcingManagement">管理</el-button>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<div class="donut-chart-wrapper">
|
<div class="donut-chart-wrapper">
|
||||||
@@ -58,7 +58,7 @@
|
|||||||
<span class="card-icon">🛡️</span>
|
<span class="card-icon">🛡️</span>
|
||||||
风险管理
|
风险管理
|
||||||
</div>
|
</div>
|
||||||
<!-- <el-button type="text" class="manage-btn">管理</el-button> -->
|
<el-button type="text" class="manage-btn" @click="openRiskManagement">管理</el-button>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<div class="donut-chart-wrapper">
|
<div class="donut-chart-wrapper">
|
||||||
@@ -99,7 +99,7 @@
|
|||||||
<span class="card-icon warning">⚠️</span>
|
<span class="card-icon warning">⚠️</span>
|
||||||
隐患管理
|
隐患管理
|
||||||
</div>
|
</div>
|
||||||
<!-- <el-button type="text" class="manage-btn">管理</el-button> -->
|
<el-button type="text" class="manage-btn" @click="openHiddenDangerManagement">管理</el-button>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<div class="line-chart-wrapper">
|
<div class="line-chart-wrapper">
|
||||||
@@ -151,7 +151,7 @@
|
|||||||
<span class="card-icon">🚧</span>
|
<span class="card-icon">🚧</span>
|
||||||
高危作业
|
高危作业
|
||||||
</div>
|
</div>
|
||||||
<!-- <el-button type="text" class="manage-btn">管理</el-button> -->
|
<el-button type="text" class="manage-btn" @click="openHighRiskManagement">管理</el-button>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<div class="high-risk-top">
|
<div class="high-risk-top">
|
||||||
@@ -188,7 +188,7 @@
|
|||||||
<span class="card-icon">📄</span>
|
<span class="card-icon">📄</span>
|
||||||
应急预案
|
应急预案
|
||||||
</div>
|
</div>
|
||||||
<!-- <el-button type="text" class="manage-btn">管理</el-button> -->
|
<el-button type="text" class="manage-btn" @click="openEmergencyPlanManagement">管理</el-button>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<div class="emergency-plan-top">
|
<div class="emergency-plan-top">
|
||||||
@@ -230,7 +230,7 @@
|
|||||||
<span class="card-icon">📚</span>
|
<span class="card-icon">📚</span>
|
||||||
安全培训
|
安全培训
|
||||||
</div>
|
</div>
|
||||||
<!-- <el-button type="text" class="manage-btn">管理</el-button> -->
|
<el-button type="text" class="manage-btn" @click="openTrainingManagement">管理</el-button>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<div class="bar-chart-wrapper">
|
<div class="bar-chart-wrapper">
|
||||||
@@ -312,6 +312,30 @@ interface RecentDrillItem {
|
|||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const route = useRoute()
|
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<string>('')
|
const selectedPark = ref<string>('')
|
||||||
|
|
||||||
|
|||||||
@@ -208,7 +208,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div style=" display: flex; width: 100%;margin-top: 1vw; flex: 1; justify-content: flex-end;">
|
<div style=" display: flex; width: 100%;margin-top: 1vw; flex: 1; justify-content: flex-end;">
|
||||||
<AlertList style="margin-right: 1vw;" title="告警详情" :list-data="mockData.alertData.details" />
|
<AlertList linkUrl="http://10.0.64.20/security/console/command-center?p=tabl" style="margin-right: 1vw;" title="告警详情" :list-data="mockData.alertData.details" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- 右下区域 -->
|
<!-- 右下区域 -->
|
||||||
@@ -231,7 +231,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div style=" display: flex; width: 100%;margin-top: 1vw; flex: 1; justify-content: flex-end;">
|
<div style=" display: flex; width: 100%;margin-top: 1vw; flex: 1; justify-content: flex-end;">
|
||||||
<AlertList style="margin-right: 1vw;" title="工单详情" :list-data="mockData.timeoutWorkOrders.details" />
|
<AlertList linkUrl="http://10.0.64.20/pms/workorder-list" style="margin-right: 1vw;" title="工单详情" :list-data="mockData.timeoutWorkOrders.details" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -680,6 +680,50 @@ interface RegionItem {
|
|||||||
code: string
|
code: string
|
||||||
pic_url: 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<RegionItem[]>([])
|
const regionOption = ref<RegionItem[]>([])
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
updateTime()
|
updateTime()
|
||||||
@@ -692,50 +736,40 @@ onMounted(async () => {
|
|||||||
|
|
||||||
handleRiskTabChange('安全类')
|
handleRiskTabChange('安全类')
|
||||||
|
|
||||||
try {
|
// 先检查缓存
|
||||||
let { records } = await getTableList(
|
const cachedRecords = getCachedRegionOption()
|
||||||
'park_info_list'
|
let records = cachedRecords
|
||||||
)
|
|
||||||
// records = [
|
if (!records || records.length === 0) {
|
||||||
// {
|
// 缓存不存在或已过期,调用接口
|
||||||
// "region_id": "130601",
|
try {
|
||||||
// "park_code": "1825468527486140416",
|
let result = await getTableList('park_info_list')
|
||||||
// "region": "北京",
|
records = result.records || []
|
||||||
// "park_name": "雄安新区总部",
|
|
||||||
// "pic_url": "1"
|
if (records && records.length > 0) {
|
||||||
// },
|
// 保存到缓存
|
||||||
// {
|
setCachedRegionOption(records)
|
||||||
// "region_id": "130601",
|
}
|
||||||
// "park_code": "1825468527486140417",
|
} catch (error) {
|
||||||
// "region": "北京",
|
console.error('初始化园区数据失败:', error)
|
||||||
// "park_name": "雄安地面站",
|
records = []
|
||||||
// "pic_url": "2"
|
}
|
||||||
// },
|
}
|
||||||
// {
|
|
||||||
// "region_id": "130603",
|
if (records && records.length > 0) {
|
||||||
// "park_code": "1825468527486140426",
|
// 更新为新的数据格式
|
||||||
// "region": "武汉",
|
regionOption.value = records.map(el => ({
|
||||||
// "park_name": "花山新区总部",
|
name: el.park_name,
|
||||||
// "pic_url": "3"
|
code: el.park_code,
|
||||||
// }
|
pic_url: el.pic_url
|
||||||
// ]
|
}))
|
||||||
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++) {
|
for (let i = 0; i < regionOption.value.length; i++) {
|
||||||
const el = regionOption.value[i];
|
const el = regionOption.value[i];
|
||||||
if (el.code == query.campus_id && el.pic_url) {
|
if (el.code == query.campus_id && el.pic_url) {
|
||||||
backgroundImage.value = el.pic_url
|
backgroundImage.value = el.pic_url
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
|
||||||
console.error('初始化园区数据失败:', error)
|
|
||||||
}
|
}
|
||||||
// 初始化数据
|
// 初始化数据
|
||||||
await loadDashboardData()
|
await loadDashboardData()
|
||||||
@@ -880,7 +914,7 @@ const loadDashboardData = () => {
|
|||||||
|
|
||||||
// 获取超期工单数据
|
// 获取超期工单数据
|
||||||
getTableList('timeout_work_order', query).then(timeout_work_order => {
|
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.total = timeout_work_order.records.length
|
||||||
mockData.timeoutWorkOrders.details = timeout_work_order.records
|
mockData.timeoutWorkOrders.details = timeout_work_order.records
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ interface Props {
|
|||||||
scrollSpeed?: number
|
scrollSpeed?: number
|
||||||
scrollInterval?: number,
|
scrollInterval?: number,
|
||||||
tableTitle?: TableTitle[]
|
tableTitle?: TableTitle[]
|
||||||
|
linkUrl?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = withDefaults(defineProps<Props>(), {
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
@@ -73,7 +74,7 @@ let scrollTimer: NodeJS.Timeout | null = null
|
|||||||
let isScrolling = false
|
let isScrolling = false
|
||||||
|
|
||||||
const handleItemClick = (item: AlertItem) => {
|
const handleItemClick = (item: AlertItem) => {
|
||||||
window.open(`http://10.0.64.20/pms/workorder-list`, '_blank')
|
window.open(props.linkUrl, '_blank')
|
||||||
}
|
}
|
||||||
|
|
||||||
// 自动滚动功能
|
// 自动滚动功能
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ const progressChartOption = ref<any>({
|
|||||||
tooltip: {
|
tooltip: {
|
||||||
show: true,
|
show: true,
|
||||||
trigger: 'item',
|
trigger: 'item',
|
||||||
formatter: '{a} <br/>{b}: {c}% ({d}%)'
|
formatter: '{b}: {c}%'
|
||||||
},
|
},
|
||||||
series: [
|
series: [
|
||||||
{
|
{
|
||||||
@@ -248,7 +248,7 @@ const refreshProcessCharts = (process): void => {
|
|||||||
tooltip: {
|
tooltip: {
|
||||||
show: true,
|
show: true,
|
||||||
trigger: 'item',
|
trigger: 'item',
|
||||||
formatter: '{a} <br/>{b}: {c}% ({d}%)'
|
formatter: '{b}: {c}%'
|
||||||
},
|
},
|
||||||
series: [
|
series: [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -45,7 +45,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div> -->
|
</div> -->
|
||||||
<AlertList style="margin-right: 1vw;" title="告警详情" :list-data="alertDetails" ></AlertList>
|
<AlertList style="margin-right: 1vw;" title="告警详情" :list-data="alertDetails" :linkUrl="linkUrl"></AlertList>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -72,6 +72,7 @@ interface Props {
|
|||||||
alertData?: AlertData
|
alertData?: AlertData
|
||||||
alertDetails?: AlertItem[]
|
alertDetails?: AlertItem[]
|
||||||
sourceIndex?: number
|
sourceIndex?: number
|
||||||
|
linkUrl?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
// 默认值
|
// 默认值
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
<div class="chart-grid">
|
<div class="chart-grid">
|
||||||
<div class="chart-card" v-for="item in currentCharts" :key="`${activeTab}-${item.title}`">
|
<div class="chart-card" v-for="item in currentCharts" :key="`${activeTab}-${item.title}`">
|
||||||
<div class="chart-title">{{ item.title }}</div>
|
<div class="chart-title" @click="handleChartTitleClick()">{{ item.title }}</div>
|
||||||
<div class="chart-content">
|
<div class="chart-content">
|
||||||
<div class="chart-wrapper">
|
<div class="chart-wrapper">
|
||||||
<Echart class="donut-chart" :options="buildOption(item)" />
|
<Echart class="donut-chart" :options="buildOption(item)" />
|
||||||
@@ -75,6 +75,10 @@ const defaultChart: ChartItem[] = [
|
|||||||
{ title: '每年检查(巡检类)', total: 6, rate: 0, status: { notStarted: 3, inProgress: 0, done: 3, voided: 0 } }
|
{ 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<Record<TabType, ChartItem[]>>({
|
const tabCharts = ref<Record<TabType, ChartItem[]>>({
|
||||||
安全类: [...defaultChart],
|
安全类: [...defaultChart],
|
||||||
工程类: [...defaultChart]
|
工程类: [...defaultChart]
|
||||||
@@ -204,6 +208,7 @@ const handleTabClick = (tab: TabType) => {
|
|||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin-bottom: 6px;
|
margin-bottom: 6px;
|
||||||
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.chart-content {
|
.chart-content {
|
||||||
|
|||||||
@@ -32,7 +32,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div> -->
|
</div> -->
|
||||||
<AlertList style="margin-right: 1vw;" title="工单详情" :list-data="alertDetails" ></AlertList>
|
<AlertList :linkUrl="linkUrl" style="margin-right: 1vw;" title="工单详情" :list-data="alertDetails" ></AlertList>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -55,6 +55,7 @@ interface Props {
|
|||||||
timeoutWorkOrders?: TimeoutWorkOrders
|
timeoutWorkOrders?: TimeoutWorkOrders
|
||||||
alertDetails?: AlertItem[]
|
alertDetails?: AlertItem[]
|
||||||
sourceIndex?: number
|
sourceIndex?: number
|
||||||
|
linkUrl?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
// 默认值
|
// 默认值
|
||||||
|
|||||||
@@ -30,9 +30,11 @@
|
|||||||
<div class="right-wrapper">
|
<div class="right-wrapper">
|
||||||
<HighRiskAlertPanel :alertData="dashboardData?.alertData"
|
<HighRiskAlertPanel :alertData="dashboardData?.alertData"
|
||||||
:alertDetails="dashboardData?.alertData.details"
|
:alertDetails="dashboardData?.alertData.details"
|
||||||
|
linkUrl="http://10.0.64.20/security/console/command-center?p=tabl"
|
||||||
:sourceIndex="sourceIndex"/>
|
:sourceIndex="sourceIndex"/>
|
||||||
<TimeoutWorkOrderPanel :timeoutWorkOrders="dashboardData?.timeoutWorkOrders"
|
<TimeoutWorkOrderPanel :timeoutWorkOrders="dashboardData?.timeoutWorkOrders"
|
||||||
:alertDetails="dashboardData?.timeoutWorkOrders.details"
|
:alertDetails="dashboardData?.timeoutWorkOrders.details"
|
||||||
|
linkUrl="http://10.0.64.20/pms/workorder-list"
|
||||||
:sourceIndex="sourceIndex"/>
|
:sourceIndex="sourceIndex"/>
|
||||||
</div>
|
</div>
|
||||||
<HiddenDangerPanel :hiddenDangerData="dashboardData?.hiddenDangerData"/>
|
<HiddenDangerPanel :hiddenDangerData="dashboardData?.hiddenDangerData"/>
|
||||||
@@ -215,29 +217,22 @@ const query = reactive({
|
|||||||
campus_id: "",
|
campus_id: "",
|
||||||
})
|
})
|
||||||
|
|
||||||
// 缓存工具函数
|
// 缓存工具函数 - 三个页面共享的缓存
|
||||||
const CACHE_KEY = 'regionOption_cache'
|
const CACHE_KEY = 'shared_regionOption_cache'
|
||||||
const CACHE_DURATION = 5 * 60 * 1000 // 5分钟
|
const CACHE_DURATION = 5 * 60 * 1000 // 5分钟
|
||||||
|
|
||||||
interface CacheData {
|
interface CacheData {
|
||||||
regionOption: RegionItem[]
|
records: any[] // 原始接口返回的数据
|
||||||
campus_id: string
|
timestamp: number
|
||||||
}
|
}
|
||||||
|
|
||||||
const getCachedRegionOption = (): CacheData | null => {
|
const getCachedRegionOption = (): any[] | null => {
|
||||||
try {
|
try {
|
||||||
const cached = sessionStorage.getItem(CACHE_KEY)
|
const cached = sessionStorage.getItem(CACHE_KEY)
|
||||||
if (cached) {
|
if (cached) {
|
||||||
const {data, timestamp} = JSON.parse(cached)
|
const cacheData: CacheData = JSON.parse(cached)
|
||||||
const now = Date.now()
|
|
||||||
// 检查缓存是否在有效期内
|
// 检查缓存是否在有效期内
|
||||||
if (now - timestamp < CACHE_DURATION) {
|
return cacheData.records
|
||||||
console.log('使用缓存的 regionOption 数据')
|
|
||||||
return data
|
|
||||||
} else {
|
|
||||||
console.log('缓存已过期,清除缓存')
|
|
||||||
sessionStorage.removeItem(CACHE_KEY)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('读取缓存失败:', error)
|
console.error('读取缓存失败:', error)
|
||||||
@@ -246,17 +241,13 @@ const getCachedRegionOption = (): CacheData | null => {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
const setCachedRegionOption = (regionOption: RegionItem[], campus_id: string) => {
|
const setCachedRegionOption = (records: any[]) => {
|
||||||
try {
|
try {
|
||||||
const cacheData: CacheData = {
|
const cacheData: CacheData = {
|
||||||
regionOption,
|
records,
|
||||||
campus_id
|
|
||||||
}
|
|
||||||
const cache = {
|
|
||||||
data: cacheData,
|
|
||||||
timestamp: Date.now()
|
timestamp: Date.now()
|
||||||
}
|
}
|
||||||
sessionStorage.setItem(CACHE_KEY, JSON.stringify(cache))
|
sessionStorage.setItem(CACHE_KEY, JSON.stringify(cacheData))
|
||||||
console.log('regionOption 数据已缓存')
|
console.log('regionOption 数据已缓存')
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('保存缓存失败:', error)
|
console.error('保存缓存失败:', error)
|
||||||
@@ -269,76 +260,61 @@ onMounted(async () => {
|
|||||||
timeUpdateTimerId.value = setInterval(updateTime, 1000)
|
timeUpdateTimerId.value = setInterval(updateTime, 1000)
|
||||||
|
|
||||||
// 先检查缓存
|
// 先检查缓存
|
||||||
const cachedData = getCachedRegionOption()
|
const cachedRecords = getCachedRegionOption()
|
||||||
if (cachedData && cachedData.regionOption && cachedData.regionOption.length > 0) {
|
let records = cachedRecords
|
||||||
regionOption.value = cachedData.regionOption
|
|
||||||
query.campus_id = cachedData.campus_id || ''
|
if (!records || records.length === 0) {
|
||||||
console.log('从缓存加载 regionOption:', regionOption.value, 'campus_id:', query.campus_id)
|
|
||||||
} else {
|
|
||||||
// 缓存不存在或已过期,调用接口
|
// 缓存不存在或已过期,调用接口
|
||||||
try {
|
try {
|
||||||
let {records} = await getTableList(
|
let result = await getTableList('park_info_list')
|
||||||
'park_info_list'
|
records = result.records || []
|
||||||
)
|
|
||||||
// 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) {
|
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) {
|
} catch (error) {
|
||||||
console.error('初始化园区数据失败:', 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()
|
await loadDashboardData()
|
||||||
|
|
||||||
// 启动定时器
|
// 启动定时器
|
||||||
@@ -446,7 +422,7 @@ const loadDashboardData = async (): Promise<void> => {
|
|||||||
try {
|
try {
|
||||||
// 获取超期工单数据
|
// 获取超期工单数据
|
||||||
getTableList('timeout_work_order', query).then(timeout_work_order => {
|
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.total = timeout_work_order.records.length
|
||||||
dashboardData.value.timeoutWorkOrders.details = timeout_work_order.records
|
dashboardData.value.timeoutWorkOrders.details = timeout_work_order.records
|
||||||
}
|
}
|
||||||
@@ -482,11 +458,6 @@ const handleHiddenDangerPannelData = (query) => {
|
|||||||
pending: 0
|
pending: 0
|
||||||
}
|
}
|
||||||
try {
|
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 => {
|
getTableList('risk_level_count', query).then(res => {
|
||||||
if (res.records && res.records.length > 0) {
|
if (res.records && res.records.length > 0) {
|
||||||
|
|||||||
@@ -109,7 +109,7 @@
|
|||||||
<a
|
<a
|
||||||
:class="['detail-link', row.hasAlarm ? 'detail-alarm' : 'detail-normal']"
|
:class="['detail-link', row.hasAlarm ? 'detail-alarm' : 'detail-normal']"
|
||||||
@click="handleViewDetail(row)"
|
@click="handleViewDetail(row)"
|
||||||
:href="'http://10.0.64.20/configcenter/console/device-manage'"
|
:href="'http://10.0.64.20/ibms/render/configure/render?formUuid=LCC-1840031646260649984'"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
<span v-if="row.hasAlarm" class="alarm-badge">异常</span>
|
<span v-if="row.hasAlarm" class="alarm-badge">异常</span>
|
||||||
|
|||||||
@@ -33,9 +33,11 @@
|
|||||||
<div class="right-wrapper">
|
<div class="right-wrapper">
|
||||||
<HighRiskAlertPanel :alertData="dashboardData?.alertData"
|
<HighRiskAlertPanel :alertData="dashboardData?.alertData"
|
||||||
:alertDetails="dashboardData?.alertData.details"
|
:alertDetails="dashboardData?.alertData.details"
|
||||||
|
linkUrl="http://10.0.64.20/security/console/command-center?p=tabl"
|
||||||
:sourceIndex="sourceIndex"/>
|
:sourceIndex="sourceIndex"/>
|
||||||
<TimeoutWorkOrderPanel :timeoutWorkOrders="dashboardData?.timeoutWorkOrders"
|
<TimeoutWorkOrderPanel :timeoutWorkOrders="dashboardData?.timeoutWorkOrders"
|
||||||
:alertDetails="dashboardData?.timeoutWorkOrders.details"
|
:alertDetails="dashboardData?.timeoutWorkOrders.details"
|
||||||
|
linkUrl="http://10.0.64.20/pms/workorder-list"
|
||||||
:sourceIndex="sourceIndex"/>
|
:sourceIndex="sourceIndex"/>
|
||||||
</div>
|
</div>
|
||||||
<HiddenDangerPanel :hiddenDangerData="dashboardData?.hiddenDangerData"/>
|
<HiddenDangerPanel :hiddenDangerData="dashboardData?.hiddenDangerData"/>
|
||||||
@@ -221,55 +223,38 @@ const query = reactive({
|
|||||||
regionCode: ""
|
regionCode: ""
|
||||||
})
|
})
|
||||||
|
|
||||||
// 缓存工具函数
|
// 缓存工具函数 - 三个页面共享的缓存
|
||||||
const CACHE_KEY_PREFIX = 'regionOption_cache_'
|
const CACHE_KEY = 'shared_regionOption_cache'
|
||||||
const CACHE_DURATION = 5 * 60 * 1000 // 5分钟
|
const CACHE_DURATION = 5 * 60 * 1000 // 5分钟
|
||||||
|
|
||||||
interface CacheData {
|
interface CacheData {
|
||||||
regionOption: RegionItem[]
|
records: any[] // 原始接口返回的数据
|
||||||
campus_id: string
|
timestamp: number
|
||||||
}
|
}
|
||||||
|
|
||||||
const getCachedRegionOption = (regionCode: string): CacheData | null => {
|
const getCachedRegionOption = (): any[] | null => {
|
||||||
if (!regionCode) return null
|
|
||||||
try {
|
try {
|
||||||
const cacheKey = CACHE_KEY_PREFIX + regionCode
|
const cached = sessionStorage.getItem(CACHE_KEY)
|
||||||
const cached = sessionStorage.getItem(cacheKey)
|
|
||||||
if (cached) {
|
if (cached) {
|
||||||
const { data, timestamp } = JSON.parse(cached)
|
const cacheData: CacheData = JSON.parse(cached)
|
||||||
const now = Date.now()
|
|
||||||
// 检查缓存是否在有效期内
|
// 检查缓存是否在有效期内
|
||||||
if (now - timestamp < CACHE_DURATION) {
|
return cacheData.records
|
||||||
console.log('使用缓存的 regionOption 数据,regionCode:', regionCode)
|
|
||||||
return data
|
|
||||||
} else {
|
|
||||||
console.log('缓存已过期,清除缓存,regionCode:', regionCode)
|
|
||||||
sessionStorage.removeItem(cacheKey)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('读取缓存失败:', error)
|
console.error('读取缓存失败:', error)
|
||||||
if (regionCode) {
|
sessionStorage.removeItem(CACHE_KEY)
|
||||||
sessionStorage.removeItem(CACHE_KEY_PREFIX + regionCode)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
const setCachedRegionOption = (regionCode: string, regionOption: RegionItem[], campus_id: string) => {
|
const setCachedRegionOption = (records: any[]) => {
|
||||||
if (!regionCode) return
|
|
||||||
try {
|
try {
|
||||||
const cacheKey = CACHE_KEY_PREFIX + regionCode
|
|
||||||
const cacheData: CacheData = {
|
const cacheData: CacheData = {
|
||||||
regionOption,
|
records,
|
||||||
campus_id
|
|
||||||
}
|
|
||||||
const cache = {
|
|
||||||
data: cacheData,
|
|
||||||
timestamp: Date.now()
|
timestamp: Date.now()
|
||||||
}
|
}
|
||||||
sessionStorage.setItem(cacheKey, JSON.stringify(cache))
|
sessionStorage.setItem(CACHE_KEY, JSON.stringify(cacheData))
|
||||||
console.log('regionOption 数据已缓存,regionCode:', regionCode)
|
console.log('regionOption 数据已缓存')
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('保存缓存失败:', error)
|
console.error('保存缓存失败:', error)
|
||||||
}
|
}
|
||||||
@@ -288,66 +273,49 @@ onMounted(async () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 先检查缓存
|
// 先检查缓存
|
||||||
const cachedData = getCachedRegionOption(query.regionCode)
|
const cachedRecords = getCachedRegionOption()
|
||||||
if (cachedData && cachedData.regionOption && cachedData.regionOption.length > 0) {
|
let records = cachedRecords
|
||||||
regionOption.value = cachedData.regionOption
|
|
||||||
query.campus_id = cachedData.campus_id || ''
|
if (!records || records.length === 0) {
|
||||||
console.log('从缓存加载 regionOption:', regionOption.value, 'campus_id:', query.campus_id)
|
|
||||||
} else {
|
|
||||||
// 缓存不存在或已过期,调用接口
|
// 缓存不存在或已过期,调用接口
|
||||||
try {
|
try {
|
||||||
let {records} = await getTableList(
|
let result = await getTableList('park_info_list')
|
||||||
'park_info_list'
|
records = result.records || []
|
||||||
)
|
|
||||||
// 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);
|
|
||||||
|
|
||||||
query.campus_id = regionOption.value.map(el => el.code).join()
|
if (records && records.length > 0) {
|
||||||
|
// 保存到缓存
|
||||||
// 保存到缓存
|
setCachedRegionOption(records)
|
||||||
setCachedRegionOption(query.regionCode, regionOption.value, query.campus_id)
|
}
|
||||||
}
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('初始化园区数据失败:', 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()
|
await loadDashboardData()
|
||||||
|
|
||||||
@@ -444,7 +412,7 @@ const loadDashboardData = async (): Promise<void> => {
|
|||||||
// 获取风险预警详情数据
|
// 获取风险预警详情数据
|
||||||
getTableList('risk_alert_detail', query).then(risk_alert_detail => {
|
getTableList('risk_alert_detail', query).then(risk_alert_detail => {
|
||||||
// if (risk_alert_detail.records && risk_alert_detail.records.length > 0) {
|
// 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 => {
|
}).catch(error => {
|
||||||
console.error('获取风险预警详情数据失败:', error)
|
console.error('获取风险预警详情数据失败:', error)
|
||||||
@@ -456,7 +424,7 @@ const loadDashboardData = async (): Promise<void> => {
|
|||||||
try {
|
try {
|
||||||
// 获取超期工单数据
|
// 获取超期工单数据
|
||||||
getTableList('timeout_work_order', query).then(timeout_work_order => {
|
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.total = timeout_work_order.records.length
|
||||||
dashboardData.value.timeoutWorkOrders.details = timeout_work_order.records
|
dashboardData.value.timeoutWorkOrders.details = timeout_work_order.records
|
||||||
}
|
}
|
||||||
@@ -493,11 +461,6 @@ const handleHiddenDangerPannelData = (query) => {
|
|||||||
pending: 0
|
pending: 0
|
||||||
}
|
}
|
||||||
try {
|
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 => {
|
getTableList('risk_level_count', query).then(res => {
|
||||||
if (res.records && res.records.length > 0) {
|
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'
|
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'
|
pendingCnt = totalCnt > 0 ? ((_data.pending + _data2.pending) / totalCnt * 100).toFixed(2) : '0.00'
|
||||||
}
|
}
|
||||||
|
|
||||||
dashboardData.value.hiddenDangerData.progress = {
|
dashboardData.value.hiddenDangerData.progress = {
|
||||||
overdue: overdueCnt,
|
overdue: overdueCnt,
|
||||||
processed: processedCnt,
|
processed: processedCnt,
|
||||||
@@ -673,13 +636,21 @@ const handleRiskTabChange = async (tab: TabType) => {
|
|||||||
|
|
||||||
// 同时获取维保任务和巡检任务的数据
|
// 同时获取维保任务和巡检任务的数据
|
||||||
const [maintenanceResponse, inspectionResponse] = await Promise.all([
|
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)
|
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)
|
console.error('获取巡检任务数据失败:', error)
|
||||||
return { records: [] }
|
return {records: []}
|
||||||
})
|
})
|
||||||
])
|
])
|
||||||
|
|
||||||
@@ -711,7 +682,7 @@ const handleRiskTabChange = async (tab: TabType) => {
|
|||||||
// 将API数据转换为图表数据格式
|
// 将API数据转换为图表数据格式
|
||||||
const convertToChartData = (records: any[], taskTypeName: string): any[] => {
|
const convertToChartData = (records: any[], taskTypeName: string): any[] => {
|
||||||
const charts: any[] = []
|
const charts: any[] = []
|
||||||
|
|
||||||
// 按周期分组
|
// 按周期分组
|
||||||
const cycleGroups: Record<string, any> = {}
|
const cycleGroups: Record<string, any> = {}
|
||||||
records.forEach((record: any) => {
|
records.forEach((record: any) => {
|
||||||
@@ -726,7 +697,7 @@ const handleRiskTabChange = async (tab: TabType) => {
|
|||||||
cycles.forEach((cycle) => {
|
cycles.forEach((cycle) => {
|
||||||
const data = cycleGroups[cycle] || {}
|
const data = cycleGroups[cycle] || {}
|
||||||
const title = `${cycleMap[cycle]}检查(${taskTypeName})`
|
const title = `${cycleMap[cycle]}检查(${taskTypeName})`
|
||||||
|
|
||||||
charts.push({
|
charts.push({
|
||||||
title,
|
title,
|
||||||
total: Number(data.total) || 0,
|
total: Number(data.total) || 0,
|
||||||
|
|||||||
Reference in New Issue
Block a user