@jx3box/jx3box-common 8.7.5 → 9.0.0
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/js/api.js +242 -0
- package/js/user.js +34 -57
- package/js/user_old.js +330 -0
- package/js/utils.js +19 -57
- package/package.json +1 -2
package/js/api.js
ADDED
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
// 统一 API 封装(由 https_v2.js / https.js / request.js 合并)
|
|
2
|
+
import axios from "axios";
|
|
3
|
+
import domains from "../data/jx3box.json";
|
|
4
|
+
import { SSE } from "./sse";
|
|
5
|
+
import { ElMessage, ElMessageBox, ElNotification } from "element-plus";
|
|
6
|
+
import utilModule, { getTokenFromUrl } from "./utils";
|
|
7
|
+
|
|
8
|
+
const { jx3ClientType } = utilModule;
|
|
9
|
+
|
|
10
|
+
function readAuthToken() {
|
|
11
|
+
const tokenFromUrl = getTokenFromUrl();
|
|
12
|
+
if (tokenFromUrl) return tokenFromUrl;
|
|
13
|
+
return (localStorage && (localStorage.getItem("__token") || localStorage.getItem("token"))) || "";
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function readEnv(key) {
|
|
17
|
+
// 需要在 vite.config.js 配置 envPrefix 包含 VUE_APP_
|
|
18
|
+
return (import.meta && import.meta.env && import.meta.env[key]) || "";
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function localProxyEnabled(options) {
|
|
22
|
+
if (!import.meta?.env?.DEV) return false;
|
|
23
|
+
if (options && options.proxy === false) return false;
|
|
24
|
+
if (options && options.proxy === true) return true;
|
|
25
|
+
const raw = (readEnv("VUE_APP_PROXY_ENABLE") || "").toString().toLowerCase();
|
|
26
|
+
return raw === "1" || raw === "true" || raw === "yes" || raw === "on";
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function localProxyBase(serviceKey) {
|
|
30
|
+
const prefix = readEnv("VUE_APP_PROXY_PREFIX") || "/__proxy";
|
|
31
|
+
return `${prefix}/${serviceKey}`;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function loadPop(msg, popType = "message") {
|
|
35
|
+
const message = msg || "网络请求异常";
|
|
36
|
+
switch (popType) {
|
|
37
|
+
case "message":
|
|
38
|
+
ElMessage({ message, type: "error" });
|
|
39
|
+
break;
|
|
40
|
+
case "alert":
|
|
41
|
+
ElMessageBox.alert(message, "错误");
|
|
42
|
+
break;
|
|
43
|
+
case "notify":
|
|
44
|
+
ElNotification({ title: "错误", message, duration: 3000 });
|
|
45
|
+
break;
|
|
46
|
+
default:
|
|
47
|
+
ElMessage({ message, type: "error" });
|
|
48
|
+
break;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function throwError(err) {
|
|
53
|
+
console.log(err?.response);
|
|
54
|
+
return Promise.reject(err);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function loadDefaultRequestErrorPop(err, popType = "message") {
|
|
58
|
+
const status = err?.response?.status ?? "";
|
|
59
|
+
const statusText = err?.response?.statusText ?? "Request Error";
|
|
60
|
+
loadPop(`[${status}]${statusText}`, popType);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function installInterceptors(target, options) {
|
|
64
|
+
const popType = (options && options.popType) || "message";
|
|
65
|
+
target.interceptors.response.use(
|
|
66
|
+
(response) => response,
|
|
67
|
+
(err) => {
|
|
68
|
+
if (!options || !options.mute) {
|
|
69
|
+
if (err?.response?.data?.msg) {
|
|
70
|
+
loadPop(err.response.data.msg, popType);
|
|
71
|
+
} else {
|
|
72
|
+
loadDefaultRequestErrorPop(err, popType);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return throwError(err);
|
|
76
|
+
}
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function installStandardInterceptors(target, options) {
|
|
81
|
+
const popType = (options && options.popType) || "message";
|
|
82
|
+
target.interceptors.response.use(
|
|
83
|
+
(response) => {
|
|
84
|
+
if (response?.data?.code) {
|
|
85
|
+
if (!options || !options.mute) {
|
|
86
|
+
response.data.msg && loadPop(`[${response.data.code}]${response.data.msg}`, popType);
|
|
87
|
+
}
|
|
88
|
+
return Promise.reject(response);
|
|
89
|
+
}
|
|
90
|
+
return response;
|
|
91
|
+
},
|
|
92
|
+
(err) => {
|
|
93
|
+
if (!options || !options.mute) {
|
|
94
|
+
if (err?.response?.data?.msg) {
|
|
95
|
+
loadPop(err.response.data.msg, popType);
|
|
96
|
+
} else {
|
|
97
|
+
loadDefaultRequestErrorPop(err, popType);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return throwError(err);
|
|
101
|
+
}
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function installHelperInterceptors(target, options) {
|
|
106
|
+
const popType = (options && options.popType) || "message";
|
|
107
|
+
target.interceptors.response.use(
|
|
108
|
+
(response) => {
|
|
109
|
+
const code = response?.data?.code;
|
|
110
|
+
if (code === 200 || !code) return response;
|
|
111
|
+
if (!options || !options.mute) {
|
|
112
|
+
loadPop(`[${code}]${response?.data?.message || ""}`, popType);
|
|
113
|
+
}
|
|
114
|
+
return Promise.reject(response);
|
|
115
|
+
},
|
|
116
|
+
(err) => {
|
|
117
|
+
if (!options || !options.mute) {
|
|
118
|
+
loadDefaultRequestErrorPop(err, popType);
|
|
119
|
+
}
|
|
120
|
+
return throwError(err);
|
|
121
|
+
}
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function $cms(options = {}, axiosConfig = {}) {
|
|
126
|
+
const { interceptor = true, domain, progress } = options;
|
|
127
|
+
const requestDomain = domain || readEnv("VUE_APP_CMS_API") || domains.__cms;
|
|
128
|
+
const token = readAuthToken();
|
|
129
|
+
|
|
130
|
+
const config = {
|
|
131
|
+
withCredentials: true,
|
|
132
|
+
auth: { username: token || "", password: "cms common request" },
|
|
133
|
+
baseURL: localProxyEnabled(options) ? localProxyBase("cms") : requestDomain,
|
|
134
|
+
headers: {},
|
|
135
|
+
};
|
|
136
|
+
if (progress) config.onUploadProgress = progress;
|
|
137
|
+
|
|
138
|
+
const ins = axios.create(Object.assign(axiosConfig, config));
|
|
139
|
+
interceptor && installStandardInterceptors(ins, options);
|
|
140
|
+
return ins;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
function $helper(options = {}) {
|
|
144
|
+
const domain = (options && options.domain) || readEnv("VUE_APP_HELPER_API") || domains.__helperUrl;
|
|
145
|
+
const token = readAuthToken();
|
|
146
|
+
|
|
147
|
+
const config = {
|
|
148
|
+
withCredentials: true,
|
|
149
|
+
auth: { username: token || "", password: "helper common request" },
|
|
150
|
+
baseURL: localProxyEnabled(options) ? localProxyBase("helper") : domain,
|
|
151
|
+
headers: {
|
|
152
|
+
Accept: "application/prs.helper.v2+json",
|
|
153
|
+
"JX3-Client-Type": (options && options.client_id) || jx3ClientType(),
|
|
154
|
+
},
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
if (options && options.headers) {
|
|
158
|
+
config.headers = Object.assign(config.headers, options.headers);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
const ins = axios.create(config);
|
|
162
|
+
installHelperInterceptors(ins, options);
|
|
163
|
+
return ins;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
function $next(options = {}, axiosConfig = {}) {
|
|
167
|
+
const { interceptor = true, domain, progress } = options;
|
|
168
|
+
const requestDomain = domain || readEnv("VUE_APP_NEXT_API") || domains.__next;
|
|
169
|
+
const token = readAuthToken();
|
|
170
|
+
const serviceKey = (options && options.serviceKey) || "next";
|
|
171
|
+
|
|
172
|
+
const config = {
|
|
173
|
+
withCredentials: true,
|
|
174
|
+
auth: { username: token || "", password: "next common request" },
|
|
175
|
+
baseURL: localProxyEnabled(options) ? localProxyBase(serviceKey) : requestDomain,
|
|
176
|
+
headers: {},
|
|
177
|
+
};
|
|
178
|
+
if (progress) config.onUploadProgress = progress;
|
|
179
|
+
|
|
180
|
+
const ins = axios.create(Object.assign(axiosConfig, config));
|
|
181
|
+
interceptor && installStandardInterceptors(ins, options);
|
|
182
|
+
return ins;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
function $team(options = {}) {
|
|
186
|
+
const requestDomain = (options && options.domain) || readEnv("VUE_APP_TEAM_API") || domains.__team;
|
|
187
|
+
return $next(Object.assign({}, options, { domain: requestDomain, serviceKey: "team" }));
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
function $pay(options = {}) {
|
|
191
|
+
const requestDomain = (options && options.domain) || readEnv("VUE_APP_PAY_API") || domains.__pay;
|
|
192
|
+
return $next(Object.assign({}, options, { domain: requestDomain, serviceKey: "pay" }));
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
function $lua(options = {}) {
|
|
196
|
+
const requestDomain = (options && options.domain) || readEnv("VUE_APP_LUA_API") || domains.__lua;
|
|
197
|
+
return $next(Object.assign({}, options, { domain: requestDomain, serviceKey: "lua" }));
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
function $node(options = {}) {
|
|
201
|
+
const requestDomain = (options && options.domain) || readEnv("VUE_APP_NODE_API") || domains.__node;
|
|
202
|
+
const token = readAuthToken();
|
|
203
|
+
const config = {
|
|
204
|
+
withCredentials: true,
|
|
205
|
+
auth: { username: token || "", password: "node common request" },
|
|
206
|
+
baseURL: localProxyEnabled(options) ? localProxyBase("node") : requestDomain,
|
|
207
|
+
};
|
|
208
|
+
const ins = axios.create(config);
|
|
209
|
+
installInterceptors(ins, options);
|
|
210
|
+
return ins;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
function $http(options) {
|
|
214
|
+
const domain = typeof options === "string" ? options : options.domain;
|
|
215
|
+
const token = readAuthToken();
|
|
216
|
+
const config = {
|
|
217
|
+
withCredentials: true,
|
|
218
|
+
auth: { username: token || "", password: "common request" },
|
|
219
|
+
baseURL: domain,
|
|
220
|
+
headers: Object.assign({}, (options && options.headers) || {}),
|
|
221
|
+
};
|
|
222
|
+
const ins = axios.create(config);
|
|
223
|
+
installStandardInterceptors(ins, options);
|
|
224
|
+
return ins;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
export {
|
|
228
|
+
axios,
|
|
229
|
+
SSE,
|
|
230
|
+
$cms,
|
|
231
|
+
$next,
|
|
232
|
+
$helper,
|
|
233
|
+
$node,
|
|
234
|
+
$team,
|
|
235
|
+
$pay,
|
|
236
|
+
$lua,
|
|
237
|
+
$http,
|
|
238
|
+
// 兼容:少数脚本会直接用到拦截器
|
|
239
|
+
installInterceptors,
|
|
240
|
+
installStandardInterceptors,
|
|
241
|
+
installHelperInterceptors,
|
|
242
|
+
};
|
package/js/user.js
CHANGED
|
@@ -1,11 +1,6 @@
|
|
|
1
1
|
import { showAvatar } from "./utils";
|
|
2
|
-
import { $pay, $cms } from "./
|
|
3
|
-
import {
|
|
4
|
-
__Links,
|
|
5
|
-
default_avatar,
|
|
6
|
-
__server,
|
|
7
|
-
__userLevel,
|
|
8
|
-
} from "../data/jx3box.json";
|
|
2
|
+
import { $pay, $cms } from "./api";
|
|
3
|
+
import { __Links, default_avatar, __userLevel } from "../data/jx3box.json";
|
|
9
4
|
import { tokenExpires } from "../data/conf.json";
|
|
10
5
|
import Fingerprint2 from "fingerprintjs2";
|
|
11
6
|
import { getTokenFromUrl } from "./utils";
|
|
@@ -38,22 +33,15 @@ class User {
|
|
|
38
33
|
check() {
|
|
39
34
|
if (this.isLogin()) {
|
|
40
35
|
this.profile.uid = localStorage && localStorage.getItem("uid");
|
|
41
|
-
this.profile.group =
|
|
42
|
-
(localStorage && localStorage.getItem("group")) || 1;
|
|
36
|
+
this.profile.group = (localStorage && localStorage.getItem("group")) || 1;
|
|
43
37
|
this.profile.token = localStorage && localStorage.getItem("token");
|
|
44
38
|
this.profile.name = localStorage && localStorage.getItem("name");
|
|
45
|
-
this.profile.status =
|
|
46
|
-
|
|
47
|
-
this.profile.
|
|
48
|
-
localStorage && localStorage.getItem("bind_wx");
|
|
49
|
-
this.profile.avatar_origin =
|
|
50
|
-
(localStorage && localStorage.getItem("avatar")) ||
|
|
51
|
-
default_avatar;
|
|
39
|
+
this.profile.status = localStorage && localStorage.getItem("status");
|
|
40
|
+
this.profile.bind_wx = localStorage && localStorage.getItem("bind_wx");
|
|
41
|
+
this.profile.avatar_origin = (localStorage && localStorage.getItem("avatar")) || default_avatar;
|
|
52
42
|
this.profile.avatar = showAvatar(this.profile.avatar_origin, "s");
|
|
53
|
-
this.profile.permission =
|
|
54
|
-
|
|
55
|
-
this.profile.is_teammate =
|
|
56
|
-
localStorage && localStorage.getItem("is_teammate");
|
|
43
|
+
this.profile.permission = localStorage && localStorage.getItem("jx3box_permission");
|
|
44
|
+
this.profile.is_teammate = localStorage && localStorage.getItem("is_teammate");
|
|
57
45
|
} else {
|
|
58
46
|
this.profile = this.anonymous;
|
|
59
47
|
}
|
|
@@ -71,11 +59,8 @@ class User {
|
|
|
71
59
|
if (token) {
|
|
72
60
|
return true;
|
|
73
61
|
}
|
|
74
|
-
this.created_at = !localStorage.getItem("created_at")
|
|
75
|
-
|
|
76
|
-
: localStorage.getItem("created_at");
|
|
77
|
-
this.logged_in =
|
|
78
|
-
localStorage.getItem("logged_in") == "true" ? true : false;
|
|
62
|
+
this.created_at = !localStorage.getItem("created_at") ? -Infinity : localStorage.getItem("created_at");
|
|
63
|
+
this.logged_in = localStorage.getItem("logged_in") == "true" ? true : false;
|
|
79
64
|
return this.logged_in && Date.now() - this.created_at < this.expires;
|
|
80
65
|
}
|
|
81
66
|
|
|
@@ -108,7 +93,7 @@ class User {
|
|
|
108
93
|
if (localStorage) {
|
|
109
94
|
localStorage.clear();
|
|
110
95
|
this._save(data);
|
|
111
|
-
resolve(
|
|
96
|
+
resolve(data);
|
|
112
97
|
} else {
|
|
113
98
|
reject(new Error("localStorage不可用"));
|
|
114
99
|
}
|
|
@@ -185,13 +170,11 @@ class User {
|
|
|
185
170
|
if (this.isLogin()) {
|
|
186
171
|
return $cms()
|
|
187
172
|
.get("/api/cms/user/is_super_author/" + this.getInfo().uid)
|
|
188
|
-
.then(res => {
|
|
173
|
+
.then((res) => {
|
|
189
174
|
return res.data.data;
|
|
190
175
|
});
|
|
191
176
|
} else {
|
|
192
|
-
return
|
|
193
|
-
resolve(false);
|
|
194
|
-
});
|
|
177
|
+
return Promise.resolve(false);
|
|
195
178
|
}
|
|
196
179
|
}
|
|
197
180
|
|
|
@@ -229,11 +212,9 @@ class User {
|
|
|
229
212
|
// 判断是否为VIP
|
|
230
213
|
isVIP() {
|
|
231
214
|
if (this.asset) {
|
|
232
|
-
return
|
|
233
|
-
resolve(this._isPRO(this.asset) || this._isVIP(this.asset));
|
|
234
|
-
});
|
|
215
|
+
return Promise.resolve(this._isPRO(this.asset) || this._isVIP(this.asset));
|
|
235
216
|
} else {
|
|
236
|
-
return this.getAsset().then(asset => {
|
|
217
|
+
return this.getAsset().then((asset) => {
|
|
237
218
|
return this._isPRO(asset) || this._isVIP(asset);
|
|
238
219
|
});
|
|
239
220
|
}
|
|
@@ -242,11 +223,9 @@ class User {
|
|
|
242
223
|
// 判断是否为PRO
|
|
243
224
|
isPRO() {
|
|
244
225
|
if (this.asset) {
|
|
245
|
-
return
|
|
246
|
-
resolve(this._isPRO(this.asset));
|
|
247
|
-
});
|
|
226
|
+
return Promise.resolve(this._isPRO(this.asset));
|
|
248
227
|
} else {
|
|
249
|
-
return this.getAsset().then(asset => {
|
|
228
|
+
return this.getAsset().then((asset) => {
|
|
250
229
|
return this._isPRO(asset);
|
|
251
230
|
});
|
|
252
231
|
}
|
|
@@ -255,28 +234,26 @@ class User {
|
|
|
255
234
|
// 获取用户资产
|
|
256
235
|
getAsset() {
|
|
257
236
|
if (!this.isLogin()) {
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
resolve(asset);
|
|
275
|
-
});
|
|
237
|
+
const asset = {
|
|
238
|
+
was_vip: 0,
|
|
239
|
+
expire_date: "1970-02-02T16:00:00.000Z",
|
|
240
|
+
total_day: 0,
|
|
241
|
+
was_pro: 0,
|
|
242
|
+
pro_expire_date: "1970-02-02T16:00:00.000Z",
|
|
243
|
+
pro_total_day: 0,
|
|
244
|
+
rename_card_count: 0,
|
|
245
|
+
had_renamed: 0,
|
|
246
|
+
namespace_card_count: 0,
|
|
247
|
+
box_coin: 0,
|
|
248
|
+
points: 0,
|
|
249
|
+
};
|
|
250
|
+
this.asset = asset;
|
|
251
|
+
// 空资产
|
|
252
|
+
return Promise.resolve(asset);
|
|
276
253
|
} else {
|
|
277
254
|
return $pay()
|
|
278
255
|
.get("/api/vip/i")
|
|
279
|
-
.then(res => {
|
|
256
|
+
.then((res) => {
|
|
280
257
|
let asset = res.data.data;
|
|
281
258
|
this.asset = asset;
|
|
282
259
|
return asset;
|
package/js/user_old.js
ADDED
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
import { showAvatar } from "./utils";
|
|
2
|
+
import { $pay, $cms } from "./request";
|
|
3
|
+
import {
|
|
4
|
+
__Links,
|
|
5
|
+
default_avatar,
|
|
6
|
+
__server,
|
|
7
|
+
__userLevel,
|
|
8
|
+
} from "../data/jx3box.json";
|
|
9
|
+
import { tokenExpires } from "../data/conf.json";
|
|
10
|
+
import Fingerprint2 from "fingerprintjs2";
|
|
11
|
+
import { getTokenFromUrl } from "./utils";
|
|
12
|
+
|
|
13
|
+
class User {
|
|
14
|
+
constructor() {
|
|
15
|
+
// TOKEN有效期
|
|
16
|
+
this.expires = tokenExpires;
|
|
17
|
+
this.created_at = 0;
|
|
18
|
+
// 登录状态
|
|
19
|
+
this.logged_in = false;
|
|
20
|
+
|
|
21
|
+
// 缓存资料
|
|
22
|
+
this.profile = {};
|
|
23
|
+
this.anonymous = {
|
|
24
|
+
uid: 0,
|
|
25
|
+
group: 0,
|
|
26
|
+
name: "未登录",
|
|
27
|
+
status: 0,
|
|
28
|
+
bind_wx: 0,
|
|
29
|
+
avatar: showAvatar(null, "s"),
|
|
30
|
+
avatar_origin: default_avatar,
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
// 资产缓存
|
|
34
|
+
this.asset = "";
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// 检查当前状态
|
|
38
|
+
check() {
|
|
39
|
+
if (this.isLogin()) {
|
|
40
|
+
this.profile.uid = localStorage && localStorage.getItem("uid");
|
|
41
|
+
this.profile.group =
|
|
42
|
+
(localStorage && localStorage.getItem("group")) || 1;
|
|
43
|
+
this.profile.token = localStorage && localStorage.getItem("token");
|
|
44
|
+
this.profile.name = localStorage && localStorage.getItem("name");
|
|
45
|
+
this.profile.status =
|
|
46
|
+
localStorage && localStorage.getItem("status");
|
|
47
|
+
this.profile.bind_wx =
|
|
48
|
+
localStorage && localStorage.getItem("bind_wx");
|
|
49
|
+
this.profile.avatar_origin =
|
|
50
|
+
(localStorage && localStorage.getItem("avatar")) ||
|
|
51
|
+
default_avatar;
|
|
52
|
+
this.profile.avatar = showAvatar(this.profile.avatar_origin, "s");
|
|
53
|
+
this.profile.permission =
|
|
54
|
+
localStorage && localStorage.getItem("jx3box_permission");
|
|
55
|
+
this.profile.is_teammate =
|
|
56
|
+
localStorage && localStorage.getItem("is_teammate");
|
|
57
|
+
} else {
|
|
58
|
+
this.profile = this.anonymous;
|
|
59
|
+
}
|
|
60
|
+
return this;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// 更新指定缓存字段
|
|
64
|
+
refresh(key, val) {
|
|
65
|
+
return localStorage.setItem(key, val);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// 判断是否已登录
|
|
69
|
+
isLogin() {
|
|
70
|
+
const token = getTokenFromUrl();
|
|
71
|
+
if (token) {
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
74
|
+
this.created_at = !localStorage.getItem("created_at")
|
|
75
|
+
? -Infinity
|
|
76
|
+
: localStorage.getItem("created_at");
|
|
77
|
+
this.logged_in =
|
|
78
|
+
localStorage.getItem("logged_in") == "true" ? true : false;
|
|
79
|
+
return this.logged_in && Date.now() - this.created_at < this.expires;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// 判断是否已过期
|
|
83
|
+
isExpired() {
|
|
84
|
+
return Date.now() - this.created_at > this.expires;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// 保存用户资料
|
|
88
|
+
_save(data) {
|
|
89
|
+
localStorage.setItem("created_at", Date.now());
|
|
90
|
+
localStorage.setItem("logged_in", true);
|
|
91
|
+
localStorage.setItem("token", data.token);
|
|
92
|
+
localStorage.setItem("uid", data.uid);
|
|
93
|
+
localStorage.setItem("group", data.group);
|
|
94
|
+
localStorage.setItem("name", data.name);
|
|
95
|
+
localStorage.setItem("status", data.status);
|
|
96
|
+
localStorage.setItem("bind_wx", data.bind_wx);
|
|
97
|
+
localStorage.setItem("avatar", data.avatar);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// 更新用户资料
|
|
101
|
+
update(data) {
|
|
102
|
+
return new Promise((resolve, reject) => {
|
|
103
|
+
try {
|
|
104
|
+
this._save(data);
|
|
105
|
+
resolve(this);
|
|
106
|
+
} catch (err) {
|
|
107
|
+
//如果localStorage不存在或已满
|
|
108
|
+
if (localStorage) {
|
|
109
|
+
localStorage.clear();
|
|
110
|
+
this._save(data);
|
|
111
|
+
resolve(value);
|
|
112
|
+
} else {
|
|
113
|
+
reject(new Error("localStorage不可用"));
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// 获取用户基础缓存信息
|
|
120
|
+
getInfo() {
|
|
121
|
+
this.check();
|
|
122
|
+
return this.profile;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// 销毁登录状态
|
|
126
|
+
async destroy() {
|
|
127
|
+
return $cms()
|
|
128
|
+
.post("api/cms/user/account/email/logout")
|
|
129
|
+
.finally(() => {
|
|
130
|
+
localStorage.removeItem("created_at");
|
|
131
|
+
localStorage.setItem("logged_in", "false");
|
|
132
|
+
localStorage.removeItem("token");
|
|
133
|
+
localStorage.removeItem("jx3box_permission");
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// 跳转至登录
|
|
138
|
+
toLogin(url) {
|
|
139
|
+
url = url ? encodeURIComponent(url) : encodeURIComponent(location.href);
|
|
140
|
+
location.href = __Links.account.login + "?redirect=" + url;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// 获取本地令牌
|
|
144
|
+
getToken() {
|
|
145
|
+
return this.getInfo().token;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// 获取UUID
|
|
149
|
+
getUUID() {
|
|
150
|
+
return localStorage.getItem("device_id");
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// 判断是否邮箱验证
|
|
154
|
+
isEmailMember() {
|
|
155
|
+
return this.getInfo().group >= 8;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// 判断是否绑定手机
|
|
159
|
+
isPhoneMember() {
|
|
160
|
+
return this.getInfo().group >= 16;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// 判断是否为管理员|编辑
|
|
164
|
+
isEditor() {
|
|
165
|
+
return this.getInfo().group >= 64;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// 判断是否为管理员|运营
|
|
169
|
+
isAdmin() {
|
|
170
|
+
return this.getInfo().group >= 128;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// 判断是否为管理员|开发
|
|
174
|
+
isDeveloper() {
|
|
175
|
+
return this.getInfo().group >= 256;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// 判断是否为超管
|
|
179
|
+
isSuperAdmin() {
|
|
180
|
+
return this.getInfo().group >= 512;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// 判断是否为签约作者
|
|
184
|
+
isSuperAuthor() {
|
|
185
|
+
if (this.isLogin()) {
|
|
186
|
+
return $cms()
|
|
187
|
+
.get("/api/cms/user/is_super_author/" + this.getInfo().uid)
|
|
188
|
+
.then(res => {
|
|
189
|
+
return res.data.data;
|
|
190
|
+
});
|
|
191
|
+
} else {
|
|
192
|
+
return new Promise((resolve, reject) => {
|
|
193
|
+
resolve(false);
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// 判断是否为团队成员
|
|
199
|
+
isTeammate() {
|
|
200
|
+
return this.getInfo().is_teammate == "true";
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// 是否绑定微信
|
|
204
|
+
hasBindwx() {
|
|
205
|
+
return this.getInfo().bind_wx;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// PRE身份判断
|
|
209
|
+
_isVIP(asset) {
|
|
210
|
+
let isPRE = asset.was_vip;
|
|
211
|
+
if (isPRE) {
|
|
212
|
+
let isExpired = new Date(asset.expire_date) - new Date() > 0;
|
|
213
|
+
return isExpired;
|
|
214
|
+
} else {
|
|
215
|
+
return false;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
// PRO身份判断
|
|
219
|
+
_isPRO(asset) {
|
|
220
|
+
let isPRO = asset.was_pro;
|
|
221
|
+
if (isPRO) {
|
|
222
|
+
let isExpired = new Date(asset.pro_expire_date) - new Date() > 0;
|
|
223
|
+
return isExpired;
|
|
224
|
+
} else {
|
|
225
|
+
return false;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// 判断是否为VIP
|
|
230
|
+
isVIP() {
|
|
231
|
+
if (this.asset) {
|
|
232
|
+
return new Promise((resolve, reject) => {
|
|
233
|
+
resolve(this._isPRO(this.asset) || this._isVIP(this.asset));
|
|
234
|
+
});
|
|
235
|
+
} else {
|
|
236
|
+
return this.getAsset().then(asset => {
|
|
237
|
+
return this._isPRO(asset) || this._isVIP(asset);
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
// 判断是否为PRO
|
|
243
|
+
isPRO() {
|
|
244
|
+
if (this.asset) {
|
|
245
|
+
return new Promise((resolve, reject) => {
|
|
246
|
+
resolve(this._isPRO(this.asset));
|
|
247
|
+
});
|
|
248
|
+
} else {
|
|
249
|
+
return this.getAsset().then(asset => {
|
|
250
|
+
return this._isPRO(asset);
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// 获取用户资产
|
|
256
|
+
getAsset() {
|
|
257
|
+
if (!this.isLogin()) {
|
|
258
|
+
return new Promise((resolve, reject) => {
|
|
259
|
+
let asset = {
|
|
260
|
+
was_vip: 0,
|
|
261
|
+
expire_date: "1970-02-02T16:00:00.000Z",
|
|
262
|
+
total_day: 0,
|
|
263
|
+
was_pro: 0,
|
|
264
|
+
pro_expire_date: "1970-02-02T16:00:00.000Z",
|
|
265
|
+
pro_total_day: 0,
|
|
266
|
+
rename_card_count: 0,
|
|
267
|
+
had_renamed: 0,
|
|
268
|
+
namespace_card_count: 0,
|
|
269
|
+
box_coin: 0,
|
|
270
|
+
points: 0,
|
|
271
|
+
};
|
|
272
|
+
this.asset = asset;
|
|
273
|
+
// 空资产
|
|
274
|
+
resolve(asset);
|
|
275
|
+
});
|
|
276
|
+
} else {
|
|
277
|
+
return $pay()
|
|
278
|
+
.get("/api/vip/i")
|
|
279
|
+
.then(res => {
|
|
280
|
+
let asset = res.data.data;
|
|
281
|
+
this.asset = asset;
|
|
282
|
+
return asset;
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
// 获取用户等级
|
|
288
|
+
getLevel(exp) {
|
|
289
|
+
for (let level in __userLevel) {
|
|
290
|
+
let range = __userLevel[level];
|
|
291
|
+
if (exp >= range[0] && exp < range[1]) {
|
|
292
|
+
return ~~level;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
// 用户是否有权限
|
|
298
|
+
hasPermission(permission) {
|
|
299
|
+
if (this.getInfo().group >= 512) return true;
|
|
300
|
+
let userPermission = this.getInfo().permission;
|
|
301
|
+
if (userPermission) {
|
|
302
|
+
const permissions = userPermission.split(",");
|
|
303
|
+
return permissions.includes(permission);
|
|
304
|
+
} else {
|
|
305
|
+
return false;
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
// 生成设备指纹
|
|
310
|
+
generateFingerprint(callback) {
|
|
311
|
+
const cache = localStorage.getItem("jx3box_fingerprint");
|
|
312
|
+
if (cache) {
|
|
313
|
+
return cache;
|
|
314
|
+
}
|
|
315
|
+
Fingerprint2.get(function (components) {
|
|
316
|
+
const values = components.map((component) => component.value);
|
|
317
|
+
const murmur = Fingerprint2.x64hash128(values.join(""), 31);
|
|
318
|
+
|
|
319
|
+
localStorage.setItem("jx3box_fingerprint", murmur);
|
|
320
|
+
callback(murmur);
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
// 获取设备指纹
|
|
325
|
+
getDeviceFingerprint() {
|
|
326
|
+
return localStorage.getItem("jx3box_fingerprint");
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
export default new User();
|
package/js/utils.js
CHANGED
|
@@ -1,15 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
default_avatar,
|
|
3
|
-
__sourceType,
|
|
4
|
-
__postType,
|
|
5
|
-
__wikiType,
|
|
6
|
-
__appType,
|
|
7
|
-
__gameType,
|
|
8
|
-
__imgPath,
|
|
9
|
-
__iconPath,
|
|
10
|
-
__clients,
|
|
11
|
-
__ossMirror,
|
|
12
|
-
} from "../data/jx3box.json";
|
|
1
|
+
import { default_avatar, __sourceType, __postType, __wikiType, __appType, __gameType, __imgPath, __iconPath, __clients, __ossMirror } from "../data/jx3box.json";
|
|
13
2
|
import tvmap from "../data/tvmap.json";
|
|
14
3
|
|
|
15
4
|
export function resolveImagePath(str) {
|
|
@@ -26,10 +15,7 @@ export function checkImageLoad(jq) {
|
|
|
26
15
|
jq.length &&
|
|
27
16
|
jq.one("error", function () {
|
|
28
17
|
var img_url = $(this).attr("src");
|
|
29
|
-
var fix_url = img_url.replace(
|
|
30
|
-
/cdn\.jx3box\.com/g,
|
|
31
|
-
"oss.jx3box.com"
|
|
32
|
-
);
|
|
18
|
+
var fix_url = img_url.replace(/cdn\.jx3box\.com/g, "oss.jx3box.com");
|
|
33
19
|
$(this).attr("src", fix_url);
|
|
34
20
|
});
|
|
35
21
|
}
|
|
@@ -150,12 +136,7 @@ export function iconLink(icon_id, client = "std") {
|
|
|
150
136
|
* 获取应用图标
|
|
151
137
|
*/
|
|
152
138
|
export function getAppIcon(key, colorful = false) {
|
|
153
|
-
return (
|
|
154
|
-
__imgPath +
|
|
155
|
-
(colorful ? "image/box-colorful/" : "image/box/") +
|
|
156
|
-
key +
|
|
157
|
-
".svg"
|
|
158
|
-
);
|
|
139
|
+
return __imgPath + (colorful ? "image/box-colorful/" : "image/box/") + key + ".svg";
|
|
159
140
|
}
|
|
160
141
|
|
|
161
142
|
/**
|
|
@@ -189,10 +170,7 @@ export function getLink(type, id, level) {
|
|
|
189
170
|
id = id || "";
|
|
190
171
|
|
|
191
172
|
// 核心作品、休闲数据
|
|
192
|
-
if (
|
|
193
|
-
__sourceType.cms_types.includes(type) ||
|
|
194
|
-
__sourceType.pvx_types.includes(type)
|
|
195
|
-
) {
|
|
173
|
+
if (__sourceType.cms_types.includes(type) || __sourceType.pvx_types.includes(type)) {
|
|
196
174
|
return "/" + type + "/" + id;
|
|
197
175
|
|
|
198
176
|
// 百科类型
|
|
@@ -290,13 +268,7 @@ export function getQuery(key) {
|
|
|
290
268
|
}
|
|
291
269
|
|
|
292
270
|
export function getTypeLabel(type) {
|
|
293
|
-
let types = Object.assign(
|
|
294
|
-
{},
|
|
295
|
-
__postType,
|
|
296
|
-
__wikiType,
|
|
297
|
-
__appType,
|
|
298
|
-
__gameType
|
|
299
|
-
);
|
|
271
|
+
let types = Object.assign({}, __postType, __wikiType, __appType, __gameType);
|
|
300
272
|
return types[type] || "未知";
|
|
301
273
|
}
|
|
302
274
|
|
|
@@ -316,11 +288,7 @@ export function ts2str(timestamp, opt = { polished: true, separator: "-" }) {
|
|
|
316
288
|
let year = dt.getFullYear();
|
|
317
289
|
let month = dt.getMonth() + 1;
|
|
318
290
|
let date = dt.getDate();
|
|
319
|
-
let str = opt.polished
|
|
320
|
-
? `${year}${opt.separator}${polish(month)}${opt.separator}${polish(
|
|
321
|
-
date
|
|
322
|
-
)}`
|
|
323
|
-
: `${year}${opt.separator}${month}${opt.separator}${date}`;
|
|
291
|
+
let str = opt.polished ? `${year}${opt.separator}${polish(month)}${opt.separator}${polish(date)}` : `${year}${opt.separator}${month}${opt.separator}${date}`;
|
|
324
292
|
return str;
|
|
325
293
|
|
|
326
294
|
function polish(val) {
|
|
@@ -340,10 +308,7 @@ export function jx3ClientType() {
|
|
|
340
308
|
*/
|
|
341
309
|
export function extractTextContent(str) {
|
|
342
310
|
if (!str || typeof str !== "string") return [];
|
|
343
|
-
const innerHTML = str.replace(
|
|
344
|
-
/<Text>(.*?)<\/text>/gimsy,
|
|
345
|
-
`<span $1></span>`
|
|
346
|
-
);
|
|
311
|
+
const innerHTML = str.replace(/<Text>(.*?)<\/text>/gimsy, `<span $1></span>`);
|
|
347
312
|
const parser = new DOMParser();
|
|
348
313
|
const doc = parser.parseFromString(innerHTML, "text/html");
|
|
349
314
|
const spans = doc.querySelectorAll("span");
|
|
@@ -388,8 +353,7 @@ export function showClientLabel(client) {
|
|
|
388
353
|
}
|
|
389
354
|
|
|
390
355
|
export function getMedalLink(event_id, subtype) {
|
|
391
|
-
if (subtype === "rank" || subtype === "superstar")
|
|
392
|
-
return `/rank/race/#/${event_id}/${subtype}`;
|
|
356
|
+
if (subtype === "rank" || subtype === "superstar") return `/rank/race/#/${event_id}/${subtype}`;
|
|
393
357
|
return `${subtype}/${event_id}`;
|
|
394
358
|
}
|
|
395
359
|
|
|
@@ -415,34 +379,33 @@ export function isMiniProgram() {
|
|
|
415
379
|
return navigator.userAgent.toLowerCase().includes("miniprogram");
|
|
416
380
|
}
|
|
417
381
|
|
|
418
|
-
|
|
419
382
|
/**
|
|
420
383
|
* 判断当前环境是否为app
|
|
421
384
|
* 判断url是否包含__env=app
|
|
422
385
|
*/
|
|
423
386
|
export function isApp() {
|
|
424
|
-
return new URLSearchParams(window.location.search).get("__env") === "app";
|
|
387
|
+
return new URLSearchParams(window.location.search).get("__env") === "app" || localStorage.getItem("__env") === "app";
|
|
425
388
|
}
|
|
426
389
|
|
|
427
390
|
export function miniprogramHack() {
|
|
428
|
-
document.addEventListener(
|
|
391
|
+
document.addEventListener("DOMContentLoaded", function () {
|
|
429
392
|
// 检查 html 标签是否有 wechat-miniprogram 类
|
|
430
|
-
if (document.documentElement.classList.contains(
|
|
393
|
+
if (document.documentElement.classList.contains("wechat-miniprogram")) {
|
|
431
394
|
// 为整个 document 添加一个点击事件监听器
|
|
432
|
-
document.addEventListener(
|
|
395
|
+
document.addEventListener("click", function (event) {
|
|
433
396
|
// 检查被点击的元素是否是一个链接
|
|
434
|
-
if (event.target.tagName ===
|
|
435
|
-
var href = event.target.getAttribute(
|
|
436
|
-
|
|
397
|
+
if (event.target.tagName === "A") {
|
|
398
|
+
var href = event.target.getAttribute("href");
|
|
399
|
+
|
|
437
400
|
// 检查是否是相对链接
|
|
438
|
-
var isRelative = !href.startsWith(
|
|
439
|
-
|
|
401
|
+
var isRelative = !href.startsWith("http://") && !href.startsWith("https://") && !href.startsWith("//");
|
|
402
|
+
|
|
440
403
|
// 检查是否是jx3box.com域名
|
|
441
404
|
var isJx3boxDomain = /jx3box\.com/.test(href);
|
|
442
|
-
|
|
405
|
+
|
|
443
406
|
// 检查是否是jx3.xoyo.com域名
|
|
444
407
|
var isJx3Domain = /jx3\.xoyo\.com/.test(href);
|
|
445
|
-
|
|
408
|
+
|
|
446
409
|
// 如果不是相对链接且不是jx3box.com域名
|
|
447
410
|
if (!isRelative && !isJx3boxDomain && !isJx3Domain) {
|
|
448
411
|
// 阻止默认行为
|
|
@@ -476,7 +439,6 @@ export function getTokenFromUrl() {
|
|
|
476
439
|
}
|
|
477
440
|
}
|
|
478
441
|
|
|
479
|
-
|
|
480
442
|
export default {
|
|
481
443
|
resolveImagePath,
|
|
482
444
|
checkImageLoad,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jx3box/jx3box-common",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "9.0.0",
|
|
4
4
|
"description": "JX3BOX公共基础模块",
|
|
5
5
|
"main": "main.js",
|
|
6
6
|
"repository": {
|
|
@@ -12,7 +12,6 @@
|
|
|
12
12
|
"axios": "^1.6.8",
|
|
13
13
|
"cheerio": "1.0.0-rc.12",
|
|
14
14
|
"dayjs": "^1.11.10",
|
|
15
|
-
"element-ui": "^2.13.2",
|
|
16
15
|
"fingerprintjs2": "^2.1.4",
|
|
17
16
|
"localforage": "^1.7.3",
|
|
18
17
|
"uuid": "^9.0.0",
|