go-viee-fetch-Demo/src/packages/components/Charts/MyComponents/ParkingScene/index.vue

194 lines
4.5 KiB
Vue
Raw Normal View History

2025-08-24 21:23:02 +08:00
<template>
<div class="go-parking-scene">
<PublicSmallBorder :title-text="option.titleText">
2025-08-24 21:23:02 +08:00
<div class="content">
<div v-for="(scene, index) in option.dataset" :key="index" class="scene-item">
<div class="scene-header">
<img src="./assets/dot.png" alt="" class="dots"></img>
<span class="scene-name" :style="{ color: option.sceneNameColor, fontSize: option.sceneNameSize + 'px' }">{{
scene.name }}</span>
</div>
<div class="scene-metrics">
<img src="./assets/area.png" alt="" class="metric-icon"></img>
<div class="scene-content">
<div v-for="(metric, mIndex) in scene.metrics" :key="mIndex" class="metric-box">
<span class="metric-label" :style="{ color: option.labelColor, fontSize: option.labelSize + 'px' }">{{
metric.label }}</span>
<span class="metric-value"
:style="{ color: mIndex === 0 ? option.valueColor : option.valueColor2, fontSize: option.valueSize + 'px' }">{{
metric.value }}</span>
</div>
</div>
</div>
</div>
</div>
</PublicSmallBorder>
2025-08-24 21:23:02 +08:00
</div>
2025-08-24 21:23:02 +08:00
</template>
<script setup lang="ts">
import { PropType, computed, onMounted, watch, ref } from 'vue'
2025-08-24 21:23:02 +08:00
import { option as configOption } from './config'
import { ParkingSceneConfig } from './index'
import axios from 'axios';
import PublicSmallBorder from '../../PublicSmallBorder/index.vue'
2025-08-24 21:23:02 +08:00
const props = defineProps({
chartConfig: {
type: Object as PropType<{ option: typeof configOption }>,
required: true
}
})
const key = ParkingSceneConfig.key;
2025-08-24 21:23:02 +08:00
const option = computed(() => props.chartConfig.option)
const isFetching = ref(false) // 防止重复请求
// 获取静态数据
const getStaticData = async (key: string, componentIndexKey: string, sceneCode: string) => {
try {
const response = await axios.get('/staticData/static.json');
if (response.data) {
console.log('静态数据:', response.data);
const dataTemp = response.data[sceneCode]?.[key]?.[componentIndexKey]?.['source'];
if (!dataTemp) {
console.warn(`Data not found for sceneCode: ${sceneCode}, key: ${key}, componentIndexKey: ${componentIndexKey}`);
return props.chartConfig.option.dataset; // 返回默认数据
}
return dataTemp;
}
} catch (err) {
console.error('获取static.json失败:', err);
}
return props.chartConfig.option.dataset; // 出错时返回默认数据
}
// 统一数据获取方法
const fetchData = async () => {
// 防止重复请求
if (isFetching.value) return;
isFetching.value = true;
try {
let data;
// 静态数据
data = await getStaticData(key, option.value.componentIndexKey, option.value.sceneCode);
props.chartConfig.option.dataset = data;
if (JSON.stringify(data) !== JSON.stringify(option.value.dataset)) {
console.log('更新数据:', data);
}
} finally {
isFetching.value = false;
}
}
watch(
() => [
props.chartConfig.option.sceneCode,
2025-09-04 16:42:32 +08:00
props.chartConfig.option.componentIndexKey
],
async () => {
await fetchData();
},
{
immediate: true,
deep: true
}
)
// 组件挂载时获取数据
onMounted(async () => {
await fetchData();
})
2025-08-24 21:23:02 +08:00
</script>
<style lang="scss" scoped>
.go-parking-scene {
width: 100%;
box-sizing: border-box;
display: flex;
flex-direction: column;
.content {
flex: 1;
display: flex;
flex-direction: column;
justify-content: space-around;
z-index: 2;
2025-08-24 21:23:02 +08:00
}
.scene-item:nth-child(n+2) {
margin-top: 7px;
;
2025-08-24 21:23:02 +08:00
}
.scene-header {
display: flex;
align-items: center;
justify-content: center;
.dots {
color: #4A90E2;
font-weight: bold;
margin-right: 10px;
}
.scene-name {
font-weight: bold;
}
}
.scene-metrics {
2025-08-24 21:23:02 +08:00
height: 46px;
width: 384px;
margin: 0 auto;
position: relative;
display: flex;
.metric-icon {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
}
.scene-content {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
display: flex;
}
.metric-box {
flex: 1;
display: flex;
align-items: center;
height: 100%;
padding: 0 20px 0 70px;
2025-08-24 21:23:02 +08:00
box-sizing: border-box;
justify-content: space-between;
// background-color: #4A90E2;
2025-08-24 21:23:02 +08:00
}
.metric-value {
flex: 1; // 占据剩余空间
text-align: left; // 右对齐确保数值对齐
margin-left: 8px;
2025-08-24 21:23:02 +08:00
}
}
</style>