Replace QR login with OAuth button; auto-authorize register/bind; follow OA in settings; advisor text styling. Co-authored-by: Cursor <cursoragent@cursor.com>
97 lines
3.4 KiB
TypeScript
97 lines
3.4 KiB
TypeScript
import type { AxiosError } from 'axios';
|
||
import { axiosInstance } from '@/api/rbac';
|
||
import { omsUrl, unwrapData } from '@/api/oms/common';
|
||
import type {
|
||
WeChatCustomerBindInput,
|
||
WeChatCustomerRegisterInput,
|
||
WeChatCustomerRegisterResult,
|
||
WeChatOAuthUserInfo,
|
||
WxFollowQrcodeResult,
|
||
WxLoginQrcodeResult,
|
||
WxLoginResult,
|
||
} from './types';
|
||
|
||
export * from './types';
|
||
|
||
function unwrapOrSelf<T>(body: unknown): T {
|
||
if (body == null || typeof body !== 'object') {
|
||
return body as T;
|
||
}
|
||
const record = body as Record<string, unknown>;
|
||
if (
|
||
'qrCodeUrl' in record ||
|
||
'jumpUrl' in record ||
|
||
'accessToken' in record ||
|
||
'openid' in record
|
||
) {
|
||
return body as T;
|
||
}
|
||
return unwrapData<T>(body);
|
||
}
|
||
|
||
/** 获取微信公众号登录二维码(loginUuid 可选,不传则由后端生成 key) */
|
||
export async function getLoginQrcode(loginUuid?: string): Promise<WxLoginQrcodeResult> {
|
||
const res = await axiosInstance.get(omsUrl('/wechat/mp/login-qrcode'), {
|
||
params: loginUuid ? { loginUuid } : undefined,
|
||
});
|
||
return unwrapOrSelf<WxLoginQrcodeResult>(res.data);
|
||
}
|
||
|
||
/** 获取注册成功后跳转的公众号链接 */
|
||
export async function getFollowQrcode(): Promise<WxFollowQrcodeResult> {
|
||
const res = await axiosInstance.get(omsUrl('/wechat/mp/follow-qrcode'));
|
||
return unwrapOrSelf<WxFollowQrcodeResult>(res.data);
|
||
}
|
||
|
||
/** 查询扫码 key 是否已关联账号(轮询用,无值时不抛错) */
|
||
export async function getWxLoginStatus(loginUuid: string): Promise<WxLoginStatusResult> {
|
||
const res = await axiosInstance.get('/rbac/auth/wx-login/status', {
|
||
params: { loginUuid },
|
||
});
|
||
return unwrapOrSelf<WxLoginStatusResult>(res.data);
|
||
}
|
||
|
||
/** 是否属于「等待扫码」类错误(轮询时应静默继续) */
|
||
export function isWxLoginPendingError(error: unknown): boolean {
|
||
const axiosErr = error as AxiosError<{ message?: string; Message?: string }>;
|
||
const message =
|
||
axiosErr?.response?.data?.message ??
|
||
axiosErr?.response?.data?.Message ??
|
||
axiosErr?.message ??
|
||
'';
|
||
const pendingHints = ['请扫码', '扫码登录', '等待扫码', '未扫码'];
|
||
return pendingHints.some((hint) => message.includes(hint));
|
||
}
|
||
|
||
/** 微信扫码登录轮询 */
|
||
export async function wxLogin(loginUuid: string): Promise<WxLoginResult> {
|
||
const res = await axiosInstance.post('/rbac/auth/wx-login', { loginUuid });
|
||
return unwrapOrSelf<WxLoginResult>(res.data);
|
||
}
|
||
|
||
/** 微信网页授权登录(H5 点按钮,无需扫码) */
|
||
export async function wxOAuthLogin(code: string): Promise<WxLoginResult> {
|
||
const res = await axiosInstance.post('/rbac/auth/wx-oauth-login', { code });
|
||
return unwrapOrSelf<WxLoginResult>(res.data);
|
||
}
|
||
|
||
/** OAuth code 换取微信用户信息 */
|
||
export async function getOAuthUserInfo(code: string): Promise<WeChatOAuthUserInfo> {
|
||
const res = await axiosInstance.post(omsUrl('/wechat/oauth/user-info'), { code });
|
||
return unwrapOrSelf<WeChatOAuthUserInfo>(res.data);
|
||
}
|
||
|
||
/** 微信授权注册客户 */
|
||
export async function registerByWechat(
|
||
input: WeChatCustomerRegisterInput,
|
||
): Promise<WeChatCustomerRegisterResult> {
|
||
const res = await axiosInstance.post(omsUrl('/wechat/customer/register'), input);
|
||
return unwrapOrSelf<WeChatCustomerRegisterResult>(res.data);
|
||
}
|
||
|
||
/** 微信授权绑定已有客户 */
|
||
export async function bindByWechat(input: WeChatCustomerBindInput): Promise<void> {
|
||
const res = await axiosInstance.post(omsUrl('/wechat/customer/bind'), input);
|
||
unwrapOrSelf(res.data);
|
||
}
|