feat: 页面骨架

This commit is contained in:
bunny 2025-05-11 22:17:16 +08:00
parent 637fc4a614
commit 61bbf51282
12 changed files with 346 additions and 204 deletions

BIN
public/images/bg/bg05.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 MiB

View File

@ -0,0 +1,132 @@
import type { Ref } from 'vue';
import echarts from '@/plugins/echarts';
import { debounceChart } from '@/utils/chart';
let myChart = null;
const option = {
grid: {
left: '4%',
right: '4%',
bottom: '19%',
top: '20%',
containLabel: true,
},
title: {
text: '单位:(万元)',
textStyle: {
color: 'rgba(131, 162, 192, 1)',
fontSize: 12,
},
top: '4%',
left: '2%',
},
tooltip: {
trigger: 'axis',
},
legend: {
data: ['增加值'],
icon: 'rich',
show: true,
itemWidth: 18,
itemHeight: 2,
textStyle: {
color: '#AFBDD1',
fontSize: '12px',
},
top: 8,
right: 10,
itemGap: 34,
},
xAxis: {
data: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
type: 'category',
boundaryGap: false,
axisLine: {
symbol: 'none',
lineStyle: {
color: '#50637A',
},
},
axisTick: {
show: false,
},
axisLabel: {
interval: 0,
color: '#6071A9',
fontSize: 12,
padding: [10, 0, 0, 0],
},
},
yAxis: {
type: 'value',
axisLabel: {
color: '#6071A9',
fontSize: 12,
padding: [0, 10, 0, 0],
},
splitLine: {
lineStyle: {
color: '#50637A',
type: 'dashed',
},
},
},
series: [
{
name: '增加值',
data: [1, 2, 3, 4, 7, 6, 7, 8, 4, 10],
type: 'line',
smooth: true,
color: '#00F7FF',
lineStyle: {
width: 2,
},
areaStyle: {
color: new echarts.graphic.LinearGradient(
0,
0,
0,
1,
[
{
offset: 0,
color: 'rgba(0, 247, 255, .6)',
},
{
offset: 0.8,
color: 'rgba(0, 247, 255, .2)',
},
],
false
),
shadowColor: 'rgba(0, 0, 0, 0.1)',
shadowBlur: 10,
},
symbol: 'circle',
symbolSize: 6,
},
],
};
/** 渲染图表 */
export const renderFooterChart = (element: Ref<HTMLDivElement>) => {
myChart = echarts.init(element.value, null, {
renderer: 'canvas',
devicePixelRatio: window.devicePixelRatio,
});
debounceChart(myChart);
myChart.setOption(option);
};
/** 更新图表数据 */
export const updateChart = (option: Array<Array<number>>) => {
const series = myChart.getOption().series;
// series[0].data = option[0];
// series[1].data = option[1];
myChart.setOption({ series });
};

View File

@ -0,0 +1,28 @@
import type { Ref } from 'vue';
import echarts from '@/plugins/echarts';
import { debounceChart } from '@/utils/chart';
let myChart = null;
const option = {};
/** 渲染图表 */
export const renderBodyChart = (element: Ref<HTMLDivElement>) => {
myChart = echarts.init(element.value, null, {
renderer: 'canvas',
devicePixelRatio: window.devicePixelRatio,
});
debounceChart(myChart);
myChart.setOption(option);
};
/** 更新图表数据 */
export const updateChart = (option: Array<Array<number>>) => {
const series = myChart.getOption().series;
// series[0].data = option[0];
// series[1].data = option[1];
myChart.setOption({ series });
};

View File

