Commit b98979af by chunhong.mu

fix(*): 修正 mini 登录接口名并统一 SDK 错误提取

mini 的验证码登录与密码登录均无法登录:接口名写错,后端返回
HTTP 200 + rescode 9999 + "No signature of method"(不是 404),
在 Network 面板里看起来是成功的,极易误判。

问题来源:从 uniapp-mp-template 移植时带进来一份手写的
packages/mini/src/api/auth.ts,接口名为 snake_case,后端没有这些方法。
而 @common/sdk 里的 createLoginService/createVerifyService 才是正确实现
(admin/web 一直在用)。login.vue 恰好横跨两者——图形验证码与发短信走
SDK(正常),登录走手写实现(失败)。

已用测试后端逐个验证:
- loginWithPassword     返回"用户名或密码错误"(login_with_password  方法不存在)
- loginWithVerifyCode   返回"验证码不正确"(login_with_mobile  方法不存在)
- sendVerifyCode        返回"请输入正确的计算结果"(send_verifycode  方法不存在)
- bind_phone            在 anonymous/system.wechat 下
- 图形验证码不是接口,是同步拼 URL(get_image_code  方法不存在)

改动:
- mini 的 api/auth.ts 改为纯委托 @common/sdk 服务,删除手写实现;
  微信登录接 WechatLoginService,utils/sdk.ts 补 getWechatLoginService()
- 新增 @common/sdk 的 resolveSdkError():SDK 业务错误 reject 的是纯字符串
  (拦截器 Promise.reject(errorMsg)),网络错误才是对象,原先各包写的
  err?.message || "失败" 会把后端真实原因吞成兜底文案。admin/web/mini
  三个包的 auth-service 全部换上
- login.vue 不再直连 SDK:发短信走 services、验证码走 api,符合分层约定;
  图形验证码校验失败时自动换一张
- CLAUDE.md 加两条硬规则,ARCHITECTURE.md 补「登录/验证码接口一律走 SDK
  服务」对照表与「SDK 错误 reject 是字符串」说明

