添加登录和后端校验

完成后端设计(未在本仓库体现),通过安全的手段完成了登录鉴权
This commit is contained in:
2026-08-06 16:27:36 +08:00
commit b19a56003f
286 changed files with 51650 additions and 0 deletions
+90
View File
@@ -0,0 +1,90 @@
import http, { setToken, clearToken, getToken } from './request'
export { getToken }
/**
* 后端 API 方法集合
* 对应 wxmp_backend 的路由(见后端 Swagger /docs
* 说明:登录会调用后端 /api/auth/login,成功后把 accessToken 存入本地,
* 供后续请求自动携带。购物车/订单等仍可用本地 store.ts 作为离线兜底。
*/
export interface LoginResult {
accessToken: string
isNewUser: boolean // 首次登录(未设资料)为 true,前端需引导补填头像/姓名
nickname: string | null
avatar: string | null
}
/**
* 登录:把 wx.login() 的 code 交给后端,后端用 code2Session 换 openid
* 自动注册/续登并签发 accessToken(个人主体无需手机号)。
* 返回 isNewUser 供前端判断是否需补全资料。
*/
export async function login(code: string): Promise<LoginResult> {
const data = await http.post<LoginResult>('/api/auth/login', { code }, { auth: false })
if (data?.accessToken) {
setToken(data.accessToken)
}
return data
}
/** 更新当前用户资料(昵称/头像),新用户在补填后提交到后端持久化 */
export async function updateProfile(profile: { nickname?: string; avatar?: string }): Promise<UserProfile> {
return http.patch<UserProfile>('/api/users/me', profile)
}
/**
* 首次注册:用 registerTicket + wx.getPhoneNumber 的 code 验证手机号,完成后自动登录
*/
export async function registerWithPhone(
registerTicket: string,
phoneCode: string,
profile?: { nickname?: string; avatar?: string },
): Promise<{ accessToken: string }> {
const data = await http.post<{ accessToken: string }>(
'/api/auth/register',
{ registerTicket, phoneCode, ...profile },
{ auth: false },
)
setToken(data.accessToken)
return data
}
/** 登出:仅清除本地 token(后端 JWT 无状态,无需撤销) */
export function logout(): void {
clearToken()
}
/** 后端用户信息(对应 User 模型;openpid 为主标识,openid 可空) */
export interface UserProfile {
id: string
openpid?: string | null
openid?: string | null
unionid?: string | null
nickname?: string | null
avatar?: string | null
phone?: string | null
createdAt?: string
updatedAt?: string
}
/** 获取当前登录用户信息 */
export async function getMe(): Promise<UserProfile> {
return http.get<UserProfile>('/api/users/me')
}
/** 商品列表 */
export async function fetchProducts() {
return http.get('/api/products', { auth: false })
}
/** 商品详情 */
export async function fetchProduct(id: string) {
return http.get(`/api/products/${id}`, { auth: false })
}
/** 分类列表 */
export async function fetchCategories() {
return http.get('/api/categories', { auth: false })
}