Files
pda-overseas-uniapp/src/pages/home/home.vue
T
2026-08-28 10:39:02 +08:00

81 lines
4.0 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>
<view v-if="user" class="page-shell portal-page home-page">
<PortalHeader ref="portalHeader" title="海外仓工作台" :user="user" menu @menu-change="menuOpen = $event" />
<view class="home-menu">
<view class="home-overview">
<view class="home-overview-copy">
<text class="home-overview-eyebrow">OVERSEAS WAREHOUSE</text>
<text class="home-overview-title">{{ greeting }},{{ displayName }}</text>
<text class="home-overview-warehouse">{{ warehouseLabel }}</text>
</view>
<view class="home-overview-status"><text class="home-overview-status-value">{{ availableCount }}</text><text class="home-overview-status-label">项可处理</text></view>
</view>
<view v-for="group in groups" :key="group.key" class="home-group">
<view class="home-group-title"><view class="home-group-mark" :class="`home-group-mark-${group.key}`"></view><text>{{ group.name }}</text><text class="home-group-count">{{ group.operations.length }}</text></view>
<view class="home-operation-grid">
<button v-for="operation in group.operations" :key="operation.name" class="home-operation" :class="{ 'home-operation-primary': operation.available, 'home-operation-disabled': !operation.available }" :disabled="!operation.available" @tap="openOperation(operation)">
<view class="home-operation-icon" aria-hidden="true"><uni-icons :type="operation.iconType" :color="operation.available ? '#135ee8' : '#9aa6b2'" size="28" /></view>
<text class="home-operation-name">{{ operation.name }}</text>
<text v-if="operation.available" class="home-operation-pending">可处理</text>
<text v-else class="home-operation-unavailable">暂未开放</text>
</button>
</view>
</view>
</view>
</view>
</template>
<script>
import PortalHeader from '@/components/PortalHeader.vue'
import { getCurrentWarehouseProfile } from '@/api/inbound.js'
import { MODULES } from '@/data/overseas-workbench.js'
import { applyWarehouseProfile, session, requireSession } from '@/stores/session.js'
const HOME_GROUPS = MODULES.map((module) => ({
...module,
available: module.operations.some((operation) => operation.available),
operations: module.operations.map((operation) => ({ ...operation, iconType: operation.iconType || 'circle' }))
}))
export default {
components: { PortalHeader },
data() { return { user: session.currentUser, groups: HOME_GROUPS, menuOpen: false } },
computed: {
availableCount() { return this.groups.reduce((total, group) => total + group.operations.filter((operation) => operation.available).length, 0) },
displayName() {
const name = String(this.user?.name || '').trim()
return name && !/^[a-z0-9._-]+$/i.test(name) ? name : '仓库作业员'
},
warehouseLabel() {
if (this.user?.warehouseName) return this.user.warehouseCode ? `${this.user.warehouseName} · ${this.user.warehouseCode}` : this.user.warehouseName
const warehouseId = String(this.user?.warehouseId || '')
if (warehouseId) return `当前作业仓 · ${warehouseId.slice(-6)}`
return this.user?.warehouse || '仓库由当前账号自动绑定'
},
greeting() {
const hour = new Date().getHours()
if (hour < 6) return '夜间作业请注意安全'
if (hour < 12) return '早上好'
if (hour < 18) return '下午好'
return '晚上好'
}
},
onShow() { if (!requireSession()) return; this.user = session.currentUser; this.loadWarehouseProfile() },
onBackPress() {
if (!this.menuOpen) return false
this.$refs.portalHeader.closeMenu()
return true
},
methods: {
async loadWarehouseProfile() {
try { this.user = applyWarehouseProfile(await getCurrentWarehouseProfile()) } catch (_) { this.user = session.currentUser }
},
openOperation(operation) {
if (!operation.available) return
const module = this.groups.find((group) => group.operations.some((item) => item.name === operation.name))
uni.navigateTo({ url: operation.route || `/pages/operation/operation?module=${module?.key || 'query'}&op=${operation.key}` })
}
}
}
</script>