@ -0,0 +1,36 @@
import type { Ref } from 'vue';
import echarts from '@/plugins/echarts';
import { debounceChart } from '@/utils/chart';
let myChart = null;
const data = [
{ name: '张三', value: 88 },
{ name: '李四', value: 250 },
{ name: '王五', value: 5438 },
{ name: '赵六', value: 8848 },
{ name: '陈七', value: 9527 },
{ name: '朱八', value: 10086 },
];
const option = {};
/** 渲染图表 */
export const renderFooterChart = (element: Ref<HTMLDivElement>) => {
myChart = echarts.init(element.value, null, {
renderer: 'canvas',
devicePixelRatio: window.devicePixelRatio,
});
debounceChart(myChart);
myChart.setOption(option);
};
/** 更新图表数据 */
export const updateChart = (option: Array<Array<number>>) => {
const series = myChart.getOption().series;
// series[0].data = option[0];
// series[1].data = option[1];
myChart.setOption({ series });
};

View File

@ -1,97 +0,0 @@
import type { Ref } from 'vue';
import echarts from '@/plugins/echarts';
import { debounceChart } from '@/utils/chart';
let myChart = null;
const myData = [
{
value: 137,
name: '数学',
},
{
value: 103,
name: '语文',
},
{
value: 124,
name: '英语',
},
{
value: 180,
name: '理综',
},
];
const option = {
color: ['#1aa3ff', '#04f9fa', '#16bd87', '#c961ff', '#7cfc12'],
tooltip: {
trigger: 'item',
formatter: '{b}{c} ({d}%)',
},
legend: {
bottom: '20%',
itemWidth: 10,
itemHeight: 10,
textStyle: {
color: '#fff',
fontSize: '14',
},
},
series: [
// 内圈
{
type: 'pie',
center: ['50%', '40%'],
radius: ['33.5%', '35.5%'],
silent: true, //取消高亮
label: { show: false, position: 'center' },
data: myData,
},
// 外圈
{
type: 'pie',
center: ['50%', '40%'],
radius: ['40%', '50%'],
label: { show: false, position: 'center' },
emphasis: {
label: {
show: true,
fontSize: 33,
lineHeight: 45,
formatter: (params) => {
return '{name|' + params.name + '}\n{value|' + params.value + '}';
},
rich: {
name: {
color: '#fff',
},
value: {
color: '#04F9FA',
},
},
},
},
data: myData,
},
],
};
/** 渲染图表 */
export const renderEcharts = (element: Ref<HTMLDivElement>) => {
myChart = echarts.init(element.value, null, {
renderer: 'canvas',
devicePixelRatio: window.devicePixelRatio,
});
debounceChart(myChart);
myChart.setOption(option);
};
/** 更新图表数据 */
export const updateChart = (option: Array<Array<number>>) => {
const series = myChart.getOption().series;
// series[0].data = option[0];
// series[1].data = option[1];
myChart.setOption({ series });
};

View File

@ -1,5 +1,20 @@
<script lang="ts" setup>
import { onMounted, ref } from 'vue';
import PanelTitle1 from '@/components/PanelItem/PanelTitle/PanelTitle1.vue';
import { renderFooterChart } from '@/views/data-analyse/charts/content-footer';
const titleList = [170582, 586220, 168902];
const footerChartRef = ref();
const footerChart = () => {
renderFooterChart(footerChartRef);
};
onMounted(() => {
footerChart();
});
</script>
<template>
@ -14,7 +29,10 @@ const titleList = [170582, 586220, 168902];
<main class="data-analyse-content__body">body</main>
<footer class="data-analyse-content__footer">footer</footer>
<footer class="data-analyse-content__footer">
<PanelTitle1 title="销售设备数量区域占比" />
<div ref="footerChartRef" class="data-analyse-content__footer-chart" />
</footer>
</div>
</template>
@ -24,6 +42,10 @@ const titleList = [170582, 586220, 168902];
width: 803px;
height: 970px;
h1 {
color: white;
}
&__header {
display: flex;
justify-content: space-between;
@ -48,14 +70,19 @@ const titleList = [170582, 586220, 168902];
&__body {
margin: 14px 0 0 0;
width: 803px;
width: 100%;
height: 567px;
}
&__footer {
margin: 6px 0 0 0;
width: 860px;
width: 100%;
height: 284px;
&-chart {
width: 100%;
height: 275px;
}
}
}
</style>

View File

