2026-08-20 20:10:20 +08:00
|
|
|
|
<template>
|
2026-08-26 16:50:25 +08:00
|
|
|
|
<view v-if="user" class="page-shell portal-page">
|
|
|
|
|
|
<PortalHeader :title="$t('profile.title')" :user="user" :show-profile="false" />
|
|
|
|
|
|
<view class="portal-content profile-content">
|
|
|
|
|
|
<view class="profile-card"><view class="profile-avatar">{{ avatar }}</view><view><text class="profile-name">{{ displayName }}</text><text class="profile-role">{{ user.role }} · {{ user.id }}</text></view></view>
|
|
|
|
|
|
<view class="profile-list">
|
|
|
|
|
|
<view class="profile-row"><text>{{ $t('profile.warehouse') }}</text><text class="profile-value">{{ warehouseDisplay }}</text></view>
|
|
|
|
|
|
<view class="profile-row"><text>{{ $t('profile.shift') }}</text><text class="profile-value">{{ $t('profile.shiftValue') }}</text></view>
|
|
|
|
|
|
<view class="profile-row"><text>{{ $t('profile.version') }}</text><text class="profile-value">0.1.0</text></view>
|
|
|
|
|
|
<picker mode="selector" :range="localeLabels" :value="localeIndex" @change="changeLocale"><view class="profile-row language-row"><text>{{ $t('profile.language') }}</text><text class="profile-value">{{ localeLabels[localeIndex] }} ›</text></view></picker>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<button class="profile-action" @tap="showSettings">{{ $t('profile.settings') }} <text>›</text></button>
|
|
|
|
|
|
<button class="logout-action" @tap="openLogout">{{ $t('profile.logout') }}</button>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<uni-popup ref="logoutPopup" type="center" :is-mask-click="true" @change="handleLogoutChange"><view class="logout-dialog-card" role="dialog" aria-modal="true" :aria-label="$t('profile.logoutTitle')"><PopupHeader :title="$t('profile.logoutTitle')" tone="danger" @close="closeLogout" /><text class="logout-dialog-content">{{ $t('profile.logoutDescription') }}</text><view class="logout-dialog-actions"><button class="logout-dialog-cancel" @tap="closeLogout">{{ $t('common.cancel') }}</button><button class="logout-dialog-confirm" @tap="logout">{{ $t('common.confirm') }}</button></view></view></uni-popup>
|
|
|
|
|
|
<view v-if="toast" class="app-toast warning" role="status">{{ $t('profile.settingsLater') }}</view>
|
|
|
|
|
|
</view>
|
2026-08-20 20:10:20 +08:00
|
|
|
|
</template>
|
|
|
|
|
|
<script>
|
2026-08-26 16:50:25 +08:00
|
|
|
|
import PortalHeader from '@/components/PortalHeader.vue'
|
|
|
|
|
|
import PopupHeader from '@/components/PopupHeader.vue'
|
|
|
|
|
|
import { getCurrentWarehouseProfile } from '@/api/inbound.js'
|
|
|
|
|
|
import { currentLocale, LOCALE_OPTIONS, setLocale } from '@/i18n/index.js'
|
|
|
|
|
|
import { applyWarehouseProfile, session, requireSession, signOut } from '@/stores/session.js'
|
|
|
|
|
|
export default {
|
|
|
|
|
|
components: { PopupHeader, PortalHeader },
|
|
|
|
|
|
data() { return { user: session.currentUser, logoutOpen: false, toast: false, locale: currentLocale() } },
|
|
|
|
|
|
computed: {
|
|
|
|
|
|
localeLabels() { return LOCALE_OPTIONS.map((item) => this.$t(item.labelKey)) },
|
|
|
|
|
|
localeIndex() { const index = LOCALE_OPTIONS.findIndex((item) => item.value === this.locale); return Math.max(0, index) },
|
|
|
|
|
|
displayName() { const name = String(this.user?.name || ''); return name && !/^[a-z0-9._-]+$/i.test(name) ? name : this.$t('common.warehouseOperator') },
|
|
|
|
|
|
avatar() { return this.displayName.slice(0, 1).toUpperCase() },
|
|
|
|
|
|
warehouseDisplay() { return this.user?.warehouseName ? (this.user.warehouseCode ? `${this.user.warehouseName} · ${this.user.warehouseCode}` : this.user.warehouseName) : (this.user?.warehouse || this.$t('profile.warehousePending')) }
|
|
|
|
|
|
},
|
|
|
|
|
|
onShow() { if (!requireSession()) return; this.user = session.currentUser; this.locale = currentLocale(); this.loadWarehouseProfile() },
|
|
|
|
|
|
beforeUnmount() { clearTimeout(this._toastTimer) },
|
|
|
|
|
|
onBackPress() { if (!this.logoutOpen) return false; this.closeLogout(); return true },
|
|
|
|
|
|
methods: {
|
|
|
|
|
|
async loadWarehouseProfile() { try { this.user = applyWarehouseProfile(await getCurrentWarehouseProfile()) } catch (_) { this.user = session.currentUser } },
|
|
|
|
|
|
changeLocale(event) { this.locale = setLocale(LOCALE_OPTIONS[Number(event.detail.value)]?.value || 'en') },
|
|
|
|
|
|
openLogout() { this.logoutOpen = true; this.$refs.logoutPopup.open() }, closeLogout() { this.logoutOpen = false; this.$refs.logoutPopup.close() }, handleLogoutChange(event) { this.logoutOpen = Boolean(event.show) },
|
|
|
|
|
|
showSettings() { clearTimeout(this._toastTimer); this.toast = true; this._toastTimer = setTimeout(() => { this.toast = false }, 2200) },
|
|
|
|
|
|
logout() { signOut(); uni.reLaunch({ url: '/pages/login/login' }) }
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2026-08-20 20:10:20 +08:00
|
|
|
|
</script>
|