update
This commit is contained in:
parent
86e4c38663
commit
9a32fb8fb8
134
app.js
134
app.js
|
|
@ -4,9 +4,143 @@ App(injectApp()({
|
||||||
|
|
||||||
},
|
},
|
||||||
async onLaunch() {
|
async onLaunch() {
|
||||||
|
if (wx.canIUse('getUpdateManager')) {
|
||||||
|
const updateManager = wx.getUpdateManager();
|
||||||
|
updateManager.onCheckForUpdate(function (res) {
|
||||||
|
if (res.hasUpdate) {
|
||||||
|
updateManager.onUpdateReady(function () {
|
||||||
|
wx.showModal({
|
||||||
|
title: '更新提示',
|
||||||
|
content: '新版本已经准备好,是否重启应用?',
|
||||||
|
success(res) {
|
||||||
|
if (res.confirm) {
|
||||||
|
updateManager.applyUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
// 等待登陆完成以后请求自动携带token
|
// 等待登陆完成以后请求自动携带token
|
||||||
await waitLogin()
|
await waitLogin()
|
||||||
// 三方登录本地缓存
|
// 三方登录本地缓存
|
||||||
console.log(wx.getStorageSync('jdwx-userinfo'))
|
console.log(wx.getStorageSync('jdwx-userinfo'))
|
||||||
},
|
},
|
||||||
|
|
||||||
|
//内容安全
|
||||||
|
async checkdata(txt = '', checkType, mediaUrl = '') {
|
||||||
|
try {
|
||||||
|
if (!checkType || (checkType !== 2 && checkType !== 3)) {
|
||||||
|
throw new Error('checkType必须为2(图片检测)或3(文本检测)')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (checkType === 3 && !txt) {
|
||||||
|
throw new Error('文本检测时content不能为空')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (checkType === 2 && !mediaUrl) {
|
||||||
|
throw new Error('图片检测时mediaUrl不能为空')
|
||||||
|
}
|
||||||
|
|
||||||
|
const postdata = {
|
||||||
|
content: txt,
|
||||||
|
checkType: checkType,
|
||||||
|
mediaUrl: mediaUrl
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = await gatewayHttpClient.request('/wx/v1/api/app/content/check', 'post', postdata)
|
||||||
|
|
||||||
|
if (data.code === 200) {
|
||||||
|
if (checkType == 3) {
|
||||||
|
return data.data.suggest === 'pass' ? 1 : 2
|
||||||
|
}
|
||||||
|
|
||||||
|
if (checkType == 2) {
|
||||||
|
return data.data.id || null
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.error('内容检测API调用失败:', data)
|
||||||
|
return 2
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('checkdata函数执行错误:', error)
|
||||||
|
return 2
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 轮询检查图片是否合规
|
||||||
|
//imgurl 为本地图片地址
|
||||||
|
async checkimage(imgurl){
|
||||||
|
wx.showLoading({
|
||||||
|
title: '正在检查图片...',
|
||||||
|
mask: true
|
||||||
|
});
|
||||||
|
try{
|
||||||
|
const upfileData = await gatewayHttpClient.uploadFile(imgurl, 'image');
|
||||||
|
const checkid = await this.checkdata('',2,upfileData.data.url)
|
||||||
|
let retryCount = 0;
|
||||||
|
const maxRetries = 5;
|
||||||
|
while (retryCount < maxRetries) {
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 1000)); // 间隔1秒
|
||||||
|
|
||||||
|
const passcode = await this.checkSafetyResults(checkid);
|
||||||
|
|
||||||
|
// 检查具体的错误码
|
||||||
|
switch (passcode) {
|
||||||
|
case 100:
|
||||||
|
wx.hideLoading();
|
||||||
|
return upfileData.data;
|
||||||
|
case 20001:
|
||||||
|
wx.hideLoading();
|
||||||
|
await gatewayHttpClient.deleteFile(upfileData.data.id);
|
||||||
|
this.showwarning('图片时政内容,请重新选择');
|
||||||
|
return null;
|
||||||
|
case 20002:
|
||||||
|
wx.hideLoading();
|
||||||
|
await gatewayHttpClient.deleteFile(upfileData.data.id);
|
||||||
|
this.showwarning('图片含有色情内容,请重新选择');
|
||||||
|
return null;
|
||||||
|
case 20006:
|
||||||
|
wx.hideLoading();
|
||||||
|
await gatewayHttpClient.deleteFile(upfileData.data.id);
|
||||||
|
this.showwarning('图片含有违法犯罪内容,请重新选择');
|
||||||
|
return null;
|
||||||
|
case 21000:
|
||||||
|
wx.hideLoading();
|
||||||
|
await gatewayHttpClient.deleteFile(upfileData.data.id);
|
||||||
|
this.showwarning('图片非法内容,请重新选择');
|
||||||
|
return null;
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
retryCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5次超时,返回失败
|
||||||
|
wx.hideLoading();
|
||||||
|
await gatewayHttpClient.deleteFile(upfileData.data.id)//删除图片
|
||||||
|
wx.showToast({
|
||||||
|
title: '图片检查超时,请重试',
|
||||||
|
icon: 'none'
|
||||||
|
});
|
||||||
|
return null;
|
||||||
|
} catch (error) {
|
||||||
|
wx.hideLoading();
|
||||||
|
console.error('图片检查失败:', error);
|
||||||
|
wx.showToast({
|
||||||
|
title: '检查失败,请重试',
|
||||||
|
icon: 'none'
|
||||||
|
});
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
showwarning(txt){
|
||||||
|
wx.showModal({
|
||||||
|
title: '提示',
|
||||||
|
content: txt,
|
||||||
|
showCancel: false,
|
||||||
|
success: () => {
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}))
|
}))
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import { injectPage, adManager } from '@jdmini/api'
|
import { injectPage, adManager,waitLogin } from '@jdmini/api'
|
||||||
|
const { requireLogin, httpClient, IS_DEV } = require('../../utils/index.js')
|
||||||
|
|
||||||
Page(injectPage({
|
Page(injectPage({
|
||||||
//showInterstitialAd:true// 插屏广告
|
//showInterstitialAd:true// 插屏广告
|
||||||
|
|
@ -10,5 +11,22 @@ Page(injectPage({
|
||||||
async showRewardedVideoAd() {
|
async showRewardedVideoAd() {
|
||||||
const isEnded = await adManager.createAndShowRewardedVideoAd(this)
|
const isEnded = await adManager.createAndShowRewardedVideoAd(this)
|
||||||
console.log(isEnded)
|
console.log(isEnded)
|
||||||
|
},
|
||||||
|
choosePhoto(){
|
||||||
|
wx.chooseMedia({
|
||||||
|
count: 1,
|
||||||
|
mediaType: ['image'],
|
||||||
|
sourceType: ['album'],
|
||||||
|
success(res) {
|
||||||
|
const tempFiles = res.tempFiles
|
||||||
|
console.log(tempFiles)
|
||||||
|
// tempFiles.forEach(file => {
|
||||||
|
// that.addWatermarkToPhoto(file.tempFilePath)
|
||||||
|
// })
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}))
|
}))
|
||||||
|
|
@ -1 +1 @@
|
||||||
<view>null</view>
|
<view>首页</view>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"compileType": "miniprogram",
|
"compileType": "miniprogram",
|
||||||
"libVersion": "trial",
|
"libVersion": "3.10.1",
|
||||||
"packOptions": {
|
"packOptions": {
|
||||||
"ignore": [],
|
"ignore": [],
|
||||||
"include": []
|
"include": []
|
||||||
|
|
|
||||||
|
|
@ -19,5 +19,6 @@
|
||||||
"checkInvalidKey": true,
|
"checkInvalidKey": true,
|
||||||
"ignoreDevUnusedFiles": true
|
"ignoreDevUnusedFiles": true
|
||||||
},
|
},
|
||||||
"libVersion": "3.10.1"
|
"libVersion": "3.10.1",
|
||||||
|
"condition": {}
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
/**
|
||||||
|
* API 接口定义
|
||||||
|
* 所有业务 API 接口的统一管理
|
||||||
|
*/
|
||||||
|
|
||||||
|
const { get, post, put, del, uploadFile } = require('./request.js')
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ===============================
|
||||||
|
* 相关接口
|
||||||
|
* ===============================
|
||||||
|
*/
|
||||||
|
|
@ -0,0 +1,269 @@
|
||||||
|
/**
|
||||||
|
* 用户认证工具模块
|
||||||
|
* 统一管理登录状态检查、登录跳转等
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查用户是否已登录
|
||||||
|
* @returns {Boolean} 是否已登录
|
||||||
|
*/
|
||||||
|
function isLoggedIn() {
|
||||||
|
const userId = wx.getStorageSync('userId')
|
||||||
|
const token = wx.getStorageSync('token')
|
||||||
|
return !!(userId && token)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取用户信息
|
||||||
|
* @returns {Object|null} 用户信息对象或null
|
||||||
|
*/
|
||||||
|
function getUserInfo() {
|
||||||
|
if (!isLoggedIn()) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
const userInfo = wx.getStorageSync('userInfo')
|
||||||
|
return userInfo || null
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取用户ID
|
||||||
|
* @returns {String|null} 用户ID或null
|
||||||
|
*/
|
||||||
|
function getUserId() {
|
||||||
|
return wx.getStorageSync('userId') || null
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取Token
|
||||||
|
* @returns {String|null} Token或null
|
||||||
|
*/
|
||||||
|
function getToken() {
|
||||||
|
return wx.getStorageSync('token') || null
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查登录状态,未登录则跳转登录页
|
||||||
|
* @param {Object} options 配置项
|
||||||
|
* @param {String} options.returnUrl 登录成功后返回的页面URL
|
||||||
|
* @param {String} options.returnType 返回类型: navigateTo/redirectTo/switchTab
|
||||||
|
* @param {Function} options.success 已登录时的回调
|
||||||
|
* @param {Function} options.fail 未登录时的回调
|
||||||
|
* @returns {Boolean} 是否已登录
|
||||||
|
*/
|
||||||
|
function checkLogin(options = {}) {
|
||||||
|
const {
|
||||||
|
returnUrl = '',
|
||||||
|
returnType = 'navigateTo',
|
||||||
|
success,
|
||||||
|
fail
|
||||||
|
} = options
|
||||||
|
|
||||||
|
if (isLoggedIn()) {
|
||||||
|
// 已登录
|
||||||
|
success && success()
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
// 未登录,跳转登录页
|
||||||
|
fail && fail()
|
||||||
|
|
||||||
|
// 保存返回信息
|
||||||
|
if (returnUrl) {
|
||||||
|
wx.setStorageSync('returnTo', {
|
||||||
|
url: returnUrl,
|
||||||
|
type: returnType
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
wx.navigateTo({
|
||||||
|
url: '/pages/login/login'
|
||||||
|
})
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 要求登录后执行操作
|
||||||
|
* @param {Function} callback 登录后执行的回调
|
||||||
|
* @param {Object} options 配置项
|
||||||
|
*/
|
||||||
|
function requireLogin(callback, options = {}) {
|
||||||
|
return checkLogin({
|
||||||
|
...options,
|
||||||
|
success: callback,
|
||||||
|
fail: () => {
|
||||||
|
wx.showToast({
|
||||||
|
title: '请先登录',
|
||||||
|
icon: 'none',
|
||||||
|
duration: 2000
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存用户信息到本地
|
||||||
|
* @param {Object} data 用户数据
|
||||||
|
* @param {String} data.userId 用户ID
|
||||||
|
* @param {String} data.token Token
|
||||||
|
* @param {Object} data.userInfo 用户信息
|
||||||
|
*/
|
||||||
|
function saveUserData(data) {
|
||||||
|
const { userId, token, userInfo } = data
|
||||||
|
|
||||||
|
if (userId) {
|
||||||
|
wx.setStorageSync('userId', userId)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (token) {
|
||||||
|
wx.setStorageSync('token', token)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (userInfo) {
|
||||||
|
wx.setStorageSync('userInfo', userInfo)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清除用户登录信息
|
||||||
|
*/
|
||||||
|
function clearUserData() {
|
||||||
|
wx.removeStorageSync('userId')
|
||||||
|
wx.removeStorageSync('token')
|
||||||
|
wx.removeStorageSync('userInfo')
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 跳转到登录页面(带返回功能)
|
||||||
|
* 参考 checkin.js 的实现,显示弹窗确认后跳转登录页
|
||||||
|
* @param {Object} options 配置项
|
||||||
|
* @param {String} options.message 提示信息
|
||||||
|
* @param {String} options.returnUrl 登录成功后返回的页面URL(不传则自动获取当前页面)
|
||||||
|
* @param {String} options.returnType 返回类型: navigateTo/redirectTo/switchTab
|
||||||
|
* @param {Boolean} options.showCancel 是否显示取消按钮
|
||||||
|
* @param {Function} options.onCancel 取消回调
|
||||||
|
*/
|
||||||
|
function navigateToLogin(options = {}) {
|
||||||
|
const {
|
||||||
|
message = '请先登录',
|
||||||
|
returnUrl = '',
|
||||||
|
returnType = 'navigateTo',
|
||||||
|
showCancel = true,
|
||||||
|
onCancel = null
|
||||||
|
} = options
|
||||||
|
|
||||||
|
// 自动获取当前页面路径
|
||||||
|
let finalReturnUrl = returnUrl
|
||||||
|
if (!finalReturnUrl) {
|
||||||
|
const pages = getCurrentPages()
|
||||||
|
if (pages.length > 0) {
|
||||||
|
const currentPage = pages[pages.length - 1]
|
||||||
|
finalReturnUrl = '/' + currentPage.route
|
||||||
|
// 添加页面参数
|
||||||
|
if (currentPage.options && Object.keys(currentPage.options).length > 0) {
|
||||||
|
const params = Object.keys(currentPage.options)
|
||||||
|
.map(key => `${key}=${currentPage.options[key]}`)
|
||||||
|
.join('&')
|
||||||
|
finalReturnUrl += '?' + params
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wx.showModal({
|
||||||
|
title: '提示',
|
||||||
|
content: message,
|
||||||
|
confirmText: '去登录',
|
||||||
|
cancelText: '返回',
|
||||||
|
showCancel: showCancel,
|
||||||
|
success: (res) => {
|
||||||
|
if (res.confirm) {
|
||||||
|
// 保存返回信息,登录成功后返回当前页面
|
||||||
|
if (finalReturnUrl) {
|
||||||
|
wx.setStorageSync('returnTo', {
|
||||||
|
type: returnType,
|
||||||
|
url: finalReturnUrl
|
||||||
|
})
|
||||||
|
}
|
||||||
|
wx.redirectTo({
|
||||||
|
url: '/pages/login/login'
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
// 点击取消
|
||||||
|
if (onCancel) {
|
||||||
|
onCancel()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退出登录
|
||||||
|
* @param {Object} options 配置项
|
||||||
|
* @param {String} options.redirectUrl 退出后跳转的页面
|
||||||
|
* @param {Boolean} options.confirm 是否需要确认
|
||||||
|
* @param {Function} options.success 成功回调
|
||||||
|
*/
|
||||||
|
function logout(options = {}) {
|
||||||
|
const {
|
||||||
|
redirectUrl = '/pages/home/home',
|
||||||
|
confirm = true,
|
||||||
|
success
|
||||||
|
} = options
|
||||||
|
|
||||||
|
const doLogout = () => {
|
||||||
|
clearUserData()
|
||||||
|
|
||||||
|
wx.showToast({
|
||||||
|
title: '已退出登录',
|
||||||
|
icon: 'success',
|
||||||
|
duration: 1500
|
||||||
|
})
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
success && success()
|
||||||
|
|
||||||
|
// 跳转到指定页面
|
||||||
|
if (redirectUrl.startsWith('/pages/home/') ||
|
||||||
|
redirectUrl.startsWith('/pages/index/') ||
|
||||||
|
redirectUrl.startsWith('/pages/record/') ||
|
||||||
|
redirectUrl.startsWith('/pages/settings/')) {
|
||||||
|
wx.reLaunch({
|
||||||
|
url: redirectUrl
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
wx.redirectTo({
|
||||||
|
url: redirectUrl
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}, 1500)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (confirm) {
|
||||||
|
wx.showModal({
|
||||||
|
title: '退出登录',
|
||||||
|
content: '确定要退出登录吗?',
|
||||||
|
success: (res) => {
|
||||||
|
if (res.confirm) {
|
||||||
|
doLogout()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
doLogout()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
isLoggedIn,
|
||||||
|
getUserInfo,
|
||||||
|
getUserId,
|
||||||
|
getToken,
|
||||||
|
checkLogin,
|
||||||
|
requireLogin,
|
||||||
|
navigateToLogin,
|
||||||
|
saveUserData,
|
||||||
|
clearUserData,
|
||||||
|
logout
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
/**
|
||||||
|
* API 配置文件
|
||||||
|
* 统一管理开发环境和生产环境的配置
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 开发模式开关
|
||||||
|
const IS_DEV = false
|
||||||
|
|
||||||
|
// 开发环境配置
|
||||||
|
const DEV_CONFIG = {
|
||||||
|
apiBase: 'http://localhost:3001/api',
|
||||||
|
timeout: 30000,
|
||||||
|
enableLog: true
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生产环境配置
|
||||||
|
const PROD_CONFIG = {
|
||||||
|
apiBase: '/mp/jd-haiba', // jd-haiba是模块名
|
||||||
|
timeout: 30000,
|
||||||
|
enableLog: false
|
||||||
|
}
|
||||||
|
|
||||||
|
// 当前环境配置
|
||||||
|
const CONFIG = IS_DEV ? DEV_CONFIG : PROD_CONFIG
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
IS_DEV,
|
||||||
|
API_BASE: CONFIG.apiBase,
|
||||||
|
TIMEOUT: CONFIG.timeout,
|
||||||
|
ENABLE_LOG: CONFIG.enableLog,
|
||||||
|
|
||||||
|
// 切换环境方法(用于调试)
|
||||||
|
switchEnv: (isDev) => {
|
||||||
|
return isDev ? DEV_CONFIG : PROD_CONFIG
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,88 @@
|
||||||
|
/**
|
||||||
|
* 统一的 HTTP 客户端
|
||||||
|
* 自动根据环境切换使用 gatewayHttpClient 或 HttpClient
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { gatewayHttpClient, HttpClient } from '@jdmini/api'
|
||||||
|
const { IS_DEV, API_BASE } = require('./config.js')
|
||||||
|
|
||||||
|
// 开发环境使用 HttpClient
|
||||||
|
const devHttpClient = IS_DEV ? new HttpClient({
|
||||||
|
baseURL: API_BASE,
|
||||||
|
timeout: 30000,
|
||||||
|
}) : null
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 统一的 HTTP 请求方法
|
||||||
|
* @param {String} url - 请求路径(相对路径,不包含 baseURL)
|
||||||
|
* @param {String} method - 请求方法 GET/POST/PUT/DELETE
|
||||||
|
* @param {Object} data - 请求数据
|
||||||
|
* @param {Object} options - 额外选项
|
||||||
|
* @returns {Promise}
|
||||||
|
*/
|
||||||
|
function request(url, method = 'GET', data = {}, options = {}) {
|
||||||
|
// 确保 URL 以 / 开头
|
||||||
|
const apiUrl = url.startsWith('/') ? url : `/${url}`
|
||||||
|
|
||||||
|
if (IS_DEV) {
|
||||||
|
// 开发环境:使用 HttpClient
|
||||||
|
console.log(`[DEV] ${method} ${API_BASE}${apiUrl}`, data)
|
||||||
|
return devHttpClient.request(apiUrl, method, data, options)
|
||||||
|
} else {
|
||||||
|
// 生产环境:使用 gatewayHttpClient
|
||||||
|
// gatewayHttpClient 需要完整的路径:mp/jd-haiba/user/login
|
||||||
|
const fullUrl = `${API_BASE}${apiUrl}`
|
||||||
|
console.log(`[PROD] ${method} ${fullUrl}`, data)
|
||||||
|
|
||||||
|
// gatewayHttpClient.request 的参数顺序:(url, method, data, options)
|
||||||
|
return gatewayHttpClient.request(fullUrl, method, data, options)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GET 请求
|
||||||
|
*/
|
||||||
|
function get(url, params = {}, options = {}) {
|
||||||
|
return request(url, 'GET', params, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* POST 请求
|
||||||
|
*/
|
||||||
|
function post(url, data = {}, options = {}) {
|
||||||
|
return request(url, 'POST', data, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PUT 请求
|
||||||
|
*/
|
||||||
|
function put(url, data = {}, options = {}) {
|
||||||
|
return request(url, 'PUT', data, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DELETE 请求
|
||||||
|
*/
|
||||||
|
function del(url, data = {}, options = {}) {
|
||||||
|
return request(url, 'DELETE', data, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上传文件(暂时保留原有逻辑)
|
||||||
|
*/
|
||||||
|
function upload(filePath, formData = {}) {
|
||||||
|
return gatewayHttpClient.uploadFile(filePath,formData)
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
request,
|
||||||
|
get,
|
||||||
|
post,
|
||||||
|
put,
|
||||||
|
del,
|
||||||
|
upload,
|
||||||
|
|
||||||
|
// 导出原始客户端供特殊场景使用
|
||||||
|
gatewayHttpClient,
|
||||||
|
devHttpClient
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
/**
|
||||||
|
* Utils 统一导出
|
||||||
|
* 方便各个页面统一引入
|
||||||
|
*/
|
||||||
|
|
||||||
|
const config = require('./config.js')
|
||||||
|
const request = require('./request.js')
|
||||||
|
const api = require('./api.js')
|
||||||
|
const auth = require('./auth.js')
|
||||||
|
const httpClient = require('./httpClient.js')
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
// 配置
|
||||||
|
...config,
|
||||||
|
|
||||||
|
// 请求方法
|
||||||
|
...request,
|
||||||
|
|
||||||
|
// API接口
|
||||||
|
...api,
|
||||||
|
|
||||||
|
// 认证
|
||||||
|
...auth,
|
||||||
|
|
||||||
|
// 统一 HTTP 客户端
|
||||||
|
httpClient
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,278 @@
|
||||||
|
/**
|
||||||
|
* 统一请求模块
|
||||||
|
* 封装所有 API 请求,支持拦截器、错误处理等
|
||||||
|
*/
|
||||||
|
|
||||||
|
const { API_BASE, TIMEOUT, ENABLE_LOG, IS_DEV } = require('./config.js')
|
||||||
|
const httpClient = require('./httpClient.js')
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 统一请求方法
|
||||||
|
* @param {Object} options 请求配置
|
||||||
|
* @param {String} options.url 请求路径(相对路径,会自动拼接 API_BASE)
|
||||||
|
* @param {String} options.method 请求方法 GET/POST/PUT/DELETE
|
||||||
|
* @param {Object} options.data 请求数据
|
||||||
|
* @param {Object} options.header 自定义请求头
|
||||||
|
* @param {Boolean} options.showLoading 是否显示加载提示
|
||||||
|
* @param {String} options.loadingText 加载提示文字
|
||||||
|
* @param {Boolean} options.showError 是否显示错误提示
|
||||||
|
* @returns {Promise}
|
||||||
|
*/
|
||||||
|
function request(options = {}) {
|
||||||
|
const {
|
||||||
|
url,
|
||||||
|
method = 'GET',
|
||||||
|
data = {},
|
||||||
|
header = {},
|
||||||
|
showLoading = false,
|
||||||
|
loadingText = '加载中...',
|
||||||
|
showError = true
|
||||||
|
} = options
|
||||||
|
|
||||||
|
// 显示加载提示
|
||||||
|
if (showLoading) {
|
||||||
|
wx.showLoading({
|
||||||
|
title: loadingText,
|
||||||
|
mask: true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 拼接完整URL
|
||||||
|
const fullUrl = url.startsWith('http') ? url : `${API_BASE}${url}`
|
||||||
|
|
||||||
|
// 构建请求头
|
||||||
|
const requestHeader = {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
...header
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加 token(如果存在)
|
||||||
|
const token = wx.getStorageSync('token')
|
||||||
|
if (token) {
|
||||||
|
requestHeader['Authorization'] = `Bearer ${token}`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 日志输出
|
||||||
|
if (ENABLE_LOG) {
|
||||||
|
console.log('[API Request]', {
|
||||||
|
url: fullUrl,
|
||||||
|
method,
|
||||||
|
data,
|
||||||
|
header: requestHeader
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
wx.request({
|
||||||
|
url: fullUrl,
|
||||||
|
method,
|
||||||
|
data,
|
||||||
|
header: requestHeader,
|
||||||
|
timeout: TIMEOUT,
|
||||||
|
success: (res) => {
|
||||||
|
// 隐藏加载提示
|
||||||
|
if (showLoading) {
|
||||||
|
wx.hideLoading()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 日志输出
|
||||||
|
if (ENABLE_LOG) {
|
||||||
|
console.log('[API Response]', res.data)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 统一处理响应
|
||||||
|
const { statusCode, data: resData } = res
|
||||||
|
|
||||||
|
// HTTP 状态码检查
|
||||||
|
if (statusCode >= 200 && statusCode < 300) {
|
||||||
|
// 业务状态码检查
|
||||||
|
if (resData.code === 200 || resData.success === true) {
|
||||||
|
resolve(resData)
|
||||||
|
} else {
|
||||||
|
// 业务错误
|
||||||
|
const errorMsg = resData.msg || resData.message || '请求失败'
|
||||||
|
if (showError) {
|
||||||
|
wx.showToast({
|
||||||
|
title: errorMsg,
|
||||||
|
icon: 'none',
|
||||||
|
duration: 2000
|
||||||
|
})
|
||||||
|
}
|
||||||
|
reject({
|
||||||
|
code: resData.code,
|
||||||
|
msg: errorMsg,
|
||||||
|
data: resData
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// HTTP 错误
|
||||||
|
const errorMsg = `服务器错误 (${statusCode})`
|
||||||
|
if (showError) {
|
||||||
|
wx.showToast({
|
||||||
|
title: errorMsg,
|
||||||
|
icon: 'none',
|
||||||
|
duration: 2000
|
||||||
|
})
|
||||||
|
}
|
||||||
|
reject({
|
||||||
|
code: statusCode,
|
||||||
|
msg: errorMsg,
|
||||||
|
data: res
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
fail: (err) => {
|
||||||
|
// 隐藏加载提示
|
||||||
|
if (showLoading) {
|
||||||
|
wx.hideLoading()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 日志输出
|
||||||
|
if (ENABLE_LOG) {
|
||||||
|
console.error('[API Error]', err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 网络错误
|
||||||
|
const errorMsg = err.errMsg || '网络请求失败'
|
||||||
|
if (showError) {
|
||||||
|
wx.showToast({
|
||||||
|
title: errorMsg,
|
||||||
|
icon: 'none',
|
||||||
|
duration: 2000
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
reject({
|
||||||
|
code: -1,
|
||||||
|
msg: errorMsg,
|
||||||
|
data: err
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GET 请求
|
||||||
|
*/
|
||||||
|
function get(url, data = {}, options = {}) {
|
||||||
|
// 直接使用 httpClient,它会自动处理环境切换
|
||||||
|
return httpClient.get(url, data, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* POST 请求
|
||||||
|
*/
|
||||||
|
function post(url, data = {}, options = {}) {
|
||||||
|
// 直接使用 httpClient,它会自动处理环境切换
|
||||||
|
return httpClient.post(url, data, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PUT 请求
|
||||||
|
*/
|
||||||
|
function put(url, data = {}, options = {}) {
|
||||||
|
// 直接使用 httpClient,它会自动处理环境切换
|
||||||
|
return httpClient.put(url, data, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DELETE 请求
|
||||||
|
*/
|
||||||
|
function del(url, data = {}, options = {}) {
|
||||||
|
// 直接使用 httpClient,它会自动处理环境切换
|
||||||
|
return httpClient.del(url, data, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上传文件
|
||||||
|
* @param {String} url 上传地址
|
||||||
|
* @param {String} filePath 文件路径
|
||||||
|
* @param {Object} formData 额外的表单数据
|
||||||
|
* @param {Object} options 其他配置
|
||||||
|
*/
|
||||||
|
function uploadFile(filePath, formData = {}) {
|
||||||
|
const {
|
||||||
|
name = 'file',
|
||||||
|
showLoading = true,
|
||||||
|
loadingText = '上传中...',
|
||||||
|
showError = true
|
||||||
|
} = options
|
||||||
|
|
||||||
|
if (showLoading) {
|
||||||
|
wx.showLoading({
|
||||||
|
title: loadingText,
|
||||||
|
mask: true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const fullUrl = url.startsWith('http') ? url : `${API_BASE}${url}`
|
||||||
|
|
||||||
|
// 构建请求头
|
||||||
|
const header = {}
|
||||||
|
const token = wx.getStorageSync('token')
|
||||||
|
if (token) {
|
||||||
|
header['Authorization'] = `Bearer ${token}`
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
wx.uploadFile({
|
||||||
|
url: fullUrl,
|
||||||
|
filePath,
|
||||||
|
name,
|
||||||
|
formData,
|
||||||
|
header,
|
||||||
|
timeout: TIMEOUT,
|
||||||
|
success: (res) => {
|
||||||
|
if (showLoading) {
|
||||||
|
wx.hideLoading()
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = JSON.parse(res.data)
|
||||||
|
if (data.code === 200 || data.success === true) {
|
||||||
|
resolve(data)
|
||||||
|
} else {
|
||||||
|
const errorMsg = data.msg || data.message || '上传失败'
|
||||||
|
if (showError) {
|
||||||
|
wx.showToast({
|
||||||
|
title: errorMsg,
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
reject({
|
||||||
|
code: data.code,
|
||||||
|
msg: errorMsg,
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
fail: (err) => {
|
||||||
|
if (showLoading) {
|
||||||
|
wx.hideLoading()
|
||||||
|
}
|
||||||
|
|
||||||
|
const errorMsg = err.errMsg || '上传失败'
|
||||||
|
if (showError) {
|
||||||
|
wx.showToast({
|
||||||
|
title: errorMsg,
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
reject({
|
||||||
|
code: -1,
|
||||||
|
msg: errorMsg,
|
||||||
|
data: err
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
request,
|
||||||
|
get,
|
||||||
|
post,
|
||||||
|
put,
|
||||||
|
del,
|
||||||
|
uploadFile
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue