门店页面修改

This commit is contained in:
2026-07-07 00:18:29 +08:00
parent 1fcafac2a7
commit 5d19089f91
11 changed files with 432 additions and 39 deletions
+22
View File
@@ -0,0 +1,22 @@
/** 从微信扫码结果解析核销 token32 位 hex 或带 token 参数的 URL */
export function parseRedeemTokenFromScan(raw: string): string | null {
const trimmed = raw.trim();
if (!trimmed) return null;
if (/^[a-f0-9]{32}$/i.test(trimmed)) {
return trimmed.toLowerCase();
}
try {
const url = trimmed.startsWith('http') ? new URL(trimmed) : new URL(trimmed, 'https://local.invalid');
const fromQuery = url.searchParams.get('token');
if (fromQuery && /^[a-f0-9]{32}$/i.test(fromQuery)) {
return fromQuery.toLowerCase();
}
} catch {
/* not a URL */
}
const hexMatch = trimmed.match(/[a-f0-9]{32}/i);
return hexMatch ? hexMatch[0].toLowerCase() : null;
}
+57
View File
@@ -0,0 +1,57 @@
import type { WechatLoginResult } from '@dukang/shared-types';
import { isWechatEnv, weixinSdk } from './weixin';
import { request, saveAuth, type ShopSessionPayload } from './api';
export type ShopAccountProfile = {
id: string;
storeId: string;
name: string;
phone: string;
wxOpenId?: string | null;
store?: { name: string };
};
export async function fetchShopAccount(): Promise<ShopAccountProfile> {
return request<ShopAccountProfile>('SHOP_H5', '/shop/auth/me');
}
export function needsWechatAuth(profile: ShopAccountProfile | null): boolean {
return isWechatEnv() && !!profile && !profile.wxOpenId;
}
export function sessionFromWechatLogin(result: WechatLoginResult): ShopSessionPayload | null {
if (!result.accessToken || !result.refreshToken) return null;
const store = result.store;
return {
accessToken: result.accessToken,
refreshToken: result.refreshToken,
store: store
? {
id: String(store.id ?? ''),
storeId: String(store.storeId ?? ''),
name: String(store.name ?? ''),
phone: String(store.phone ?? ''),
storeName: String(store.storeName ?? store.name ?? ''),
}
: undefined,
};
}
export function saveShopWechatAuth(result: WechatLoginResult): boolean {
const session = sessionFromWechatLogin(result);
if (!session) return false;
saveAuth(session);
return true;
}
export async function authorizeShopWechat(): Promise<WechatLoginResult | void> {
if (!isWechatEnv()) {
throw new Error('请在微信内打开以完成授权');
}
return weixinSdk.login();
}
export async function handleShopWechatCallback(): Promise<WechatLoginResult | null> {
if (!isWechatEnv()) return null;
return weixinSdk.handleOAuthCallback();
}
+1
View File
@@ -4,6 +4,7 @@ export const weixinSdk = createWeixinSdk({
apiBase: '/api/v1',
clientApp: 'SHOP_H5',
getAccessToken: () => localStorage.getItem('accessToken'),
wechatLoginPath: '/shop/auth/login/wechat',
});
export { isWechatEnv };