411 lines
9.6 KiB
JavaScript
Raw Normal View History

2026-04-10 01:49:07 +08:00
const { API, getBaseUrl } = require('./constants');
2026-03-30 18:08:27 +08:00
const { request } = require('./http');
2026-04-10 01:49:07 +08:00
/**
* 上传文件到 /api/file/upload,返回文件 URL 字符串
*/
function uploadFile(filePath) {
return new Promise((resolve, reject) => {
const app = getApp();
const baseUrl = getBaseUrl();
const accessToken =
(app && app.globalData && app.globalData.accessToken) ||
wx.getStorageSync('accessToken') ||
'';
wx.uploadFile({
url: baseUrl + API.fileUpload,
filePath,
name: 'file',
header: accessToken ? { Authorization: `Bearer ${accessToken}` } : {},
success(res) {
try {
const body = typeof res.data === 'string' ? JSON.parse(res.data) : res.data;
// 接口返回数组 [{name, url}] 或 RESTfulResult 包装
let url = '';
if (Array.isArray(body) && body[0] && body[0].url) {
url = body[0].url;
} else if (body && body.data && Array.isArray(body.data) && body.data[0]) {
url = body.data[0].url || '';
} else if (body && body.data && typeof body.data === 'string') {
url = body.data;
}
if (url) resolve(url);
else reject(new Error('上传失败:未获取到文件URL'));
} catch (e) {
reject(new Error('上传响应解析失败'));
}
},
fail(err) {
reject(new Error((err && err.errMsg) || '文件上传失败'));
}
});
});
}
/**
* OCR 识别身份证,返回 IdCardRecognitionResult
* { success, name, gender, idCardNumber, birthDate }
*/
async function ocrIdCard(imageUrl) {
return request({
path: API.ocrIdCard,
method: 'POST',
needAuth: true,
data: { imageUrl },
contentType: 'application/json'
});
}
/**
* OCR 识别护照,返回 PassportRecognitionResult
* { success, name, gender, passportNumber, nationality, birthDate, issueDate, expiryDate, ... }
*/
async function ocrPassport(imageUrl) {
return request({
path: API.ocrPassport,
method: 'POST',
needAuth: true,
data: { imageUrl },
contentType: 'application/json'
});
}
2026-03-31 18:09:37 +08:00
function pickString(obj, key) {
return obj && typeof obj[key] === 'string' ? obj[key] : '';
2026-03-30 18:08:27 +08:00
}
2026-04-03 17:57:08 +08:00
let refreshPromise = null;
async function refreshAccessToken() {
if (refreshPromise) return refreshPromise;
const app = getApp();
const storedRefreshToken = wx.getStorageSync('refreshToken') || '';
const globalRefreshToken = app && app.globalData ? app.globalData.refreshToken : '';
const refreshToken = typeof globalRefreshToken === 'string' && globalRefreshToken.length > 0 ? globalRefreshToken : storedRefreshToken;
if (!refreshToken) throw new Error('refreshAccessToken: missing refreshToken');
refreshPromise = (async () => {
const tokenData = await request({
path: API.oauthRefreshToken,
method: 'POST',
needAuth: false,
data: { refreshToken },
contentType: 'application/json'
});
const accessToken = pickString(tokenData, 'accessToken');
const nextRefreshToken = pickString(tokenData, 'refreshToken') || refreshToken;
if (!accessToken) throw new Error('refreshAccessToken: missing accessToken');
app.setAuth({
accessToken,
refreshToken: nextRefreshToken
});
return {
accessToken,
refreshToken: nextRefreshToken,
tokenData
};
})().finally(() => {
refreshPromise = null;
});
return refreshPromise;
}
2026-03-31 18:09:37 +08:00
async function loginWithMobilePassword({ mobile, password }) {
2026-03-30 18:08:27 +08:00
const loginData = await request({
path: API.wechatLogin,
method: 'POST',
needAuth: false,
data: {
2026-03-31 18:09:37 +08:00
mobile,
password: password != null ? password : ''
2026-03-30 18:08:27 +08:00
},
contentType: 'application/json'
});
const app = getApp();
2026-03-31 18:09:37 +08:00
const accessToken = pickString(loginData, 'accessToken');
const refreshToken = pickString(loginData, 'refreshToken');
const userInfo =
loginData && loginData.userInfo && typeof loginData.userInfo === 'object'
? loginData.userInfo
: null;
const openid = userInfo ? pickString(userInfo, 'openid') : '';
2026-03-30 18:08:27 +08:00
app.setAuth({
accessToken,
2026-03-31 18:09:37 +08:00
refreshToken,
openid,
userProfile: userInfo
2026-03-30 18:08:27 +08:00
});
let myProfile = null;
try {
myProfile = await request({
path: API.myProfile,
method: 'GET',
needAuth: true
});
} catch (e) {
myProfile = null;
}
if (myProfile && typeof myProfile === 'object') {
app.setAuth({
userProfile: myProfile
});
}
return {
loginData,
myProfile
};
}
2026-03-31 23:27:35 +08:00
async function loginWithMobileCode({ mobile, verificationCode }) {
const loginData = await request({
path: API.loginByCode,
method: 'POST',
needAuth: false,
data: {
mobile,
verificationCode
},
contentType: 'application/json'
});
const app = getApp();
const accessToken = pickString(loginData, 'accessToken');
const refreshToken = pickString(loginData, 'refreshToken');
const userInfo =
loginData && loginData.userInfo && typeof loginData.userInfo === 'object'
? loginData.userInfo
: null;
const openid = userInfo ? pickString(userInfo, 'openid') : '';
app.setAuth({
accessToken,
refreshToken,
openid,
userProfile: userInfo
});
let myProfile = null;
try {
myProfile = await request({
path: API.myProfile,
method: 'GET',
needAuth: true
});
} catch (e) {
myProfile = null;
}
if (myProfile && typeof myProfile === 'object') {
app.setAuth({
userProfile: myProfile
});
}
return {
loginData,
myProfile
};
}
2026-03-31 18:09:37 +08:00
async function sendVerificationCode(phone) {
return request({
path: API.sendVerificationCode,
method: 'POST',
needAuth: false,
data: { phone },
contentType: 'application/json'
});
}
async function registerWithVerification({ mobile, password, verificationCode, nickName, avatar }) {
const data = {
mobile,
password,
verificationCode
};
if (nickName) data.nickName = nickName;
if (avatar) data.avatar = avatar;
return request({
path: API.oauthRegister,
method: 'POST',
needAuth: false,
data,
contentType: 'application/json'
});
}
async function resetPassword({ mobile, password, verificationCode }) {
return request({
path: API.oauthResetPassword,
method: 'POST',
needAuth: false,
2026-04-03 17:57:08 +08:00
data: { mobile, newPassword: password, verificationCode },
contentType: 'application/json'
});
}
2026-03-30 18:08:27 +08:00
async function fetchMyProfile() {
return request({
path: API.myProfile,
method: 'GET',
needAuth: true
});
}
async function fetchMyAuth() {
return request({
path: API.myAuth,
method: 'GET',
needAuth: true
});
}
async function submitMyAuth(payload) {
// 兼容旧调用方式:submitMyAuth({ name, mobile, idCardNumber, idCardImageUrl, idCardBackImageUrl })
// 新页面会直接把表单对象透传进来(如 authType、passport 字段等),后端若不识别会忽略。
const p = payload && typeof payload === 'object' ? payload : {};
2026-03-30 18:08:27 +08:00
return request({
path: API.myAuth,
method: 'POST',
needAuth: true,
data: p,
2026-03-30 18:08:27 +08:00
contentType: 'application/json'
});
}
async function fetchMyRegistrations({ pageNo = 1, pageSize = 10 } = {}) {
return request({
path: API.myRegistrations,
method: 'GET',
needAuth: true,
data: {
PageNo: pageNo,
PageSize: pageSize
}
});
}
2026-04-03 17:57:08 +08:00
async function fetchMyPoints({
pageNo = 1,
pageSize = 10,
// 新接口参数(按 swagger):1=获取,2=消耗,不传查全部
type,
// 单位认证ID筛选,不传查全部
merchantCertificationId,
// 兼容旧调用方:也可能传 Type / MerchantCertificationId
Type,
MerchantCertificationId
} = {}) {
const t = type != null ? type : Type;
const mcId = merchantCertificationId != null ? merchantCertificationId : MerchantCertificationId;
const data = {
PageNo: pageNo,
PageSize: pageSize
};
if (t != null && t !== '') data.Type = t;
if (mcId != null && mcId !== '') data.MerchantCertificationId = mcId;
2026-03-31 23:27:35 +08:00
return request({
path: API.myPoints,
method: 'GET',
needAuth: true,
2026-04-03 17:57:08 +08:00
data
2026-03-31 23:27:35 +08:00
});
}
2026-04-08 00:40:29 +08:00
async function fetchMyTeams({ pageNo = 1, pageSize = 20 } = {}) {
return request({
path: API.myTeams,
method: 'GET',
needAuth: true,
data: {
PageNo: pageNo,
PageSize: pageSize
}
});
}
2026-04-10 16:10:33 +08:00
async function fetchMyTeamDetail(id) {
if (id == null || id === '') throw new Error('缺少团队ID');
return request({
path: `${API.myTeams}/${id}`,
method: 'GET',
needAuth: true
});
}
2026-04-08 00:40:29 +08:00
async function fetchMyOrders({ pageNo = 1, pageSize = 10 } = {}) {
return request({
path: API.myOrders,
method: 'GET',
needAuth: true,
data: {
PageNo: pageNo,
PageSize: pageSize
}
});
}
2026-04-14 11:17:13 +08:00
async function fetchMyOrderDetail(id) {
if (id == null || id === '') throw new Error('缺少订单ID');
return request({
path: `${API.myOrders}/${id}`,
method: 'GET',
needAuth: true
});
}
async function fetchMyCertificates({ pageNo = 1, pageSize = 10, type } = {}) {
const data = {
PageNo: pageNo,
PageSize: pageSize
};
// type: 1=个人 2=团队 (若后端支持)
if (type != null) data.Type = type;
return request({
path: API.myCertificates,
method: 'GET',
needAuth: true,
data
});
}
2026-03-30 18:08:27 +08:00
module.exports = {
2026-03-31 18:09:37 +08:00
loginWithMobilePassword,
2026-03-31 23:27:35 +08:00
loginWithMobileCode,
2026-03-31 18:09:37 +08:00
sendVerificationCode,
registerWithVerification,
resetPassword,
2026-03-30 18:08:27 +08:00
fetchMyProfile,
fetchMyAuth,
submitMyAuth,
2026-03-31 23:27:35 +08:00
fetchMyRegistrations,
fetchMyPoints,
2026-04-08 00:40:29 +08:00
fetchMyTeams,
2026-04-10 16:10:33 +08:00
fetchMyTeamDetail,
2026-04-08 00:40:29 +08:00
fetchMyOrders,
2026-04-14 11:17:13 +08:00
fetchMyOrderDetail,
2026-04-03 17:57:08 +08:00
fetchMyCertificates,
2026-04-10 01:49:07 +08:00
refreshAccessToken,
uploadFile,
ocrIdCard,
ocrPassport
2026-03-30 18:08:27 +08:00
};