import { reactive } from 'vue'; import { optionalBoolean, getBindingSuccessState } from '@/utils/phone-bind.js'; import { useAssetStore } from './asset.js'; const PHONE_STATE_KEY = 'customerAssetPhoneState'; const emptyPhoneState = () => ({ customerPhone: null, assetPhoneBound: null, assetPhoneIsOwn: null, needBindPhone: null }); const savedPhoneState = uni.getStorageSync(PHONE_STATE_KEY); const token = uni.getStorageSync('token') || ''; const identifier = uni.getStorageSync('identifier') || ''; const phoneState = savedPhoneState?.token === token && savedPhoneState?.identifier === identifier && token ? { customerPhone: typeof savedPhoneState.customerPhone === 'string' ? savedPhoneState.customerPhone : null, assetPhoneBound: optionalBoolean(savedPhoneState.assetPhoneBound), assetPhoneIsOwn: optionalBoolean(savedPhoneState.assetPhoneIsOwn), needBindPhone: optionalBoolean(savedPhoneState.needBindPhone) } : emptyPhoneState(); const state = reactive({ token, assetToken: '', identifier, ...phoneState, phoneRevision: 0, isDevice: false, realNameStatus: 0, userInfo: uni.getStorageSync('userInfo') || { avatar: '', nickname: '' } }); export const useUserStore = () => { const persistPhoneState = () => { uni.setStorageSync(PHONE_STATE_KEY, { token: state.token, identifier: state.identifier, customerPhone: state.customerPhone, assetPhoneBound: state.assetPhoneBound, assetPhoneIsOwn: state.assetPhoneIsOwn, needBindPhone: state.needBindPhone }); }; const resetContext = () => { Object.assign(state, emptyPhoneState()); state.phoneRevision++; uni.removeStorageSync(PHONE_STATE_KEY); // The legacy per-asset cache mixed customer phones with asset phones. uni.removeStorageSync('phoneBindStatus'); useAssetStore().clearAsset(); }; const setToken = (token) => { if (state.token !== token) resetContext(); state.token = token; uni.setStorageSync('token', token); }; const setAssetToken = (assetToken) => { state.assetToken = assetToken; }; const setIdentifier = (identifier) => { if (state.identifier !== identifier) resetContext(); state.identifier = identifier; uni.setStorageSync('identifier', identifier); }; const setIsDevice = (isDevice) => { state.isDevice = isDevice; }; const setRealNameStatus = (status) => { state.realNameStatus = status; }; const setUserInfo = (userInfo) => { Object.assign(state.userInfo, userInfo); uni.setStorageSync('userInfo', userInfo); }; const setLoginPhoneState = (data) => { state.assetPhoneBound = optionalBoolean(data.asset_phone_bound); state.assetPhoneIsOwn = optionalBoolean(data.asset_phone_is_own); state.needBindPhone = optionalBoolean(data.need_bind_phone); // A required prompt with an already-bound asset means only the customer // needs a phone. Other login combinations do not expose the customer phone. if (state.assetPhoneBound === true && state.needBindPhone === true) state.customerPhone = ''; persistPhoneState(); }; const setCustomerPhone = (phone) => { if (typeof phone !== 'string') return; state.customerPhone = phone; persistPhoneState(); }; const completePhoneBinding = (phone, mode) => { Object.assign(state, getBindingSuccessState(state, phone, mode)); state.phoneRevision++; persistPhoneState(); }; const completeCustomerPhoneChange = (phone) => { state.customerPhone = phone; state.assetPhoneIsOwn = null; state.phoneRevision++; persistPhoneState(); }; const clearUser = () => { resetContext(); state.token = ''; state.assetToken = ''; state.identifier = ''; state.isDevice = false; state.realNameStatus = 0; state.userInfo = { avatar: '', nickname: '' }; uni.removeStorageSync('token'); uni.removeStorageSync('identifier'); uni.removeStorageSync('userInfo'); }; return { state, setToken, setAssetToken, setIdentifier, setIsDevice, setRealNameStatus, setUserInfo, setLoginPhoneState, setCustomerPhone, completePhoneBinding, completeCustomerPhoneChange, clearUser }; };