2026-06-09 19:29:04 +08:00
|
|
|
|
import { useUserStore } from '@/store'
|
|
|
|
|
|
|
2026-06-16 19:26:48 +08:00
|
|
|
|
export const baseUrl = 'https://lygcgs.com.cn:8078/shjapi/api/'
|
2026-06-24 16:50:38 +08:00
|
|
|
|
export const baseFileUrl = 'https://lygcgs.com.cn:8078/shj/'
|
2026-06-09 19:29:04 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
2026-07-06 16:46:07 +08:00
|
|
|
|
* 将参数对象序列化为 URL query string
|
|
|
|
|
|
* 手动构建确保跨平台(小程序 / H5 / App)行为一致
|
|
|
|
|
|
* - 过滤 undefined 和 null
|
|
|
|
|
|
* - encodeURIComponent 编码中文和特殊字符
|
2026-06-09 19:29:04 +08:00
|
|
|
|
*/
|
2026-07-06 16:46:07 +08:00
|
|
|
|
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('&') : ''
|
2026-06-09 19:29:04 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2026-07-06 16:46:07 +08:00
|
|
|
|
* 核心请求方法(兼容 小程序 / H5 / App)
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param {string} url - API 路径(不含 baseUrl)
|
|
|
|
|
|
* @param {object} options - 可选配置
|
|
|
|
|
|
* {string} method - GET | POST,默认 GET
|
|
|
|
|
|
* {object} data - GET 时自动拼入 query string,POST 时作为请求体
|
|
|
|
|
|
* {object} header - 自定义请求头
|
|
|
|
|
|
* {boolean} loading - 是否显示 loading,默认 true
|
|
|
|
|
|
* {boolean} toast - 是否在失败时弹 toast,默认 true
|
2026-06-09 19:29:04 +08:00
|
|
|
|
*/
|
2026-07-06 16:46:07 +08:00
|
|
|
|
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
|
2026-06-09 19:29:04 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-07-06 16:46:07 +08:00
|
|
|
|
// GET: 手动拼 query string(不依赖 uni.request 各平台差异)
|
|
|
|
|
|
let fullUrl = `${baseUrl}${url}`
|
|
|
|
|
|
if (method === 'GET' && data) {
|
|
|
|
|
|
fullUrl += toQueryString(data)
|
|
|
|
|
|
}
|
2026-06-09 19:29:04 +08:00
|
|
|
|
|
2026-07-06 16:46:07 +08:00
|
|
|
|
if (loading) {
|
|
|
|
|
|
uni.showLoading({ title: '加载中...', mask: true })
|
|
|
|
|
|
}
|
2026-06-09 19:29:04 +08:00
|
|
|
|
|
2026-07-06 16:46:07 +08:00
|
|
|
|
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)
|
|
|
|
|
|
}
|
2026-06-09 19:29:04 +08:00
|
|
|
|
})
|
2026-07-06 16:46:07 +08:00
|
|
|
|
})
|
2026-06-09 19:29:04 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2026-07-06 16:46:07 +08:00
|
|
|
|
* GET 快捷方法
|
|
|
|
|
|
* 兼容两种调用方式:
|
|
|
|
|
|
* get('/path?key=val') 旧风格(URL 自带参数)
|
|
|
|
|
|
* get('/path', { key: 'val' }) 新风格(参数对象,自动编码)
|
2026-06-09 19:29:04 +08:00
|
|
|
|
*/
|
2026-07-06 16:46:07 +08:00
|
|
|
|
export const get = (url, params) => {
|
|
|
|
|
|
if (params) {
|
|
|
|
|
|
url += toQueryString(params)
|
|
|
|
|
|
}
|
|
|
|
|
|
return request(url, { method: 'GET' })
|
2026-06-09 19:29:04 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-07-06 16:46:07 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* POST 快捷方法
|
|
|
|
|
|
*/
|
|
|
|
|
|
export const post = (url, data) => {
|
|
|
|
|
|
return request(url, { method: 'POST', data })
|
2026-06-09 19:29:04 +08:00
|
|
|
|
}
|
2026-06-11 09:43:42 +08:00
|
|
|
|
|
2026-06-24 16:50:38 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 解析附件 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
|
2026-07-06 16:46:07 +08:00
|
|
|
|
return urlStr.split(',').filter(Boolean).map((url) => ({
|
2026-06-24 16:50:38 +08:00
|
|
|
|
_id: ++id,
|
|
|
|
|
|
src: `${baseFileUrl}${url}`,
|
2026-06-24 20:50:15 +08:00
|
|
|
|
_attachUrl: url,
|
2026-06-24 16:50:38 +08:00
|
|
|
|
uploaded: true
|
|
|
|
|
|
}))
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-06-11 09:43:42 +08:00
|
|
|
|
export const getUrlParam = (url, name) => {
|
2026-07-06 16:46:07 +08:00
|
|
|
|
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
|
|
|
|
|
|
}
|