import { defineStore } from 'pinia' import { uniStorage } from '@/utils/uniStorage' export interface SettlementSignContext { signTraceId: string subjectLocation: string createdAt: number } interface SettlementSignState { context?: SettlementSignContext returnedSignTraceId: string processingSignTraceId: string } const SIGN_CONTEXT_EXPIRE_TIME = 30 * 60 * 1000 const createSignTraceId = (subjectLocation: string): string => { return `${Date.now()}_${subjectLocation}` } export const useSettlementSignStore = defineStore('settlementSign', { state: (): SettlementSignState => ({ context: undefined, returnedSignTraceId: '', processingSignTraceId: '', }), getters: { validContext(state): SettlementSignContext | undefined { if (!state.context?.subjectLocation) return undefined const isExpired = Date.now() - state.context.createdAt > SIGN_CONTEXT_EXPIRE_TIME if (isExpired) return undefined return state.context }, pendingSubjectLocation(): string { return this.validContext?.subjectLocation || '' }, returnedContext(): SettlementSignContext | undefined { const context = this.validContext return context?.signTraceId === this.returnedSignTraceId ? context : undefined }, }, actions: { createContext(subjectLocation: string): SettlementSignContext { const context: SettlementSignContext = { signTraceId: createSignTraceId(subjectLocation), subjectLocation, createdAt: Date.now(), } this.context = context this.returnedSignTraceId = '' return context }, markReturned(subjectLocation: string, signTraceId: string): void { const context = this.validContext if ( !context || context.subjectLocation !== subjectLocation || context.signTraceId !== signTraceId || this.processingSignTraceId === signTraceId ) { return } this.returnedSignTraceId = signTraceId }, // query 回跳与 WebView 返回共用同一把锁,避免两个页面实例重复处理。 beginSignRedirect(subjectLocation: string, signTraceId: string): boolean { if (this.processingSignTraceId) return false const context = this.validContext if ( signTraceId && (context?.signTraceId !== signTraceId || context.subjectLocation !== subjectLocation) ) { return false } this.processingSignTraceId = signTraceId || (context?.subjectLocation === subjectLocation ? context.signTraceId : subjectLocation) this.returnedSignTraceId = '' return true }, finishSignRedirect(): void { this.processingSignTraceId = '' }, clearContext(signTraceId?: string): void { if (signTraceId && this.context?.signTraceId !== signTraceId) return this.context = undefined this.returnedSignTraceId = '' }, }, persist: { key: 'settlement-sign-store', storage: uniStorage, pick: ['context'], }, })