| | |
| | | |
| | | <!-- 功能菜单 --> |
| | | <view class="menu-section"> |
| | | <view class="menu-grid"> |
| | | <view class="menu-item" v-for="(item, index) in elements" :key="index" |
| | | @click="navigateTo(item)" :style="{animationDelay: (index * 0.1) + 's'}"> |
| | | <view class="menu-card" :class="'card-' + item.color"> |
| | | <view class="card-icon"> |
| | | <uni-icons :type="getIconType(item)" size="32" color="#ffffff"></uni-icons> |
| | | <!-- 分类模式:显示分类标题和折叠菜单 --> |
| | | <template v-if="useCategoryMode"> |
| | | <!-- 分类菜单 --> |
| | | <view class="category-section" v-for="(category, catIndex) in categorizedMenus" :key="category.key"> |
| | | <!-- 分类头部 - 渐变色卡片风格 --> |
| | | <view class="category-card" :class="'category-card-' + category.color" @click="toggleCategory(category.key)"> |
| | | <view class="category-card-icon"> |
| | | <uni-icons :type="category.icon" size="24" color="#ffffff"></uni-icons> |
| | | </view> |
| | | <view class="card-info"> |
| | | <text class="card-title">{{item.title}}</text> |
| | | <text class="card-desc">{{item.name}}</text> |
| | | <view class="category-card-info"> |
| | | <text class="category-card-title">{{category.name}}</text> |
| | | <text class="category-card-count">{{category.items.length}} 个功能</text> |
| | | </view> |
| | | <view class="card-arrow"> |
| | | <uni-icons type="right" size="16" color="rgba(255,255,255,0.6)"></uni-icons> |
| | | <view class="category-card-arrow" :class="{'expanded': expandedCategories.includes(category.key)}"> |
| | | <uni-icons type="down" size="20" color="rgba(255,255,255,0.8)"></uni-icons> |
| | | </view> |
| | | </view> |
| | | <!-- 子菜单项 - 白色卡片配左侧彩色指示条 --> |
| | | <view class="sub-menu-container" v-show="expandedCategories.includes(category.key)"> |
| | | <view class="sub-menu-item" v-for="(item, index) in category.items" :key="item.name" |
| | | @click="navigateTo(item)" :style="{animationDelay: (index * 0.06) + 's'}"> |
| | | <view class="sub-menu-card"> |
| | | <view class="sub-menu-indicator" :class="'indicator-' + item.color"></view> |
| | | <view class="sub-menu-icon" :class="'icon-bg-' + item.color"> |
| | | <uni-icons :type="getIconType(item)" size="24" color="#ffffff"></uni-icons> |
| | | </view> |
| | | <view class="sub-menu-info"> |
| | | <text class="sub-menu-title">{{item.title}}</text> |
| | | <text class="sub-menu-desc">{{item.name}}</text> |
| | | </view> |
| | | <view class="sub-menu-arrow"> |
| | | <uni-icons type="right" size="16" color="#c0c4cc"></uni-icons> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | |
| | | <!-- 未分类菜单分隔区域 --> |
| | | <view class="uncategorized-section" v-if="uncategorizedMenus.length > 0"> |
| | | <view class="section-divider"> |
| | | <view class="divider-line"></view> |
| | | <text class="divider-text">其他</text> |
| | | <view class="divider-line"></view> |
| | | </view> |
| | | <view class="menu-grid-flat"> |
| | | <view class="menu-item-flat" v-for="(item, index) in uncategorizedMenus" :key="item.name" |
| | | @click="navigateTo(item)" :style="{animationDelay: (index * 0.1) + 's'}"> |
| | | <view class="menu-card-flat" :class="'card-flat-' + item.color"> |
| | | <view class="card-flat-icon"> |
| | | <uni-icons :type="getIconType(item)" size="28" color="#ffffff"></uni-icons> |
| | | </view> |
| | | <view class="card-flat-info"> |
| | | <text class="card-flat-title">{{item.title}}</text> |
| | | <text class="card-flat-desc">{{item.name}}</text> |
| | | </view> |
| | | <view class="card-flat-arrow"> |
| | | <uni-icons type="right" size="16" color="rgba(255,255,255,0.6)"></uni-icons> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </template> |
| | | |
| | | <!-- 平铺模式:直接显示所有菜单 --> |
| | | <template v-else> |
| | | <view class="menu-grid-flat"> |
| | | <view class="menu-item-flat" v-for="(item, index) in elements" :key="item.name" |
| | | @click="navigateTo(item)" :style="{animationDelay: (index * 0.1) + 's'}"> |
| | | <view class="menu-card-flat" :class="'card-flat-' + item.color"> |
| | | <view class="card-flat-icon"> |
| | | <uni-icons :type="getIconType(item)" size="28" color="#ffffff"></uni-icons> |
| | | </view> |
| | | <view class="card-flat-info"> |
| | | <text class="card-flat-title">{{item.title}}</text> |
| | | <text class="card-flat-desc">{{item.name}}</text> |
| | | </view> |
| | | <view class="card-flat-arrow"> |
| | | <uni-icons type="right" size="16" color="rgba(255,255,255,0.6)"></uni-icons> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </template> |
| | | </view> |
| | | |
| | | <!-- 底部版权 --> |
| | | <view class="footer"> |
| | | <text class="footer-text">WMS Mobile v1.0</text> |
| | | <text class="footer-text">© 2025 WMS Mobile v2.0</text> |
| | | </view> |
| | | </view> |
| | | </template> |
| | |
| | | token: '', |
| | | icon: '', |
| | | elements: [], |
| | | // 是否使用分类模式(true: 上下层折叠菜单模式, false: 平铺菜单模式) |
| | | useCategoryMode: true, |
| | | // 默认菜单数据(用于后端无返回时) |
| | | elements2: [ |
| | | { |
| | | title: '组托', |
| | |
| | | 'orderPutDown': 'bottom', |
| | | 'restock': 'refresh', |
| | | 'stockCheck': 'checkbox', |
| | | } |
| | | 'agv_start': 'navigate', |
| | | 'agv_back': 'refresh', |
| | | }, |
| | | // 菜单分类配置(仅分类模式使用) |
| | | // key: 分类唯一标识 |
| | | // name: 分类显示名称 |
| | | // color: 分类图标颜色 |
| | | // icon: 分类图标 |
| | | // menuNames: 该分类包含的菜单name列表 |
| | | categoryConfig: [ |
| | | { |
| | | key: 'pakin_category', |
| | | name: '入库管理', |
| | | color: 'cyan', |
| | | icon: 'upload', |
| | | menuNames: ['pakin', 'orderPakin'] |
| | | }, |
| | | { |
| | | key: 'agv_category', |
| | | name: 'AGV管理', |
| | | color: 'blue', |
| | | icon: 'navigate', |
| | | menuNames: ['agv_start', 'agv_back'] |
| | | }, |
| | | { |
| | | key: 'stock_category', |
| | | name: '库存管理', |
| | | color: 'green', |
| | | icon: 'search', |
| | | menuNames: ['stockQuery'] |
| | | } |
| | | ], |
| | | // 不参与分类的菜单项(如退出登录,始终单独显示) |
| | | excludeFromCategory: ['logOut'], |
| | | // 当前展开的分类列表 |
| | | expandedCategories: [] |
| | | }; |
| | | }, |
| | | computed: { |
| | | // 分类后的菜单数据(过滤掉空分类) |
| | | categorizedMenus() { |
| | | return this.categoryConfig.map(category => { |
| | | const items = this.elements.filter(item => |
| | | category.menuNames.includes(item.name) |
| | | ); |
| | | return { |
| | | ...category, |
| | | items: items |
| | | }; |
| | | }).filter(category => category.items.length > 0); |
| | | }, |
| | | // 未分类的菜单(不在任何分类中或在排除列表中) |
| | | uncategorizedMenus() { |
| | | const allCategorizedNames = this.categoryConfig.flatMap(c => c.menuNames); |
| | | return this.elements.filter(item => |
| | | !allCategorizedNames.includes(item.name) || this.excludeFromCategory.includes(item.name) |
| | | ); |
| | | } |
| | | }, |
| | | onShow() { |
| | | this.baseUrl = uni.getStorageSync('baseUrl'); |
| | |
| | | this.getAuth(); |
| | | }, |
| | | methods: { |
| | | // 切换分类展开/收起 |
| | | toggleCategory(categoryKey) { |
| | | const index = this.expandedCategories.indexOf(categoryKey); |
| | | if (index > -1) { |
| | | this.expandedCategories.splice(index, 1); |
| | | } else { |
| | | this.expandedCategories.push(categoryKey); |
| | | } |
| | | }, |
| | | // 获取图标类型 |
| | | getIconType(item) { |
| | | return this.iconMap[item.name] || 'circle'; |
| | |
| | | position: relative; |
| | | } |
| | | |
| | | .menu-grid { |
| | | /* 分类区域 */ |
| | | .category-section { |
| | | margin-bottom: 24rpx; |
| | | } |
| | | |
| | | /* 分类卡片 - 渐变色风格 */ |
| | | .category-card { |
| | | display: flex; |
| | | align-items: center; |
| | | padding: 24rpx 28rpx; |
| | | border-radius: 20rpx; |
| | | box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.15); |
| | | transition: transform 0.2s ease, box-shadow 0.2s ease; |
| | | } |
| | | |
| | | .category-card:active { |
| | | transform: scale(0.98); |
| | | box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.2); |
| | | } |
| | | |
| | | .category-card-icon { |
| | | width: 56rpx; |
| | | height: 56rpx; |
| | | background: rgba(255, 255, 255, 0.25); |
| | | border-radius: 14rpx; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | margin-right: 20rpx; |
| | | } |
| | | |
| | | .category-card-info { |
| | | flex: 1; |
| | | display: flex; |
| | | flex-direction: column; |
| | | } |
| | | |
| | | .menu-item { |
| | | margin-bottom: 20rpx; |
| | | animation: slideUp 0.5s ease forwards; |
| | | .category-card-title { |
| | | font-size: 32rpx; |
| | | color: #ffffff; |
| | | font-weight: 600; |
| | | } |
| | | |
| | | .category-card-count { |
| | | font-size: 24rpx; |
| | | color: rgba(255, 255, 255, 0.7); |
| | | margin-top: 4rpx; |
| | | } |
| | | |
| | | .category-card-arrow { |
| | | width: 44rpx; |
| | | height: 44rpx; |
| | | background: rgba(255, 255, 255, 0.15); |
| | | border-radius: 50%; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | transition: transform 0.3s ease; |
| | | } |
| | | |
| | | .category-card-arrow.expanded { |
| | | transform: rotate(180deg); |
| | | } |
| | | |
| | | /* 分类卡片颜色 */ |
| | | .category-card-cyan { |
| | | background: linear-gradient(135deg, #1cbbb4 0%, #16a085 100%); |
| | | } |
| | | |
| | | .category-card-blue { |
| | | background: linear-gradient(135deg, #0081ff 0%, #00bcd4 100%); |
| | | } |
| | | |
| | | .category-card-green { |
| | | background: linear-gradient(135deg, #39b54a 0%, #8dc63f 100%); |
| | | } |
| | | |
| | | .category-card-purple { |
| | | background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); |
| | | } |
| | | |
| | | .category-card-orange { |
| | | background: linear-gradient(135deg, #f37b1d 0%, #fbbd08 100%); |
| | | } |
| | | |
| | | /* 子菜单容器 */ |
| | | .sub-menu-container { |
| | | padding: 16rpx 0 0 0; |
| | | } |
| | | |
| | | .sub-menu-item { |
| | | margin-bottom: 16rpx; |
| | | animation: slideUp 0.4s ease forwards; |
| | | opacity: 0; |
| | | transform: translateY(20rpx); |
| | | transform: translateY(16rpx); |
| | | } |
| | | |
| | | @keyframes slideUp { |
| | |
| | | } |
| | | } |
| | | |
| | | .menu-card { |
| | | /* 子菜单卡片 - 白底配彩色指示条 */ |
| | | .sub-menu-card { |
| | | display: flex; |
| | | align-items: center; |
| | | padding: 28rpx 24rpx; |
| | | border-radius: 20rpx; |
| | | box-shadow: 0 8rpx 30rpx rgba(0, 0, 0, 0.12); |
| | | padding: 20rpx 24rpx; |
| | | background: #ffffff; |
| | | border-radius: 16rpx; |
| | | box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.08); |
| | | position: relative; |
| | | overflow: hidden; |
| | | transition: transform 0.2s ease, box-shadow 0.2s ease; |
| | | } |
| | | |
| | | .menu-card:active { |
| | | .sub-menu-card:active { |
| | | transform: scale(0.98); |
| | | box-shadow: 0 4rpx 15rpx rgba(0, 0, 0, 0.15); |
| | | box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.12); |
| | | } |
| | | |
| | | .card-icon { |
| | | width: 80rpx; |
| | | height: 80rpx; |
| | | background: rgba(255, 255, 255, 0.25); |
| | | border-radius: 20rpx; |
| | | /* 左侧彩色指示条 */ |
| | | .sub-menu-indicator { |
| | | position: absolute; |
| | | left: 0; |
| | | top: 0; |
| | | bottom: 0; |
| | | width: 6rpx; |
| | | border-radius: 0 6rpx 6rpx 0; |
| | | } |
| | | |
| | | .indicator-cyan { background: linear-gradient(180deg, #1cbbb4 0%, #16a085 100%); } |
| | | .indicator-purple { background: linear-gradient(180deg, #667eea 0%, #764ba2 100%); } |
| | | .indicator-blue { background: linear-gradient(180deg, #0081ff 0%, #00bcd4 100%); } |
| | | .indicator-green { background: linear-gradient(180deg, #39b54a 0%, #8dc63f 100%); } |
| | | .indicator-orange { background: linear-gradient(180deg, #f37b1d 0%, #fbbd08 100%); } |
| | | .indicator-red { background: linear-gradient(180deg, #e54d42 0%, #f37b1d 100%); } |
| | | .indicator-pink { background: linear-gradient(180deg, #e03997 0%, #f37b1d 100%); } |
| | | .indicator-mauve { background: linear-gradient(180deg, #9c26b0 0%, #667eea 100%); } |
| | | .indicator-brown { background: linear-gradient(180deg, #a5673f 0%, #8799a3 100%); } |
| | | .indicator-olive { background: linear-gradient(180deg, #8dc63f 0%, #39b54a 100%); } |
| | | .indicator-yellow { background: linear-gradient(180deg, #fbbd08 0%, #f37b1d 100%); } |
| | | .indicator-grey { background: linear-gradient(180deg, #8799a3 0%, #606266 100%); } |
| | | |
| | | /* 子菜单图标背景 */ |
| | | .sub-menu-icon { |
| | | width: 56rpx; |
| | | height: 56rpx; |
| | | border-radius: 14rpx; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | margin-right: 24rpx; |
| | | margin-left: 12rpx; |
| | | margin-right: 20rpx; |
| | | } |
| | | |
| | | .card-info { |
| | | .icon-bg-cyan { background: linear-gradient(135deg, #1cbbb4 0%, #16a085 100%); } |
| | | .icon-bg-purple { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); } |
| | | .icon-bg-blue { background: linear-gradient(135deg, #0081ff 0%, #00bcd4 100%); } |
| | | .icon-bg-green { background: linear-gradient(135deg, #39b54a 0%, #8dc63f 100%); } |
| | | .icon-bg-orange { background: linear-gradient(135deg, #f37b1d 0%, #fbbd08 100%); } |
| | | .icon-bg-red { background: linear-gradient(135deg, #e54d42 0%, #f37b1d 100%); } |
| | | .icon-bg-pink { background: linear-gradient(135deg, #e03997 0%, #f37b1d 100%); } |
| | | .icon-bg-mauve { background: linear-gradient(135deg, #9c26b0 0%, #667eea 100%); } |
| | | .icon-bg-brown { background: linear-gradient(135deg, #a5673f 0%, #8799a3 100%); } |
| | | .icon-bg-olive { background: linear-gradient(135deg, #8dc63f 0%, #39b54a 100%); } |
| | | .icon-bg-yellow { background: linear-gradient(135deg, #fbbd08 0%, #f37b1d 100%); } |
| | | .icon-bg-grey { background: linear-gradient(135deg, #8799a3 0%, #606266 100%); } |
| | | |
| | | .sub-menu-info { |
| | | flex: 1; |
| | | display: flex; |
| | | flex-direction: column; |
| | | } |
| | | |
| | | .sub-menu-title { |
| | | font-size: 30rpx; |
| | | color: #303133; |
| | | font-weight: 500; |
| | | } |
| | | |
| | | .sub-menu-desc { |
| | | font-size: 24rpx; |
| | | color: #909399; |
| | | margin-top: 4rpx; |
| | | } |
| | | |
| | | .sub-menu-arrow { |
| | | width: 36rpx; |
| | | height: 36rpx; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | } |
| | | |
| | | /* 未分类菜单区域 */ |
| | | .uncategorized-section { |
| | | margin-top: 20rpx; |
| | | } |
| | | |
| | | .section-divider { |
| | | display: flex; |
| | | align-items: center; |
| | | padding: 20rpx 0 24rpx; |
| | | } |
| | | |
| | | .divider-line { |
| | | flex: 1; |
| | | height: 2rpx; |
| | | background: linear-gradient(90deg, transparent 0%, #dcdfe6 50%, transparent 100%); |
| | | } |
| | | |
| | | .divider-text { |
| | | padding: 0 24rpx; |
| | | font-size: 26rpx; |
| | | color: #909399; |
| | | } |
| | | |
| | | /* 平铺模式菜单 */ |
| | | .menu-grid-flat { |
| | | display: flex; |
| | | flex-direction: column; |
| | | } |
| | | |
| | | .menu-item-flat { |
| | | margin-bottom: 20rpx; |
| | | animation: slideUp 0.5s ease forwards; |
| | | opacity: 0; |
| | | transform: translateY(20rpx); |
| | | } |
| | | |
| | | .menu-card-flat { |
| | | display: flex; |
| | | align-items: center; |
| | | padding: 24rpx 24rpx; |
| | | border-radius: 18rpx; |
| | | box-shadow: 0 6rpx 24rpx rgba(0, 0, 0, 0.12); |
| | | transition: transform 0.2s ease, box-shadow 0.2s ease; |
| | | } |
| | | |
| | | .menu-card-flat:active { |
| | | transform: scale(0.98); |
| | | box-shadow: 0 3rpx 12rpx rgba(0, 0, 0, 0.15); |
| | | } |
| | | |
| | | .card-flat-icon { |
| | | width: 64rpx; |
| | | height: 64rpx; |
| | | background: rgba(255, 255, 255, 0.25); |
| | | border-radius: 16rpx; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | margin-right: 20rpx; |
| | | } |
| | | |
| | | .card-flat-info { |
| | | flex: 1; |
| | | } |
| | | |
| | | .card-title { |
| | | font-size: 32rpx; |
| | | .card-flat-title { |
| | | font-size: 30rpx; |
| | | color: #ffffff; |
| | | font-weight: 600; |
| | | display: block; |
| | | } |
| | | |
| | | .card-desc { |
| | | .card-flat-desc { |
| | | font-size: 24rpx; |
| | | color: rgba(255, 255, 255, 0.7); |
| | | display: block; |
| | | margin-top: 6rpx; |
| | | margin-top: 4rpx; |
| | | } |
| | | |
| | | .card-arrow { |
| | | width: 40rpx; |
| | | height: 40rpx; |
| | | .card-flat-arrow { |
| | | width: 36rpx; |
| | | height: 36rpx; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | } |
| | | |
| | | /* 卡片颜色 */ |
| | | .card-cyan { |
| | | background: linear-gradient(135deg, #1cbbb4 0%, #16a085 100%); |
| | | } |
| | | |
| | | .card-purple { |
| | | background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); |
| | | } |
| | | |
| | | .card-blue { |
| | | background: linear-gradient(135deg, #0081ff 0%, #00bcd4 100%); |
| | | } |
| | | |
| | | .card-green { |
| | | background: linear-gradient(135deg, #39b54a 0%, #8dc63f 100%); |
| | | } |
| | | |
| | | .card-orange { |
| | | background: linear-gradient(135deg, #f37b1d 0%, #fbbd08 100%); |
| | | } |
| | | |
| | | .card-red { |
| | | background: linear-gradient(135deg, #e54d42 0%, #f37b1d 100%); |
| | | } |
| | | |
| | | .card-pink { |
| | | background: linear-gradient(135deg, #e03997 0%, #f37b1d 100%); |
| | | } |
| | | |
| | | .card-mauve { |
| | | background: linear-gradient(135deg, #9c26b0 0%, #667eea 100%); |
| | | } |
| | | |
| | | .card-brown { |
| | | background: linear-gradient(135deg, #a5673f 0%, #8799a3 100%); |
| | | } |
| | | |
| | | .card-olive { |
| | | background: linear-gradient(135deg, #8dc63f 0%, #39b54a 100%); |
| | | } |
| | | |
| | | .card-yellow { |
| | | background: linear-gradient(135deg, #fbbd08 0%, #f37b1d 100%); |
| | | } |
| | | |
| | | .card-grey { |
| | | background: linear-gradient(135deg, #8799a3 0%, #606266 100%); |
| | | } |
| | | /* 平铺卡片颜色 */ |
| | | .card-flat-cyan { background: linear-gradient(135deg, #1cbbb4 0%, #16a085 100%); } |
| | | .card-flat-purple { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); } |
| | | .card-flat-blue { background: linear-gradient(135deg, #0081ff 0%, #00bcd4 100%); } |
| | | .card-flat-green { background: linear-gradient(135deg, #39b54a 0%, #8dc63f 100%); } |
| | | .card-flat-orange { background: linear-gradient(135deg, #f37b1d 0%, #fbbd08 100%); } |
| | | .card-flat-red { background: linear-gradient(135deg, #e54d42 0%, #f37b1d 100%); } |
| | | .card-flat-pink { background: linear-gradient(135deg, #e03997 0%, #f37b1d 100%); } |
| | | .card-flat-mauve { background: linear-gradient(135deg, #9c26b0 0%, #667eea 100%); } |
| | | .card-flat-brown { background: linear-gradient(135deg, #a5673f 0%, #8799a3 100%); } |
| | | .card-flat-olive { background: linear-gradient(135deg, #8dc63f 0%, #39b54a 100%); } |
| | | .card-flat-yellow { background: linear-gradient(135deg, #fbbd08 0%, #f37b1d 100%); } |
| | | .card-flat-grey { background: linear-gradient(135deg, #8799a3 0%, #606266 100%); } |
| | | |
| | | /* 底部 */ |
| | | .footer { |