优化
This commit is contained in:
@@ -7,12 +7,25 @@
|
||||
<view class="profile-row"><text>作业仓库</text><text class="profile-value">{{ warehouseDisplay }}</text></view>
|
||||
<view class="profile-row"><text>当前班次</text><text class="profile-value">以海外仓排班为准</text></view>
|
||||
<view class="profile-row"><text>应用版本</text><text class="profile-value">{{ appVersion }}</text></view>
|
||||
<button class="profile-row profile-row-action" @tap="checkUpdate"><text>检查更新</text><text class="profile-row-arrow">›</text></button>
|
||||
<button class="profile-row profile-row-action" @tap="checkUpdate" :disabled="checkingUpdate"><text>{{ checkingUpdate ? '检查中…' : '检查更新' }}</text><text class="profile-row-arrow">›</text></button>
|
||||
<button class="profile-row profile-row-action" @tap="showSettings"><text>系统设置</text><text class="profile-row-arrow">›</text></button>
|
||||
<button class="profile-row profile-row-action" @tap="selectLanguage"><text>切换语言</text><view class="profile-row-end"><text class="profile-value">{{ languageLabel }}</text><text class="profile-row-arrow">›</text></view></button>
|
||||
</view>
|
||||
<button class="logout-action" @tap="openLogout">退出登录</button>
|
||||
</view>
|
||||
<uni-popup ref="languagePopup" type="bottom" background-color="transparent" :is-mask-click="true" @change="handleLanguageChange">
|
||||
<view class="language-sheet" role="dialog" aria-modal="true" aria-label="选择语言">
|
||||
<PopupHeader title="选择语言" @close="closeLanguage" />
|
||||
<view class="language-options" role="radiogroup" aria-label="可选语言">
|
||||
<button v-for="item in languageOptions" :key="item.value" class="language-option" :class="{ selected: locale === item.value }" role="radio" :aria-checked="locale === item.value" @tap="applyLanguage(item.value)">
|
||||
<text class="language-option-name">{{ item.label }}</text>
|
||||
<view v-if="locale === item.value" class="language-option-current"><text>已选择</text><uni-icons type="checkmarkempty" color="#135ee8" size="20" /></view>
|
||||
</button>
|
||||
</view>
|
||||
<text class="language-sheet-hint">业务页面暂以中文显示,语言偏好将保存在本机。</text>
|
||||
<button class="language-cancel" @tap="closeLanguage">取消</button>
|
||||
</view>
|
||||
</uni-popup>
|
||||
<uni-popup ref="logoutPopup" type="center" :is-mask-click="true" @change="handleLogoutChange"><view class="logout-dialog-card" role="dialog" aria-modal="true" aria-label="确认退出登录"><PopupHeader title="确认退出登录?" tone="danger" @close="closeLogout" /><text class="logout-dialog-content">退出会撤销当前登录会话并清空本地作业草稿;未提交作业数据不得跨账号保留。</text><view class="logout-dialog-actions"><button class="logout-dialog-cancel" @tap="closeLogout">取消</button><button class="logout-dialog-confirm" @tap="logout">确认退出</button></view></view></uni-popup>
|
||||
<view v-if="toast" class="app-toast warning" role="status">设置功能将在后续版本开放</view>
|
||||
</view>
|
||||
@@ -20,6 +33,7 @@
|
||||
<script>
|
||||
import PortalHeader from '@/components/PortalHeader.vue'
|
||||
import PopupHeader from '@/components/PopupHeader.vue'
|
||||
import appManifest from '@/manifest.json'
|
||||
import { getCurrentWarehouseProfile } from '@/api/inbound.js'
|
||||
import { currentLocale, LOCALE_OPTIONS, setLocale } from '@/i18n/index.js'
|
||||
import { applyWarehouseProfile, session, requireSession, getSessionRevision } from '@/stores/session.js'
|
||||
@@ -27,7 +41,7 @@
|
||||
import { checkForAppUpdate } from '@/utils/app-update.js'
|
||||
export default {
|
||||
components: { PopupHeader, PortalHeader },
|
||||
data() { return { user: session.currentUser, appVersion: '0.0.1', locale: currentLocale(), logoutOpen: false, toast: false } },
|
||||
data() { return { user: session.currentUser, appVersion: appManifest.versionName, checkingUpdate: false, locale: currentLocale(), languageOptions: LOCALE_OPTIONS, languageOpen: false, logoutOpen: false, toast: false } },
|
||||
computed: {
|
||||
displayName() { const name = String(this.user?.name || ''); return name && !/^[a-z0-9._-]+$/i.test(name) ? name : '仓库作业员' },
|
||||
avatar() { return this.displayName.slice(0, 1).toUpperCase() },
|
||||
@@ -35,34 +49,47 @@
|
||||
warehouseDisplay() { return String(this.user?.warehouseName || '').trim() || '海外仓未关联' },
|
||||
languageLabel() { return LOCALE_OPTIONS.find((item) => item.value === this.locale)?.label || 'English' }
|
||||
},
|
||||
onShow() { if (!requireSession()) return; this.user = session.currentUser; this.loadAppVersion(); this.loadWarehouseProfile() },
|
||||
onShow() { if (!requireSession()) return; this.user = session.currentUser; this.locale = currentLocale(); this.loadAppVersion(); this.loadWarehouseProfile() },
|
||||
beforeUnmount() { clearTimeout(this._toastTimer) },
|
||||
onBackPress() { if (!this.logoutOpen) return false; this.closeLogout(); return true },
|
||||
onBackPress() { if (this.languageOpen) { this.closeLanguage(); return true }; if (!this.logoutOpen) return false; this.closeLogout(); return true },
|
||||
methods: {
|
||||
loadAppVersion() {
|
||||
this.appVersion = appManifest.versionName
|
||||
// #ifdef APP-PLUS
|
||||
if (typeof plus === 'undefined' || !plus.runtime) return
|
||||
this.appVersion = String(plus.runtime.version || this.appVersion)
|
||||
plus.runtime.getProperty(plus.runtime.appid, (properties) => {
|
||||
this.appVersion = String(properties?.version || plus.runtime.version || appManifest.versionName)
|
||||
})
|
||||
// #endif
|
||||
},
|
||||
checkUpdate() {
|
||||
// #ifdef APP-PLUS
|
||||
checkForAppUpdate({ manual: true })
|
||||
return
|
||||
// #endif
|
||||
// #ifndef APP-PLUS
|
||||
uni.showToast({ title: '请在 PDA App 中检查更新', icon: 'none' })
|
||||
// #endif
|
||||
async checkUpdate() {
|
||||
if (this.checkingUpdate) return
|
||||
this.checkingUpdate = true
|
||||
try {
|
||||
// #ifdef APP-PLUS
|
||||
await checkForAppUpdate({ manual: true })
|
||||
return
|
||||
// #endif
|
||||
// #ifndef APP-PLUS
|
||||
uni.showToast({ title: '请在 PDA App 中检查更新', icon: 'none' })
|
||||
// #endif
|
||||
} finally { this.checkingUpdate = false }
|
||||
},
|
||||
selectLanguage() {
|
||||
uni.showActionSheet({
|
||||
itemList: LOCALE_OPTIONS.map((item) => item.label),
|
||||
success: ({ tapIndex }) => {
|
||||
const selected = LOCALE_OPTIONS[tapIndex]
|
||||
if (!selected) return
|
||||
this.locale = setLocale(selected.value)
|
||||
uni.showToast({ title: `语言设置已保存:${selected.label}`, icon: 'none' })
|
||||
}
|
||||
})
|
||||
this.languageOpen = true
|
||||
this.$refs.languagePopup.open()
|
||||
},
|
||||
closeLanguage() { this.languageOpen = false; this.$refs.languagePopup.close() },
|
||||
handleLanguageChange(event) { this.languageOpen = Boolean(event.show) },
|
||||
applyLanguage(value) {
|
||||
const selected = LOCALE_OPTIONS.find((item) => item.value === value)
|
||||
if (!selected) return
|
||||
if (selected.value !== this.locale) {
|
||||
this.locale = setLocale(selected.value)
|
||||
uni.showToast({ title: `语言偏好已保存:${selected.label}`, icon: 'none' })
|
||||
}
|
||||
this.closeLanguage()
|
||||
},
|
||||
async loadWarehouseProfile() { try { this.user = applyWarehouseProfile(await getCurrentWarehouseProfile()) } catch (_) { this.user = session.currentUser } },
|
||||
openLogout() { this.logoutOpen = true; this.$refs.logoutPopup.open() }, closeLogout() { this.logoutOpen = false; this.$refs.logoutPopup.close() }, handleLogoutChange(event) { this.logoutOpen = Boolean(event.show) },
|
||||
@@ -83,3 +110,17 @@
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.profile-row-end{flex-shrink:0}
|
||||
.profile-row-end .profile-value{max-width:none;flex-shrink:0;white-space:nowrap;overflow-wrap:normal}
|
||||
.language-sheet{box-sizing:border-box;width:100%;max-width:480px;margin:0 auto;padding:4px 16px calc(16px + env(safe-area-inset-bottom,0px));border-radius:20px 20px 0 0;background:#fff}
|
||||
.language-options{display:flex;flex-direction:column;gap:8px;margin-top:8px}
|
||||
.language-option{display:flex;box-sizing:border-box;align-items:center;justify-content:space-between;gap:12px;width:100%;min-height:52px;margin:0;padding:12px 14px;border:1px solid #dce5f0;border-radius:10px;color:#1f2937;font-size:15px;line-height:22px;text-align:left;background:#fff}
|
||||
.language-option::after,.language-cancel::after{border:0}
|
||||
.language-option.selected{border-color:#b8d1f5;color:#135ee8;background:#f1f6ff}
|
||||
.language-option-name{min-width:0;white-space:nowrap}
|
||||
.language-option-current{display:flex;flex-shrink:0;align-items:center;gap:6px;color:#135ee8;font-size:12px;line-height:20px}
|
||||
.language-sheet-hint{display:block;margin:12px 2px;color:#718095;font-size:11px;line-height:18px}
|
||||
.language-cancel{display:flex;align-items:center;justify-content:center;width:100%;min-height:44px;margin:0;padding:0 12px;border:1px solid #dce5f0;border-radius:10px;color:#526174;font-size:14px;line-height:22px;background:#f7f9fc}
|
||||
</style>
|
||||
|
||||
@@ -146,7 +146,8 @@ test('Chinese English and Spanish locale selection is persisted from profile wit
|
||||
for (const label of ['简体中文', 'English', 'Español']) assert.match(i18n, new RegExp(label))
|
||||
assert.match(profile, /currentLocale, LOCALE_OPTIONS, setLocale/)
|
||||
assert.match(profile, /@tap="selectLanguage"[\s\S]*切换语言/)
|
||||
assert.match(profile, /uni\.showActionSheet[\s\S]*setLocale\(selected\.value\)/)
|
||||
assert.match(profile, /ref="languagePopup"[\s\S]*role="radiogroup"/)
|
||||
assert.match(profile, /applyLanguage\(value\)[\s\S]*setLocale\(selected\.value\)/)
|
||||
assert.match(inbound, /warehouse-profile/)
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user