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 string,POST 时作为请求体 * {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 }