This commit is contained in:
Austin 2026-07-14 23:13:59 +08:00
parent be81b63b0e
commit 9d8b85987b
2 changed files with 69 additions and 41 deletions

View File

@ -1,5 +1,6 @@
import { APP_CONFIG } from '@/config'; import { APP_CONFIG } from '@/config';
import { HttpStatusError, httpRequest, toFormUrlEncoded } from '@/utils/http'; import { HttpStatusError, httpRequest, toFormUrlEncoded } from '@/utils/http';
import { postForm } from '@/utils/request';
export interface LoginResponse { export interface LoginResponse {
code: number | string; code: number | string;
@ -53,30 +54,25 @@ export const loginByCode = async (code: string) => {
/** @deprecated 使用 loginByCode */ /** @deprecated 使用 loginByCode */
export const loginByWechatCode = loginByCode; export const loginByWechatCode = loginByCode;
export interface MobileAuthBindResponse { export interface BindMobileResponse {
code: number | string; code: number | string;
msg?: string; msg?: string;
data?: unknown; data?: {
code?: string;
msg?: string;
mobile?: string;
};
} }
/** 小程序授权绑定手机号(微信/支付宝) */ /**
export const mobileAuthBind = async (code: string) => { *
const response = await httpRequest<MobileAuthBindResponse>({ * encryptedData = my.getPhoneNumber response.response
url: `${APP_CONFIG.API_BASE_URL}/user/v1/mobile.auth.bind`, * postForm Authorization: Bearer <token>
method: 'POST', */
data: toFormUrlEncoded({ export const bindMobile = (encryptedData: string) => {
code, return postForm<BindMobileResponse>('user/v1/bind.mobile', {
encryptedData,
app_id: APP_CONFIG.APP_ID, app_id: APP_CONFIG.APP_ID,
platform: resolveLoginPlatform() platform: resolveLoginPlatform()
}),
header: {
'content-type': 'application/x-www-form-urlencoded'
}
}); });
if (response.statusCode < 200 || response.statusCode >= 300) {
throw new HttpStatusError('手机号绑定失败', response.statusCode, response.data);
}
return response.data;
}; };

View File

