/** * MotherShip 登录态刷价 hold 状态(Redis) */ import { MS_REFINE_HOLD_REDIS_PREFIX, MS_REFINE_MSG, MS_REFINE_TOTAL_MS, type MsRefineHoldState, buildMsRefineHoldState, isMsRefineHoldExpired, } from "@/lib/constants/ms-refine-hold"; import { withBoundedRedis } from "@/lib/redis"; function key(sessionId: string): string { return `${MS_REFINE_HOLD_REDIS_PREFIX}${sessionId}`; } function ttlSeconds(): number { return Math.ceil(MS_REFINE_TOTAL_MS / 1000) + 30; } export async function saveMsRefineHold( state: MsRefineHoldState, ): Promise { const ok = await withBoundedRedis((redis) => redis.setex( key(state.quote_session_id), ttlSeconds(), JSON.stringify(state), ), ); if (ok === null) { console.warn("[ms-refine-hold] save skipped: Redis 不可达"); } } export async function readMsRefineHold( sessionId: string, ): Promise { const raw = await withBoundedRedis((redis) => redis.get(key(sessionId))); if (!raw) return null; try { return JSON.parse(raw) as MsRefineHoldState; } catch { return null; } } export async function readMsRefineHoldByQuoteId( quoteId: string, ): Promise { const sid = await withBoundedRedis((redis) => redis.get(`${MS_REFINE_HOLD_REDIS_PREFIX}by_quote:${quoteId}`), ); if (!sid) return null; return readMsRefineHold(sid); } export async function createMsRefineHold(input: { quoteId: string; sessionId: string; customerId: string; }): Promise { const state = buildMsRefineHoldState(input); await saveMsRefineHold(state); await withBoundedRedis((redis) => redis.setex( `${MS_REFINE_HOLD_REDIS_PREFIX}by_quote:${input.quoteId}`, ttlSeconds(), input.sessionId, ), ); return state; } export async function updateMsRefineHoldStatus( sessionId: string, status: MsRefineHoldState["status"], ): Promise { const cur = await readMsRefineHold(sessionId); if (!cur) return null; const next = { ...cur, status }; await saveMsRefineHold(next); return next; } export async function clearMsRefineHold(sessionId: string): Promise { const cur = await readMsRefineHold(sessionId); await withBoundedRedis(async (redis) => { await redis.del(key(sessionId)); if (cur?.quote_id) { await redis.del( `${MS_REFINE_HOLD_REDIS_PREFIX}by_quote:${cur.quote_id}`, ); } }); } export async function assertMsRefineHoldUsable( sessionId: string, ): Promise { const state = await readMsRefineHold(sessionId); if (!state) { throw new Error("刷价会话不存在或已释放"); } if (isMsRefineHoldExpired(state)) { throw new Error(MS_REFINE_MSG.sessionGone); } if (state.status === "declined" || state.status === "expired") { throw new Error(MS_REFINE_MSG.sessionGone); } if (state.status === "refined") { throw new Error("该报价已完成更新"); } return state; }