校验:pnpm lint 全绿,4 包 type-check 与 build:test 通过,
mini 产物中确认为 camelCase 接口名

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
parent 527c65d0
...@@ -212,9 +212,46 @@ common/sdk/src/ ...@@ -212,9 +212,46 @@ common/sdk/src/
| `uniAdapter` / `webAdapter` | HTTP 适配器 | | `uniAdapter` / `webAdapter` | HTTP 适配器 |
| `TokenManager` | Token 管理(`hasToken` / `saveToken2Storage` / `clearToken` / `setupStorage`) | | `TokenManager` | Token 管理(`hasToken` / `saveToken2Storage` / `clearToken` / `setupStorage`) |
| `createLoginService` / `createVerifyService` | 登录与验证码服务工厂 | | `createLoginService` / `createVerifyService` | 登录与验证码服务工厂 |
| `resolveSdkError` | 从 SDK reject 值中提取错误文案(见下方「错误处理」) |
| `buildImage` / `buildFilePath` | 图片/文件 URL 构建 | | `buildImage` / `buildFilePath` | 图片/文件 URL 构建 |
| `webMonitor` | 监控上报(需先 `setupEndpoint` 配置地址,未配置则不上报) | | `webMonitor` | 监控上报(需先 `setupEndpoint` 配置地址,未配置则不上报) |
#### 登录/验证码接口:一律走 SDK 服务,不要自己拼
平台的通行证接口名是 **camelCase**,且都挂在 `uniplat_base` + `anonymous/system.user` 下:
| 功能 | 正确接口名 | 常见误写 |
|------|-----------|---------|
| 密码登录 | `loginWithPassword` | ~~`login_with_password`~~ |
| 验证码登录 | `loginWithVerifyCode` | ~~`login_with_mobile`~~ |
| 发送短信验证码 | `sendVerifyCode` | ~~`send_verifycode`~~ |
| 微信绑定手机号登录 | `bind_phone`(在 `anonymous/system.wechat` 下) | — |
| 图形验证码 | **不是接口**`generateImage()` 同步拼图片 URL | ~~`get_image_code`~~ |
⚠️ 接口名写错时,后端返回的是 **HTTP 200 + `rescode: 9999` + `No signature of method: ...`**,不是 404。很容易被误判成参数问题或鉴权问题,排查时先确认接口名。
因此**不要在业务包里手写 `domainServicePost("login_with_password", ...)` 这类调用**,统一用 `createLoginService` / `createVerifyService` / `WechatLoginService`,接口名收敛在 `@common/sdk` 内部的枚举里。
#### 错误处理:SDK 的业务错误 reject 出来是字符串
uniplat-sdk 的响应拦截器:
- **业务错误**(HTTP 200 但 `rescode !== 0`)→ `Promise.reject(errorMsg)`,reject 值是**纯字符串**
- **网络/HTTP 错误**`Promise.reject(error.response.data || error)`,reject 值是**对象**
所以业务代码里写 `err?.message || "失败"` 会在最常见的业务错误分支上拿不到内容,把后端返回的真实原因(如「用户名或密码错误」)吞成兜底文案。统一用:
```typescript
import { resolveSdkError } from "@common/sdk"
try {
await passwordLogin(username, password)
}
catch (err) {
Toast.error(resolveSdkError(err, "登录失败"))
}
```
**导入约定**(重要): **导入约定**(重要):
```typescript ```typescript
......
...@@ -84,6 +84,8 @@ types/ 类型定义 ...@@ -84,6 +84,8 @@ types/ 类型定义
- 业务代码不要直接用 `import.meta.env`,一律从 `config` - 业务代码不要直接用 `import.meta.env`,一律从 `config`
- `api/` 里不操作 store、不跳路由,那是 `services/` 的事 - `api/` 里不操作 store、不跳路由,那是 `services/` 的事
- 登录成功必须同时做三件事:持久化 Token(`TokenManager.saveToken2Storage`)、同步 SDK 登录态(`sdk.core.loginByToken`)、写 store。已封装在各包 `services/auth-service.ts` 里,不要绕过 - 登录成功必须同时做三件事:持久化 Token(`TokenManager.saveToken2Storage`)、同步 SDK 登录态(`sdk.core.loginByToken`)、写 store。已封装在各包 `services/auth-service.ts` 里,不要绕过
- **登录/验证码类接口不要自己拼 `domainService`**,一律走 `@common/sdk``createLoginService` / `createVerifyService` / `WechatLoginService`。平台接口名是 **camelCase**`loginWithPassword` / `loginWithVerifyCode` / `sendVerifyCode`),写成 snake_case 后端会返回 `rescode: 9999` + `No signature of method`,而不是 404,很容易误判成参数问题
- **SDK 的业务错误 reject 出来的是纯字符串**(拦截器里 `Promise.reject(errorMsg)`),网络错误才是对象。统一用 `resolveSdkError(err, "兜底文案")` 提取,不要写 `err?.message || "失败"`——那样会把后端真实原因吞掉
- `@common/sdk` 根入口不导出小程序模块,小程序专属能力从 `@common/sdk/mini-program` 引入(避免 Web 包引入 `uni.*` 类型) - `@common/sdk` 根入口不导出小程序模块,小程序专属能力从 `@common/sdk/mini-program` 引入(避免 Web 包引入 `uni.*` 类型)
- `@common/sdk` 里不要写死任何域名/appid/client id,需要环境相关值就加到 `SdkConfig` - `@common/sdk` 里不要写死任何域名/appid/client id,需要环境相关值就加到 `SdkConfig`
......
/**
* SDK 错误信息提取
*
* uniplat-sdk 的响应拦截器对「业务错误」(HTTP 200 但 rescode !== 0)是
* `Promise.reject(errorMsg)` —— reject 出来的是**纯字符串**,不是 Error;
* 对「网络/HTTP 错误」则是 `Promise.reject(error.response.data || error)`,
* 此时是对象(可能带 msg / message)。
*
* 因此业务代码里常见的 `err?.message || "失败"` 会在最常见的业务错误分支上
* 拿不到内容,把后端返回的真实原因(如「用户名或密码错误」)吞掉。统一用本
* 方法提取。
*/
export function resolveSdkError(err: unknown, fallback = "请求失败"): string {
if (typeof err === "string") {
return err || fallback
}
if (err && typeof err === "object") {
const e = err as Record<string, any>
return e.msg || e.message || e.error || fallback
}
return fallback
}
// 错误信息提取
export { resolveSdkError } from "./error"
// 图片/文件 URL 构建 // 图片/文件 URL 构建
export { buildFilePath, buildImage } from "./image-builder" export { buildFilePath, buildImage } from "./image-builder"
......
...@@ -3,6 +3,9 @@ export { uniAdapter } from "./adapters/uni-adapter" ...@@ -3,6 +3,9 @@ export { uniAdapter } from "./adapters/uni-adapter"
export { webAdapter } from "./adapters/web-adapter" export { webAdapter } from "./adapters/web-adapter"
// 错误信息提取
export { resolveSdkError } from "./core/error"
// 图片/文件 URL 构建 // 图片/文件 URL 构建
export { buildFilePath, buildImage } from "./core/image-builder" export { buildFilePath, buildImage } from "./core/image-builder"
......
import { resolveSdkError } from '@common/sdk'
import { passwordLogin, sendSmsCode, smsLogin } from '@/api/auth' import { passwordLogin, sendSmsCode, smsLogin } from '@/api/auth'
import { sdk } from '@/api/request' import { sdk } from '@/api/request'
import { useAuthStore } from '@/stores/auth' import { useAuthStore } from '@/stores/auth'
...@@ -27,7 +28,7 @@ export async function handleSendSmsCode( ...@@ -27,7 +28,7 @@ export async function handleSendSmsCode(
return true return true
} }
catch (e: any) { catch (e: any) {
Toast.error(e?.message || '发送失败') Toast.error(resolveSdkError(e, '发送失败'))
return false return false
} }
} }
...@@ -44,7 +45,7 @@ export async function handleSmsLogin( ...@@ -44,7 +45,7 @@ export async function handleSmsLogin(
return true return true
} }
catch (e: any) { catch (e: any) {
Toast.error(e?.message || '登录失败') Toast.error(resolveSdkError(e, '登录失败'))
return false return false
} }
} }
...@@ -61,7 +62,7 @@ export async function handlePasswordLogin( ...@@ -61,7 +62,7 @@ export async function handlePasswordLogin(
return true return true
} }
catch (e: any) { catch (e: any) {
Toast.error(e?.message || '登录失败') Toast.error(resolveSdkError(e, '登录失败'))
return false return false
} }
} }
import { config } from "@/config" import type {
import { getSdk } from "@/utils/sdk" LoginRegisterResult,
RegisterChannel,
VerifyImageResult,
} from "@common/sdk"
import {
getLoginService,
getVerifyService,
getWechatLoginService,
} from "@/utils/sdk"
export interface LoginResult { export type { LoginRegisterResult, RegisterChannel, VerifyImageResult }
jwt: string
user_id?: string
mobile?: string
}
export interface RegisterChannel {
app?: string
scene?: string
channel?: string
app_store?: string
[key: string]: any
}
/**
* 获取微信登录 code
*/
export function getWxLoginCode(): Promise<string> {
return new Promise((resolve, reject) => {
uni.login({
provider: "weixin",
success: res => resolve(res.code),
fail: err => reject(err),
})
})
}
/** /**
* 微信小程序绑定手机号登录 * 获取图形验证码
*
* 注意:这是同步方法,SDK 只负责拼出图片 URL,实际加载由 `<image>` 完成。
* 因此拿不到验证码时不会 reject,需要判断 `img` 是否为空 + 监听 `<image>`
* 的 error 事件。
*/ */
export function miniProgramBindPhone( export function getVerifyImage(): VerifyImageResult {
code: string, return getVerifyService().generateImage()
encryptedData: string,
iv: string,
registerChannel: RegisterChannel = {},
): Promise<LoginResult> {
return getSdk().domainServicePost<any, any, LoginResult>(
"bind_phone",
{
data: {
appid: config.mpAppid,
code,
client_id: config.clientId,
encryptedData,
iv,
...registerChannel,
},
},
true, // 匿名接口
"uniplat_base",
"system.wechat",
config,
)
} }
/** /**
* 发送短信验证码 * 发送短信验证码
*
* @param mobile 手机号
* @param seed 图形验证码的 seed(来自 getVerifyImage)
* @param imgCode 用户填写的图形验证码
*/ */
export function sendSmsCode(mobile: string, imgCode: string): Promise<void> { export function sendSmsCode(mobile: string, seed: string, imgCode: string) {
return getSdk().domainServicePost<any, any, void>( return getVerifyService().sendVerifyCode(mobile, seed, imgCode)
"send_verifycode",
{
data: {
mobile,
img_code: imgCode,
client_id: config.clientId,
},
},
true,
"uniplat_base",
"anonymous/system.user",
config,
)
} }
/** /**
...@@ -82,62 +39,46 @@ export function sendSmsCode(mobile: string, imgCode: string): Promise<void> { ...@@ -82,62 +39,46 @@ export function sendSmsCode(mobile: string, imgCode: string): Promise<void> {
export function smsLogin( export function smsLogin(
mobile: string, mobile: string,
verifycode: string, verifycode: string,
registerChannel: RegisterChannel = {}, registerChannel?: RegisterChannel,
): Promise<LoginResult> { ) {
return getSdk().domainServicePost<any, any, LoginResult>( return getLoginService().verifyCodeLogin(mobile, verifycode, registerChannel)
"login_with_mobile",
{
data: {
mobile,
verifycode,
client_id: config.clientId,
...registerChannel,
},
},
true,
"uniplat_base",
"anonymous/system.user",
config,
)
} }
/** /**
* 密码登录 * 密码登录
*/ */
export function passwordLogin( export function passwordLogin(username: string, password: string) {
username: string, return getLoginService().login(username, password)
password: string,
registerChannel: RegisterChannel = {},
): Promise<LoginResult> {
return getSdk().domainServicePost<any, any, LoginResult>(
"login_with_password",
{
data: {
username,
password,
client_id: config.clientId,
...registerChannel,
},
},
true,
"uniplat_base",
"anonymous/system.user",
config,
)
} }
/** /**
* 获取图形验证码 * 获取微信登录 code(uni API,非 HTTP 请求)
*/
export function getWxLoginCode(): Promise<string> {
return new Promise((resolve, reject) => {
uni.login({
provider: "weixin",
success: res => resolve(res.code),
fail: err => reject(err),
})
})
}
/**
* 微信小程序绑定手机号登录
*/ */
export function getImageCode(): Promise<string> { export function miniProgramBindPhone(
return getSdk() appid: string,
.domainServiceGet<any, { img_code: string }>( code: string,
"get_image_code", encryptedData: string,
{}, iv: string,
true, registerChannel: RegisterChannel = {},
"uniplat_base", ) {
"system.user", return getWechatLoginService().miniProgramBindPhone(
config, appid,
) code,
.then(res => res.img_code) encryptedData,
iv,
registerChannel,
)
} }
export { export {
getImageCode, getVerifyImage,
getWxLoginCode, getWxLoginCode,
miniProgramBindPhone, miniProgramBindPhone,
passwordLogin, passwordLogin,
...@@ -7,7 +7,11 @@ export { ...@@ -7,7 +7,11 @@ export {
smsLogin, smsLogin,
} from "./auth" } from "./auth"
export type { LoginResult, RegisterChannel } from "./auth" export type {
LoginRegisterResult,
RegisterChannel,
VerifyImageResult,
} from "./auth"
export { fetchHomeData } from "./home" export { fetchHomeData } from "./home"
......
...@@ -154,11 +154,16 @@ import { SMS_COUNTDOWN } from "@common/utils/constants" ...@@ -154,11 +154,16 @@ import { SMS_COUNTDOWN } from "@common/utils/constants"
import { isPhone } from "@common/utils/regex" import { isPhone } from "@common/utils/regex"
import { onLoad } from "@dcloudio/uni-app" import { onLoad } from "@dcloudio/uni-app"
import { computed, reactive, ref } from "vue" import { computed, reactive, ref } from "vue"
import { getVerifyImage } from "@/api"
import { useToast } from "@/composables" import { useToast } from "@/composables"
import { handlePasswordLogin, handleSmsLogin } from "@/services" import {
import { getVerifyService } from "@/utils/sdk" handlePasswordLogin,
handleSendSmsCode,
handleSmsLogin,
} from "@/services"
const { error: toastError, success: toastSuccess } = useToast() // 成功提示统一由 services 层发出,这里只处理页面级校验提示
const { error: toastError } = useToast()
const activeTab = ref<"sms" | "password">("sms") const activeTab = ref<"sms" | "password">("sms")
...@@ -194,7 +199,7 @@ const imageCodeFailed = ref(false) ...@@ -194,7 +199,7 @@ const imageCodeFailed = ref(false)
// 同步拼 URL,加载失败由 <image> error 事件兜住 // 同步拼 URL,加载失败由 <image> error 事件兜住
function getVerifyCodeImg() { function getVerifyCodeImg() {
imageCodeFailed.value = false imageCodeFailed.value = false
imageCodeModel.value = getVerifyService().generateImage() imageCodeModel.value = getVerifyImage()
if (!imageCodeModel.value.img) { if (!imageCodeModel.value.img) {
imageCodeFailed.value = true imageCodeFailed.value = true
toastError("获取图形验证码失败,请检查 VITE_APP_UNIPLAT 配置") toastError("获取图形验证码失败,请检查 VITE_APP_UNIPLAT 配置")
...@@ -243,17 +248,21 @@ async function getCode() { ...@@ -243,17 +248,21 @@ async function getCode() {
} }
uni.showLoading({ title: "正在获取验证码", mask: true }) uni.showLoading({ title: "正在获取验证码", mask: true })
try { try {
await getVerifyService().sendVerifyCode( const ok = await handleSendSmsCode(
smsModel.mobile, smsModel.mobile,
imageCodeModel.value?.seed || "", imageCodeModel.value?.seed || "",
smsModel.imgCode, smsModel.imgCode,
) )
if (ok) {
startCodeCountdown()
}
else {
// 图形验证码错误时刷新一张新的
getVerifyCodeImg()
}
}
finally {
uni.hideLoading() uni.hideLoading()
toastSuccess("验证码已发送")
startCodeCountdown()
} catch (err: any) {
uni.hideLoading()
toastError(err?.msg || err?.message || "发送失败")
} }
} }
......
import { TokenManager } from "@common/sdk" import type { LoginRegisterResult, RegisterChannel } from "@common/sdk"
import { resolveSdkError, TokenManager } from "@common/sdk"
import { import {
getWxLoginCode, getWxLoginCode,
type LoginResult,
miniProgramBindPhone, miniProgramBindPhone,
passwordLogin, passwordLogin,
type RegisterChannel, sendSmsCode,
smsLogin, smsLogin,
} from "@/api" } from "@/api"
import { useToast } from "@/composables" import { useToast } from "@/composables"
...@@ -14,6 +14,28 @@ import { getSdk } from "@/utils/sdk" ...@@ -14,6 +14,28 @@ import { getSdk } from "@/utils/sdk"
const { success, error } = useToast() const { success, error } = useToast()
/**
* 发送短信验证码
*
* @param mobile 手机号
* @param seed 图形验证码的 seed
* @param imgCode 用户填写的图形验证码
*/
export async function handleSendSmsCode(
mobile: string,
seed: string,
imgCode: string,
): Promise<boolean> {
try {
await sendSmsCode(mobile, seed, imgCode)
success("验证码已发送")
return true
} catch (err: any) {
error(resolveSdkError(err, "发送失败"))
return false
}
}
/** 短信验证码登录 */ /** 短信验证码登录 */
export async function handleSmsLogin( export async function handleSmsLogin(
mobile: string, mobile: string,
...@@ -25,8 +47,8 @@ export async function handleSmsLogin( ...@@ -25,8 +47,8 @@ export async function handleSmsLogin(
saveLoginResult(result) saveLoginResult(result)
success("登录成功") success("登录成功")
return true return true
} catch { } catch (err: any) {
error("登录失败,请检查手机号与验证码") error(resolveSdkError(err, "登录失败"))
return false return false
} }
} }
...@@ -35,15 +57,14 @@ export async function handleSmsLogin( ...@@ -35,15 +57,14 @@ export async function handleSmsLogin(
export async function handlePasswordLogin( export async function handlePasswordLogin(
username: string, username: string,
password: string, password: string,
registerChannel: RegisterChannel = config.registerConfig || {},
): Promise<boolean> { ): Promise<boolean> {
try { try {
const result = await passwordLogin(username, password, registerChannel) const result = await passwordLogin(username, password)
saveLoginResult(result) saveLoginResult(result)
success("登录成功") success("登录成功")
return true return true
} catch { } catch (err: any) {
error("登录失败,请检查账号密码") error(resolveSdkError(err, "登录失败"))
return false return false
} }
} }
...@@ -57,6 +78,7 @@ export async function handleWxLogin( ...@@ -57,6 +78,7 @@ export async function handleWxLogin(
try { try {
const code = await getWxLoginCode() const code = await getWxLoginCode()
const result = await miniProgramBindPhone( const result = await miniProgramBindPhone(
config.mpAppid || "",
code, code,
encryptedData, encryptedData,
iv, iv,
...@@ -65,8 +87,8 @@ export async function handleWxLogin( ...@@ -65,8 +87,8 @@ export async function handleWxLogin(
saveLoginResult(result) saveLoginResult(result)
success("登录成功") success("登录成功")
return true return true
} catch { } catch (err: any) {
error("微信登录失败") error(resolveSdkError(err, "微信登录失败"))
return false return false
} }
} }
...@@ -77,7 +99,7 @@ export function handleLogout() { ...@@ -77,7 +99,7 @@ export function handleLogout() {
useUserInfo().clearUserInfo() useUserInfo().clearUserInfo()
} }
function saveLoginResult(result: LoginResult) { function saveLoginResult(result: LoginRegisterResult) {
// 持久化 Token,并同步到 SDK 的登录态 // 持久化 Token,并同步到 SDK 的登录态
TokenManager.saveToken2Storage(result.jwt) TokenManager.saveToken2Storage(result.jwt)
getSdk().core.loginByToken({ token: result.jwt }) getSdk().core.loginByToken({ token: result.jwt })
......
export { export {
handleLogout, handleLogout,
handlePasswordLogin, handlePasswordLogin,
handleSendSmsCode,
handleSmsLogin, handleSmsLogin,
handleWxLogin, handleWxLogin,
} from "./auth-service" } from "./auth-service"
import { Sdk as SdkBase, TokenManager, uniAdapter } from "@common/sdk" import { Sdk as SdkBase, TokenManager, uniAdapter } from "@common/sdk"
import { WechatLoginService } from "@common/sdk/mini-program"
import { createLoginService } from "@common/sdk/services/login-service" import { createLoginService } from "@common/sdk/services/login-service"
import { createVerifyService } from "@common/sdk/services/verify-service" import { createVerifyService } from "@common/sdk/services/verify-service"
import { config } from "@/config" import { config } from "@/config"
...@@ -47,6 +48,7 @@ class Sdk extends SdkBase { ...@@ -47,6 +48,7 @@ class Sdk extends SdkBase {
let sdkInstance: Sdk | null = null let sdkInstance: Sdk | null = null
let loginServiceInstance: ReturnType<typeof createLoginService> | null = null let loginServiceInstance: ReturnType<typeof createLoginService> | null = null
let verifyServiceInstance: ReturnType<typeof createVerifyService> | null = null let verifyServiceInstance: ReturnType<typeof createVerifyService> | null = null
let wechatLoginServiceInstance: WechatLoginService | null = null
/** /**
* 初始化 SDK(在 main.ts 的 createApp 中调用,幂等) * 初始化 SDK(在 main.ts 的 createApp 中调用,幂等)
...@@ -58,6 +60,7 @@ export function initSdk() { ...@@ -58,6 +60,7 @@ export function initSdk() {
sdkInstance = new Sdk() sdkInstance = new Sdk()
loginServiceInstance = createLoginService(sdkInstance.core, sdkInstance.clientId) loginServiceInstance = createLoginService(sdkInstance.core, sdkInstance.clientId)
verifyServiceInstance = createVerifyService(sdkInstance.core, sdkInstance.clientId) verifyServiceInstance = createVerifyService(sdkInstance.core, sdkInstance.clientId)
wechatLoginServiceInstance = new WechatLoginService(sdkInstance)
} }
export function getSdk() { export function getSdk() {
...@@ -80,3 +83,10 @@ export function getVerifyService() { ...@@ -80,3 +83,10 @@ export function getVerifyService() {
} }
return verifyServiceInstance! return verifyServiceInstance!
} }
export function getWechatLoginService() {
if (!wechatLoginServiceInstance) {
initSdk()
}
return wechatLoginServiceInstance!
}
import { resolveSdkError } from '@common/sdk'
import { passwordLogin, sendSmsCode, smsLogin } from '@/api/auth' import { passwordLogin, sendSmsCode, smsLogin } from '@/api/auth'
import { sdk } from '@/api/request' import { sdk } from '@/api/request'
import { useAuthStore } from '@/stores/auth' import { useAuthStore } from '@/stores/auth'
...@@ -21,7 +22,7 @@ export async function handleSendSmsCode( ...@@ -21,7 +22,7 @@ export async function handleSendSmsCode(
return true return true
} }
catch (e: any) { catch (e: any) {
Toast.error(e?.message || '发送失败') Toast.error(resolveSdkError(e, '发送失败'))
return false return false
} }
} }
...@@ -38,7 +39,7 @@ export async function handleSmsLogin( ...@@ -38,7 +39,7 @@ export async function handleSmsLogin(
return true return true
} }
catch (e: any) { catch (e: any) {
Toast.error(e?.message || '登录失败') Toast.error(resolveSdkError(e, '登录失败'))
return false return false
} }
} }
...@@ -55,7 +56,7 @@ export async function handlePasswordLogin( ...@@ -55,7 +56,7 @@ export async function handlePasswordLogin(
return true return true
} }
catch (e: any) { catch (e: any) {
Toast.error(e?.message || '登录失败') Toast.error(resolveSdkError(e, '登录失败'))
return false return false
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment