import { getStoreBenefitAPI, getStoreVipListAPI } from "@/apis"; import useStore from "@/store"; // 按账号隔离最近选择,刷新登录令牌后仍可恢复同一门店。 const selectionKey = () => { const version = uni.getAccountInfoSync().miniProgram.envVersion; return `${version}_experience_store_${useStore().user.id || "guest"}`; }; export const getSelectedExperienceStore = () => { const value = uni.getStorageSync(selectionKey()); return value && /^\d+$/.test(String(value.id)) && Number(value.id) > 0 ? { id: String(value.id), name: String(value.name || "") } : null; }; export const rememberExperienceStore = (id, name) => { uni.setStorageSync(selectionKey(), { id: String(id), name }); }; // 入口汇总所有门店;找到有效会员即可结束,未开通须查询完整列表。 export const hasAnyStoreVip = async () => { const pageSize = 20; let received = 0; for (let page = 1; ; page += 1) { const result = await getStoreVipListAPI({ page, pageSize }); const list = result?.list; if (!Array.isArray(list) || !Number.isSafeInteger(result.total) || result.total < 0) { throw new Error("门店会员列表响应格式异常"); } if (list.some((item) => item?.isVip === true)) return true; if (list.some((item) => typeof item?.isVip !== "boolean")) { throw new Error("门店会员状态缺失"); } received += list.length; if (received >= result.total) return false; // 列表尚未读完却返回空页时,不把不完整结果判为未开通。 if (!list.length) throw new Error("门店会员列表分页异常"); } }; // 只接受非负整数,缺失或异常值不能转换成“已用完”的 0 次。 const normalizeRemaining = (benefit) => { const remain = benefit?.remain; return Number.isSafeInteger(remain) && remain >= 0 ? remain : "--"; }; export const normalizeStoreMembership = (store) => { if (typeof store?.isVip !== "boolean") throw new Error("门店会员状态缺失"); const active = store.isVip === true; return { active, cardImage: `https://static.shelingxingqiu.com/shootmini/static/coin/store-vip-card-${active ? "active" : "inactive"}.png`, expiresAt: active ? String(store.vipExpireAt || "").slice(0, 10).replace(/-/g, "/") || "--" : "", // 未开通或已过期统一为 0;有效会员逐项读取后端剩余次数。 remaining: { trial: active ? normalizeRemaining(store.freeTrial) : 0, discount: active ? normalizeRemaining(store.discountPurchase) : 0, drink: active ? normalizeRemaining(store.drink) : 0, }, }; }; export const loadStoreMembership = async (storeId) => { const result = await getStoreBenefitAPI(storeId); if (String(result?.storeId) !== String(storeId)) { throw new Error("门店权益响应与当前门店不匹配"); } return { name: result.storeName || "", ...normalizeStoreMembership(result) }; };