@ -2,15 +2,22 @@
import { onMounted, ref } from 'vue';
import PanelTitle1 from '@/components/PanelItem/PanelTitle/PanelTitle1.vue';
import { renderEcharts } from '@/views/data-analyse/charts/right-header';
import { renderBodyChart } from '@/views/data-analyse/charts/right-body';
import { renderFooterChart } from '@/views/data-analyse/charts/right-footer';
const footerChartRef = ref();
const renderFooterChart = () => {
renderEcharts(footerChartRef);
const footerChart = () => {
renderFooterChart(footerChartRef);
};
const bodyChartRef = ref();
const bodyChart = () => {
renderBodyChart(bodyChartRef);
};
onMounted(() => {
renderFooterChart();
bodyChart();
footerChart();
});
</script>
@ -18,10 +25,12 @@ onMounted(() => {
<div class="data-analyse-right">
<header class="data-analyse-right__header">
<PanelTitle1 title="数据占有率" />
<div ref="bodyChartRef" class="data-analyse-right-chart" />
</header>
<main class="data-analyse-right__body">
<PanelTitle1 title="数据分析展示" />
<div ref="bodyChartRef" class="data-analyse-right__body-chart" />
</main>
<footer class="data-analyse-right__footer">
@ -48,9 +57,14 @@ onMounted(() => {
}
&__body {
margin: 10px 0 0 0;
margin: 10px;
width: 100%;
height: 350px;
&-chart {
width: 100%;
height: 320px;
}
}
&__footer {

View File

@ -1,7 +1,16 @@
<script lang="ts" setup>
import { onBeforeMount } from 'vue';
import { useAppStore } from '@/store/app';
import DataAnalyseContent from '@/views/data-analyse/components/data-analyse-content/index.vue';
import DataAnalyseLeft from '@/views/data-analyse/components/data-analyse-left/index.vue';
import DataAnalyseRight from '@/views/data-analyse/components/data-analyse-right/index.vue';
const appStore = useAppStore();
onBeforeMount(() => {
appStore.setBackground('/images/bg/bg05.png');
});
</script>
<template>

View File

@ -1,94 +0,0 @@
<script lang="ts" setup>
import { useIntervalFn } from '@vueuse/core';
import { onMounted, ref } from 'vue';
import { renderEcharts, updateChart } from '@/views/smart-park/charts/right-sidebar';
const weekDataChart = ref<HTMLDivElement>();
/** 随机数据 */
const randomData = () => {
function random() {
return Array(11)
.fill(0)
.map(() => {
const num = (Math.random() * 100).toFixed(2);
return parseInt(num);
});
}
useIntervalFn(() => {
updateChart({ data1: random(), data2: random() });
}, 1000);
};
onMounted(() => {
renderEcharts(weekDataChart);
randomData();
});
</script>
<template>
<div class="smart-park__sidebar ml-[20px]">
<div class="pt-[55px] pl-[25px]">
<!-- 路况 -->
<div class="smart-park__sidebar-title">
<h1>近7天车流量概览</h1>
</div>
<!-- 汽车列表 -->
<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>
</ul>
<!-- 七天数据 -->
<div class="w-[325px] h-[205px]">
<div ref="weekDataChart" class="smart-park__sidebar-charts" />
</div>
</div>
</div>
</template>
<style lang="scss" scoped>
.smart-park__sidebar-flow-item {
display: flex;
flex-direction: column;
justify-content: space-between;
width: 162px;
height: 111px;
text-align: center;
span:nth-child(1) {
width: 161px;
height: 40px;
color: #fff;
line-height: 40px;
font-size: 16px;
background: url('@/assets/images/smart-park/bg/bg-frame-2.png') no-repeat center;
background-size: cover;
}
span:nth-child(2) {
width: 161px;
height: 66px;
color: var(--color-primary-secondary);
line-height: 66px;
font-size: 34px;
background: url('@/assets/images/smart-park/bg/bg-frame-3.png') no-repeat center;
background-size: cover;
}
}
.smart-park__sidebar-charts {
margin: 71px 0 0 0;
width: 100%;
height: 100%;
}
</style>

View File

@ -1,13 +1,100 @@
<script lang="ts" setup>
import { useIntervalFn } from '@vueuse/core';
import { onMounted, ref } from 'vue';
import { renderEcharts, updateChart } from '@/views/smart-park/charts/right-sidebar';
import SmartPartContent from '@/views/smart-park/components/smart-park-content/components/smart-park-content/index.vue';
import SmartPartSidebarLeft from '@/views/smart-park/components/smart-park-content/components/smart-park-sidebar-left/index.vue';
import SmartPartSidebarRight from '@/views/smart-park/components/smart-park-content/components/smart-park-sidebar-right/index.vue';
const weekDataChart = ref<HTMLDivElement>();
/** 随机数据 */
const randomData = () => {
renderEcharts(weekDataChart);
function random() {
return Array(11)
.fill(0)
.map(() => {
const num = (Math.random() * 100).toFixed(2);
return parseInt(num);
});
}
useIntervalFn(() => {
updateChart({ data1: random(), data2: random() });
}, 1000);
};
onMounted(() => {
randomData();
});
</script>
<template>
<main class="pt-[78px] mx-auto flex-center w-[1620px] h-[650px]">
<smart-part-sidebar-left />
<smart-part-content />
<smart-part-sidebar-right />
<div class="smart-park__sidebar ml-[20px]">
<div class="pt-[55px] pl-[25px]">
<!-- 路况 -->
<div class="smart-park__sidebar-title">
<h1>近7天车流量概览</h1>
</div>
<!-- 汽车列表 -->
<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>
</ul>
<!-- 七天数据 -->
<div class="w-[325px] h-[205px]">
<div ref="weekDataChart" class="smart-park__sidebar-flow-item-charts" />
</div>
</div>
</div>
</main>
</template>
<style lang="scss" scoped>
.smart-park__sidebar-flow-item {
display: flex;
flex-direction: column;
justify-content: space-between;
width: 162px;
height: 111px;
text-align: center;
span:nth-child(1) {
width: 161px;
height: 40px;
color: #fff;
line-height: 40px;
font-size: 16px;
background: url('@/assets/images/smart-park/bg/bg-frame-2.png') no-repeat center;
background-size: cover;
}
span:nth-child(2) {
width: 161px;
height: 66px;
color: var(--color-primary-secondary);
line-height: 66px;
font-size: 34px;
background: url('@/assets/images/smart-park/bg/bg-frame-3.png') no-repeat center;
background-size: cover;
}
&-charts {
margin: 71px 0 0 0;
width: 100%;
height: 100%;
}
}
</style>

View File

@ -4,8 +4,8 @@ import { useRouter } from 'vue-router';
const router = useRouter();
const list = [
{ title: '智慧停车', image: '/images/welcome/car.png', target: '/smart-park' },
{ title: '智慧配送', image: '/images/welcome/distribution.png', target: '/data-analyse' },
{ title: '停车', image: '/images/welcome/car.png', target: '/smart-park' },
{ title: '数据分析', image: '/images/welcome/distribution.png', target: '/data-analyse' },
{ title: '智慧渣土', image: '/images/welcome/muck.png', target: '/smart-park' },
{ title: '智慧洁城', image: '/images/welcome/clean-city.png', target: '/smart-park' },
{ title: '智慧路灯', image: '/images/welcome/lamp.png', target: '/smart-park' },

View File

@ -7,7 +7,7 @@ const router = useRouter();
const list = ref([
{ icon: 'i-material-symbols:home-and-garden', name: '园区', target: '/' },
{ icon: 'i-fa:building', name: '园区', target: '/' },
{ icon: 'i-fa-solid:chart-line', name: '经营', target: '/business-supervision' },
{ icon: 'i-fa-solid:chart-line', name: '经营监督', target: '/business-supervision' },
{ icon: 'i-eos-icons:big-data-outlined', name: '大数据', target: '/big-data' },
]);
</script>