Files
QSY-lvjuxcx/utils/app-state.js
liangjian 9fee2c3a74 feat: 优化首页服务入口与租住业务流程
补齐首页待办跳转、押金支付引导和多类租住服务页面能力,统一租客端关键业务流程体验。
2026-08-25 13:53:12 +08:00

432 lines
13 KiB
JavaScript

import store from '@/store'
const STORAGE_KEYS = {
REGISTERED_USER: 'registeredUser',
AUTH_TOKEN: 'authToken',
AUTH_TOKEN_EXPIRES: 'authTokenExpires',
IS_LOGIN: 'isLogin',
USER_INFO: 'userInfo',
HAS_CHECKED_IN: 'hasCheckedIn',
MY_ROOM_DATA: 'myRoomData',
CURRENT_BOOKING: 'currentBooking',
BOOKING_LIST: 'bookingList',
PENDING_CONTRACTS: 'pendingContracts',
PENDING_CONTRACT_COUNT: 'pendingContractCount',
EFFECTIVE_CONTRACTS: 'effectiveContracts',
MY_APPLICATION: 'myApplication',
ACTIVE_APPLICATION_CODE: 'activeApplicationCode',
FAILED_REGISTRATION_DRAFT: 'failedRegistrationDraft',
HOME_PAGE_TAB_ID: 'homePageTabId',
MESSAGE_LIST: 'messageList',
SERVICE_ORDER_LIST: 'serviceOrderList',
UTILITY_RECHARGE_LIST: 'utilityRechargeList',
LEGACY_DEMO_CACHE_CLEARED: 'legacyDemoCacheCleared'
}
function getStorage(key, fallback = null) {
const value = uni.getStorageSync(key)
return value === '' || typeof value === 'undefined' ? fallback : value
}
function getStoreState() {
return (store && store.state) || {}
}
function getStoreUser() {
const user = getStoreState().vuex_user
return user && typeof user === 'object' ? user : {}
}
function getStorePendingContracts() {
const list = getStoreState().vuex_pending_contracts
return Array.isArray(list) ? list : []
}
function getStoreEffectiveContracts() {
const list = getStoreState().vuex_effective_contracts
return Array.isArray(list) ? list : []
}
function getStoreValidOrders() {
const list = getStoreState().vuex_valid_orders
return Array.isArray(list) ? list : []
}
function getStoreCurrentOrder() {
return getStoreState().vuex_current_order || null
}
function buildRoomDataFromOrder(order = {}) {
if (!order || typeof order !== 'object' || !Object.keys(order).length) {
return null
}
const imageUrls = Array.isArray(order.imageUrls)
? order.imageUrls
: typeof order.imageUrls === 'string'
? order.imageUrls.split(',').map(item => item.trim()).filter(Boolean)
: []
const roomLabel = [
order.buildingName || order.buildingSectionName || order.unitName || '',
order.roomNo || order.roomCode || order.roomName || ''
].filter(Boolean).join(' ')
const title = [
order.areaName || order.campusName || '',
order.roomTypeName || order.roomType || ''
].filter(Boolean).join(' · ')
const start = String(order.contractStartTime || order.startDate || order.start || order.checkinDate || '').slice(0, 10)
const end = String(order.contractEndTime || order.endDate || order.end || order.checkoutDate || '').slice(0, 10)
return {
...order,
id: roomLabel || order.roomNo || order.roomCode || order.orderNo || '',
roomLabel: roomLabel || order.roomNo || order.roomCode || '',
titleZh: title || order.roomTypeName || order.roomName || '当前入住房间',
titleEn: order.roomTypeNameEn || title || order.roomTypeName || 'Current Stay',
leaseText: [start, end].filter(Boolean).join(' - '),
image: order.imageUrl || imageUrls[0] || ''
}
}
function clearStoreSessionState() {
if (!store || !store.commit) {
return
}
store.commit('$tStore', { name: 'vuex_user', value: {} })
store.commit('$tStore', { name: 'vuex_checkin_status', value: false })
store.commit('$tStore', { name: 'vuex_current_order', value: null })
store.commit('$tStore', { name: 'vuex_pending_contracts', value: [] })
store.commit('$tStore', { name: 'vuex_pending_contract_count', value: 0 })
store.commit('$tStore', { name: 'vuex_effective_contracts', value: [] })
store.commit('$tStore', { name: 'vuex_valid_orders', value: [] })
}
export { STORAGE_KEYS }
export function getRegisteredUser() {
return getStorage(STORAGE_KEYS.REGISTERED_USER, null)
}
export function saveRegisteredUser(user) {
uni.setStorageSync(STORAGE_KEYS.REGISTERED_USER, user)
return user
}
export function getCurrentUser() {
return getStorage(STORAGE_KEYS.USER_INFO, null)
}
export function saveCurrentUser(user) {
uni.setStorageSync(STORAGE_KEYS.USER_INFO, user)
return user
}
export function getLoginStatus() {
return !!getStorage(STORAGE_KEYS.IS_LOGIN, false)
}
export function setLoginStatus(isLogin) {
uni.setStorageSync(STORAGE_KEYS.IS_LOGIN, !!isLogin)
return !!isLogin
}
export function getAuthToken() {
return getStorage(STORAGE_KEYS.AUTH_TOKEN, '')
}
export function saveAuthToken(token) {
uni.setStorageSync(STORAGE_KEYS.AUTH_TOKEN, token || '')
return token || ''
}
export function clearAuthToken() {
uni.removeStorageSync(STORAGE_KEYS.AUTH_TOKEN)
}
export function getAuthTokenExpires() {
return getStorage(STORAGE_KEYS.AUTH_TOKEN_EXPIRES, '')
}
export function saveAuthTokenExpires(expires) {
uni.setStorageSync(STORAGE_KEYS.AUTH_TOKEN_EXPIRES, expires || '')
return expires || ''
}
export function clearAuthTokenExpires() {
uni.removeStorageSync(STORAGE_KEYS.AUTH_TOKEN_EXPIRES)
}
export function startLoginSession(user) {
setLoginStatus(true)
saveCurrentUser(user)
if (store && store.commit) {
store.commit('$tStore', {
name: 'vuex_user',
value: user && typeof user === 'object' ? user : {}
})
}
return user
}
export function startAuthorizedLoginSession(user, token, expires) {
if (token) saveAuthToken(token)
if (expires) saveAuthTokenExpires(expires)
return startLoginSession(user)
}
export function registerAndLogin(user) {
saveRegisteredUser(user)
startLoginSession(user)
return user
}
export function clearLoginSession() {
clearAuthToken()
clearAuthTokenExpires()
uni.removeStorageSync('lifeData')
clearStoreSessionState()
clearBookingState()
clearContractState()
clearMyRoomData()
uni.removeStorageSync(STORAGE_KEYS.HAS_CHECKED_IN)
uni.removeStorageSync(STORAGE_KEYS.IS_LOGIN)
uni.removeStorageSync(STORAGE_KEYS.USER_INFO)
uni.removeStorageSync(STORAGE_KEYS.MY_APPLICATION)
uni.removeStorageSync(STORAGE_KEYS.ACTIVE_APPLICATION_CODE)
}
export function getCheckedInStatus() {
return !!getStorage(STORAGE_KEYS.HAS_CHECKED_IN, false)
}
export function setCheckedInStatus(hasCheckedIn) {
uni.setStorageSync(STORAGE_KEYS.HAS_CHECKED_IN, !!hasCheckedIn)
return !!hasCheckedIn
}
export function getMyRoomData() {
return getStorage(STORAGE_KEYS.MY_ROOM_DATA, null)
}
export function saveMyRoomData(roomData) {
uni.setStorageSync(STORAGE_KEYS.MY_ROOM_DATA, roomData)
return roomData
}
export function clearMyRoomData() {
uni.removeStorageSync(STORAGE_KEYS.MY_ROOM_DATA)
}
export function getCurrentBooking() {
return getStorage(STORAGE_KEYS.CURRENT_BOOKING, null)
}
export function saveCurrentBooking(booking) {
uni.setStorageSync(STORAGE_KEYS.CURRENT_BOOKING, booking)
return booking
}
export function getBookingList() {
return getStorage(STORAGE_KEYS.BOOKING_LIST, [])
}
export function saveBookingList(list) {
uni.setStorageSync(STORAGE_KEYS.BOOKING_LIST, list)
return list
}
export function clearBookingState() {
uni.removeStorageSync(STORAGE_KEYS.CURRENT_BOOKING)
uni.removeStorageSync(STORAGE_KEYS.BOOKING_LIST)
}
export function getPendingContracts() {
return getStorage(STORAGE_KEYS.PENDING_CONTRACTS, [])
}
export function savePendingContracts(list) {
uni.setStorageSync(STORAGE_KEYS.PENDING_CONTRACTS, list || [])
return list || []
}
export function getPendingContractCount() {
return Number(getStorage(STORAGE_KEYS.PENDING_CONTRACT_COUNT, 0) || 0)
}
export function savePendingContractCount(count) {
const nextCount = Number(count || 0)
uni.setStorageSync(STORAGE_KEYS.PENDING_CONTRACT_COUNT, nextCount)
return nextCount
}
export function getEffectiveContracts() {
return getStorage(STORAGE_KEYS.EFFECTIVE_CONTRACTS, [])
}
export function saveEffectiveContracts(list) {
uni.setStorageSync(STORAGE_KEYS.EFFECTIVE_CONTRACTS, list || [])
return list || []
}
function patchContractListSign(list = [], contractNo = '', signImageUrl = '') {
const targetNo = String(contractNo || '').trim()
const targetSignImageUrl = String(signImageUrl || '').trim()
if (!targetNo || !Array.isArray(list) || !list.length) {
return Array.isArray(list) ? list : []
}
return list.map(item => {
const currentNo = String((item && (item.no || item.contractNo)) || '').trim()
if (currentNo !== targetNo) {
return item
}
return {
...item,
signImageUrl: targetSignImageUrl || item.signImageUrl || ''
}
})
}
export function patchStoredContractSign(contractNo, signImageUrl) {
const nextPendingContracts = patchContractListSign(getPendingContracts(), contractNo, signImageUrl)
const nextEffectiveContracts = patchContractListSign(getEffectiveContracts(), contractNo, signImageUrl)
savePendingContracts(nextPendingContracts)
saveEffectiveContracts(nextEffectiveContracts)
return {
pendingContracts: nextPendingContracts,
effectiveContracts: nextEffectiveContracts
}
}
export function clearContractState() {
uni.removeStorageSync(STORAGE_KEYS.PENDING_CONTRACTS)
uni.removeStorageSync(STORAGE_KEYS.PENDING_CONTRACT_COUNT)
uni.removeStorageSync(STORAGE_KEYS.EFFECTIVE_CONTRACTS)
}
export function getListStorage(key) {
return getStorage(key, [])
}
export function saveListStorage(key, list) {
uni.setStorageSync(key, list)
return list
}
export function prependListStorage(key, item) {
const currentList = getListStorage(key)
const nextList = [item, ...currentList]
saveListStorage(key, nextList)
return nextList
}
export function getMyApplicationList() {
return getListStorage(STORAGE_KEYS.MY_APPLICATION)
}
export function saveMyApplicationList(list) {
return saveListStorage(STORAGE_KEYS.MY_APPLICATION, list || [])
}
export function getActiveApplicationCode() {
return getStorage(STORAGE_KEYS.ACTIVE_APPLICATION_CODE, '')
}
export function saveActiveApplicationCode(code) {
const nextCode = code || ''
uni.setStorageSync(STORAGE_KEYS.ACTIVE_APPLICATION_CODE, nextCode)
return nextCode
}
export function getFailedRegistrationDraft() {
return getStorage(STORAGE_KEYS.FAILED_REGISTRATION_DRAFT, null)
}
export function saveFailedRegistrationDraft(draft) {
const nextDraft = draft && typeof draft === 'object' ? draft : null
if (!nextDraft) {
uni.removeStorageSync(STORAGE_KEYS.FAILED_REGISTRATION_DRAFT)
return null
}
uni.setStorageSync(STORAGE_KEYS.FAILED_REGISTRATION_DRAFT, nextDraft)
return nextDraft
}
export function clearFailedRegistrationDraft() {
uni.removeStorageSync(STORAGE_KEYS.FAILED_REGISTRATION_DRAFT)
}
export function getHomePageTabId() {
return getStorage(STORAGE_KEYS.HOME_PAGE_TAB_ID, '')
}
export function saveHomePageTabId(tabId) {
const nextTabId = tabId || ''
uni.setStorageSync(STORAGE_KEYS.HOME_PAGE_TAB_ID, nextTabId)
return nextTabId
}
export function buildHomePageUrl(tabId) {
const nextTabId = tabId || getHomePageTabId()
return nextTabId
? `/pages/index/index?pageId=${encodeURIComponent(nextTabId)}`
: '/pages/index/index'
}
export function getSessionSnapshot() {
const storeUser = getStoreUser()
const storageCurrentUser = getCurrentUser() || {}
const registeredUser = getRegisteredUser() || {}
const currentUser = Object.keys(storeUser).length ? storeUser : storageCurrentUser
const resolvedUser = Object.keys(currentUser).length ? currentUser : registeredUser
const storeCurrentOrder = getStoreCurrentOrder()
const storeBookingList = getStoreValidOrders()
const storePendingContracts = getStorePendingContracts()
const storeEffectiveContracts = getStoreEffectiveContracts()
const currentBooking = resolvedUser.currentBooking || getCurrentBooking()
const pendingContractCount = storePendingContracts.length || getPendingContractCount()
const hasCheckedIn = !!(resolvedUser.hasCheckedIn || getStoreState().vuex_checkin_status || getCheckedInStatus())
const myRoomData = hasCheckedIn
? (getMyRoomData() || buildRoomDataFromOrder(storeCurrentOrder))
: null
const isLogin = getLoginStatus() || !!Object.keys(currentUser).length
return {
isLogin,
currentUser,
registeredUser,
resolvedUser,
hasCheckedIn: isLogin && hasCheckedIn,
currentBooking,
bookingList: storeBookingList.length ? storeBookingList : getBookingList(),
myRoomData,
pendingContracts: storePendingContracts.length ? storePendingContracts : getPendingContracts(),
pendingContractCount,
effectiveContracts: storeEffectiveContracts.length ? storeEffectiveContracts : getEffectiveContracts()
}
}
export function clearLegacyDemoCache() {
if (uni.getStorageSync(STORAGE_KEYS.LEGACY_DEMO_CACHE_CLEARED)) {
return
}
;[
STORAGE_KEYS.CURRENT_BOOKING,
STORAGE_KEYS.BOOKING_LIST,
STORAGE_KEYS.MY_APPLICATION,
STORAGE_KEYS.MESSAGE_LIST,
STORAGE_KEYS.SERVICE_ORDER_LIST,
STORAGE_KEYS.UTILITY_RECHARGE_LIST
].forEach(key => {
uni.removeStorageSync(key)
})
uni.setStorageSync(STORAGE_KEYS.LEGACY_DEMO_CACHE_CLEARED, true)
}