Files
aiot-uniapp/src/pages/index/components/menu-section.vue

141 lines
4.7 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<scroll-view class="min-h-0 flex-1" scroll-y scroll-with-animation>
<!-- 常用应用 -->
<view class="mx-32rpx mt-24rpx">
<view class="mb-24rpx flex items-center">
<view class="mr-8rpx h-32rpx w-6rpx rounded-4rpx bg-[#F97316]" />
<text class="text-28rpx text-[#1F2937] font-bold">常用应用</text>
</view>
<view class="ai-card p-32rpx">
<view class="grid grid-cols-4 gap-y-40rpx">
<view
v-for="app in quickApps"
:key="app.key"
class="flex flex-col items-center"
@click="handleQuickApp(app)"
>
<view
class="app-icon-wrap"
:style="{ background: app.bgLight }"
>
<view :class="app.icon" class="text-44rpx" :style="{ color: app.color }" />
</view>
<text class="mt-16rpx text-24rpx text-[#1F2937] font-600">{{ app.name }}</text>
</view>
</view>
</view>
</view>
<!-- 区域预警暂时隐藏 -->
<!--
<view class="mx-32rpx mt-48rpx">
<view class="mb-16rpx flex items-center">
<view class="mr-8rpx h-32rpx w-6rpx rounded-4rpx bg-[#F97316]" />
<text class="text-28rpx text-[#1F2937] font-bold">区域预警</text>
</view>
<view class="ai-card p-32rpx">
<view v-for="(warning, index) in areaWarnings" :key="index" class="warning-item">
<view class="mb-12rpx flex items-center justify-between">
<view class="flex items-center">
<text class="text-28rpx text-[#1F2937] font-600">{{ warning.area }}</text>
<view
class="ml-12rpx rounded-999px px-16rpx py-4rpx text-22rpx font-bold"
:class="warning.level === '高' ? 'ai-badge&#45;&#45;red' : warning.level === '中' ? 'ai-badge&#45;&#45;orange' : 'ai-badge&#45;&#45;green'"
>
{{ warning.level }}风险
</view>
</view>
</view>
</view>
</view>
</view>
-->
<!-- 工作流程 -->
<view v-for="group in menuGroups" :key="group.key" class="mx-32rpx mt-32rpx">
<view class="mb-16rpx flex items-center justify-between" @click="toggleGroup(group.key)">
<view class="flex items-center">
<view class="mr-8rpx h-32rpx w-6rpx rounded-4rpx bg-[#F97316]" />
<text class="text-28rpx text-[#1F2937] font-bold">{{ group.name }}</text>
</view>
<view
class="i-carbon-chevron-down text-16px text-[#9CA3AF] transition-transform"
:class="{ 'rotate-180': expandedGroups.includes(group.key) }"
/>
</view>
<view v-show="expandedGroups.includes(group.key)" class="ai-card overflow-hidden">
<MenuGrid :menus="group.menus" />
</view>
</view>
<!-- 底部留白 tabbar 腾出空间 -->
<view class="pb-safe" style="height: 140rpx;" />
</scroll-view>
</template>
<script lang="ts" setup>
import type { MenuGroup } from '../index'
import { useToast } from 'wot-design-uni'
import { getMenuGroups } from '../index'
import MenuGrid from './menu-grid.vue'
defineOptions({
name: 'MenuSection',
})
const toast = useToast()
/** 菜单分组列表(仅保留工作流程) */
const menuGroups = ref<MenuGroup[]>([])
/** 展开的分组 */
const expandedGroups = ref<string[]>([])
/** 快速应用 — 重新设计图标与配色 */
const quickApps = [
{ key: 'workOrder', name: '工单中心', icon: 'i-carbon-task-complete', color: '#F97316', bgLight: '#FFF7ED', url: '/pages/scan/work-order/index' },
{ key: 'inspection', name: '巡检记录', icon: 'i-carbon-list-checked', color: '#8B5CF6', bgLight: '#F5F3FF', url: '/pages/scan/inspection/list' },
{ key: 'workOrderStats', name: '工单统计', icon: 'i-carbon-chart-bar', color: '#3B82F6', bgLight: '#EFF6FF', url: '/pages/scan/work-order/stats' },
{ key: 'trafficStats', name: '客流统计', icon: 'i-carbon-pedestrian', color: '#10B981', bgLight: '#ECFDF5', url: '/pages/scan/traffic/index' },
]
function handleQuickApp(app: any) {
if (app.url) {
uni.navigateTo({ url: app.url })
} else {
toast.info(`${app.name}功能开发中`)
}
}
function toggleGroup(key: string) {
const idx = expandedGroups.value.indexOf(key)
if (idx === -1) {
expandedGroups.value.push(key)
} else {
expandedGroups.value.splice(idx, 1)
}
}
/** 初始化数据:过滤掉系统管理和基础设施 */
function initData() {
menuGroups.value = getMenuGroups().filter(
g => g.key !== 'system' && g.key !== 'infra',
)
}
onShow(() => {
initData()
})
</script>
<style lang="scss" scoped>
.app-icon-wrap {
width: 96rpx;
height: 96rpx;
border-radius: 28rpx;
display: flex;
align-items: center;
justify-content: center;
}
</style>