OfficeSystem/utils/url.js
2025-11-27 10:14:55 +08:00

166 lines
4.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.

/**
* URL构建工具
* 统一处理查询参数的构建,支持数组、对象、特殊字符编码等
*/
/**
* 构建带查询参数的URL
* @param {string} basePath - 基础路径(如 'bst/task/list'
* @param {Object} params - 查询参数对象
* @param {Object} options - 配置选项
* @param {boolean} options.encodeValues - 是否对值进行URL编码默认true
* @param {boolean} options.skipEmpty - 是否跳过空值默认true
* @param {string} options.arrayFormat - 数组格式:'repeat'(重复参数)或 'bracket'(带索引),默认'repeat'
* @returns {string} 完整的URL字符串
*
* @example
* // 基础用法
* buildUrl('bst/task/list', { pageNum: 1, pageSize: 10 })
* // => 'bst/task/list?pageNum=1&pageSize=10'
*
* @example
* // 数组参数(重复格式)
* buildUrl('bst/task/list', { statusList: [1, 2, 3] })
* // => 'bst/task/list?statusList=1&statusList=2&statusList=3'
*
* @example
* // 数组参数(带索引格式)
* buildUrl('bst/project/list', { keys: ['key1', 'key2'] }, { arrayFormat: 'bracket' })
* // => 'bst/project/list?keys[0]=key1&keys[1]=key2'
*
* @example
* // 包含特殊字符
* buildUrl('bst/task/list', { orderByColumn: 'create time', isAsc: 'ascending' })
* // => 'bst/task/list?orderByColumn=create%20time&isAsc=ascending'
*/
export function buildUrl(basePath, params = {}, options = {}) {
const {
encodeValues = true,
skipEmpty = true,
arrayFormat = 'repeat' // 'repeat' | 'bracket'
} = options
// 如果没有参数,直接返回基础路径
if (!params || Object.keys(params).length === 0) {
return basePath
}
const queryParams = []
/**
* 编码值
* @param {any} value - 要编码的值
* @returns {string} 编码后的字符串
*/
const encodeValue = (value) => {
if (encodeValues) {
return encodeURIComponent(String(value))
}
return String(value)
}
/**
* 添加查询参数
* @param {string} key - 参数名
* @param {any} value - 参数值
*/
const addParam = (key, value) => {
// 跳过空值
if (skipEmpty && (value === null || value === undefined || value === '')) {
return
}
const encodedKey = encodeURIComponent(key)
// 处理数组
if (Array.isArray(value)) {
if (value.length === 0) return
value.forEach((item, index) => {
// 跳过数组中的空值
if (skipEmpty && (item === null || item === undefined || item === '')) {
return
}
if (arrayFormat === 'bracket') {
// 带索引格式keys[0]=value1
queryParams.push(`${encodedKey}[${index}]=${encodeValue(item)}`)
} else {
// 重复格式key=value1&key=value2
queryParams.push(`${encodedKey}=${encodeValue(item)}`)
}
})
return
}
// 处理对象转换为JSON字符串
if (typeof value === 'object' && value !== null) {
queryParams.push(`${encodedKey}=${encodeValue(JSON.stringify(value))}`)
return
}
// 处理布尔值
if (typeof value === 'boolean') {
queryParams.push(`${encodedKey}=${value}`)
return
}
// 处理普通值
queryParams.push(`${encodedKey}=${encodeValue(value)}`)
}
// 遍历所有参数
Object.entries(params).forEach(([key, value]) => {
addParam(key, value)
})
// 构建查询字符串
const queryString = queryParams.length > 0 ? `?${queryParams.join('&')}` : ''
return `${basePath}${queryString}`
}
/**
* 合并默认参数和用户参数
* @param {Object} defaultParams - 默认参数
* @param {Object} userParams - 用户传入的参数
* @returns {Object} 合并后的参数对象(用户参数优先)
*
* @example
* mergeParams({ pageNum: 1, pageSize: 10 }, { pageNum: 2 })
* // => { pageNum: 2, pageSize: 10 }
*/
export function mergeParams(defaultParams = {}, userParams = {}) {
return { ...defaultParams, ...userParams }
}
/**
* 从URL中提取查询参数
* @param {string} url - 完整URL或查询字符串
* @returns {Object} 参数对象
*
* @example
* parseUrl('bst/task/list?pageNum=1&pageSize=10')
* // => { pageNum: '1', pageSize: '10' }
*/
export function parseUrl(url) {
const params = {}
try {
const queryString = url.includes('?') ? url.split('?')[1] : url
if (!queryString) return params
queryString.split('&').forEach(param => {
const [key, value] = param.split('=')
if (key) {
params[decodeURIComponent(key)] = value ? decodeURIComponent(value) : ''
}
})
} catch (error) {
console.error('解析URL参数失败:', error)
}
return params
}