微信登录日志

This commit is contained in:
2026-07-07 17:17:03 +08:00
parent 2c74f6a08c
commit 7e3c0011bb
4 changed files with 146 additions and 17 deletions
+78 -17
View File
@@ -7,6 +7,39 @@ export type ChooseWechatImageOptions = {
sourceType?: Array<'album' | 'camera'>;
};
async function reportChooseImageEvent(
config: WeixinSdkConfig,
payload: {
status: 'fail';
errMsg: string;
sourceType?: string;
stage: 'jssdk' | 'choose' | 'read' | 'empty';
},
) {
if (/cancel/i.test(payload.errMsg)) return;
try {
const headers: Record<string, string> = {
'Content-Type': 'application/json',
'X-Client-App': config.clientApp,
};
const token = config.getAccessToken?.();
if (token) headers.Authorization = `Bearer ${token}`;
await fetch(`${config.apiBase ?? '/api/v1'}/common/wechat/choose-image`, {
method: 'POST',
headers,
body: JSON.stringify({
status: 'fail',
errMsg: payload.errMsg,
sourceType: payload.sourceType,
stage: payload.stage,
pageUrl: typeof window !== 'undefined' ? window.location.href.split('#')[0] : undefined,
}),
});
} catch {
/* 上报失败不影响主流程 */
}
}
function base64ToFile(base64: string, fileName: string): File {
const normalized = base64.startsWith('data:')
? base64
@@ -52,30 +85,58 @@ export async function chooseWechatImages(
if (platform === 'wechat-h5') {
const pageUrl = typeof window !== 'undefined' ? window.location.href.split('#')[0] : '';
await ensureJssdkReady({
apiBase: config.apiBase ?? '/api/v1',
clientApp: config.clientApp,
getAccessToken: config.getAccessToken,
url: pageUrl,
jsApiList: ['chooseImage', 'getLocalImgData'],
});
const sourceTypeKey = sourceType.join(',');
try {
await ensureJssdkReady({
apiBase: config.apiBase ?? '/api/v1',
clientApp: config.clientApp,
getAccessToken: config.getAccessToken,
url: pageUrl,
jsApiList: ['chooseImage', 'getLocalImgData'],
});
} catch (e) {
const errMsg = e instanceof Error ? e.message : 'JSSDK 初始化失败';
void reportChooseImageEvent(config, { status: 'fail', errMsg, sourceType: sourceTypeKey, stage: 'jssdk' });
throw e;
}
if (!window.wx?.chooseImage) {
throw new Error('微信选图接口不可用,请刷新页面后重试');
const errMsg = '微信选图接口不可用,请刷新页面后重试';
void reportChooseImageEvent(config, { status: 'fail', errMsg, sourceType: sourceTypeKey, stage: 'jssdk' });
throw new Error(errMsg);
}
const localIds = await new Promise<string[]>((resolve, reject) => {
window.wx!.chooseImage!({
count,
sizeType: ['compressed'],
sourceType,
success: (res) => resolve(res.localIds ?? []),
fail: (err) => reject(new Error(err.errMsg || '无法打开相册')),
let localIds: string[];
try {
localIds = await new Promise<string[]>((resolve, reject) => {
window.wx!.chooseImage!({
count,
sizeType: ['compressed'],
sourceType,
success: (res) => resolve(res.localIds ?? []),
fail: (err) => reject(new Error(err.errMsg || '无法打开相册')),
});
});
});
} catch (e) {
const errMsg = e instanceof Error ? e.message : '无法打开相册';
void reportChooseImageEvent(config, { status: 'fail', errMsg, sourceType: sourceTypeKey, stage: 'choose' });
throw e;
}
if (!localIds.length) {
const errMsg = '未选择图片';
void reportChooseImageEvent(config, { status: 'fail', errMsg, sourceType: sourceTypeKey, stage: 'empty' });
return [];
}
const files: File[] = [];
for (const localId of localIds) {
files.push(await localIdToFile(localId));
try {
files.push(await localIdToFile(localId));
} catch (e) {
const errMsg = e instanceof Error ? e.message : '读取图片失败';
void reportChooseImageEvent(config, { status: 'fail', errMsg, sourceType: sourceTypeKey, stage: 'read' });
throw e;
}
}
return files;
}