238 lines
7.5 KiB
JavaScript
238 lines
7.5 KiB
JavaScript
|
|
|
|||
|
|
import api from '@/api/http'
|
|||
|
|
import { setToken, getRefreshToken } from '@/utils/auth'
|
|||
|
|
|
|||
|
|
const SERVER_BASE = import.meta.env.VITE_BASE_URL + '/app-api/member'
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 保存 token 的辅助函数
|
|||
|
|
* @param {Object} info - 包含 accessToken 和 refreshToken 的对象
|
|||
|
|
*/
|
|||
|
|
function saveTokens(info) {
|
|||
|
|
if (info?.accessToken || info?.refreshToken) {
|
|||
|
|
setToken({
|
|||
|
|
accessToken: info.accessToken || '',
|
|||
|
|
refreshToken: info.refreshToken || '',
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 响应拦截(可选):统一错误处理
|
|||
|
|
*/
|
|||
|
|
// api.interceptors.response.use(
|
|||
|
|
// (resp) => resp,
|
|||
|
|
// (err) => {
|
|||
|
|
// // 统一错误日志/提示
|
|||
|
|
// return Promise.reject(err);
|
|||
|
|
// }
|
|||
|
|
// );
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 短信场景枚举(请与后端配置保持一致)
|
|||
|
|
* - MEMBER_LOGIN: 会员短信登录场景
|
|||
|
|
* - MEMBER_UPDATE_PASSWORD: 已登录用户修改密码(短信校验)场景
|
|||
|
|
* - MEMBER_RESET_PASSWORD: 未登录用户忘记密码重置(短信校验)场景
|
|||
|
|
* 如有"注册"独立场景,可在此添加:MEMBER_REGISTER: 13
|
|||
|
|
*/
|
|||
|
|
export const SMS_SCENE = {
|
|||
|
|
MEMBER_LOGIN: 1,
|
|||
|
|
MEMBER_UPDATE_PASSWORD: 3,
|
|||
|
|
MEMBER_RESET_PASSWORD: 4,
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 短信模板编码常量
|
|||
|
|
*/
|
|||
|
|
export const SMS_TEMPLATE_CODE = {
|
|||
|
|
USER_REGISTER: 'muye-user-code', // 用户注册模板编码
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 账号密码登录
|
|||
|
|
* POST /member/auth/login
|
|||
|
|
*
|
|||
|
|
* @param {string} mobile - 手机号(必填)
|
|||
|
|
* @param {string} password - 密码(必填,长度 4-16)
|
|||
|
|
* @returns {Promise<Object>} data.data: { accessToken, refreshToken, expiresTime, userInfo }
|
|||
|
|
*/
|
|||
|
|
export async function loginByPassword(mobile, password) {
|
|||
|
|
const { data } = await api.post(`${SERVER_BASE}/auth/login`, { mobile, password });
|
|||
|
|
const info = data || {};
|
|||
|
|
saveTokens(info);
|
|||
|
|
return info;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 发送短信验证码
|
|||
|
|
* POST /member/auth/send-sms-code
|
|||
|
|
*
|
|||
|
|
* @param {string} mobile - 手机号(登录/忘记密码等需要;修改密码场景可不传)
|
|||
|
|
* @param {number} scene - 短信场景(见 SMS_SCENE)
|
|||
|
|
* @param {string} templateCode - 模板编码(可选,如 'muye-user-code')
|
|||
|
|
* @returns {Promise<Object>} 后端通用响应结构
|
|||
|
|
*/
|
|||
|
|
export async function sendSmsCode(mobile, scene, templateCode) {
|
|||
|
|
const body = { scene };
|
|||
|
|
if (mobile) body.mobile = mobile; // 修改密码场景后端会根据当前登录用户自动填充手机号
|
|||
|
|
if (templateCode) body.templateCode = templateCode; // 添加模板编码参数
|
|||
|
|
const { data } = await api.post(`${SERVER_BASE}/auth/send-sms-code`, body);
|
|||
|
|
return data;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 校验短信验证码(可选前置校验,一般直接在业务接口 use)
|
|||
|
|
* POST /member/auth/validate-sms-code
|
|||
|
|
*
|
|||
|
|
* @param {string} mobile - 手机号(必填)
|
|||
|
|
* @param {string} code - 验证码(必填,4-6 位数字)
|
|||
|
|
* @param {number} scene - 短信场景(必填,见 SMS_SCENE)
|
|||
|
|
* @returns {Promise<Object>} 后端通用响应结构
|
|||
|
|
*/
|
|||
|
|
export async function validateSmsCode(mobile, code, scene) {
|
|||
|
|
const { data } = await api.post(`${SERVER_BASE}/auth/validate-sms-code`, { mobile, code, scene });
|
|||
|
|
return data;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 手机+验证码登录(首次即自动注册)
|
|||
|
|
* POST /member/auth/sms-login
|
|||
|
|
*
|
|||
|
|
* @param {string} mobile - 手机号(必填)
|
|||
|
|
* @param {string} code - 短信验证码(必填)
|
|||
|
|
* @returns {Promise<Object>} data.data: { accessToken, refreshToken, expiresTime, userInfo }
|
|||
|
|
*/
|
|||
|
|
export async function loginBySms(mobile, code) {
|
|||
|
|
const { data } = await api.post(`${SERVER_BASE}/auth/sms-login`, { mobile, code });
|
|||
|
|
const info = data || {};
|
|||
|
|
saveTokens(info);
|
|||
|
|
return info;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 刷新令牌
|
|||
|
|
* POST /member/auth/refresh-token?refreshToken=xxx
|
|||
|
|
*
|
|||
|
|
* @returns {Promise<Object>} data.data: { accessToken, refreshToken, expiresTime, userInfo }
|
|||
|
|
*/
|
|||
|
|
export async function refreshToken() {
|
|||
|
|
const rt = getRefreshToken();
|
|||
|
|
if (!rt) throw new Error('缺少 refresh_token');
|
|||
|
|
// refreshToken 作为 URL 查询参数传递
|
|||
|
|
const { data } = await api.post(`${SERVER_BASE}/auth/refresh-token`, null, { params: { refreshToken: rt } });
|
|||
|
|
const info = data || {};
|
|||
|
|
saveTokens(info);
|
|||
|
|
return info;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 登录态下:发送“修改密码”验证码
|
|||
|
|
* - 场景:SMS_SCENE.MEMBER_UPDATE_PASSWORD
|
|||
|
|
* - 特性:后端会以当前登录用户的手机号为准,无需传 mobile
|
|||
|
|
* POST /member/auth/send-sms-code
|
|||
|
|
*
|
|||
|
|
* @returns {Promise<Object>} 后端通用响应结构
|
|||
|
|
*/
|
|||
|
|
export async function sendUpdatePasswordCode() {
|
|||
|
|
const { data } = await api.post(`${SERVER_BASE}/auth/send-sms-code`, {
|
|||
|
|
scene: SMS_SCENE.MEMBER_UPDATE_PASSWORD,
|
|||
|
|
});
|
|||
|
|
return data;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 登录态下:通过短信验证码修改密码
|
|||
|
|
* PUT /member/user/update-password
|
|||
|
|
*
|
|||
|
|
* @param {string} newPassword - 新密码(必填,4-16 位)
|
|||
|
|
* @param {string} smsCode - 短信验证码(必填,4-6 位数字)
|
|||
|
|
* @returns {Promise<Object>} 后端通用响应结构
|
|||
|
|
*/
|
|||
|
|
export async function updatePasswordBySmsCode(newPassword, smsCode) {
|
|||
|
|
const { data } = await api.put(`${SERVER_BASE}/user/update-password`, {
|
|||
|
|
password: newPassword,
|
|||
|
|
code: smsCode,
|
|||
|
|
});
|
|||
|
|
return data;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 未登录:发送“忘记密码”验证码
|
|||
|
|
* - 场景:SMS_SCENE.MEMBER_RESET_PASSWORD
|
|||
|
|
* POST /member/auth/send-sms-code
|
|||
|
|
*
|
|||
|
|
* @param {string} mobile - 手机号(必填)
|
|||
|
|
* @returns {Promise<Object>} 后端通用响应结构
|
|||
|
|
*/
|
|||
|
|
export async function sendResetPasswordCode(mobile) {
|
|||
|
|
const { data } = await api.post(`${SERVER_BASE}/auth/send-sms-code`, {
|
|||
|
|
mobile,
|
|||
|
|
scene: SMS_SCENE.MEMBER_RESET_PASSWORD,
|
|||
|
|
});
|
|||
|
|
return data;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 未登录:通过手机验证码重置密码(忘记密码)
|
|||
|
|
* PUT /member/user/reset-password
|
|||
|
|
*
|
|||
|
|
* @param {string} mobile - 手机号(必填)
|
|||
|
|
* @param {string} newPassword - 新密码(必填,4-16 位)
|
|||
|
|
* @param {string} smsCode - 短信验证码(必填,4-6 位数字)
|
|||
|
|
* @returns {Promise<Object>} 后端通用响应结构
|
|||
|
|
*/
|
|||
|
|
export async function resetPasswordBySms(mobile, newPassword, smsCode) {
|
|||
|
|
const { data } = await api.put(`${SERVER_BASE}/user/reset-password`, {
|
|||
|
|
mobile,
|
|||
|
|
password: newPassword,
|
|||
|
|
code: smsCode,
|
|||
|
|
});
|
|||
|
|
return data;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* “手机+验证码+密码注册”组合流程(基于短信登录即注册 + 设置密码)
|
|||
|
|
* 说明:
|
|||
|
|
* - 1) 发送登录场景验证码(可选:若已拿到 code 可跳过)
|
|||
|
|
* - 2) 短信登录:首次会自动注册并返回 token
|
|||
|
|
* - 3) 登录态下发送“修改密码”验证码
|
|||
|
|
* - 4) 用短信验证码设置密码
|
|||
|
|
*
|
|||
|
|
* @param {string} mobile - 手机号(必填)
|
|||
|
|
* @param {string} loginCode - 第一次登录使用的短信验证码(必填)
|
|||
|
|
* @param {string} newPassword - 注册后设置的新密码(必填)
|
|||
|
|
* @param {string} updatePwdCode - 设置密码用到的短信验证码(必填)
|
|||
|
|
* @returns {Promise<void>}
|
|||
|
|
*/
|
|||
|
|
export async function registerWithMobileCodePassword(mobile, loginCode, newPassword, updatePwdCode) {
|
|||
|
|
// 1) 可选:发送登录场景验证码(若已拿到 loginCode 可跳过)
|
|||
|
|
// await sendSmsCode(mobile, SMS_SCENE.MEMBER_LOGIN);
|
|||
|
|
|
|||
|
|
// 2) 短信登录(首次即注册)
|
|||
|
|
await loginBySms(mobile, loginCode);
|
|||
|
|
|
|||
|
|
// 3) 登录态下发送“修改密码”验证码(短信会发到当前账号绑定的手机号)
|
|||
|
|
// await sendUpdatePasswordCode();
|
|||
|
|
|
|||
|
|
// 4) 用短信验证码设置密码
|
|||
|
|
await updatePasswordBySmsCode(newPassword, updatePwdCode);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 导出一个默认对象,便于统一引入
|
|||
|
|
*/
|
|||
|
|
export default {
|
|||
|
|
SMS_SCENE,
|
|||
|
|
SMS_TEMPLATE_CODE,
|
|||
|
|
loginByPassword,
|
|||
|
|
sendSmsCode,
|
|||
|
|
validateSmsCode,
|
|||
|
|
loginBySms,
|
|||
|
|
refreshToken,
|
|||
|
|
sendUpdatePasswordCode,
|
|||
|
|
updatePasswordBySmsCode,
|
|||
|
|
sendResetPasswordCode,
|
|||
|
|
resetPasswordBySms,
|
|||
|
|
registerWithMobileCodePassword,
|
|||
|
|
};
|