|
@@ -161,3 +161,70 @@ export function getEnvBaseUploadUrl() {
|
|
|
|
|
|
return baseUploadUrl
|
|
|
}
|
|
|
+
|
|
|
+// 其他公共方法
|
|
|
+
|
|
|
+export function extractAndRetained(obj, keys) {
|
|
|
+ const extract = {}
|
|
|
+ const retained = { ...obj } // 创建浅拷贝
|
|
|
+
|
|
|
+ keys.forEach((key) => {
|
|
|
+ if (Object.prototype.hasOwnProperty.call(retained, key)) {
|
|
|
+ extract[key] = retained[key]
|
|
|
+ delete retained[key]
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ return { extract, retained }
|
|
|
+}
|
|
|
+// 地址栏参数拼接
|
|
|
+/**
|
|
|
+ * 将对象序列化为 URL 查询字符串
|
|
|
+ * @param {object} params - 需要序列化的参数对象
|
|
|
+ * @returns {string} 序列化后的查询字符串
|
|
|
+ */
|
|
|
+export function qs(params) {
|
|
|
+ return Object.entries(params)
|
|
|
+ .map(([key, value]) => {
|
|
|
+ const encodedKey = encodeURIComponent(key)
|
|
|
+ const encodedValue
|
|
|
+ = value === undefined || value === null
|
|
|
+ ? ''
|
|
|
+ : encodeURIComponent(String(value))
|
|
|
+ return `${encodedKey}=${encodedValue}`
|
|
|
+ })
|
|
|
+ .join('&')
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 解析 URL 查询字符串为对象
|
|
|
+ * @param {string} queryString - 需要解析的查询字符串(如 "a=1&b=2")
|
|
|
+ * @returns {object} 解析后的参数对象
|
|
|
+ */
|
|
|
+export function parseQs(queryString) {
|
|
|
+ if (!queryString)
|
|
|
+ return {}
|
|
|
+
|
|
|
+ // 移除开头的问号(如果有)
|
|
|
+ const cleanQuery = queryString.startsWith('?')
|
|
|
+ ? queryString.slice(1)
|
|
|
+ : queryString
|
|
|
+
|
|
|
+ return cleanQuery.split('&')
|
|
|
+ .reduce((acc, pair) => {
|
|
|
+ const [encodedKey, encodedValue] = pair.split('=')
|
|
|
+
|
|
|
+ if (encodedKey === undefined)
|
|
|
+ return acc
|
|
|
+
|
|
|
+ const key = decodeURIComponent(encodedKey)
|
|
|
+ const value = encodedValue === undefined
|
|
|
+ ? undefined
|
|
|
+ : decodeURIComponent(encodedValue)
|
|
|
+
|
|
|
+ // 处理空字符串值
|
|
|
+ acc[key] = value === '' ? null : value
|
|
|
+
|
|
|
+ return acc
|
|
|
+ }, {})
|
|
|
+}
|