befly-admin 3.13.1 → 3.13.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +3 -3
- package/src/layouts/default.vue +0 -1
- package/src/plugins/http.js +99 -101
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "befly-admin",
|
|
3
|
-
"version": "3.13.
|
|
4
|
-
"gitHead": "
|
|
3
|
+
"version": "3.13.3",
|
|
4
|
+
"gitHead": "c71ecec269032dcc0aa8ca995da4918f99f5ee0e",
|
|
5
5
|
"private": false,
|
|
6
6
|
"description": "Befly Admin - 基于 Vue3 + TDesign Vue Next 的后台管理系统",
|
|
7
7
|
"files": [
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"axios": "^1.13.5",
|
|
32
32
|
"befly-admin-ui": "1.8.14",
|
|
33
|
-
"befly-vite": "^1.5.
|
|
33
|
+
"befly-vite": "^1.5.1",
|
|
34
34
|
"pinia": "^3.0.4",
|
|
35
35
|
"tdesign-icons-vue-next": "^0.4.0",
|
|
36
36
|
"tdesign-vue-next": "^1.18.2",
|
package/src/layouts/default.vue
CHANGED
|
@@ -77,7 +77,6 @@
|
|
|
77
77
|
<script setup>
|
|
78
78
|
import { arrayToTree } from "befly-admin-ui/utils/arrayToTree";
|
|
79
79
|
import { isString } from "../utils/is.js";
|
|
80
|
-
import { CloseCircleIcon, CloudIcon, CodeIcon, LinkIcon, MenuIcon, SettingIcon, UserIcon } from "tdesign-icons-vue-next";
|
|
81
80
|
|
|
82
81
|
import { reactive } from "vue";
|
|
83
82
|
|
package/src/plugins/http.js
CHANGED
|
@@ -1,140 +1,138 @@
|
|
|
1
|
-
import axios, { AxiosHeaders } from "axios";
|
|
2
1
|
import { cleanParams } from "befly-admin-ui/utils/cleanParams";
|
|
3
2
|
|
|
4
3
|
import { $Storage } from "./storage";
|
|
5
4
|
|
|
6
|
-
function
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
function buildUrl(url, queryData) {
|
|
6
|
+
const baseUrl = import.meta.env["VITE_API_BASE_URL"] || "";
|
|
7
|
+
const absoluteInputUrl = /^https?:\/\//i.test(url);
|
|
8
|
+
let finalUrl = absoluteInputUrl ? String(url) : `${String(baseUrl).replace(/\/+$/, "")}/${String(url).replace(/^\/+/, "")}`;
|
|
9
|
+
|
|
10
|
+
if (!queryData || typeof queryData !== "object") {
|
|
11
|
+
return finalUrl;
|
|
9
12
|
}
|
|
10
13
|
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
+
const params = new URLSearchParams();
|
|
15
|
+
for (const key of Object.keys(queryData)) {
|
|
16
|
+
const value = queryData[key];
|
|
14
17
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
+
if (value === null || value === undefined) {
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
18
21
|
|
|
19
|
-
|
|
20
|
-
|
|
22
|
+
if (Array.isArray(value)) {
|
|
23
|
+
for (const item of value) {
|
|
24
|
+
if (item === null || item === undefined) {
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
params.append(key, String(item));
|
|
28
|
+
}
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
21
31
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
if (Array.isArray(value)) return false;
|
|
25
|
-
if (value instanceof FormData) return false;
|
|
26
|
-
return true;
|
|
27
|
-
}
|
|
32
|
+
params.append(key, String(value));
|
|
33
|
+
}
|
|
28
34
|
|
|
29
|
-
|
|
30
|
-
if (
|
|
31
|
-
return
|
|
35
|
+
const query = params.toString();
|
|
36
|
+
if (query.length === 0) {
|
|
37
|
+
return finalUrl;
|
|
32
38
|
}
|
|
33
39
|
|
|
34
|
-
|
|
35
|
-
const dropKeyValue = cleanOptions?.dropKeyValue;
|
|
36
|
-
return cleanParams(data, dropValues ?? [], dropKeyValue);
|
|
40
|
+
return `${finalUrl}${finalUrl.includes("?") ? "&" : "?"}${query}`;
|
|
37
41
|
}
|
|
38
42
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
43
|
+
async function request(method, url, data, options) {
|
|
44
|
+
const requestConfig = options ? Object.assign({}, options) : {};
|
|
45
|
+
delete requestConfig["dropValues"];
|
|
46
|
+
delete requestConfig["dropKeyValue"];
|
|
47
|
+
|
|
48
|
+
const headers = new Headers(requestConfig.headers || {});
|
|
49
|
+
const token = $Storage.local.get("token");
|
|
50
|
+
if (token) {
|
|
51
|
+
headers.set("Authorization", `Bearer ${token}`);
|
|
46
52
|
}
|
|
47
|
-
}
|
|
48
53
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
}
|
|
54
|
+
let finalUrl = String(url);
|
|
55
|
+
if (method === "GET") {
|
|
56
|
+
const inputData = data ?? {};
|
|
57
|
+
const queryData = typeof inputData === "object" && inputData !== null && !Array.isArray(inputData) && !(inputData instanceof FormData) ? cleanParams(inputData, options?.dropValues ?? [], options?.dropKeyValue) : inputData;
|
|
58
|
+
finalUrl = buildUrl(finalUrl, queryData);
|
|
59
|
+
} else {
|
|
60
|
+
finalUrl = buildUrl(finalUrl);
|
|
61
|
+
|
|
62
|
+
let body = data;
|
|
63
|
+
if (data === undefined) {
|
|
64
|
+
body = {};
|
|
65
|
+
}
|
|
52
66
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
67
|
+
if (!(body instanceof FormData)) {
|
|
68
|
+
const cleaned = typeof body === "object" && body !== null && !Array.isArray(body) ? cleanParams(body, options?.dropValues ?? [], options?.dropKeyValue) : body;
|
|
69
|
+
const finalBody = typeof cleaned === "object" && cleaned !== null && !Array.isArray(cleaned) && Object.keys(cleaned).length === 0 ? {} : cleaned;
|
|
70
|
+
headers.set("Content-Type", "application/json");
|
|
71
|
+
requestConfig.body = JSON.stringify(finalBody);
|
|
72
|
+
} else {
|
|
73
|
+
requestConfig.body = body;
|
|
74
|
+
}
|
|
59
75
|
}
|
|
60
|
-
}
|
|
61
76
|
|
|
62
|
-
|
|
77
|
+
requestConfig.method = method;
|
|
78
|
+
requestConfig.headers = headers;
|
|
79
|
+
|
|
63
80
|
try {
|
|
64
|
-
const response = await
|
|
65
|
-
|
|
81
|
+
const response = await fetch(finalUrl, requestConfig);
|
|
82
|
+
if (!response.ok) {
|
|
83
|
+
throw new Error(`HTTP ${response.status}`, {
|
|
84
|
+
cause: null,
|
|
85
|
+
code: "runtime",
|
|
86
|
+
subsystem: "adminHttp",
|
|
87
|
+
operation: "request"
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const contentType = response.headers.get("content-type") || "";
|
|
92
|
+
if (!contentType.toLowerCase().includes("application/json")) {
|
|
93
|
+
throw new Error("响应不是 JSON", {
|
|
94
|
+
cause: null,
|
|
95
|
+
code: "runtime",
|
|
96
|
+
subsystem: "adminHttp",
|
|
97
|
+
operation: "request"
|
|
98
|
+
});
|
|
99
|
+
}
|
|
66
100
|
|
|
101
|
+
const res = await response.json();
|
|
67
102
|
if (res.code !== 0) {
|
|
68
|
-
throw new
|
|
103
|
+
throw new Error(res.msg || "请求失败", {
|
|
104
|
+
cause: {
|
|
105
|
+
type: "api",
|
|
106
|
+
apiCode: res.code,
|
|
107
|
+
apiData: res.data
|
|
108
|
+
},
|
|
109
|
+
code: "runtime",
|
|
110
|
+
subsystem: "adminHttp",
|
|
111
|
+
operation: "request"
|
|
112
|
+
});
|
|
69
113
|
}
|
|
70
114
|
|
|
71
115
|
return res;
|
|
72
116
|
} catch (error) {
|
|
73
|
-
|
|
74
|
-
if (isNormalizedHttpError(error)) {
|
|
117
|
+
if (error instanceof Error && error.cause && typeof error.cause === "object" && error.cause.type === "api") {
|
|
75
118
|
throw error;
|
|
76
119
|
}
|
|
77
120
|
|
|
78
|
-
|
|
79
|
-
|
|
121
|
+
throw new Error("网络连接失败", {
|
|
122
|
+
cause: error,
|
|
123
|
+
code: "runtime",
|
|
124
|
+
subsystem: "adminHttp",
|
|
125
|
+
operation: "request"
|
|
126
|
+
});
|
|
80
127
|
}
|
|
81
128
|
}
|
|
82
129
|
|
|
83
|
-
// 创建 axios 实例
|
|
84
|
-
const request = axios.create({
|
|
85
|
-
baseURL: import.meta.env["VITE_API_BASE_URL"] || "",
|
|
86
|
-
timeout: 10000,
|
|
87
|
-
headers: {
|
|
88
|
-
"Content-Type": "application/json"
|
|
89
|
-
}
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
// 请求拦截器
|
|
93
|
-
request.interceptors.request.use(
|
|
94
|
-
(config) => {
|
|
95
|
-
const token = $Storage.local.get("token");
|
|
96
|
-
if (token) {
|
|
97
|
-
const headers = new AxiosHeaders(config.headers);
|
|
98
|
-
headers.set("Authorization", `Bearer ${token}`);
|
|
99
|
-
config.headers = headers;
|
|
100
|
-
}
|
|
101
|
-
return config;
|
|
102
|
-
},
|
|
103
|
-
(error) => {
|
|
104
|
-
return Promise.reject(error);
|
|
105
|
-
}
|
|
106
|
-
);
|
|
107
|
-
|
|
108
130
|
async function httpGet(url, data, options) {
|
|
109
|
-
|
|
110
|
-
const inputData = data ?? {};
|
|
111
|
-
const cleanedData = maybeCleanRequestData(inputData, options);
|
|
112
|
-
|
|
113
|
-
// 规则:GET 必须传 params;为空也传空对象
|
|
114
|
-
const finalConfig = Object.assign({}, axiosConfig);
|
|
115
|
-
finalConfig.params = cleanedData;
|
|
116
|
-
|
|
117
|
-
return unwrapApiResponse(request.get(url, finalConfig));
|
|
131
|
+
return request("GET", url, data, options);
|
|
118
132
|
}
|
|
119
133
|
|
|
120
134
|
async function httpPost(url, data, options) {
|
|
121
|
-
|
|
122
|
-
if (data === undefined) {
|
|
123
|
-
// 规则:POST 必须传 body;为空也传空对象
|
|
124
|
-
return unwrapApiResponse(request.post(url, {}, axiosConfig));
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
if (data instanceof FormData) {
|
|
128
|
-
return unwrapApiResponse(request.post(url, data, axiosConfig));
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
const cleanedData = maybeCleanRequestData(data, options);
|
|
132
|
-
if (Object.keys(cleanedData).length === 0) {
|
|
133
|
-
// 规则:POST 必须传 body;清洗为空则传空对象
|
|
134
|
-
return unwrapApiResponse(request.post(url, {}, axiosConfig));
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
return unwrapApiResponse(request.post(url, cleanedData, axiosConfig));
|
|
135
|
+
return request("POST", url, data, options);
|
|
138
136
|
}
|
|
139
137
|
|
|
140
138
|
/**
|