@ -189,7 +189,7 @@ import { computed, ref } from 'vue';
import { onLoad, onShow } from '@dcloudio/uni-app'; import { onLoad, onShow } from '@dcloudio/uni-app';
import { bindMerchantByUrl, cancelTrade, changeMerchant, merchantListByUrl, supplierByUrl } from '@/api/cashier'; import { bindMerchantByUrl, cancelTrade, changeMerchant, merchantListByUrl, supplierByUrl } from '@/api/cashier';
import type { MerchantListItem } from '@/api/cashier'; import type { MerchantListItem } from '@/api/cashier';
import { mobileAuthBind, resolveLoginPlatform } from '@/api/auth'; import { bindMobile, resolveLoginPlatform } from '@/api/auth';
import { postForm } from '@/utils/request'; import { postForm } from '@/utils/request';
import { DEFAULT_MERCHANT, APP_CONFIG, PROPERTY_APP } from '@/config'; import { DEFAULT_MERCHANT, APP_CONFIG, PROPERTY_APP } from '@/config';
import { import {
@ -680,13 +680,46 @@ const refreshPropertyAfterPhoneBind = async () => {
alipayPropertyUnbound.value = true; alipayPropertyUnbound.value = true;
}; };
const extractAlipayPhoneCode = (phoneRes: any) => { const tryParseJson = (value: any) => {
const response = phoneRes?.response; if (typeof value !== 'string') return value;
if (typeof response === 'string') return response; const text = value.trim();
if (response && typeof response === 'object') { if (!text || (text[0] !== '{' && text[0] !== '[')) return value;
return response.response || response.code || ''; try {
return JSON.parse(text);
} catch {
return value;
} }
return phoneRes?.code || ''; };
/** 调试日志用:把嵌套 JSON 字符串展开成可展开对象 */
const toLogObject = (value: any, depth = 0): any => {
if (value == null || depth > 4) return value;
const parsed = tryParseJson(value);
if (Array.isArray(parsed)) {
return parsed.map((item) => toLogObject(item, depth + 1));
}
if (parsed && typeof parsed === 'object') {
const result: Record<string, any> = {};
Object.keys(parsed).forEach((key) => {
result[key] = toLogObject(parsed[key], depth + 1);
});
return result;
}
return parsed;
};
const logPhoneAuth = (label: string, payload?: any) => {
console.log(`[收银台][手机号授权] ${label}`, payload === undefined ? undefined : toLogObject(payload));
};
/** 取 getPhoneNumber 密文response.response */
const extractAlipayEncryptedData = (phoneRes: any) => {
const parsed = tryParseJson(phoneRes?.response);
if (parsed && typeof parsed === 'object') {
const encrypted = parsed.response;
return typeof encrypted === 'string' ? encrypted.trim() : '';
}
return typeof phoneRes?.response === 'string' ? phoneRes.response.trim() : '';
}; };
const requestAlipayPhoneNumber = () => const requestAlipayPhoneNumber = () =>
@ -708,36 +741,35 @@ const requestAlipayPhoneNumber = () =>
}); });
const handleAlipayPhoneAuthTap = () => { const handleAlipayPhoneAuthTap = () => {
console.log('[收银台][手机号授权] 按钮点击'); logPhoneAuth('按钮点击');
}; };
const handleAlipayPhoneAuthError = (event?: any) => { const handleAlipayPhoneAuthError = (event?: any) => {
console.log('[收银台][手机号授权] error 回调', event); logPhoneAuth('error 回调', event);
}; };
const handleAlipayPhoneAuthorize = async (event?: any) => { const handleAlipayPhoneAuthorize = async (event?: any) => {
console.log('[收银台][手机号授权] getAuthorize 回调', event); logPhoneAuth('getAuthorize 回调', event);
if (paying.value || bindingPhone.value) return; if (paying.value || bindingPhone.value) return;
bindingPhone.value = true; bindingPhone.value = true;
try { try {
const phoneRes = await requestAlipayPhoneNumber(); const phoneRes = await requestAlipayPhoneNumber();
console.log('[收银台][手机号授权] getPhoneNumber 成功', phoneRes); logPhoneAuth('getPhoneNumber 成功', phoneRes);
const code = extractAlipayPhoneCode(phoneRes); const encryptedData = extractAlipayEncryptedData(phoneRes);
console.log('[收银台][手机号授权] 解析 code', { logPhoneAuth('解析 encryptedData', {
code, encryptedData,
response: phoneRes?.response, response: tryParseJson(phoneRes?.response)
phoneCode: phoneRes?.code
}); });
if (!code) { if (!encryptedData) {
throw new Error('手机号授权失败'); throw new Error('手机号授权失败');
} }
const response = await mobileAuthBind(code); const response = await bindMobile(encryptedData);
console.log('[收银台][手机号授权] mobileAuthBind 响应', response); logPhoneAuth('bind.mobile 响应', response);
if (Number(response?.code) !== 200) { if (Number(response?.code) !== 200) {
throw new Error(response?.msg || '手机号绑定失败'); throw new Error(response?.msg || '手机号绑定失败');
@ -745,7 +777,7 @@ const handleAlipayPhoneAuthorize = async (event?: any) => {
await refreshPropertyAfterPhoneBind(); await refreshPropertyAfterPhoneBind();
} catch (error: any) { } catch (error: any) {
console.log('[收银台][手机号授权] 授权失败', error); logPhoneAuth('授权失败', error);
const errMsg = error?.errMsg || error?.message || ''; const errMsg = error?.errMsg || error?.message || '';
if (errMsg.includes('cancel') || errMsg.includes('拒绝')) return; if (errMsg.includes('cancel') || errMsg.includes('拒绝')) return;
uni.showToast({ uni.showToast({