/**
|
* 请求封装(基于 uni.request,支持 token、错误统一处理)
|
*/
|
import config from '@/config.js'
|
|
// 存储 token 的 key
|
const TOKEN_KEY = 'cj_student_token'
|
|
export function getToken() {
|
return uni.getStorageSync(TOKEN_KEY)
|
}
|
export function setToken(t) {
|
uni.setStorageSync(TOKEN_KEY, t)
|
}
|
export function clearToken() {
|
uni.removeStorageSync(TOKEN_KEY)
|
}
|
|
function request(method, url, data = {}, options = {}) {
|
return new Promise((resolve, reject) => {
|
const token = getToken()
|
uni.request({
|
url: config.baseUrl + url,
|
method,
|
data,
|
header: {
|
'Content-Type': 'application/json',
|
...(token ? { Authorization: 'Bearer ' + token } : {}),
|
...(options.header || {}),
|
},
|
success: (res) => {
|
if (res.statusCode === 401) {
|
clearToken()
|
uni.showToast({ title: '请重新登录', icon: 'none' })
|
uni.reLaunch({ url: '/pages/login/login' })
|
reject(res.data)
|
return
|
}
|
if (res.data && res.data.code === 200) {
|
resolve(res.data)
|
} else {
|
// 后端以 HTTP 200 + body.code 401 表达登录失效:同步清 token,跳登录页
|
if (res.data && res.data.code === 401) {
|
clearToken()
|
uni.showToast({ title: '登录已失效,请重新登录', icon: 'none' })
|
uni.reLaunch({ url: '/pages/login/login' })
|
} else {
|
uni.showToast({ title: (res.data && res.data.msg) || '请求失败', icon: 'none' })
|
}
|
reject(res.data)
|
}
|
},
|
fail: (err) => {
|
uni.showToast({ title: '网络异常,请检查后端连接', icon: 'none' })
|
reject(err)
|
},
|
})
|
})
|
}
|
|
/**
|
* 上传单个文件到 /miniapp/upload。
|
* H5 可传 file(input[type=file] 选中的 File 对象);小程序/App 传 filePath(临时路径)。
|
* 后端响应为 { code, msg, data: { fileName, originalName } };
|
* 成功时 resolve 内层 data({ fileName, originalName }),兼容个别旧结构的顶层 fileName。
|
*/
|
export function uploadFile({ filePath, file }) {
|
return new Promise((resolve, reject) => {
|
const token = getToken()
|
// uni-h5 的 uploadFile 缺 filePath 会先 reject("file error")(但 XHR 仍会发出,导致
|
// 「后端传成功、前端报失败」);H5 传 File 对象时补一个 blob URL 兜底。
|
let fp = filePath
|
if (!fp && file) {
|
try { fp = URL.createObjectURL(file) } catch (e) { /* 非浏览器环境忽略 */ }
|
}
|
uni.uploadFile({
|
url: config.baseUrl + '/miniapp/upload',
|
filePath: fp,
|
file,
|
name: 'file',
|
header: token ? { Authorization: 'Bearer ' + token } : {},
|
success: (res) => {
|
let d = res.data
|
try { d = JSON.parse(res.data) } catch (e) { /* 保留原始文本 */ }
|
if (res.statusCode === 401) {
|
clearToken()
|
uni.showToast({ title: '请重新登录', icon: 'none' })
|
uni.reLaunch({ url: '/pages/login/login' })
|
reject(d)
|
return
|
}
|
if (d && d.code === 200) {
|
// 真正有用的是 data 内层;旧代码直接 resolve 整个响应体导致 res.fileName 恒为 undefined
|
resolve(d.data || d)
|
} else {
|
uni.showToast({ title: (d && d.msg) || '上传失败', icon: 'none' })
|
reject(d)
|
}
|
},
|
fail: (err) => {
|
uni.showToast({ title: '上传失败,请检查网络', icon: 'none' })
|
reject(err)
|
},
|
})
|
})
|
}
|
|
export default {
|
get: (url, data, opts) => request('GET', url, data, opts),
|
post: (url, data, opts) => request('POST', url, data, opts),
|
put: (url, data, opts) => request('PUT', url, data, opts),
|
delete: (url, data, opts) => request('DELETE', url, data, opts),
|
upload: uploadFile,
|
}
|