fix: some
All checks were successful
构建并部署前端到生产环境 / build-and-deploy (push) Successful in 2m59s

This commit is contained in:
luo
2026-10-13 14:53:19 +08:00
parent 77b0e25011
commit da95a914e3
31 changed files with 1702 additions and 116 deletions

View File

@@ -1,12 +1,30 @@
import { reactive, ref } from 'vue';
import { reactive } from 'vue';
import { isCurrentSession } from '@/utils/session-context.js';
import { getShanghaiDay, normalizeExpiryReminder } from '@/utils/expiry-reminder.js';
const receivedReminders = new Set();
const state = reactive({
assetInfo: null,
deviceRealtime: null,
currentPackage: null
currentPackage: null,
expiryReminder: null
});
export const useAssetStore = () => {
const receiveExpiryReminder = (context, value) => {
const reminder = normalizeExpiryReminder(value);
if (!reminder || !isCurrentSession(context)) return;
const day = getShanghaiDay();
const key = JSON.stringify([context.token, context.identifier, day]);
if (receivedReminders.has(key)) return;
receivedReminders.add(key);
state.expiryReminder = { ...context, day, reminder, shown: false };
};
const markExpiryReminderShown = () => {
if (state.expiryReminder) state.expiryReminder.shown = true;
};
const dismissExpiryReminder = () => { state.expiryReminder = null; };
const setAssetInfo = (info) => {
state.assetInfo = info;
};
@@ -23,6 +41,8 @@ export const useAssetStore = () => {
state.assetInfo = null;
state.deviceRealtime = null;
state.currentPackage = null;
state.expiryReminder = null;
receivedReminders.clear();
};
return {
@@ -30,6 +50,9 @@ export const useAssetStore = () => {
setAssetInfo,
setDeviceRealtime,
setCurrentPackage,
receiveExpiryReminder,
markExpiryReminderShown,
dismissExpiryReminder,
clearAsset
};
};
};

View File

@@ -1,9 +1,32 @@
import { reactive, ref } from 'vue';
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: uni.getStorageSync('token') || '',
token,
assetToken: '',
identifier: uni.getStorageSync('identifier') || '',
identifier,
...phoneState,
phoneRevision: 0,
isDevice: false,
realNameStatus: 0,
userInfo: uni.getStorageSync('userInfo') || {
@@ -13,7 +36,25 @@ const state = reactive({
});
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);
};
@@ -23,6 +64,7 @@ export const useUserStore = () => {
};
const setIdentifier = (identifier) => {
if (state.identifier !== identifier) resetContext();
state.identifier = identifier;
uni.setStorageSync('identifier', identifier);
};
@@ -40,7 +82,34 @@ export const useUserStore = () => {
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 = '';
@@ -60,6 +129,10 @@ export const useUserStore = () => {
setIsDevice,
setRealNameStatus,
setUserInfo,
setLoginPhoneState,
setCustomerPhone,
completePhoneBinding,
completeCustomerPhoneChange,
clearUser
};
};