Merge branch 'dev' of http://222.212.85.86:8222/bdzl2/bxztApp into dev
@ -19,6 +19,7 @@
|
||||
"devDependencies": {
|
||||
"@vitejs/plugin-vue": "^5.0.0",
|
||||
"vite": "^5.0.0",
|
||||
"sass": "^1.70.0"
|
||||
"sass": "^1.70.0",
|
||||
"less": "^4.4.2"
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,6 +7,11 @@ const routes = [
|
||||
name: 'Home',
|
||||
component: () => import('../views/Home.vue')
|
||||
},
|
||||
{
|
||||
path: '/cockpit',
|
||||
name: 'Cockpit',
|
||||
component: () => import('../views/cockpit/index.vue')
|
||||
},
|
||||
{
|
||||
path: '/test',
|
||||
name: 'test',
|
||||
|
||||
270
packages/screen/src/views/cockpit/README.md
Normal file
@ -0,0 +1,270 @@
|
||||
# 安全保通服务大屏 - 重构说明
|
||||
|
||||
## 📦 重构概览
|
||||
|
||||
本次重构将原来 567 行的单一组件拆分为模块化的组件架构,提高了代码的可维护性和可扩展性。
|
||||
|
||||
## 🎯 主要改进
|
||||
|
||||
### 1. **组件化架构**
|
||||
- ✅ 将单一大文件拆分为 7 个独立组件
|
||||
- ✅ 每个组件职责单一,易于维护
|
||||
- ✅ 组件可复用,便于扩展
|
||||
|
||||
### 2. **布局方式优化**
|
||||
- ❌ **重构前**: 大量使用 `position: absolute` 和固定像素定位
|
||||
- ✅ **重构后**: 使用 CSS Grid 和 Flexbox 实现响应式布局
|
||||
- ✅ 更易调整和适配不同屏幕尺寸
|
||||
|
||||
### 3. **数据驱动**
|
||||
- ❌ **重构前**: 数据硬编码在模板中
|
||||
- ✅ **重构后**: 使用 Vue 3 Composition API,数据驱动渲染
|
||||
- ✅ 便于后续接入真实 API 数据
|
||||
|
||||
### 4. **样式管理**
|
||||
- ❌ **重构前**: 类名混乱 (`box_1`, `group_3` 等)
|
||||
- ✅ **重构后**: 语义化类名,易于理解
|
||||
- ✅ 样式模块化,避免全局污染
|
||||
|
||||
## 📁 目录结构
|
||||
|
||||
```
|
||||
cockpit/
|
||||
├── index.vue # 主入口文件
|
||||
├── components/ # 组件目录
|
||||
│ ├── CockpitLayout.vue # 主布局组件
|
||||
│ ├── PageHeader.vue # 页面头部
|
||||
│ ├── WeatherWarning.vue # 气象预警 (左上)
|
||||
│ ├── EmergencyResources.vue # 应急资源 (左下)
|
||||
│ ├── BlockEvent.vue # 阻断事件 (右上)
|
||||
│ ├── YearStatistics.vue # 往年统计 (右下)
|
||||
│ └── MapCenter.vue # 中间地图区域
|
||||
└── assets/ # 资源文件
|
||||
└── img/ # 图片资源
|
||||
```
|
||||
|
||||
## 🔧 组件说明
|
||||
|
||||
### 1. CockpitLayout.vue (主布局)
|
||||
使用 CSS Grid 三列布局:
|
||||
```css
|
||||
grid-template-columns: 580px 1fr 580px;
|
||||
```
|
||||
- 左侧面板: 固定 580px
|
||||
- 中间地图: 自适应剩余空间
|
||||
- 右侧面板: 固定 580px
|
||||
|
||||
### 2. PageHeader.vue (页面头部)
|
||||
- 居中显示标题 "安全保通服务"
|
||||
- 右侧应用按钮
|
||||
- 使用 Flexbox 布局
|
||||
|
||||
### 3. WeatherWarning.vue (气象预警)
|
||||
**数据结构**:
|
||||
```javascript
|
||||
{
|
||||
warningLevels: [
|
||||
{ id, name, count, color, icon }
|
||||
],
|
||||
districts: [
|
||||
{ id, name, km, warning, warningColor }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**功能**:
|
||||
- 四级预警图标展示 (蓝/黄/橙/红)
|
||||
- 海拔800米以上气象情况
|
||||
- 区县预警列表
|
||||
|
||||
### 4. EmergencyResources.vue (应急资源)
|
||||
**数据结构**:
|
||||
```javascript
|
||||
{
|
||||
resources: [
|
||||
{ id, name, stations, supplies, equipment, equipmentClass, hasAlert }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**功能**:
|
||||
- 展示各区县应急资源数量
|
||||
- 服务站点、应急物资、应急设备统计
|
||||
- 异常状态图标提示
|
||||
|
||||
### 5. BlockEvent.vue (阻断事件)
|
||||
**数据结构**:
|
||||
```javascript
|
||||
{
|
||||
stats: [
|
||||
{ id, title, value }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**功能**:
|
||||
- 统计卡片展示 (2列网格布局)
|
||||
- 当前封闭交通、限速通行、抢通等数据
|
||||
|
||||
### 6. YearStatistics.vue (往年统计)
|
||||
**功能**:
|
||||
- 冰雪事件趋势图 (当前使用静态图片)
|
||||
- 图表图例
|
||||
- 坐标轴标签
|
||||
|
||||
**TODO**: 集成 ECharts 实现动态图表
|
||||
|
||||
### 7. MapCenter.vue (中间地图)
|
||||
**功能**:
|
||||
- 顶部功能按钮 (服务站点/预警路段/气象预警)
|
||||
- 地图标记点
|
||||
- 底部菜单 (应急体系/重大事件处置等)
|
||||
- 中央功能菜单
|
||||
|
||||
**TODO**: 集成实际地图 API (如高德地图/百度地图)
|
||||
|
||||
## 🚀 使用方式
|
||||
|
||||
### 1. 基础使用
|
||||
```vue
|
||||
<template>
|
||||
<CockpitLayout />
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import CockpitLayout from './components/CockpitLayout.vue'
|
||||
</script>
|
||||
```
|
||||
|
||||
### 2. 修改数据
|
||||
每个组件都使用 `ref` 定义响应式数据,可以直接修改:
|
||||
|
||||
```javascript
|
||||
// WeatherWarning.vue
|
||||
const districts = ref([
|
||||
{ id: 1, name: '万州区', km: 32, warning: '红色预警', warningColor: 'rgba(229, 37, 42, 1)' }
|
||||
])
|
||||
```
|
||||
|
||||
### 3. 接入 API
|
||||
将静态数据改为 API 调用:
|
||||
|
||||
```javascript
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { fetchDistricts } from '@/api/weather'
|
||||
|
||||
const districts = ref([])
|
||||
|
||||
onMounted(async () => {
|
||||
districts.value = await fetchDistricts()
|
||||
})
|
||||
```
|
||||
|
||||
## 📊 后续优化建议
|
||||
|
||||
### 1. 集成真实地图
|
||||
推荐使用:
|
||||
- 高德地图 API
|
||||
- 百度地图 API
|
||||
- Mapbox GL
|
||||
|
||||
### 2. 集成图表库
|
||||
推荐使用:
|
||||
- **ECharts** (功能强大,配置灵活)
|
||||
- Chart.js
|
||||
- D3.js
|
||||
|
||||
示例代码:
|
||||
```javascript
|
||||
import * as echarts from 'echarts'
|
||||
|
||||
onMounted(() => {
|
||||
const chart = echarts.init(chartRef.value)
|
||||
chart.setOption({
|
||||
xAxis: { data: xAxisYears.value },
|
||||
yAxis: {},
|
||||
series: [
|
||||
{ type: 'line', data: [1000, 2000, 3000, 4000, 5000] }
|
||||
]
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
### 3. 添加响应式适配
|
||||
使用媒体查询或 `vw/vh` 单位适配不同屏幕:
|
||||
|
||||
```css
|
||||
@media (max-width: 1920px) {
|
||||
.cockpit-main {
|
||||
grid-template-columns: 450px 1fr 450px;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 4. 添加数据刷新
|
||||
使用定时器或 WebSocket 实现实时数据更新:
|
||||
|
||||
```javascript
|
||||
import { useIntervalFn } from '@vueuse/core'
|
||||
|
||||
useIntervalFn(() => {
|
||||
refreshData()
|
||||
}, 30000) // 每30秒刷新
|
||||
```
|
||||
|
||||
### 5. 添加交互功能
|
||||
- 地图标记点击事件
|
||||
- 表格行点击查看详情
|
||||
- 图表数据筛选
|
||||
- 时间范围选择
|
||||
|
||||
### 6. 性能优化
|
||||
- 使用虚拟滚动处理大量数据
|
||||
- 图片懒加载
|
||||
- 组件懒加载
|
||||
|
||||
```javascript
|
||||
const MapCenter = defineAsyncComponent(() =>
|
||||
import('./components/MapCenter.vue')
|
||||
)
|
||||
```
|
||||
|
||||
## ⚠️ 注意事项
|
||||
|
||||
1. **图片路径**: 确保所有图片资源存在于 `assets/img/` 目录中
|
||||
2. **字体文件**: 部分组件使用自定义字体,需要确保字体文件已引入
|
||||
3. **浏览器兼容**: Grid 布局需要现代浏览器支持 (IE11+ 需要 polyfill)
|
||||
|
||||
## 🎨 布局对比
|
||||
|
||||
### 重构前
|
||||
```
|
||||
├── 嵌套10层+ div
|
||||
├── position: absolute 定位超过50处
|
||||
├── 固定 margin/left/top 值
|
||||
└── 567行单文件
|
||||
```
|
||||
|
||||
### 重构后
|
||||
```
|
||||
├── 语义化组件结构
|
||||
├── Grid + Flexbox 布局
|
||||
├── 响应式设计理念
|
||||
└── 7个模块化组件,平均每个约150行
|
||||
```
|
||||
|
||||
## 📝 版本历史
|
||||
|
||||
- **v2.0** (2025-01-XX) - 组件化重构,使用 Grid 布局
|
||||
- **v1.0** (之前) - 原始版本,单文件实现
|
||||
|
||||
## 🤝 贡献指南
|
||||
|
||||
1. 修改组件时保持单一职责原则
|
||||
2. 新增功能优先考虑组件复用
|
||||
3. 样式使用 scoped,避免全局污染
|
||||
4. 数据结构清晰,便于接入 API
|
||||
|
||||
---
|
||||
|
||||
如有问题或建议,请联系开发团队。
|
||||
BIN
packages/screen/src/views/cockpit/assets/img/block-panel-bg.png
Normal file
|
After Width: | Height: | Size: 372 KiB |
|
After Width: | Height: | Size: 6.1 KiB |
BIN
packages/screen/src/views/cockpit/assets/img/block-stat-icon.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 6.2 KiB |
BIN
packages/screen/src/views/cockpit/assets/img/cockpit-main-bg.png
Normal file
|
After Width: | Height: | Size: 181 KiB |
|
After Width: | Height: | Size: 7.0 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 5.6 KiB |
|
After Width: | Height: | Size: 354 B |
|
After Width: | Height: | Size: 228 KiB |
|
After Width: | Height: | Size: 12 KiB |
BIN
packages/screen/src/views/cockpit/assets/img/header-bg.png
Normal file
|
After Width: | Height: | Size: 4.7 KiB |
|
After Width: | Height: | Size: 5.3 KiB |
BIN
packages/screen/src/views/cockpit/assets/img/header-title-bg.png
Normal file
|
After Width: | Height: | Size: 58 KiB |
BIN
packages/screen/src/views/cockpit/assets/img/map-btn-service.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
BIN
packages/screen/src/views/cockpit/assets/img/map-btn-weather.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 27 KiB |
|
After Width: | Height: | Size: 3.1 KiB |
|
After Width: | Height: | Size: 4.3 KiB |
|
After Width: | Height: | Size: 3.1 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 7.2 KiB |
|
After Width: | Height: | Size: 2.5 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 212 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 4.9 KiB |
|
After Width: | Height: | Size: 8.5 KiB |
|
After Width: | Height: | Size: 6.4 KiB |
|
After Width: | Height: | Size: 9.3 KiB |
|
After Width: | Height: | Size: 293 KiB |
|
After Width: | Height: | Size: 13 KiB |
133
packages/screen/src/views/cockpit/components/BlockEvent.vue
Normal file
@ -0,0 +1,133 @@
|
||||
<template>
|
||||
<div class="block-event">
|
||||
<div class="panel-header">
|
||||
<span class="title">阻断事件</span>
|
||||
</div>
|
||||
|
||||
<!-- 统计卡片 -->
|
||||
<div class="stats-grid">
|
||||
<div
|
||||
v-for="stat in stats"
|
||||
:key="stat.id"
|
||||
class="stat-card"
|
||||
>
|
||||
<img src="../assets/img/block-stat-icon.png" alt="icon" class="stat-icon" />
|
||||
<div class="stat-content">
|
||||
<div class="stat-title">{{ stat.title }}</div>
|
||||
<div class="stat-value">{{ stat.value }}</div>
|
||||
<div class="stat-unit">公里</div>
|
||||
<img src="../assets/img/block-stat-decoration.png" alt="decoration" class="stat-decoration" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
|
||||
const stats = ref([
|
||||
{ id: 1, title: '当前封闭交通', value: 12 },
|
||||
{ id: 2, title: '当前累计封闭交通', value: 45 },
|
||||
{ id: 3, title: '当前限速通行', value: 30 },
|
||||
{ id: 4, title: '当年累计限速通行', value: 60 },
|
||||
{ id: 5, title: '当前累计抢通', value: 60 }
|
||||
])
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.block-event {
|
||||
background: url(../assets/img/block-panel-bg.png) no-repeat;
|
||||
background-size: 100% 100%;
|
||||
padding: 20px 30px;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.panel-header {
|
||||
position: relative;
|
||||
width: 293px;
|
||||
height: 49px;
|
||||
background: url(../assets/img/common-panel-header-bg.png) no-repeat;
|
||||
background-size: 100% 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-left: 24px;
|
||||
margin-bottom: 40px;
|
||||
|
||||
.title {
|
||||
color: rgba(255, 255, 255, 1);
|
||||
font-size: 22px;
|
||||
font-family: SourceHanSansCN-Medium, sans-serif;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
|
||||
.stats-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 40px 20px;
|
||||
flex: 1;
|
||||
align-content: flex-start;
|
||||
}
|
||||
|
||||
.stat-card {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
|
||||
.stat-icon {
|
||||
width: 53px;
|
||||
height: 84px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.stat-content {
|
||||
flex: 1;
|
||||
position: relative;
|
||||
|
||||
.stat-title {
|
||||
height: 28px;
|
||||
background: url(../assets/img/block-stat-title-bg.png) no-repeat;
|
||||
background-size: 100% 100%;
|
||||
color: rgba(255, 255, 255, 1);
|
||||
font-size: 15px;
|
||||
font-family: SourceHanSansCN-Bold, sans-serif;
|
||||
font-weight: 700;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-left: 10px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.stat-value {
|
||||
color: rgba(255, 255, 255, 1);
|
||||
font-size: 42px;
|
||||
font-family: SourceHanSansCN-Bold, sans-serif;
|
||||
font-weight: 700;
|
||||
line-height: 1;
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
.stat-unit {
|
||||
position: absolute;
|
||||
top: 50px;
|
||||
right: 20px;
|
||||
color: rgba(255, 255, 255, 1);
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.stat-decoration {
|
||||
width: 154px;
|
||||
height: 29px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 单独处理最后一个卡片占满整行 */
|
||||
.stat-card:nth-child(5) {
|
||||
grid-column: span 1;
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,64 @@
|
||||
<template>
|
||||
<div class="cockpit-layout">
|
||||
<!-- <PageHeader /> -->
|
||||
<div class="cockpit-main">
|
||||
<div class="left-panel">
|
||||
<WeatherWarning />
|
||||
<EmergencyResources />
|
||||
</div>
|
||||
|
||||
<div class="center-panel">
|
||||
<MapCenter />
|
||||
</div>
|
||||
|
||||
<div class="right-panel">
|
||||
<BlockEvent />
|
||||
<YearStatistics />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import PageHeader from './PageHeader.vue'
|
||||
import WeatherWarning from './WeatherWarning.vue'
|
||||
import EmergencyResources from './EmergencyResources.vue'
|
||||
import MapCenter from './MapCenter.vue'
|
||||
import BlockEvent from './BlockEvent.vue'
|
||||
import YearStatistics from './YearStatistics.vue'
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.cockpit-layout {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
background: url(../assets/img/cockpit-main-bg.png) no-repeat;
|
||||
background-size: cover;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.cockpit-main {
|
||||
flex: 1;
|
||||
display: grid;
|
||||
grid-template-columns: 580px 1fr 580px;
|
||||
gap: 20px;
|
||||
padding: 20px;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
.left-panel,
|
||||
.right-panel {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.center-panel {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,223 @@
|
||||
<template>
|
||||
<div class="emergency-resources">
|
||||
<div class="panel-header">
|
||||
<span class="title">应急资源</span>
|
||||
</div>
|
||||
|
||||
<!-- 资源列表 -->
|
||||
<div class="resource-table">
|
||||
<div class="table-header">
|
||||
<span>所属区县</span>
|
||||
<span>服务站点</span>
|
||||
<span>应急物资</span>
|
||||
<span>应急设备</span>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-for="(resource, index) in resources"
|
||||
:key="resource.id"
|
||||
class="table-row"
|
||||
:class="{ 'row-alt': index % 2 === 0 }"
|
||||
>
|
||||
<div class="row-number">{{ index + 1 }}</div>
|
||||
<span class="district-name">{{ resource.name }}</span>
|
||||
<span class="count green">{{ resource.stations }}</span>
|
||||
<span class="count orange">{{ resource.supplies }}</span>
|
||||
<div class="equipment-cell">
|
||||
<span class="count" :class="resource.equipmentClass">{{ resource.equipment }}</span>
|
||||
<img
|
||||
v-if="resource.hasAlert"
|
||||
src="../assets/img/emergency-alert-icon.png"
|
||||
alt="alert"
|
||||
class="alert-icon"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
|
||||
const resources = ref([
|
||||
{
|
||||
id: 1,
|
||||
name: '万州区',
|
||||
stations: 32,
|
||||
supplies: 32,
|
||||
equipment: 25,
|
||||
equipmentClass: 'red',
|
||||
hasAlert: true
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: '城口区',
|
||||
stations: 11,
|
||||
supplies: 11,
|
||||
equipment: 15,
|
||||
equipmentClass: 'red',
|
||||
hasAlert: true
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: '长寿区',
|
||||
stations: 136,
|
||||
supplies: 136,
|
||||
equipment: 12,
|
||||
equipmentClass: 'red',
|
||||
hasAlert: false
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
name: '涪陵区',
|
||||
stations: 35,
|
||||
supplies: 35,
|
||||
equipment: 12,
|
||||
equipmentClass: 'red',
|
||||
hasAlert: false
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
name: '合川区',
|
||||
stations: 46,
|
||||
supplies: 46,
|
||||
equipment: 12,
|
||||
equipmentClass: 'red',
|
||||
hasAlert: false
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
name: '永川区',
|
||||
stations: 35,
|
||||
supplies: 35,
|
||||
equipment: 12,
|
||||
equipmentClass: 'red',
|
||||
hasAlert: false
|
||||
}
|
||||
])
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.emergency-resources {
|
||||
background: url(../assets/img/emergency-panel-bg.png) no-repeat;
|
||||
background-size: 100% 100%;
|
||||
padding: 20px 30px;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.panel-header {
|
||||
position: relative;
|
||||
width: 293px;
|
||||
height: 49px;
|
||||
background: url(../assets/img/common-panel-header-bg.png) no-repeat;
|
||||
background-size: 100% 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-left: 24px;
|
||||
margin-bottom: 30px;
|
||||
|
||||
.title {
|
||||
color: rgba(255, 255, 255, 1);
|
||||
font-size: 22px;
|
||||
font-family: SourceHanSansCN-Medium, sans-serif;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
|
||||
.resource-table {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.table-header {
|
||||
height: 35px;
|
||||
background: url(../assets/img/emergency-table-header-bg.png) no-repeat;
|
||||
background-size: 100% 100%;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr 1fr 1fr;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
color: rgba(255, 255, 255, 1);
|
||||
font-size: 16px;
|
||||
font-family: SourceHanSansCN-Medium, sans-serif;
|
||||
font-weight: 500;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.table-row {
|
||||
height: 35px;
|
||||
display: grid;
|
||||
grid-template-columns: 35px 1fr 1fr 1fr 1fr;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
color: rgba(255, 255, 255, 1);
|
||||
font-size: 14px;
|
||||
font-family: PingFangSC-Medium, sans-serif;
|
||||
font-weight: 500;
|
||||
|
||||
&.row-alt {
|
||||
background: url(../assets/img/common-table-row-bg.png) no-repeat;
|
||||
background-size: 100% 100%;
|
||||
}
|
||||
|
||||
&:not(.row-alt) {
|
||||
background: url(../assets/img/common-table-row-bg-alt.png) no-repeat;
|
||||
background-size: 100% 100%;
|
||||
}
|
||||
|
||||
.row-number {
|
||||
width: 35px;
|
||||
height: 35px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: rgba(28, 161, 255, 0.44);
|
||||
color: rgba(255, 255, 255, 1);
|
||||
font-size: 14px;
|
||||
font-family: FZZYJW--GB1-0, sans-serif;
|
||||
}
|
||||
|
||||
&:not(.row-alt) .row-number {
|
||||
background-color: rgba(28, 161, 255, 0.2);
|
||||
}
|
||||
|
||||
.district-name {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.count {
|
||||
text-align: center;
|
||||
font-family: PingFangSC-Semibold, sans-serif;
|
||||
font-weight: 600;
|
||||
font-size: 14px;
|
||||
|
||||
&.green {
|
||||
color: rgba(17, 187, 119, 1);
|
||||
}
|
||||
|
||||
&.orange {
|
||||
color: rgba(255, 128, 11, 1);
|
||||
}
|
||||
|
||||
&.red {
|
||||
color: rgba(255, 6, 36, 1);
|
||||
}
|
||||
}
|
||||
|
||||
.equipment-cell {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 5px;
|
||||
|
||||
.alert-icon {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
286
packages/screen/src/views/cockpit/components/MapCenter.vue
Normal file
@ -0,0 +1,286 @@
|
||||
<template>
|
||||
<div class="map-center">
|
||||
<!-- 顶部功能按钮 -->
|
||||
<div class="top-buttons">
|
||||
<button
|
||||
v-for="button in topButtons"
|
||||
:key="button.id"
|
||||
class="func-button"
|
||||
:class="button.class"
|
||||
>
|
||||
<img :src="button.icon" :alt="button.label" class="button-icon" />
|
||||
<span>{{ button.label }}</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- 地图标记点 (这里应该集成实际地图,现在用占位符) -->
|
||||
<div class="map-markers">
|
||||
<div
|
||||
v-for="marker in markers"
|
||||
:key="marker.id"
|
||||
class="marker"
|
||||
:style="{ left: marker.x + 'px', top: marker.y + 'px' }"
|
||||
>
|
||||
<img :src="marker.icon" :alt="marker.type" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 底部菜单 -->
|
||||
<!--
|
||||
<div class="bottom-menu">
|
||||
<div class="menu-left">
|
||||
<div class="menu-text">
|
||||
应急体系<br />
|
||||
重大事件处置<br />
|
||||
冰雪灾害专题<br />
|
||||
水毁专题<br />
|
||||
节假日专题
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="menu-center">
|
||||
<img src="../assets/img/map-center-menu-bg.png" alt="center menu" class="center-menu-bg" />
|
||||
<div class="center-menu-content">
|
||||
<div class="menu-tabs">
|
||||
<span>总体概览</span>
|
||||
<span>综合评价</span>
|
||||
</div>
|
||||
<div class="menu-icons">
|
||||
<div class="menu-icon-item">
|
||||
<img src="../assets/img/map-menu-icon-road-network.png" alt="icon" />
|
||||
<span>路网结构<br />优化</span>
|
||||
</div>
|
||||
<div class="menu-icon-item">
|
||||
<img src="../assets/img/map-menu-icon-construction.png" alt="icon" />
|
||||
<span>建设工程<br />智监</span>
|
||||
</div>
|
||||
<div class="menu-icon-item highlighted">
|
||||
<img src="../assets/img/map-menu-icon-safety.png" alt="icon" />
|
||||
<span>安全保通<br />服务</span>
|
||||
</div>
|
||||
<div class="menu-icon-item">
|
||||
<img src="../assets/img/map-menu-icon-maintenance.png" alt="icon" />
|
||||
<span>养护作业<br />智管</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
-->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
|
||||
// 导入图片
|
||||
import btnServiceIcon from '../assets/img/map-btn-service.png'
|
||||
import btnWarningRoadIcon from '../assets/img/map-btn-warning-road.png'
|
||||
import btnWeatherIcon from '../assets/img/map-btn-weather.png'
|
||||
import markerServiceIcon from '../assets/img/map-marker-service.png'
|
||||
import markerWarningIcon from '../assets/img/map-marker-warning.png'
|
||||
import markerAlertIcon from '../assets/img/map-marker-alert.png'
|
||||
|
||||
const topButtons = ref([
|
||||
{
|
||||
id: 1,
|
||||
label: '服务站点',
|
||||
class: 'button-primary',
|
||||
icon: btnServiceIcon
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
label: '预警路段',
|
||||
class: 'button-default',
|
||||
icon: btnWarningRoadIcon
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
label: '气象预警',
|
||||
class: 'button-default',
|
||||
icon: btnWeatherIcon
|
||||
}
|
||||
])
|
||||
|
||||
const markers = ref([
|
||||
{ id: 1, type: 'service', x: 200, y: 150, icon: markerServiceIcon },
|
||||
{ id: 2, type: 'warning', x: 350, y: 200, icon: markerWarningIcon },
|
||||
{ id: 3, type: 'alert', x: 450, y: 300, icon: markerAlertIcon }
|
||||
])
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.map-center {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.top-buttons {
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.func-button {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
border: 0.5px solid rgba(60, 174, 255, 1);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 5px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
|
||||
&.button-default {
|
||||
background-color: rgba(35, 74, 117, 1);
|
||||
}
|
||||
|
||||
&.button-primary {
|
||||
background-color: rgba(33, 73, 118, 1);
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(60, 174, 255, 0.3);
|
||||
}
|
||||
|
||||
.button-icon {
|
||||
width: 28px;
|
||||
height: 23px;
|
||||
}
|
||||
|
||||
span {
|
||||
color: rgba(255, 255, 255, 1);
|
||||
font-size: 12px;
|
||||
font-family: SourceHanSansCN-Regular, sans-serif;
|
||||
}
|
||||
}
|
||||
|
||||
.map-markers {
|
||||
flex: 1;
|
||||
position: relative;
|
||||
|
||||
.marker {
|
||||
position: absolute;
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
cursor: pointer;
|
||||
transition: transform 0.3s;
|
||||
|
||||
&:hover {
|
||||
transform: scale(1.2);
|
||||
}
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bottom-menu {
|
||||
position: absolute;
|
||||
bottom: 20px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
display: flex;
|
||||
gap: 30px;
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
.menu-left {
|
||||
.menu-text {
|
||||
color: rgba(255, 255, 255, 1);
|
||||
font-size: 14px;
|
||||
line-height: 39px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
.menu-center {
|
||||
position: relative;
|
||||
width: 350px;
|
||||
height: 156px;
|
||||
|
||||
.center-menu-bg {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.center-menu-content {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
padding: 15px 34px;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.menu-tabs {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-top: auto;
|
||||
margin-bottom: 5px;
|
||||
|
||||
span {
|
||||
color: rgba(255, 255, 255, 1);
|
||||
font-size: 12px;
|
||||
font-family: Helvetica, "Microsoft YaHei", Arial, sans-serif;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.menu-icons {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-end;
|
||||
|
||||
.menu-icon-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
cursor: pointer;
|
||||
transition: transform 0.3s;
|
||||
|
||||
&:hover {
|
||||
transform: translateY(-5px);
|
||||
}
|
||||
|
||||
&.highlighted {
|
||||
background: url(../assets/img/map-menu-item-highlight-bg.png) no-repeat;
|
||||
background-size: contain;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
img {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
span {
|
||||
color: rgba(255, 255, 255, 1);
|
||||
font-size: 12px;
|
||||
font-family: Helvetica, "Microsoft YaHei", Arial, sans-serif;
|
||||
text-align: center;
|
||||
line-height: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
64
packages/screen/src/views/cockpit/components/PageHeader.vue
Normal file
@ -0,0 +1,64 @@
|
||||
<template>
|
||||
<header class="page-header">
|
||||
<div class="header-bg">
|
||||
<h1 class="title">安全保通服务</h1>
|
||||
<button class="app-button">应用</button>
|
||||
</div>
|
||||
</header>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.page-header {
|
||||
height: 137px;
|
||||
background: url(../assets/img/header-bg.png) no-repeat;
|
||||
background-size: 100% 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.header-bg {
|
||||
background-image: url(../assets/img/header-title-bg.png);
|
||||
width: 100%;
|
||||
height: 107px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.title {
|
||||
color: rgba(255, 255, 255, 1);
|
||||
font-size: 51px;
|
||||
letter-spacing: 2.32px;
|
||||
font-family: FZLTDHJW--GB1-0, sans-serif;
|
||||
white-space: nowrap;
|
||||
margin: 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.app-button {
|
||||
position: absolute;
|
||||
right: 40px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
width: 165px;
|
||||
height: 44px;
|
||||
background: url(../assets/img/header-btn-app-bg.png) no-repeat;
|
||||
background-size: 100% 100%;
|
||||
color: rgba(255, 255, 255, 1);
|
||||
font-size: 16px;
|
||||
font-family: SourceHanSansCN-Regular, sans-serif;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
transition: opacity 0.3s;
|
||||
|
||||
&:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
320
packages/screen/src/views/cockpit/components/WeatherWarning.vue
Normal file
@ -0,0 +1,320 @@
|
||||
<template>
|
||||
<div class="weather-warning">
|
||||
<div class="panel-header">
|
||||
<span class="title">气象预警</span>
|
||||
</div>
|
||||
|
||||
<!-- 预警等级展示 -->
|
||||
<div class="warning-levels">
|
||||
<div
|
||||
v-for="level in warningLevels"
|
||||
:key="level.id"
|
||||
class="warning-level-item"
|
||||
>
|
||||
<!-- 六边形徽章容器 -->
|
||||
<div class="badge-container">
|
||||
<!-- 六边形徽章 -->
|
||||
<div class="level-badge">
|
||||
<img
|
||||
src="../assets/img/weather-badge-hexagon.png"
|
||||
alt="badge"
|
||||
class="badge-bg"
|
||||
/>
|
||||
<span class="level-count" :style="{ color: level.color }">{{ level.count }}</span>
|
||||
</div>
|
||||
|
||||
<!-- 底座光圈(双背景图) -->
|
||||
<div class="glow-base"></div>
|
||||
</div>
|
||||
|
||||
<!-- 底部文字 -->
|
||||
<span class="level-name">{{ level.name }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 海拔800米以上气象情况 -->
|
||||
<div class="altitude-section">
|
||||
<div class="altitude-header">
|
||||
<img src="../assets/img/weather-altitude-icon.png" alt="icon" class="altitude-icon" />
|
||||
<span>海拔800米以上气象情况</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 区县列表 -->
|
||||
<div class="district-table">
|
||||
<div class="table-header">
|
||||
<span>所属区县</span>
|
||||
<span>公里数</span>
|
||||
<span>预警情况</span>
|
||||
</div>
|
||||
<div
|
||||
v-for="(district, index) in districts"
|
||||
:key="district.id"
|
||||
class="table-row"
|
||||
:class="{ 'row-alt': index % 2 === 0 }"
|
||||
>
|
||||
<div class="row-indicator" :style="{ backgroundColor: district.warningColor }"></div>
|
||||
<span class="district-name">{{ district.name }}</span>
|
||||
<span class="district-km">{{ district.km }}</span>
|
||||
<span class="district-warning" :style="{ color: district.warningColor }">
|
||||
{{ district.warning }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
|
||||
// 导入图片
|
||||
import glowTopIcon from '../assets/img/weather-badge-glow-top.png'
|
||||
import glowBottomIcon from '../assets/img/weather-badge-glow-bottom.png'
|
||||
|
||||
const warningLevels = ref([
|
||||
{
|
||||
id: 1,
|
||||
name: '蓝色预警',
|
||||
count: 320,
|
||||
color: 'rgba(132, 199, 255, 1)',
|
||||
glowTopIcon: glowTopIcon,
|
||||
glowBottomIcon: glowBottomIcon
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: '黄色预警',
|
||||
count: 36,
|
||||
color: 'rgba(215, 209, 38, 1)',
|
||||
glowTopIcon: glowTopIcon,
|
||||
glowBottomIcon: glowBottomIcon
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: '橙色预警',
|
||||
count: 2,
|
||||
color: 'rgba(255, 114, 0, 1)',
|
||||
glowTopIcon: glowTopIcon,
|
||||
glowBottomIcon: glowBottomIcon
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
name: '红色预警',
|
||||
count: 1,
|
||||
color: 'rgba(255, 32, 0, 1)',
|
||||
glowTopIcon: glowTopIcon,
|
||||
glowBottomIcon: glowBottomIcon
|
||||
}
|
||||
])
|
||||
|
||||
const districts = ref([
|
||||
{ id: 1, name: '万州区', km: 32, warning: '红色预警', warningColor: 'rgba(229, 37, 42, 1)' },
|
||||
{ id: 2, name: '城口区', km: 11, warning: '橙色预警', warningColor: 'rgba(255, 114, 0, 1)' },
|
||||
{ id: 3, name: '长寿区', km: 136, warning: '黄色预警', warningColor: 'rgba(215, 209, 38, 1)' },
|
||||
{ id: 4, name: '涪陵区', km: 35, warning: '蓝色预警', warningColor: 'rgba(47, 156, 246, 1)' },
|
||||
{ id: 5, name: '合川区', km: 46, warning: '蓝色预警', warningColor: 'rgba(47, 156, 246, 1)' }
|
||||
])
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.weather-warning {
|
||||
background: url(../assets/img/weather-panel-bg.png) no-repeat;
|
||||
background-size: 100% 100%;
|
||||
padding: 20px 30px;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.panel-header {
|
||||
position: relative;
|
||||
width: 293px;
|
||||
height: 49px;
|
||||
background: url(../assets/img/common-panel-header-bg.png) no-repeat;
|
||||
background-size: 100% 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-left: 24px;
|
||||
margin-bottom: 20px;
|
||||
|
||||
.title {
|
||||
color: rgba(255, 255, 255, 1);
|
||||
font-size: 22px;
|
||||
font-family: SourceHanSansCN-Medium, sans-serif;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
|
||||
.warning-levels {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 20px;
|
||||
margin: 0 30px;
|
||||
padding: 0 27px;
|
||||
}
|
||||
|
||||
.warning-level-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
|
||||
// 徽章和光圈容器
|
||||
.badge-container {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
// 六边形徽章
|
||||
.level-badge {
|
||||
position: relative;
|
||||
width: 80px;
|
||||
height: 90px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 2;
|
||||
|
||||
.badge-bg {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.level-count {
|
||||
position: relative;
|
||||
font-size: 32px;
|
||||
font-family: DISPLAYFREETFB, sans-serif;
|
||||
font-weight: normal;
|
||||
z-index: 1;
|
||||
line-height: 1;
|
||||
}
|
||||
}
|
||||
|
||||
// 底座光圈(双背景图)
|
||||
.glow-base {
|
||||
width: 72px;
|
||||
height: 65px;
|
||||
margin-top: -10px;
|
||||
z-index: 1;
|
||||
|
||||
// 双背景图实现
|
||||
background-image:
|
||||
url('../assets/img/weather-badge-glow-top.png'), // 上层
|
||||
url('../assets/img/weather-badge-glow-bottom.png'); // 下层(更宽)
|
||||
|
||||
background-position:
|
||||
center 0px, // 上层:紧贴顶部
|
||||
center 10px; // 下层:稍微偏下
|
||||
|
||||
background-size:
|
||||
100% auto, // 上层:正常宽度
|
||||
120% auto; // 下层:更宽 20%
|
||||
|
||||
background-repeat: no-repeat, no-repeat;
|
||||
}
|
||||
|
||||
// 底部文字标签
|
||||
.level-name {
|
||||
color: rgba(255, 255, 255, 1);
|
||||
font-size: 14px;
|
||||
font-family: SourceHanSansCN-Bold, sans-serif;
|
||||
font-weight: 700;
|
||||
text-align: center;
|
||||
margin-top: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
.altitude-section {
|
||||
margin: 20px 0;
|
||||
|
||||
.altitude-header {
|
||||
width: 100%;
|
||||
height: 38px;
|
||||
background: url(../assets/img/weather-altitude-bar-bg.png) no-repeat;
|
||||
background-size: 100% 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 0 10px;
|
||||
|
||||
.altitude-icon {
|
||||
width: 39px;
|
||||
height: 35px;
|
||||
}
|
||||
|
||||
span {
|
||||
color: rgba(255, 255, 255, 1);
|
||||
font-size: 16px;
|
||||
font-family: PingFangSC-Semibold, sans-serif;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.district-table {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.table-header {
|
||||
height: 35px;
|
||||
background: url(../assets/img/weather-table-header-bg.png) no-repeat;
|
||||
background-size: 100% 100%;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr 1fr;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
color: rgba(255, 255, 255, 1);
|
||||
font-size: 14px;
|
||||
font-family: SourceHanSansCN-Medium, sans-serif;
|
||||
font-weight: 500;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.table-row {
|
||||
height: 35px;
|
||||
display: grid;
|
||||
grid-template-columns: 9px 1fr 1fr 1fr;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 0 10px;
|
||||
color: rgba(255, 255, 255, 1);
|
||||
font-size: 14px;
|
||||
font-family: PingFangSC-Medium, sans-serif;
|
||||
font-weight: 500;
|
||||
|
||||
&.row-alt {
|
||||
background: url(../assets/img/common-table-row-bg.png) no-repeat;
|
||||
background-size: 100% 100%;
|
||||
}
|
||||
|
||||
&:not(.row-alt) {
|
||||
background: url(../assets/img/common-table-row-bg-alt.png) no-repeat;
|
||||
background-size: 100% 100%;
|
||||
}
|
||||
|
||||
.row-indicator {
|
||||
width: 9px;
|
||||
height: 33px;
|
||||
border-radius: 1px;
|
||||
}
|
||||
|
||||
.district-name {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.district-km {
|
||||
text-align: center;
|
||||
font-family: PingFangSC-Semibold, sans-serif;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.district-warning {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
181
packages/screen/src/views/cockpit/components/YearStatistics.vue
Normal file
@ -0,0 +1,181 @@
|
||||
<template>
|
||||
<div class="year-statistics">
|
||||
<div class="panel-header">
|
||||
<span class="title">往年统计</span>
|
||||
</div>
|
||||
|
||||
<!-- 图表标题和图例 -->
|
||||
<div class="chart-header">
|
||||
<span class="y-axis-label">数量</span>
|
||||
<span class="chart-title">冰雪事件对比趋势图</span>
|
||||
<div class="legend">
|
||||
<div class="legend-item">
|
||||
<div class="legend-color blue"></div>
|
||||
<span>限速通行</span>
|
||||
</div>
|
||||
<div class="legend-item">
|
||||
<div class="legend-color cyan"></div>
|
||||
<span>封闭交通</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 图表区域 (这里需要集成图表库如ECharts) -->
|
||||
<div class="chart-container">
|
||||
<div class="y-axis">
|
||||
<span v-for="value in yAxisValues" :key="value">{{ value }}</span>
|
||||
</div>
|
||||
<div class="chart-area">
|
||||
<img src="../assets/img/statistics-chart-image.png" alt="chart" class="chart-image" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- X轴标签 -->
|
||||
<div class="x-axis">
|
||||
<span v-for="year in xAxisYears" :key="year">{{ year }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
|
||||
const yAxisValues = ref([6000, 5000, 4000, 3000, 2000, 1000, 0])
|
||||
const xAxisYears = ref([
|
||||
'2020~2021',
|
||||
'2021~2022',
|
||||
'2022~2023',
|
||||
'2023~2024',
|
||||
'2024~2025'
|
||||
])
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.year-statistics {
|
||||
background: url(../assets/img/statistics-panel-bg.png) no-repeat;
|
||||
background-size: 100% 100%;
|
||||
padding: 20px 30px;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.panel-header {
|
||||
position: relative;
|
||||
width: 293px;
|
||||
height: 49px;
|
||||
background: url(../assets/img/common-panel-header-bg.png) no-repeat;
|
||||
background-size: 100% 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-left: 24px;
|
||||
margin-bottom: 25px;
|
||||
|
||||
.title {
|
||||
color: rgba(255, 255, 255, 1);
|
||||
font-size: 22px;
|
||||
font-family: SourceHanSansCN-Medium, sans-serif;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
|
||||
.chart-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 15px;
|
||||
margin-bottom: 10px;
|
||||
padding-left: 10px;
|
||||
|
||||
.y-axis-label {
|
||||
color: rgba(255, 255, 255, 1);
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.chart-title {
|
||||
color: rgba(255, 255, 255, 1);
|
||||
font-size: 16px;
|
||||
font-family: PingFangSC-Semibold, sans-serif;
|
||||
font-weight: 600;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.legend {
|
||||
display: flex;
|
||||
gap: 15px;
|
||||
|
||||
.legend-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
|
||||
.legend-color {
|
||||
width: 9px;
|
||||
height: 9px;
|
||||
border-radius: 4px;
|
||||
|
||||
&.blue {
|
||||
background-color: rgba(0, 143, 255, 1);
|
||||
}
|
||||
|
||||
&.cyan {
|
||||
background-color: rgba(0, 242, 245, 1);
|
||||
}
|
||||
}
|
||||
|
||||
span {
|
||||
color: rgba(255, 255, 255, 1);
|
||||
font-size: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.chart-container {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
margin-bottom: 10px;
|
||||
|
||||
.y-axis {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
padding: 5px 0;
|
||||
|
||||
span {
|
||||
color: rgba(255, 255, 255, 1);
|
||||
font-size: 12px;
|
||||
font-family: HelveticaNeue, sans-serif;
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
|
||||
.chart-area {
|
||||
flex: 1;
|
||||
background: url(../assets/img/statistics-chart-area-bg.png) no-repeat;
|
||||
background-size: 100% 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 15px;
|
||||
|
||||
.chart-image {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
object-fit: contain;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.x-axis {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
padding: 0 40px 0 60px;
|
||||
|
||||
span {
|
||||
color: rgba(255, 255, 255, 1);
|
||||
font-size: 12px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
11
packages/screen/src/views/cockpit/index.vue
Normal file
@ -0,0 +1,11 @@
|
||||
<template>
|
||||
<CockpitLayout />
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import CockpitLayout from './components/CockpitLayout.vue'
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 全局样式已在各组件中定义 */
|
||||
</style>
|
||||
148
pnpm-lock.yaml
generated
@ -54,7 +54,7 @@ importers:
|
||||
devDependencies:
|
||||
'@vitejs/plugin-vue':
|
||||
specifier: ^5.0.0
|
||||
version: 5.2.4(vite@5.4.20(sass@1.93.2)(terser@5.44.0))(vue@3.5.22)
|
||||
version: 5.2.4(vite@5.4.20(less@4.4.2)(sass@1.93.2)(terser@5.44.0))(vue@3.5.22)
|
||||
sass:
|
||||
specifier: ^1.70.0
|
||||
version: 1.93.2
|
||||
@ -66,7 +66,7 @@ importers:
|
||||
version: 0.26.0(@babel/parser@7.28.4)(rollup@4.52.4)(vue@3.5.22)
|
||||
vite:
|
||||
specifier: ^5.0.0
|
||||
version: 5.4.20(sass@1.93.2)(terser@5.44.0)
|
||||
version: 5.4.20(less@4.4.2)(sass@1.93.2)(terser@5.44.0)
|
||||
|
||||
packages/screen:
|
||||
dependencies:
|
||||
@ -91,13 +91,16 @@ importers:
|
||||
devDependencies:
|
||||
'@vitejs/plugin-vue':
|
||||
specifier: ^5.0.0
|
||||
version: 5.2.4(vite@5.4.20(sass@1.93.2)(terser@5.44.0))(vue@3.5.22)
|
||||
version: 5.2.4(vite@5.4.20(less@4.4.2)(sass@1.93.2)(terser@5.44.0))(vue@3.5.22)
|
||||
less:
|
||||
specifier: ^4.4.2
|
||||
version: 4.4.2
|
||||
sass:
|
||||
specifier: ^1.70.0
|
||||
version: 1.93.2
|
||||
vite:
|
||||
specifier: ^5.0.0
|
||||
version: 5.4.20(sass@1.93.2)(terser@5.44.0)
|
||||
version: 5.4.20(less@4.4.2)(sass@1.93.2)(terser@5.44.0)
|
||||
|
||||
packages/shared:
|
||||
dependencies:
|
||||
@ -662,6 +665,9 @@ packages:
|
||||
confbox@0.2.2:
|
||||
resolution: {integrity: sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ==}
|
||||
|
||||
copy-anything@2.0.6:
|
||||
resolution: {integrity: sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==}
|
||||
|
||||
csstype@3.1.3:
|
||||
resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
|
||||
|
||||
@ -702,6 +708,10 @@ packages:
|
||||
resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==}
|
||||
engines: {node: '>=0.12'}
|
||||
|
||||
errno@0.1.8:
|
||||
resolution: {integrity: sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==}
|
||||
hasBin: true
|
||||
|
||||
es-define-property@1.0.1:
|
||||
resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==}
|
||||
engines: {node: '>= 0.4'}
|
||||
@ -784,6 +794,9 @@ packages:
|
||||
resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
graceful-fs@4.2.11:
|
||||
resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
|
||||
|
||||
has-symbols@1.1.0:
|
||||
resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
@ -796,6 +809,15 @@ packages:
|
||||
resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
iconv-lite@0.6.3:
|
||||
resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
image-size@0.5.5:
|
||||
resolution: {integrity: sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
hasBin: true
|
||||
|
||||
immutable@5.1.4:
|
||||
resolution: {integrity: sha512-p6u1bG3YSnINT5RQmx/yRZBpenIl30kVxkTLDyHLIMk0gict704Q9n+thfDI7lTRm9vXdDYutVzXhzcThxTnXA==}
|
||||
|
||||
@ -819,9 +841,17 @@ packages:
|
||||
resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
|
||||
engines: {node: '>=0.12.0'}
|
||||
|
||||
is-what@3.14.1:
|
||||
resolution: {integrity: sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==}
|
||||
|
||||
js-tokens@9.0.1:
|
||||
resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==}
|
||||
|
||||
less@4.4.2:
|
||||
resolution: {integrity: sha512-j1n1IuTX1VQjIy3tT7cyGbX7nvQOsFLoIqobZv4ttI5axP923gA44zUj6miiA6R5Aoms4sEGVIIcucXUbRI14g==}
|
||||
engines: {node: '>=14'}
|
||||
hasBin: true
|
||||
|
||||
local-pkg@0.4.3:
|
||||
resolution: {integrity: sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==}
|
||||
engines: {node: '>=14'}
|
||||
@ -850,6 +880,10 @@ packages:
|
||||
magic-string@0.30.19:
|
||||
resolution: {integrity: sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==}
|
||||
|
||||
make-dir@2.1.0:
|
||||
resolution: {integrity: sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
math-intrinsics@1.1.0:
|
||||
resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==}
|
||||
engines: {node: '>= 0.4'}
|
||||
@ -873,6 +907,11 @@ packages:
|
||||
resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
|
||||
engines: {node: '>= 0.6'}
|
||||
|
||||
mime@1.6.0:
|
||||
resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==}
|
||||
engines: {node: '>=4'}
|
||||
hasBin: true
|
||||
|
||||
minimatch@9.0.5:
|
||||
resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==}
|
||||
engines: {node: '>=16 || 14 >=14.17'}
|
||||
@ -888,6 +927,11 @@ packages:
|
||||
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
|
||||
hasBin: true
|
||||
|
||||
needle@3.3.1:
|
||||
resolution: {integrity: sha512-6k0YULvhpw+RoLNiQCRKOl09Rv1dPLr8hHnVjHqdolKwDrdNyk+Hmrthi4lIGPPz3r39dLx0hsF5s40sZ3Us4Q==}
|
||||
engines: {node: '>= 4.4.x'}
|
||||
hasBin: true
|
||||
|
||||
node-addon-api@7.1.1:
|
||||
resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==}
|
||||
|
||||
@ -898,6 +942,10 @@ packages:
|
||||
normalize-wheel-es@1.2.0:
|
||||
resolution: {integrity: sha512-Wj7+EJQ8mSuXr2iWfnujrimU35R2W4FAErEyTmJoJ7ucwTn2hOUSsRehMb5RSYkxXGTM7Y9QpvPmp++w5ftoJw==}
|
||||
|
||||
parse-node-version@1.0.1:
|
||||
resolution: {integrity: sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==}
|
||||
engines: {node: '>= 0.10'}
|
||||
|
||||
path-parse@1.0.7:
|
||||
resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
|
||||
|
||||
@ -915,6 +963,10 @@ packages:
|
||||
resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
pify@4.0.1:
|
||||
resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
pinia@2.3.1:
|
||||
resolution: {integrity: sha512-khUlZSwt9xXCaTbbxFYBKDc/bWAGWJjOgvxETwkTN7KRm66EeT1ZdZj6i2ceh9sP2Pzqsbc704r2yngBrxBVug==}
|
||||
peerDependencies:
|
||||
@ -937,6 +989,9 @@ packages:
|
||||
proxy-from-env@1.1.0:
|
||||
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
|
||||
|
||||
prr@1.0.1:
|
||||
resolution: {integrity: sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==}
|
||||
|
||||
quansync@0.2.11:
|
||||
resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==}
|
||||
|
||||
@ -971,14 +1026,24 @@ packages:
|
||||
run-parallel@1.2.0:
|
||||
resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
|
||||
|
||||
safer-buffer@2.1.2:
|
||||
resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
|
||||
|
||||
sass@1.93.2:
|
||||
resolution: {integrity: sha512-t+YPtOQHpGW1QWsh1CHQ5cPIr9lbbGZLZnbihP/D/qZj/yuV68m8qarcV17nvkOX81BCrvzAlq2klCQFZghyTg==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
hasBin: true
|
||||
|
||||
sax@1.4.1:
|
||||
resolution: {integrity: sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==}
|
||||
|
||||
scule@1.3.0:
|
||||
resolution: {integrity: sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==}
|
||||
|
||||
semver@5.7.2:
|
||||
resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==}
|
||||
hasBin: true
|
||||
|
||||
source-map-js@1.2.1:
|
||||
resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
@ -1429,9 +1494,9 @@ snapshots:
|
||||
dependencies:
|
||||
vue: 3.5.22
|
||||
|
||||
'@vitejs/plugin-vue@5.2.4(vite@5.4.20(sass@1.93.2)(terser@5.44.0))(vue@3.5.22)':
|
||||
'@vitejs/plugin-vue@5.2.4(vite@5.4.20(less@4.4.2)(sass@1.93.2)(terser@5.44.0))(vue@3.5.22)':
|
||||
dependencies:
|
||||
vite: 5.4.20(sass@1.93.2)(terser@5.44.0)
|
||||
vite: 5.4.20(less@4.4.2)(sass@1.93.2)(terser@5.44.0)
|
||||
vue: 3.5.22
|
||||
|
||||
'@vue/compiler-core@3.5.22':
|
||||
@ -1588,6 +1653,10 @@ snapshots:
|
||||
|
||||
confbox@0.2.2: {}
|
||||
|
||||
copy-anything@2.0.6:
|
||||
dependencies:
|
||||
is-what: 3.14.1
|
||||
|
||||
csstype@3.1.3: {}
|
||||
|
||||
dayjs@1.11.18: {}
|
||||
@ -1634,6 +1703,11 @@ snapshots:
|
||||
|
||||
entities@4.5.0: {}
|
||||
|
||||
errno@0.1.8:
|
||||
dependencies:
|
||||
prr: 1.0.1
|
||||
optional: true
|
||||
|
||||
es-define-property@1.0.1: {}
|
||||
|
||||
es-errors@1.3.0: {}
|
||||
@ -1740,6 +1814,9 @@ snapshots:
|
||||
|
||||
gopd@1.2.0: {}
|
||||
|
||||
graceful-fs@4.2.11:
|
||||
optional: true
|
||||
|
||||
has-symbols@1.1.0: {}
|
||||
|
||||
has-tostringtag@1.0.2:
|
||||
@ -1750,6 +1827,14 @@ snapshots:
|
||||
dependencies:
|
||||
function-bind: 1.1.2
|
||||
|
||||
iconv-lite@0.6.3:
|
||||
dependencies:
|
||||
safer-buffer: 2.1.2
|
||||
optional: true
|
||||
|
||||
image-size@0.5.5:
|
||||
optional: true
|
||||
|
||||
immutable@5.1.4: {}
|
||||
|
||||
is-binary-path@2.1.0:
|
||||
@ -1768,8 +1853,24 @@ snapshots:
|
||||
|
||||
is-number@7.0.0: {}
|
||||
|
||||
is-what@3.14.1: {}
|
||||
|
||||
js-tokens@9.0.1: {}
|
||||
|
||||
less@4.4.2:
|
||||
dependencies:
|
||||
copy-anything: 2.0.6
|
||||
parse-node-version: 1.0.1
|
||||
tslib: 2.3.0
|
||||
optionalDependencies:
|
||||
errno: 0.1.8
|
||||
graceful-fs: 4.2.11
|
||||
image-size: 0.5.5
|
||||
make-dir: 2.1.0
|
||||
mime: 1.6.0
|
||||
needle: 3.3.1
|
||||
source-map: 0.6.1
|
||||
|
||||
local-pkg@0.4.3: {}
|
||||
|
||||
local-pkg@0.5.1:
|
||||
@ -1797,6 +1898,12 @@ snapshots:
|
||||
dependencies:
|
||||
'@jridgewell/sourcemap-codec': 1.5.5
|
||||
|
||||
make-dir@2.1.0:
|
||||
dependencies:
|
||||
pify: 4.0.1
|
||||
semver: 5.7.2
|
||||
optional: true
|
||||
|
||||
math-intrinsics@1.1.0: {}
|
||||
|
||||
memoize-one@6.0.0: {}
|
||||
@ -1814,6 +1921,9 @@ snapshots:
|
||||
dependencies:
|
||||
mime-db: 1.52.0
|
||||
|
||||
mime@1.6.0:
|
||||
optional: true
|
||||
|
||||
minimatch@9.0.5:
|
||||
dependencies:
|
||||
brace-expansion: 2.0.2
|
||||
@ -1829,6 +1939,12 @@ snapshots:
|
||||
|
||||
nanoid@3.3.11: {}
|
||||
|
||||
needle@3.3.1:
|
||||
dependencies:
|
||||
iconv-lite: 0.6.3
|
||||
sax: 1.4.1
|
||||
optional: true
|
||||
|
||||
node-addon-api@7.1.1:
|
||||
optional: true
|
||||
|
||||
@ -1836,6 +1952,8 @@ snapshots:
|
||||
|
||||
normalize-wheel-es@1.2.0: {}
|
||||
|
||||
parse-node-version@1.0.1: {}
|
||||
|
||||
path-parse@1.0.7: {}
|
||||
|
||||
pathe@2.0.3: {}
|
||||
@ -1846,6 +1964,9 @@ snapshots:
|
||||
|
||||
picomatch@4.0.3: {}
|
||||
|
||||
pify@4.0.1:
|
||||
optional: true
|
||||
|
||||
pinia@2.3.1(vue@3.5.22):
|
||||
dependencies:
|
||||
'@vue/devtools-api': 6.6.4
|
||||
@ -1874,6 +1995,9 @@ snapshots:
|
||||
|
||||
proxy-from-env@1.1.0: {}
|
||||
|
||||
prr@1.0.1:
|
||||
optional: true
|
||||
|
||||
quansync@0.2.11: {}
|
||||
|
||||
queue-microtask@1.2.3: {}
|
||||
@ -1926,6 +2050,9 @@ snapshots:
|
||||
dependencies:
|
||||
queue-microtask: 1.2.3
|
||||
|
||||
safer-buffer@2.1.2:
|
||||
optional: true
|
||||
|
||||
sass@1.93.2:
|
||||
dependencies:
|
||||
chokidar: 4.0.3
|
||||
@ -1934,8 +2061,14 @@ snapshots:
|
||||
optionalDependencies:
|
||||
'@parcel/watcher': 2.5.1
|
||||
|
||||
sax@1.4.1:
|
||||
optional: true
|
||||
|
||||
scule@1.3.0: {}
|
||||
|
||||
semver@5.7.2:
|
||||
optional: true
|
||||
|
||||
source-map-js@1.2.1: {}
|
||||
|
||||
source-map-support@0.5.21:
|
||||
@ -2034,13 +2167,14 @@ snapshots:
|
||||
'@vue/shared': 3.5.22
|
||||
vue: 3.5.22
|
||||
|
||||
vite@5.4.20(sass@1.93.2)(terser@5.44.0):
|
||||
vite@5.4.20(less@4.4.2)(sass@1.93.2)(terser@5.44.0):
|
||||
dependencies:
|
||||
esbuild: 0.21.5
|
||||
postcss: 8.5.6
|
||||
rollup: 4.52.4
|
||||
optionalDependencies:
|
||||
fsevents: 2.3.3
|
||||
less: 4.4.2
|
||||
sass: 1.93.2
|
||||
terser: 5.44.0
|
||||
|
||||
|
||||