Files
2026-07-06 16:46:07 +08:00

139 lines
3.6 KiB
JavaScript
Raw Permalink 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.
import { useUserStore } from '@/store'
export const baseUrl = 'https://lygcgs.com.cn:8078/shjapi/api/'
export const baseFileUrl = 'https://lygcgs.com.cn:8078/shj/'
/**
* 将参数对象序列化为 URL query string
* 手动构建确保跨平台(小程序 / H5 / App)行为一致
* - 过滤 undefined 和 null
* - encodeURIComponent 编码中文和特殊字符
*/
function toQueryString(params) {
if (!params) return ''
const parts = Object.keys(params)
.filter((k) => params[k] !== undefined && params[k] !== null)
.map((k) => `${encodeURIComponent(k)}=${encodeURIComponent(params[k])}`)
return parts.length ? '?' + parts.join('&') : ''
}
/**
* 核心请求方法(兼容 小程序 / H5 / App)
*
* @param {string} url - API 路径(不含 baseUrl
* @param {object} options - 可选配置
* {string} method - GET | POST,默认 GET
* {object} data - GET 时自动拼入 query stringPOST 时作为请求体
* {object} header - 自定义请求头
* {boolean} loading - 是否显示 loading,默认 true
* {boolean} toast - 是否在失败时弹 toast,默认 true
*/
export function request(url, options = {}) {
const {
method = 'GET',
data,
header = {},
loading = true,
toast = true
} = options
const userStore = useUserStore()
const headers = {
'content-type': 'application/json',
...header
}
if (userStore.token) {
headers.token = userStore.token
}
// GET: 手动拼 query string(不依赖 uni.request 各平台差异)
let fullUrl = `${baseUrl}${url}`
if (method === 'GET' && data) {
fullUrl += toQueryString(data)
}
if (loading) {
uni.showLoading({ title: '加载中...', mask: true })
}
return new Promise((resolve, reject) => {
uni.request({
url: fullUrl,
method,
data: method === 'POST' ? data : undefined,
header: headers,
success: (res) => {
if (loading) uni.hideLoading()
const body = res.data
if (body.code !== 1) {
if (toast) {
uni.showToast({
title: body.message || '请求失败',
icon: 'none'
})
}
if (body.code === 401) {
userStore.logout()
uni.reLaunch({ url: '/pages/login/index' })
}
reject(new Error(body.message || '请求失败'))
return
}
resolve(body)
},
fail: (err) => {
if (loading) uni.hideLoading()
uni.showToast({ title: '网络连接失败', icon: 'none' })
reject(err)
}
})
})
}
/**
* GET 快捷方法
* 兼容两种调用方式:
* get('/path?key=val') 旧风格(URL 自带参数)
* get('/path', { key: 'val' }) 新风格(参数对象,自动编码)
*/
export const get = (url, params) => {
if (params) {
url += toQueryString(params)
}
return request(url, { method: 'GET' })
}
/**
* POST 快捷方法
*/
export const post = (url, data) => {
return request(url, { method: 'POST', data })
}
/**
* 解析附件 URL 字符串为可展示的照片列表
* @param {string} urlStr - 逗号分隔的附件路径,如 "FileUpLoad/xxx.png,FileUpLoad/yyy.png"
* @param {number} startId - 起始 ID,用于生成唯一标识
* @returns {Array<{_id: number, src: string, uploaded: boolean}>}
*/
export const parseAttachUrls = (urlStr, startId = 0) => {
if (!urlStr) return []
let id = startId
return urlStr.split(',').filter(Boolean).map((url) => ({
_id: ++id,
src: `${baseFileUrl}${url}`,
_attachUrl: url,
uploaded: true
}))
}
export const getUrlParam = (url, name) => {
if (!url || !name) return null
const regex = new RegExp(`[?&]${name}=([^&]*)`, 'i')
const match = url.match(regex)
if (match && match[1]) {
return decodeURIComponent(match[1])
}
return null
}