Commit a4ea86ed2c8193a0b08371e249f296e56712e894
1 parent
ea214724
feat: 全局支持corpCode参数传递
从URL获取corpCode并在全局共享,菜单导航及所有API请求均自动拼接该参数,同时修复能耗统计接口数据解析逻辑并调整菜单激活样式。
Showing
7 changed files
with
108 additions
and
29 deletions
| ... | ... | @@ -11,13 +11,12 @@ |
| 11 | 11 | background-color="#304156" |
| 12 | 12 | text-color="#bfcbd9" |
| 13 | 13 | active-text-color="#409eff" |
| 14 | - :router="true" | |
| 15 | 14 | > |
| 16 | - <el-menu-item index="/smart-light"> | |
| 15 | + <el-menu-item index="/smart-light" @click="navigateTo('/smart-light')"> | |
| 17 | 16 | <el-icon><Monitor /></el-icon> |
| 18 | 17 | <span>智能灯</span> |
| 19 | 18 | </el-menu-item> |
| 20 | - <el-menu-item index="/energy"> | |
| 19 | + <el-menu-item index="/energy" @click="navigateTo('/energy')"> | |
| 21 | 20 | <el-icon><Lightning /></el-icon> |
| 22 | 21 | <span>能耗</span> |
| 23 | 22 | </el-menu-item> |
| ... | ... | @@ -31,11 +30,31 @@ |
| 31 | 30 | </template> |
| 32 | 31 | |
| 33 | 32 | <script setup> |
| 34 | -import { computed } from 'vue' | |
| 35 | -import { useRoute } from 'vue-router' | |
| 33 | +import { computed, ref, provide } from 'vue' | |
| 34 | +import { useRoute, useRouter } from 'vue-router' | |
| 36 | 35 | |
| 37 | 36 | const route = useRoute() |
| 37 | +const router = useRouter() | |
| 38 | 38 | const currentRoute = computed(() => route.path) |
| 39 | + | |
| 40 | +// 从URL获取corpCode,全局共享 | |
| 41 | +function getCorpCode() { | |
| 42 | + return new URLSearchParams(window.location.search).get('corpCode') || '' | |
| 43 | +} | |
| 44 | +const corpCode = ref(getCorpCode()) | |
| 45 | +provide('corpCode', corpCode) | |
| 46 | + | |
| 47 | +// 给URL拼接corpCode | |
| 48 | +function withCorpCode(path) { | |
| 49 | + if (!corpCode.value) return path | |
| 50 | + const sep = path.includes('?') ? '&' : '?' | |
| 51 | + return `${path}${sep}corpCode=${encodeURIComponent(corpCode.value)}` | |
| 52 | +} | |
| 53 | + | |
| 54 | +// 菜单导航:保留corpCode参数 | |
| 55 | +function navigateTo(path) { | |
| 56 | + router.push(withCorpCode(path)) | |
| 57 | +} | |
| 39 | 58 | </script> |
| 40 | 59 | |
| 41 | 60 | <style scoped> |
| ... | ... | @@ -60,6 +79,13 @@ const currentRoute = computed(() => route.path) |
| 60 | 79 | border-right: none !important; |
| 61 | 80 | padding-top: 8px; |
| 62 | 81 | } |
| 82 | +.sidebar-menu :deep(.el-menu-item) { | |
| 83 | + transition: background-color 0.2s; | |
| 84 | +} | |
| 85 | +.sidebar-menu :deep(.el-menu-item.is-active) { | |
| 86 | + background-color: #263445 !important; | |
| 87 | + color: #fff !important; | |
| 88 | +} | |
| 63 | 89 | .main-content { |
| 64 | 90 | background-color: #f0f2f5; |
| 65 | 91 | padding: 0; | ... | ... |
| ... | ... | @@ -97,7 +97,7 @@ |
| 97 | 97 | </template> |
| 98 | 98 | |
| 99 | 99 | <script setup> |
| 100 | -import { ref, reactive, computed, watch, nextTick, onBeforeUnmount } from 'vue' | |
| 100 | +import { ref, reactive, computed, watch, nextTick, onBeforeUnmount, inject } from 'vue' | |
| 101 | 101 | |
| 102 | 102 | const props = defineProps({ visible: Boolean, device: Object }) |
| 103 | 103 | const emit = defineEmits(['update:visible']) |
| ... | ... | @@ -108,6 +108,14 @@ const selectedDate = ref(new Date().toISOString().slice(0, 10)) |
| 108 | 108 | const unitSelect = ref('single') |
| 109 | 109 | const dtuSn = computed(() => props.device?._raw?.dtuSn || props.device?.name || '') |
| 110 | 110 | |
| 111 | +// 从全局获取corpCode | |
| 112 | +const corpCode = inject('corpCode') | |
| 113 | +function withCorpCode(url) { | |
| 114 | + if (!corpCode.value) return url | |
| 115 | + const sep = url.includes('?') ? '&' : '?' | |
| 116 | + return `${url}${sep}corpCode=${encodeURIComponent(corpCode.value)}` | |
| 117 | +} | |
| 118 | + | |
| 111 | 119 | // API 数据 |
| 112 | 120 | const apiData = reactive({ |
| 113 | 121 | oeeData: { list: [], statusStats: [], totalDurationSeconds: 0, totalDurationFormatted: '' }, |
| ... | ... | @@ -417,7 +425,7 @@ async function fetchData() { |
| 417 | 425 | if (!dtuSn.value || !selectedDate.value) return |
| 418 | 426 | loading.value = true |
| 419 | 427 | try { |
| 420 | - const res = await fetch(`/api/energy/detail?dtuSn=${dtuSn.value}&date=${selectedDate.value}`) | |
| 428 | + const res = await fetch(withCorpCode(`/api/energy/detail?dtuSn=${dtuSn.value}&date=${selectedDate.value}`)) | |
| 421 | 429 | const data = await res.json() |
| 422 | 430 | if (data.code === 200) { |
| 423 | 431 | Object.assign(apiData.oeeData, data.oeeData || { list: [], statusStats: [], totalDurationSeconds: 0, totalDurationFormatted: '' }) | ... | ... |
| ... | ... | @@ -110,7 +110,7 @@ |
| 110 | 110 | </template> |
| 111 | 111 | |
| 112 | 112 | <script setup> |
| 113 | -import { ref, reactive, computed, watch, onMounted, nextTick } from 'vue' | |
| 113 | +import { ref, reactive, computed, watch, onMounted, nextTick, inject } from 'vue' | |
| 114 | 114 | |
| 115 | 115 | const props = defineProps({ |
| 116 | 116 | visible: Boolean, |
| ... | ... | @@ -122,6 +122,14 @@ const queryType = ref('day') |
| 122 | 122 | const queryDate = ref(new Date()) |
| 123 | 123 | const durationFilter = ref(null) |
| 124 | 124 | |
| 125 | +// 从全局获取corpCode | |
| 126 | +const corpCode = inject('corpCode') | |
| 127 | +function withCorpCode(url) { | |
| 128 | + if (!corpCode.value) return url | |
| 129 | + const sep = url.includes('?') ? '&' : '?' | |
| 130 | + return `${url}${sep}corpCode=${encodeURIComponent(corpCode.value)}` | |
| 131 | +} | |
| 132 | + | |
| 125 | 133 | // 状态映射 |
| 126 | 134 | const stateColorMap = { 0: '#909399', 1: '#c0392b', 2: '#e67e22', 3: '#67c23a', 4: '#2463aa' } |
| 127 | 135 | const stateNameMap = { '0': '灭灯', '1': '红灯', '2': '黄灯', '3': '绿灯', '4': '蓝灯' } |
| ... | ... | @@ -666,7 +674,7 @@ async function fetchLampData() { |
| 666 | 674 | const date = formatDate(queryDate.value) |
| 667 | 675 | if (!dtuSn) return |
| 668 | 676 | try { |
| 669 | - const res = await fetch(`/api/device/lampData?dtuSn=${dtuSn}&date=${date}`) | |
| 677 | + const res = await fetch(withCorpCode(`/api/device/lampData?dtuSn=${dtuSn}&date=${date}`)) | |
| 670 | 678 | const data = await res.json() |
| 671 | 679 | // list 中只有一个元素,取其 lampData |
| 672 | 680 | const entry = (data.list && data.list[0]) || {} | ... | ... |
| ... | ... | @@ -78,7 +78,7 @@ |
| 78 | 78 | </template> |
| 79 | 79 | |
| 80 | 80 | <script setup> |
| 81 | -import { ref, reactive, computed, watch, nextTick, onBeforeUnmount } from 'vue' | |
| 81 | +import { ref, reactive, computed, watch, nextTick, onBeforeUnmount, inject } from 'vue' | |
| 82 | 82 | import { Download, Close } from '@element-plus/icons-vue' |
| 83 | 83 | |
| 84 | 84 | const props = defineProps({ visible: Boolean, device: Object }) |
| ... | ... | @@ -93,6 +93,14 @@ const selectedDate = ref(today) |
| 93 | 93 | const dayRange = ref([weekAgo, today]) |
| 94 | 94 | const dateRange = ref(null) |
| 95 | 95 | |
| 96 | +// 从全局获取corpCode | |
| 97 | +const corpCode = inject('corpCode') | |
| 98 | +function withCorpCode(url) { | |
| 99 | + if (!corpCode.value) return url | |
| 100 | + const sep = url.includes('?') ? '&' : '?' | |
| 101 | + return `${url}${sep}corpCode=${encodeURIComponent(corpCode.value)}` | |
| 102 | +} | |
| 103 | + | |
| 96 | 104 | // 禁用未来日期 |
| 97 | 105 | function disabledDateFuture(time) { |
| 98 | 106 | return time.getTime() > Date.now() |
| ... | ... | @@ -349,7 +357,7 @@ async function fetchData() { |
| 349 | 357 | let url = `/api/energy/runtimeDetail?dtuSn=${dtuSn.value}&startDate=${sd}&type=${type}` |
| 350 | 358 | if (ed) url += '&endDate=' + ed |
| 351 | 359 | |
| 352 | - const res = await fetch(url) | |
| 360 | + const res = await fetch(withCorpCode(url)) | |
| 353 | 361 | const data = await res.json() |
| 354 | 362 | if (data.code === 200) { |
| 355 | 363 | Object.assign(apiData.summary, data.summary || {}) | ... | ... |
| ... | ... | @@ -126,7 +126,7 @@ |
| 126 | 126 | </template> |
| 127 | 127 | |
| 128 | 128 | <script setup> |
| 129 | -import { ref, reactive, computed, watch, onMounted, nextTick, getCurrentInstance } from 'vue' | |
| 129 | +import { ref, reactive, computed, watch, onMounted, nextTick, getCurrentInstance, inject } from 'vue' | |
| 130 | 130 | |
| 131 | 131 | const props = defineProps({ |
| 132 | 132 | visible: Boolean, |
| ... | ... | @@ -141,6 +141,14 @@ weekAgo.setDate(weekAgo.getDate() - 6) |
| 141 | 141 | const queryDateRange = ref([formatDate(weekAgo), formatDate(now)]) |
| 142 | 142 | const oeeData = ref(null) |
| 143 | 143 | |
| 144 | +// 从全局获取corpCode | |
| 145 | +const corpCode = inject('corpCode') | |
| 146 | +function withCorpCode(url) { | |
| 147 | + if (!corpCode.value) return url | |
| 148 | + const sep = url.includes('?') ? '&' : '?' | |
| 149 | + return `${url}${sep}corpCode=${encodeURIComponent(corpCode.value)}` | |
| 150 | +} | |
| 151 | + | |
| 144 | 152 | // 布局常量 |
| 145 | 153 | const padL = 50 |
| 146 | 154 | const padB = 24 |
| ... | ... | @@ -602,7 +610,7 @@ async function fetchOeeData() { |
| 602 | 610 | params += `&startDate=${start}&endDate=${end}` |
| 603 | 611 | } |
| 604 | 612 | try { |
| 605 | - const res = await fetch(`/api/device/oeeStats?${params}`) | |
| 613 | + const res = await fetch(withCorpCode(`/api/device/oeeStats?${params}`)) | |
| 606 | 614 | oeeData.value = await res.json() |
| 607 | 615 | } catch (err) { |
| 608 | 616 | console.error('获取稼动率数据失败:', err) | ... | ... |
| ... | ... | @@ -305,7 +305,7 @@ |
| 305 | 305 | </template> |
| 306 | 306 | |
| 307 | 307 | <script setup> |
| 308 | -import { ref, reactive, computed, onMounted, watch, nextTick, onBeforeUnmount } from 'vue' | |
| 308 | +import { ref, reactive, computed, onMounted, watch, nextTick, onBeforeUnmount, inject } from 'vue' | |
| 309 | 309 | import { Search, Menu, Document, Lock, Setting, Warning, Histogram } from '@element-plus/icons-vue' |
| 310 | 310 | import EnergyReportDialog from '../components/EnergyReportDialog.vue' |
| 311 | 311 | import SafetyDialog from '../components/SafetyDialog.vue' |
| ... | ... | @@ -316,6 +316,15 @@ const searchKeyword = ref('') |
| 316 | 316 | const currentStatus = ref('realtime') |
| 317 | 317 | const runStatusFilter = ref('') // runStatus 筛选: ''=全部, '0'=离线, '1'=停机, '2'=待机, '3'=运行 |
| 318 | 318 | |
| 319 | +// 从全局获取corpCode(由App.vue提供) | |
| 320 | +const corpCode = inject('corpCode') | |
| 321 | + | |
| 322 | +// 给URL拼接corpCode | |
| 323 | +function withCorpCode(url) { | |
| 324 | + const sep = url.includes('?') ? '&' : '?' | |
| 325 | + return `${url}${sep}corpCode=${encodeURIComponent(corpCode.value)}` | |
| 326 | +} | |
| 327 | + | |
| 319 | 328 | // 各状态数量(接口返回后更新) |
| 320 | 329 | const totalCounts = reactive({ all: 0, stop: 0, standby: 0, run: 0, offline: 0 }) |
| 321 | 330 | |
| ... | ... | @@ -374,7 +383,7 @@ async function fetchDeviceList() { |
| 374 | 383 | if (searchKeyword.value) params.append('deviceName', searchKeyword.value) |
| 375 | 384 | if (runStatusFilter.value !== '') params.append('runStatus', runStatusFilter.value) |
| 376 | 385 | |
| 377 | - const res = await fetch(`/api/energy/list?${params}`) | |
| 386 | + const res = await fetch(withCorpCode(`/api/energy/list?${params}`)) | |
| 378 | 387 | const data = await res.json() |
| 379 | 388 | deviceList.value = (data.list || []).map(item => ({ |
| 380 | 389 | id: item.id, |
| ... | ... | @@ -396,7 +405,7 @@ async function fetchDeviceList() { |
| 396 | 405 | // 获取运行状态统计 |
| 397 | 406 | async function fetchStats() { |
| 398 | 407 | try { |
| 399 | - const res = await fetch('/api/energy/stats') | |
| 408 | + const res = await fetch(withCorpCode('/api/energy/stats')) | |
| 400 | 409 | const data = await res.json() |
| 401 | 410 | totalCounts.all = data.total || 0 |
| 402 | 411 | totalCounts.offline = parseInt(data['0']) || 0 // runStatus=0 离线 |
| ... | ... | @@ -486,7 +495,7 @@ async function fetchTimelineData() { |
| 486 | 495 | tsZoomLevel.value = 1 |
| 487 | 496 | tsViewCenterMs.value = 0 |
| 488 | 497 | try { |
| 489 | - const url = `/api/energy/timelineStatus?date=${tsSelectedDate.value}&pageSize=${tsPageSize.value}&pageNo=${tsPageNo.value}` | |
| 498 | + const url = withCorpCode(`/api/energy/timelineStatus?date=${tsSelectedDate.value}&pageSize=${tsPageSize.value}&pageNo=${tsPageNo.value}`) | |
| 490 | 499 | const res = await fetch(url) |
| 491 | 500 | const data = await res.json() |
| 492 | 501 | if (data.code === 200) { |
| ... | ... | @@ -791,14 +800,18 @@ async function fetchUtilData() { |
| 791 | 800 | endDate = utilMonthDate.value + '-' + String(lastDay).padStart(2, '0') |
| 792 | 801 | } |
| 793 | 802 | try { |
| 794 | - const res = await fetch(`/api/energy/eqKwhStatistics?startDate=${startDate}&endDate=${endDate}`) | |
| 803 | + const res = await fetch(withCorpCode(`/api/energy/eqKwhStatistics?startDate=${startDate}&endDate=${endDate}`)) | |
| 795 | 804 | const result = await res.json() |
| 796 | 805 | if (result.code === 200) { |
| 797 | 806 | const data = result.data || {} |
| 798 | - Object.assign(utilData.currentStatus, data.currentStatus || {}) | |
| 799 | - utilData.deviceList = data.deviceList || [] | |
| 800 | - Object.assign(utilData.summary, data.summary || {}) | |
| 801 | - utilData.abnormalRanking = data.abnormalRanking || [] | |
| 807 | + const summary = data.summary || {} | |
| 808 | + Object.assign(utilData.currentStatus, summary.currentStatus || {}) | |
| 809 | + utilData.deviceList = (summary.deviceList || []).map(d => ({ | |
| 810 | + ...d, | |
| 811 | + availabilityRateValue: parseFloat(d.availabilityRate) || 0 | |
| 812 | + })) | |
| 813 | + Object.assign(utilData.summary, summary) | |
| 814 | + utilData.abnormalRanking = summary.abnormalRanking || [] | |
| 802 | 815 | await nextTick() |
| 803 | 816 | drawUtilAll() |
| 804 | 817 | } |
| ... | ... | @@ -1369,7 +1382,7 @@ async function fetchEffData() { |
| 1369 | 1382 | } |
| 1370 | 1383 | |
| 1371 | 1384 | try { |
| 1372 | - const res = await fetch(`/api/energy/eqKwhByType?startDate=${startDate}&endDate=${endDate}&type=${type}`) | |
| 1385 | + const res = await fetch(withCorpCode(`/api/energy/eqKwhByType?startDate=${startDate}&endDate=${endDate}&type=${type}`)) | |
| 1373 | 1386 | const data = await res.json() |
| 1374 | 1387 | if (data.code === 200) { |
| 1375 | 1388 | effDataList.value = data.list || [] | ... | ... |
| ... | ... | @@ -373,7 +373,7 @@ |
| 373 | 373 | </template> |
| 374 | 374 | |
| 375 | 375 | <script setup> |
| 376 | -import { ref, reactive, computed, onMounted, watch, nextTick } from 'vue' | |
| 376 | +import { ref, reactive, computed, onMounted, watch, nextTick, inject } from 'vue' | |
| 377 | 377 | import { Search, Menu, DataLine, Setting, Document, Warning } from '@element-plus/icons-vue' |
| 378 | 378 | import { ElMessage } from 'element-plus' |
| 379 | 379 | import OeeDialog from '../components/OeeDialog.vue' |
| ... | ... | @@ -386,6 +386,14 @@ const searchKeyword = ref('') |
| 386 | 386 | const currentStatus = ref('realtime') |
| 387 | 387 | const lampStateFilter = ref('') // 灯状态筛选: ''=全部, '1'=绿, '2'=红, '3'=黄, '0'=灭灯 |
| 388 | 388 | |
| 389 | +// 从全局获取corpCode | |
| 390 | +const corpCode = inject('corpCode') | |
| 391 | +function withCorpCode(url) { | |
| 392 | + if (!corpCode.value) return url | |
| 393 | + const sep = url.includes('?') ? '&' : '?' | |
| 394 | + return `${url}${sep}corpCode=${encodeURIComponent(corpCode.value)}` | |
| 395 | +} | |
| 396 | + | |
| 389 | 397 | // 各颜色数量(接口返回后更新,初始默认值) |
| 390 | 398 | const totalCounts = reactive({ all: 0, red: 0, yellow: 0, green: 0, blue: 0, gray: 0 }) |
| 391 | 399 | |
| ... | ... | @@ -459,7 +467,7 @@ async function fetchDeviceList() { |
| 459 | 467 | if (searchKeyword.value) params.append('deviceName', searchKeyword.value) |
| 460 | 468 | if (lampStateFilter.value) params.append('lampState', lampStateFilter.value) |
| 461 | 469 | |
| 462 | - const res = await fetch(`/api/device/list?${params}`) | |
| 470 | + const res = await fetch(withCorpCode(`/api/device/list?${params}`)) | |
| 463 | 471 | const data = await res.json() |
| 464 | 472 | deviceList.value = (data.list || []).map(item => ({ |
| 465 | 473 | id: item.id, |
| ... | ... | @@ -482,7 +490,7 @@ async function fetchDeviceList() { |
| 482 | 490 | // 获取灯状态统计 |
| 483 | 491 | async function fetchStats() { |
| 484 | 492 | try { |
| 485 | - const res = await fetch('/api/device/stats') | |
| 493 | + const res = await fetch(withCorpCode('/api/device/stats')) | |
| 486 | 494 | const data = await res.json() |
| 487 | 495 | totalCounts.all = data.all || 0 |
| 488 | 496 | totalCounts.red = data.red || 0 |
| ... | ... | @@ -942,7 +950,7 @@ async function fetchTimeSeriesData() { |
| 942 | 950 | pageNo: tsPageNo.value, |
| 943 | 951 | pageSize: tsPageSize, |
| 944 | 952 | }) |
| 945 | - const res = await fetch(`/api/device/oeeTimeline?${params}`) | |
| 953 | + const res = await fetch(withCorpCode(`/api/device/oeeTimeline?${params}`)) | |
| 946 | 954 | const data = await res.json() |
| 947 | 955 | |
| 948 | 956 | if (data.data && data.data.records) { |
| ... | ... | @@ -1639,7 +1647,7 @@ async function fetchUtilData() { |
| 1639 | 1647 | |
| 1640 | 1648 | utilLoading.value = true |
| 1641 | 1649 | try { |
| 1642 | - const res = await fetch(`/api/device/lampStatistics?startDate=${startDate}&endDate=${endDate}`) | |
| 1650 | + const res = await fetch(withCorpCode(`/api/device/lampStatistics?startDate=${startDate}&endDate=${endDate}`)) | |
| 1643 | 1651 | const data = await res.json() |
| 1644 | 1652 | |
| 1645 | 1653 | if (data.totalDuration) Object.assign(utilData.totalDuration, data.totalDuration) |
| ... | ... | @@ -1750,7 +1758,7 @@ async function fetchStartupData() { |
| 1750 | 1758 | |
| 1751 | 1759 | startupLoading.value = true |
| 1752 | 1760 | try { |
| 1753 | - const res = await fetch(`/api/device/bootRate?startDate=${startDate}&endDate=${endDate}`) | |
| 1761 | + const res = await fetch(withCorpCode(`/api/device/bootRate?startDate=${startDate}&endDate=${endDate}`)) | |
| 1754 | 1762 | const data = await res.json() |
| 1755 | 1763 | |
| 1756 | 1764 | startupList.value = data.list || [] | ... | ... |