170 lines
4.6 KiB
JavaScript
170 lines
4.6 KiB
JavaScript
/**
|
||
* 手机号强制认证 - 完全自包含逻辑模块
|
||
*
|
||
* check / ensurePhoneAuth 每次均请求后端 /peizhi/yhbdsjh 判断 need_auth
|
||
*/
|
||
|
||
const API_BASE = 'https://www.abas.asia/hqhd';
|
||
const AUTH_CHECK_URL = '/peizhi/yhbdsjh';
|
||
const AUTH_SUBMIT_URL = '/yonghu/xiugai';
|
||
const AUTH_PAGE = '/pages/phone-auth/phone-auth';
|
||
const RETURN_ROLE_KEY = 'phone_auth_return_role';
|
||
|
||
function innerRequest(url, data = {}) {
|
||
return new Promise((resolve, reject) => {
|
||
const token = wx.getStorageSync('token');
|
||
const header = { 'Content-Type': 'application/json' };
|
||
if (token) header['Authorization'] = 'Bearer ' + token;
|
||
|
||
wx.request({
|
||
url: API_BASE + url,
|
||
method: 'POST',
|
||
data,
|
||
header,
|
||
success: (res) => resolve(res),
|
||
fail: (err) => reject(err),
|
||
});
|
||
});
|
||
}
|
||
|
||
function innerUpload(url, filePath, formData = {}, fileName = 'avatar') {
|
||
return new Promise((resolve, reject) => {
|
||
const token = wx.getStorageSync('token');
|
||
if (!token) {
|
||
reject(new Error('未登录'));
|
||
return;
|
||
}
|
||
|
||
wx.getFileInfo({
|
||
filePath,
|
||
success: () => {
|
||
wx.uploadFile({
|
||
url: API_BASE + url,
|
||
filePath,
|
||
name: fileName,
|
||
formData,
|
||
header: { Authorization: 'Bearer ' + token },
|
||
success: (res) => {
|
||
if (res.statusCode === 200) {
|
||
try {
|
||
resolve(JSON.parse(res.data));
|
||
} catch (e) {
|
||
reject(new Error('解析响应数据失败'));
|
||
}
|
||
} else if (res.statusCode === 401) {
|
||
wx.removeStorageSync('token');
|
||
reject(new Error('认证失败'));
|
||
} else {
|
||
reject(new Error(`上传失败,状态码:${res.statusCode}`));
|
||
}
|
||
},
|
||
fail: () => reject(new Error('网络请求失败')),
|
||
});
|
||
},
|
||
fail: () => reject(new Error('文件不存在或无法访问')),
|
||
});
|
||
});
|
||
}
|
||
|
||
function isOnPhoneAuthPage() {
|
||
const pages = getCurrentPages();
|
||
const cur = pages[pages.length - 1];
|
||
return !!(cur && cur.route === 'pages/phone-auth/phone-auth');
|
||
}
|
||
|
||
function parseCheckResponse(res) {
|
||
if (!res || res.statusCode === 401) {
|
||
return { ok: false, needAuth: false };
|
||
}
|
||
if (res.statusCode !== 200) {
|
||
return { ok: false, needAuth: false };
|
||
}
|
||
const body = res.data;
|
||
if (!body || typeof body !== 'object') {
|
||
return { ok: false, needAuth: false };
|
||
}
|
||
const code = Number(body.code);
|
||
if (code !== 0 && code !== 200) {
|
||
return { ok: false, needAuth: false };
|
||
}
|
||
const needAuth = body.need_auth === true
|
||
|| (body.data && body.data.need_auth === true);
|
||
return { ok: true, needAuth: !!needAuth };
|
||
}
|
||
|
||
/**
|
||
* 询问后端是否需要手机号认证
|
||
* @returns {Promise<boolean>} true=需要认证
|
||
*/
|
||
async function check() {
|
||
const token = wx.getStorageSync('token');
|
||
if (!token) return false;
|
||
|
||
try {
|
||
const res = await innerRequest(AUTH_CHECK_URL, {});
|
||
const parsed = parseCheckResponse(res);
|
||
if (!parsed.ok) return false;
|
||
return parsed.needAuth;
|
||
} catch (e) {
|
||
return false;
|
||
}
|
||
}
|
||
|
||
function redirectToPhoneAuth(returnRole) {
|
||
if (returnRole) {
|
||
wx.setStorageSync(RETURN_ROLE_KEY, returnRole);
|
||
}
|
||
if (!isOnPhoneAuthPage()) {
|
||
wx.reLaunch({ url: AUTH_PAGE });
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 打手端等场景:向后端确认,未认证则跳转认证页
|
||
* @returns {Promise<boolean>} true=已通过或无需认证;false=已跳转认证页
|
||
*/
|
||
async function ensurePhoneAuth(options = {}) {
|
||
const { redirect = true, role = 'dashou' } = options;
|
||
const token = wx.getStorageSync('token');
|
||
if (!token) return true;
|
||
|
||
const needAuth = await check();
|
||
if (!needAuth) return true;
|
||
if (redirect) redirectToPhoneAuth(role);
|
||
return false;
|
||
}
|
||
|
||
function getPhoneAuthReturnPage() {
|
||
const role = wx.getStorageSync(RETURN_ROLE_KEY) || '';
|
||
wx.removeStorageSync(RETURN_ROLE_KEY);
|
||
if (role === 'dashou') return '/pages/accept-order/accept-order';
|
||
if (role === 'shangjia') return '/pages/merchant-orders/merchant-orders';
|
||
return '/pages/mine/mine';
|
||
}
|
||
|
||
async function submit(phoneCode, avatarPath) {
|
||
if (!phoneCode || !avatarPath) {
|
||
throw new Error('缺少参数');
|
||
}
|
||
|
||
const data = await innerUpload(AUTH_SUBMIT_URL, avatarPath, {
|
||
shoujihao_code: phoneCode,
|
||
});
|
||
|
||
if (data && data.code === 0) {
|
||
const respData = data.data || data;
|
||
if (respData.phone) wx.setStorageSync('phone', respData.phone);
|
||
if (respData.touxiang) wx.setStorageSync('touxiang', respData.touxiang);
|
||
return respData;
|
||
}
|
||
throw new Error((data && data.msg) || '认证失败');
|
||
}
|
||
|
||
module.exports = {
|
||
check,
|
||
submit,
|
||
ensurePhoneAuth,
|
||
redirectToPhoneAuth,
|
||
getPhoneAuthReturnPage,
|
||
};
|