Files
shanxia2.0/miniprogram/utils/dbRequest.js
T
wuzilongandCursor af79aa50a2 fix(pl): 司机回执缺品牌数量时仍保存单据,并按业务结果提示成败。
未填写品牌数量不再拦截照片和备注;已填写的品牌数量仍校验。小程序在 HTTP 200 的业务失败下不再弹出保存成功。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-11-06 23:57:34 +08:00

123 lines
3.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 地磅与运输小程序 HTTP。裸 JSON 原样返回;门户信封在 HTTP 200 下若 code 不是 200/0,按业务失败处理。
* 对齐 mobile-h5/src/utils/http/db.ts
*/
import { TOKEN_KEY, REFRESH_TOKEN_KEY, USER_INFO_KEY, resolveApiBase } from '@/config/api'
import { portalBusinessErrorMessage } from '@/utils/portalEnvelope'
const DB_COLLECTION_ROOT = /^\/(plans|inventory|weighing)$/
function normalizeDbUrl(url) {
if (!url || url.endsWith('/')) return url
return DB_COLLECTION_ROOT.test(url) ? `${url}/` : url
}
function buildQuery(params) {
if (!params || typeof params !== 'object') return ''
const parts = []
Object.keys(params).forEach((key) => {
const val = params[key]
if (val === undefined || val === null || val === '') return
parts.push(`${encodeURIComponent(key)}=${encodeURIComponent(String(val))}`)
})
return parts.length ? `?${parts.join('&')}` : ''
}
function parseDetailMessage(data) {
if (!data || typeof data !== 'object') return ''
const detail = data.detail
if (typeof detail === 'string') return detail
if (Array.isArray(detail)) {
return detail
.map((x) => (x && x.msg) || '')
.filter(Boolean)
.join(';')
}
return data.message || data.msg || ''
}
async function onUnauthorized() {
uni.removeStorageSync(TOKEN_KEY)
uni.removeStorageSync(REFRESH_TOKEN_KEY)
uni.removeStorageSync(USER_INFO_KEY)
try {
const { useUserStore } = await import('@/stores/user')
useUserStore().clearLoginInfo()
} catch (e) {
// ignore
}
uni.showToast({ title: '登录已过期,请重新登录', icon: 'none' })
setTimeout(() => {
uni.reLaunch({ url: '/pages/login/login' })
}, 800)
}
/**
* @param {{ url: string, method?: string, data?: any, params?: any, showError?: boolean }} options
*/
export function dbRequest(options = {}) {
const method = String(options.method || 'GET').toUpperCase()
const showError = options.showError !== false
const token = uni.getStorageSync(TOKEN_KEY) || ''
let path = normalizeDbUrl(options.url || '')
const query = method === 'GET' ? buildQuery(options.params) : buildQuery(options.params)
const rawUrl = `${path}${query}`
const url = rawUrl.startsWith('http')
? rawUrl
: `${resolveApiBase()}${rawUrl.startsWith('/') ? rawUrl : `/${rawUrl}`}`
return new Promise((resolve, reject) => {
uni.request({
url,
method,
data: method === 'GET' ? undefined : options.data,
header: {
'Content-Type': 'application/json',
...(token ? { Authorization: `Bearer ${token}` } : {})
},
success: (res) => {
const status = res.statusCode
const data = res.data
if (status === 401) {
onUnauthorized()
reject(new Error('登录已过期'))
return
}
if (status >= 200 && status < 300) {
const businessError = portalBusinessErrorMessage(data)
if (businessError) {
if (showError) {
uni.showToast({ title: businessError.slice(0, 40), icon: 'none' })
}
reject(new Error(businessError))
return
}
resolve(data)
return
}
const message = parseDetailMessage(data) || `请求失败(${status})`
if (showError) {
uni.showToast({ title: message.slice(0, 40), icon: 'none' })
}
reject(new Error(message))
},
fail: (err) => {
if (showError) {
uni.showToast({ title: '网络异常', icon: 'none' })
}
reject(err)
}
})
})
}
export const db = {
get: (url, params, opts) => dbRequest({ ...opts, url, method: 'GET', params }),
post: (url, data, opts) => dbRequest({ ...opts, url, method: 'POST', data }),
put: (url, data, opts) => dbRequest({ ...opts, url, method: 'PUT', data }),
patch: (url, data, opts) => dbRequest({ ...opts, url, method: 'PATCH', data }),
del: (url, opts) => dbRequest({ ...opts, url, method: 'DELETE' })
}
export default db