✨ feat: smart-park接口模拟完成
This commit is contained in:
parent
a74f51fdb0
commit
c5072da2b1
|
@ -47,7 +47,7 @@ export const viteConsoleLog = (mode: string) => {
|
|||
console.log(
|
||||
boxen(
|
||||
gradientString('cyan', 'magenta').multiline(
|
||||
`🎉 恭喜打包完成(总用时${format})打包大小(${logOutputSize()})`
|
||||
`🎉 恭喜打包完成(总用时${format})打包大小(${logOutputSize()})`
|
||||
),
|
||||
boxenOptions
|
||||
)
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
import { defineFakeRoute } from 'vite-plugin-fake-server';
|
||||
|
||||
const randomNumber = (range: number = 100) => {
|
||||
return parseInt((Math.random() * range).toFixed(0));
|
||||
};
|
||||
|
||||
const mockRoadStatus = () => {
|
||||
const list = ['拥堵', '畅通'];
|
||||
const index = randomNumber(1);
|
||||
|
||||
return list[index];
|
||||
};
|
||||
|
||||
export default defineFakeRoute([
|
||||
// 道路状况
|
||||
{
|
||||
url: '/api/smart-park/road-status',
|
||||
method: 'GET',
|
||||
response: () => ({
|
||||
code: 200,
|
||||
data: {
|
||||
entrances: [
|
||||
{
|
||||
id: 1,
|
||||
name: '入卡口(西北门)',
|
||||
status: mockRoadStatus(),
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: '入卡口(东北门)',
|
||||
status: mockRoadStatus(),
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: '入卡口(东南门)',
|
||||
status: mockRoadStatus(),
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
name: '入卡口(东南门)',
|
||||
status: mockRoadStatus(),
|
||||
},
|
||||
],
|
||||
suggest: ` 高峰时段大量车流量容易造成拥堵,主要由XXX企业、XXX企业的车辆构成,
|
||||
<span>可建议XXX企业向后延迟15min错峰入园。</span>
|
||||
高峰时段大量车流量容易造成拥堵, 主要由XXX企业、XXX企业的车辆构成`,
|
||||
},
|
||||
message: '操作成功',
|
||||
}),
|
||||
},
|
||||
// 车辆监控
|
||||
{
|
||||
url: '/api/smart-park/monitor',
|
||||
method: 'GET',
|
||||
response: () => ({
|
||||
code: 200,
|
||||
data: [
|
||||
{ count: randomNumber(999), door: '入卡口(西北门)', percent: randomNumber() },
|
||||
{ count: randomNumber(999), door: '入卡口(东北门)', percent: randomNumber() },
|
||||
{ count: randomNumber(999), door: '入卡口(东南门)', percent: randomNumber() },
|
||||
{ count: randomNumber(999), door: '入卡口(东南门)', percent: randomNumber() },
|
||||
],
|
||||
message: '操作成功',
|
||||
}),
|
||||
},
|
||||
// 车流量
|
||||
{
|
||||
url: '/api/smart-park/flow-rate',
|
||||
method: 'GET',
|
||||
response: () => ({
|
||||
code: 200,
|
||||
data: {
|
||||
overview: [
|
||||
{ title: '最高进园车流量', statistics: randomNumber(9999) },
|
||||
{ title: '最高出园车流量', statistics: randomNumber(9999) },
|
||||
],
|
||||
timeline: ['02.01', '02.02', '02.03', '02.04', '02.05', '02.06', '02.22'],
|
||||
enter: Array(11)
|
||||
.fill(0)
|
||||
.map(() => randomNumber(999).toFixed(2)),
|
||||
outer: Array(11)
|
||||
.fill(0)
|
||||
.map(() => randomNumber(999).toFixed(2)),
|
||||
},
|
||||
message: '操作成功',
|
||||
}),
|
||||
},
|
||||
]);
|
|
@ -93,4 +93,4 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
import request from '@/api/server/request';
|
||||
|
||||
/* 实时道路 */
|
||||
export const fetchRoadStatus = () => {
|
||||
return request.get('/smart-park/road-status');
|
||||
};
|
||||
|
||||
/* 车辆监控 */
|
||||
export const fetchTollgateMonitoringData = () => {
|
||||
return request.get('smart-park/monitor');
|
||||
};
|
||||
|
||||
/* 车流量概览 */
|
||||
export const fetchTrafficStatistics = () => {
|
||||
return request.get('/smart-park/flow-rate');
|
||||
};
|
|
@ -0,0 +1,38 @@
|
|||
import { defineStore } from 'pinia';
|
||||
|
||||
import {
|
||||
fetchRoadStatus,
|
||||
fetchTollgateMonitoringData,
|
||||
fetchTrafficStatistics,
|
||||
} from '@/api/smartPark';
|
||||
|
||||
export const useSmartPark = defineStore('smartparkStore', {
|
||||
state: () => ({
|
||||
// 道路状态
|
||||
roadStatus: [],
|
||||
// 道路建议
|
||||
roadStatusSuggest: '',
|
||||
// 卡口车辆监控
|
||||
tollgateMonitoringData: [],
|
||||
// 车浏览概览
|
||||
trafficStatistics: { overview: [], outer: [], enter: [], timeline: [] },
|
||||
}),
|
||||
actions: {
|
||||
/* 道路情况 */
|
||||
async loadRoadStatus() {
|
||||
const result: any = await fetchRoadStatus();
|
||||
this.roadStatus = result.entrances;
|
||||
this.roadStatusSuggest = result.suggest;
|
||||
},
|
||||
/* 卡口车辆监控 */
|
||||
async loadTollgateMonitoringData() {
|
||||
const result = await fetchTollgateMonitoringData();
|
||||
this.tollgateMonitoringData = result;
|
||||
},
|
||||
/* 车流量概览 */
|
||||
async loadFlowRate() {
|
||||
const result = await fetchTrafficStatistics();
|
||||
this.trafficStatistics = result;
|
||||
},
|
||||
},
|
||||
});
|
|
@ -31,7 +31,7 @@ const option = {
|
|||
xAxis: {
|
||||
type: 'category',
|
||||
show: true,
|
||||
data: ['02.01', '02.02', '02.03', '02.04', '02.05', '02.06', '02.07'],
|
||||
data: [],
|
||||
itemStyle: { color: '#ccc' },
|
||||
splitLine: {
|
||||
show: true,
|
||||
|
@ -108,7 +108,10 @@ export const renderEcharts = (element: Ref<HTMLDivElement>) => {
|
|||
/** 更新图表数据 */
|
||||
export const updateChart = (option: any) => {
|
||||
const series = myChart.getOption().series;
|
||||
series[0].data = option.data1;
|
||||
series[1].data = option.data2;
|
||||
myChart.setOption({ series });
|
||||
const xAxis = myChart.getOption().xAxis;
|
||||
series[0].data = option.outer;
|
||||
series[1].data = option.enter;
|
||||
xAxis[0].data = option.timeline;
|
||||
|
||||
myChart.setOption({ series, xAxis });
|
||||
};
|
||||
|
|
|
@ -1,33 +1,38 @@
|
|||
<script lang="ts" setup>
|
||||
import { useIntervalFn } from '@vueuse/core';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { onMounted, ref } from 'vue';
|
||||
|
||||
import { useSmartPark } from '@/store/modules/smartPark';
|
||||
import { renderEcharts, updateChart } from '@/views/smart-park/charts/right-sidebar';
|
||||
import ContentItem from '@/views/smart-park/components/common/content-item.vue';
|
||||
import ContentPercent from '@/views/smart-park/components/common/content-percent.vue';
|
||||
|
||||
const weekDataChart = ref<HTMLDivElement>();
|
||||
|
||||
/** 随机数据 */
|
||||
const randomData = () => {
|
||||
renderEcharts(weekDataChart);
|
||||
const smartPark = useSmartPark();
|
||||
const { roadStatus, roadStatusSuggest, tollgateMonitoringData, trafficStatistics } =
|
||||
storeToRefs(smartPark);
|
||||
|
||||
function random() {
|
||||
return Array(11)
|
||||
.fill(0)
|
||||
.map(() => {
|
||||
const num = (Math.random() * 100).toFixed(2);
|
||||
return parseInt(num);
|
||||
});
|
||||
}
|
||||
const initData = () => {
|
||||
smartPark.loadRoadStatus();
|
||||
smartPark.loadTollgateMonitoringData();
|
||||
smartPark.loadFlowRate();
|
||||
|
||||
useIntervalFn(() => {
|
||||
updateChart({ data1: random(), data2: random() });
|
||||
}, 1000);
|
||||
updateChart({
|
||||
enter: trafficStatistics.value.enter,
|
||||
outer: trafficStatistics.value.outer,
|
||||
timeline: trafficStatistics.value.timeline,
|
||||
});
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
randomData();
|
||||
renderEcharts(weekDataChart);
|
||||
initData();
|
||||
|
||||
useIntervalFn(() => {
|
||||
initData();
|
||||
}, 1000);
|
||||
});
|
||||
</script>
|
||||
|
||||
|
@ -42,36 +47,33 @@ onMounted(() => {
|
|||
|
||||
<!-- 汽车列表 -->
|
||||
<ul class="mt-[32px]">
|
||||
<li class="smart-park__sidebar--left-item">
|
||||
<img alt="car-1" src="../images/car/car-1.png" />
|
||||
<p>入卡口(西北门)</p>
|
||||
<span class="dashed-circle c-primary-secondary border-b-primary-secondary">畅通</span>
|
||||
</li>
|
||||
<li class="smart-park__sidebar--left-item">
|
||||
<img alt="car-1" src="../images/car/car-1.png" />
|
||||
<p>入卡口(东北门)</p>
|
||||
<span class="dashed-circle c-primary-secondary border-b-primary-secondary">畅通</span>
|
||||
</li>
|
||||
<li class="smart-park__sidebar--left-item">
|
||||
<img alt="car-1" src="../images/car/car-2.png" />
|
||||
<p>入卡口(东北门)</p>
|
||||
<span class="dashed-circle c-warning border-b-warning">拥堵</span>
|
||||
</li>
|
||||
<li class="smart-park__sidebar--left-item">
|
||||
<img alt="car-1" src="../images/car/car-1.png" />
|
||||
<p>入卡口(东南门)</p>
|
||||
<span class="dashed-circle c-primary-secondary border-b-primary-secondary">畅通</span>
|
||||
<li
|
||||
v-for="(item, index) in roadStatus"
|
||||
:key="index"
|
||||
class="smart-park__sidebar--left-item"
|
||||
>
|
||||
<div v-show="item.status === '畅通'" class="flex-x-around w-[100%]">
|
||||
<img alt="car-1" src="../images/car/car-1.png" />
|
||||
<p>{{ item.name }}</p>
|
||||
<span class="dashed-circle c-primary-secondary border-b-primary-secondary">
|
||||
{{ item.status }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div v-show="item.status === '拥堵'" class="flex-x-around w-[100%]">
|
||||
<img alt="car-1" src="../images/car/car-2.png" />
|
||||
<p>{{ item.name }}</p>
|
||||
<span class="dashed-circle c-warning border-b-warning">
|
||||
{{ item.status }}
|
||||
</span>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<!-- 建议 -->
|
||||
<div class="smart-park__sidebar--left-suggest">
|
||||
<h5>车流量建议</h5>
|
||||
<p>
|
||||
高峰时段大量车流量容易造成拥堵,主要由XXX企业、XXX企业的车辆构成,
|
||||
<span>可建议XXX企业向后延迟15min错峰入园。</span>
|
||||
高峰时段大量车流量容易造成拥堵, 主要由XXX企业、XXX企业的车辆构成
|
||||
</p>
|
||||
<p v-html="roadStatusSuggest" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -84,21 +86,13 @@ onMounted(() => {
|
|||
|
||||
<!-- 中间布局 -->
|
||||
<div class="smart-park__body-inner">
|
||||
<div class="pos-relative">
|
||||
<content-item :count="45" class="top-[37px] left-[40px] w-[175px]" door="西北门" />
|
||||
<content-percent :percent="44" class="top-[73px] left-[193px]" />
|
||||
</div>
|
||||
<div class="pos-relative">
|
||||
<content-item :count="67" class="top-[37px] left-[120px] w-[175px]" door="东北门" />
|
||||
<content-percent :percent="25" class="top-[73px] right-[192px]" />
|
||||
</div>
|
||||
<div class="pos-relative">
|
||||
<content-item :count="345" class="top-[45px] left-[34px] w-[175px]" door="西南门" />
|
||||
<content-percent :percent="25" class="top-[40px] left-[193px]" />
|
||||
</div>
|
||||
<div class="pos-relative">
|
||||
<content-item :count="145" class="top-[45px] left-[130px] w-[175px]" door="东南门" />
|
||||
<content-percent :percent="44" class="top-[40px] left-[66px]" />
|
||||
<div v-for="(item, index) in tollgateMonitoringData" :key="index" class="pos-relative">
|
||||
<content-item
|
||||
:count="item.count"
|
||||
class="top-[37px] left-[40px] w-[175px]"
|
||||
:door="item.door"
|
||||
/>
|
||||
<content-percent :percent="item.percent" class="top-[73px] left-[193px]" />
|
||||
</div>
|
||||
|
||||
<div class="smart-park__body-content">
|
||||
|
@ -119,13 +113,13 @@ onMounted(() => {
|
|||
|
||||
<!-- 汽车列表 -->
|
||||
<ul class="flex-x-around mt-[32px] w-[331px]">
|
||||
<li class="smart-park__sidebar-flow-item">
|
||||
<span>最高进园车流量</span>
|
||||
<span>897</span>
|
||||
</li>
|
||||
<li class="smart-park__sidebar-flow-item">
|
||||
<span>最高进园车流量</span>
|
||||
<span>494</span>
|
||||
<li
|
||||
v-for="(item, index) in trafficStatistics.overview"
|
||||
:key="index"
|
||||
class="smart-park__sidebar-flow-item"
|
||||
>
|
||||
<span>{{ item.title }}</span>
|
||||
<span>{{ item.statistics }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
@ -172,7 +166,7 @@ onMounted(() => {
|
|||
background: url('@/views/smart-park/images/bg/bg-suggest.png') no-repeat center;
|
||||
background-size: cover;
|
||||
|
||||
span {
|
||||
:deep(span) {
|
||||
color: var(--color-warning-secondary);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,36 @@
|
|||
<script lang="ts" setup>
|
||||
import { useTimeoutFn } from '@vueuse/core';
|
||||
import { ref } from 'vue';
|
||||
|
||||
import SmartParkContent from '@/views/smart-park/components/smart-park-content.vue';
|
||||
import SmartParkFooter from '@/views/smart-park/components/smart-park-footer.vue';
|
||||
|
||||
const showNavigationArrows = ref(false);
|
||||
let hideArrowsTimeout: (() => void) | null = null;
|
||||
|
||||
/* 鼠标经过显示箭头 */
|
||||
const handleMouseMovement = () => {
|
||||
// 每次鼠标移动时显示箭头
|
||||
showNavigationArrows.value = true;
|
||||
|
||||
// 清除之前的定时器(如果存在)
|
||||
if (hideArrowsTimeout) {
|
||||
hideArrowsTimeout();
|
||||
}
|
||||
|
||||
// 设置新的定时器,2秒后隐藏箭头
|
||||
const { start, stop } = useTimeoutFn(() => {
|
||||
showNavigationArrows.value = false;
|
||||
}, 2000);
|
||||
|
||||
hideArrowsTimeout = stop;
|
||||
start();
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="smart-park">
|
||||
<div class="smart-park__arrow left-[38px]">
|
||||
<div class="smart-park" @mousemove="handleMouseMovement">
|
||||
<div v-show="showNavigationArrows" class="smart-park__arrow left-[38px]">
|
||||
<img alt="左箭头" src="@/views/smart-park/images/arrow/arrow-left.png" />
|
||||
</div>
|
||||
|
||||
|
@ -13,7 +38,7 @@ import SmartParkFooter from '@/views/smart-park/components/smart-park-footer.vue
|
|||
|
||||
<smart-park-footer />
|
||||
|
||||
<div class="smart-park__arrow right-[38px]">
|
||||
<div v-show="showNavigationArrows" class="smart-park__arrow right-[38px]">
|
||||
<img alt="左箭头" src="@/views/smart-park/images/arrow/arrow-right.png" />
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -17,22 +17,12 @@
|
|||
"baseUrl": ".",
|
||||
"allowJs": false,
|
||||
"resolveJsonModule": true,
|
||||
"lib": [
|
||||
"ESNext",
|
||||
"DOM"
|
||||
],
|
||||
"lib": ["ESNext", "DOM"],
|
||||
"paths": {
|
||||
"@/*": [
|
||||
"src/*"
|
||||
]
|
||||
// "@build/*": [
|
||||
// "build/*"
|
||||
// ]
|
||||
"vue": ["node_modules/vue/dist/vue.esm.js"],
|
||||
"@/*": ["src/*"]
|
||||
},
|
||||
"types": [
|
||||
"node",
|
||||
"vite/client"
|
||||
]
|
||||
"types": ["node", "vite/client"]
|
||||
},
|
||||
"include": [
|
||||
"mock/*.ts",
|
||||
|
@ -42,8 +32,5 @@
|
|||
"vite.config.ts",
|
||||
"src/**/*.d.ts"
|
||||
],
|
||||
"exclude": [
|
||||
"dist",
|
||||
"node_modules"
|
||||
]
|
||||
"exclude": ["dist", "node_modules"]
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue