beer-network 1.1.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/.eslintignore +1 -0
- package/.eslintrc.cjs +76 -0
- package/.idea/codeStyles/Project.xml +56 -0
- package/.idea/codeStyles/codeStyleConfig.xml +5 -0
- package/.idea/inspectionProfiles/Project_Default.xml +6 -0
- package/.idea/modules.xml +8 -0
- package/.idea/network.iml +12 -0
- package/.idea/vcs.xml +6 -0
- package/dist/api.d.ts +57 -0
- package/dist/api.js +117 -0
- package/dist/elementUtils.d.ts +12 -0
- package/dist/elementUtils.js +35 -0
- package/dist/session.d.ts +18 -0
- package/dist/session.js +40 -0
- package/package.json +23 -0
- package/src/api.ts +148 -0
- package/src/elementUtils.ts +34 -0
- package/src/session.ts +44 -0
- package/tsconfig.json +15 -0
package/.eslintignore
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
src/wasm
|
package/.eslintrc.cjs
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
env: {
|
|
3
|
+
browser: true
|
|
4
|
+
},
|
|
5
|
+
extends: [
|
|
6
|
+
'eslint:recommended',
|
|
7
|
+
'plugin:@typescript-eslint/recommended',
|
|
8
|
+
'plugin:react/recommended',
|
|
9
|
+
'airbnb-base'
|
|
10
|
+
],
|
|
11
|
+
parser: '@typescript-eslint/parser',
|
|
12
|
+
parserOptions: {
|
|
13
|
+
ecmaVersion: 2022,
|
|
14
|
+
sourceType: 'module',
|
|
15
|
+
requireConfigFile: false,
|
|
16
|
+
babelOptions: {
|
|
17
|
+
presets: ['@babel/preset-react']
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
plugins: [
|
|
21
|
+
'react',
|
|
22
|
+
'@typescript-eslint'
|
|
23
|
+
],
|
|
24
|
+
settings: {
|
|
25
|
+
react: {
|
|
26
|
+
version: '18'
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
rules: {
|
|
30
|
+
'class-methods-use-this': 'off',
|
|
31
|
+
'padded-blocks': 'off',
|
|
32
|
+
'max-classes-per-file': ['error', 10],
|
|
33
|
+
'import/extensions': 'off',
|
|
34
|
+
'import/no-unresolved': 'off',
|
|
35
|
+
'lines-between-class-members': 'off',
|
|
36
|
+
'no-unused-vars': 'off',
|
|
37
|
+
'import/prefer-default-export': 'off',
|
|
38
|
+
'no-restricted-syntax': 'off',
|
|
39
|
+
'no-continue': 'off',
|
|
40
|
+
'max-len': ['error', 180],
|
|
41
|
+
'no-param-reassign': 'off',
|
|
42
|
+
'vue/no-v-model-argument': 'off',
|
|
43
|
+
'arrow-body-style': 'off',
|
|
44
|
+
'vue/no-multiple-template-root': 'off',
|
|
45
|
+
'import/no-extraneous-dependencies': 'off',
|
|
46
|
+
'no-case-declarations': 'off',
|
|
47
|
+
'default-case': 'off',
|
|
48
|
+
'no-return-assign': 'off',
|
|
49
|
+
'indent': ['error', 2],
|
|
50
|
+
'no-debugger': 'off',
|
|
51
|
+
'comma-dangle': ['error', 'never'],
|
|
52
|
+
'object-curly-newline': 'off',
|
|
53
|
+
'no-use-before-define': 'off',
|
|
54
|
+
'no-shadow': 'off',
|
|
55
|
+
'vue/no-v-for-template-key': 'off',
|
|
56
|
+
'linebreak-style': [0, 'error', 'windows'],
|
|
57
|
+
'no-extra-semi': 2,
|
|
58
|
+
'no-console': 'off',
|
|
59
|
+
'spaced-comment': 'off',
|
|
60
|
+
'react/display-name': 'off',
|
|
61
|
+
'default-param-last': 'off',
|
|
62
|
+
'prefer-template': 'off',
|
|
63
|
+
'arrow-parens': 'off',
|
|
64
|
+
'react/prop-types': 'off',
|
|
65
|
+
'@typescript-eslint/no-unused-vars': ['warn', {
|
|
66
|
+
vars: 'all',
|
|
67
|
+
args: 'after-used',
|
|
68
|
+
ignoreRestSiblings: true,
|
|
69
|
+
varsIgnorePattern: '^_',
|
|
70
|
+
argsIgnorePattern: '^_'
|
|
71
|
+
}],
|
|
72
|
+
'@typescript-eslint/no-explicit-any': 'off',
|
|
73
|
+
'no-empty-interface': 'off',
|
|
74
|
+
'@typescript-eslint/ban-types': 'off'
|
|
75
|
+
}
|
|
76
|
+
};
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
<component name="ProjectCodeStyleConfiguration">
|
|
2
|
+
<code_scheme name="Project" version="173">
|
|
3
|
+
<JSCodeStyleSettings version="0">
|
|
4
|
+
<option name="FORCE_SEMICOLON_STYLE" value="true" />
|
|
5
|
+
<option name="USE_DOUBLE_QUOTES" value="false" />
|
|
6
|
+
<option name="FORCE_QUOTE_STYlE" value="true" />
|
|
7
|
+
<option name="ENFORCE_TRAILING_COMMA" value="Remove" />
|
|
8
|
+
<option name="VAR_DECLARATION_WRAP" value="2" />
|
|
9
|
+
<option name="OBJECT_LITERAL_WRAP" value="2" />
|
|
10
|
+
<option name="SPACES_WITHIN_OBJECT_LITERAL_BRACES" value="true" />
|
|
11
|
+
<option name="SPACES_WITHIN_IMPORTS" value="true" />
|
|
12
|
+
</JSCodeStyleSettings>
|
|
13
|
+
<TypeScriptCodeStyleSettings version="0">
|
|
14
|
+
<option name="FORCE_SEMICOLON_STYLE" value="true" />
|
|
15
|
+
<option name="USE_DOUBLE_QUOTES" value="false" />
|
|
16
|
+
<option name="FORCE_QUOTE_STYlE" value="true" />
|
|
17
|
+
<option name="ENFORCE_TRAILING_COMMA" value="Remove" />
|
|
18
|
+
<option name="VAR_DECLARATION_WRAP" value="2" />
|
|
19
|
+
<option name="OBJECT_LITERAL_WRAP" value="2" />
|
|
20
|
+
<option name="SPACES_WITHIN_OBJECT_LITERAL_BRACES" value="true" />
|
|
21
|
+
<option name="SPACES_WITHIN_IMPORTS" value="true" />
|
|
22
|
+
</TypeScriptCodeStyleSettings>
|
|
23
|
+
<codeStyleSettings language="JavaScript">
|
|
24
|
+
<option name="RIGHT_MARGIN" value="180" />
|
|
25
|
+
<option name="KEEP_BLANK_LINES_IN_CODE" value="1" />
|
|
26
|
+
<option name="INDENT_CASE_FROM_SWITCH" value="false" />
|
|
27
|
+
<option name="ALIGN_MULTILINE_PARAMETERS" value="false" />
|
|
28
|
+
<option name="ALIGN_MULTILINE_FOR" value="false" />
|
|
29
|
+
<option name="METHOD_CALL_CHAIN_WRAP" value="2" />
|
|
30
|
+
<option name="IF_BRACE_FORCE" value="1" />
|
|
31
|
+
<option name="DOWHILE_BRACE_FORCE" value="1" />
|
|
32
|
+
<option name="WHILE_BRACE_FORCE" value="1" />
|
|
33
|
+
<option name="FOR_BRACE_FORCE" value="1" />
|
|
34
|
+
<indentOptions>
|
|
35
|
+
<option name="INDENT_SIZE" value="2" />
|
|
36
|
+
<option name="CONTINUATION_INDENT_SIZE" value="2" />
|
|
37
|
+
</indentOptions>
|
|
38
|
+
</codeStyleSettings>
|
|
39
|
+
<codeStyleSettings language="TypeScript">
|
|
40
|
+
<option name="RIGHT_MARGIN" value="180" />
|
|
41
|
+
<option name="KEEP_BLANK_LINES_IN_CODE" value="1" />
|
|
42
|
+
<option name="INDENT_CASE_FROM_SWITCH" value="false" />
|
|
43
|
+
<option name="ALIGN_MULTILINE_PARAMETERS" value="false" />
|
|
44
|
+
<option name="ALIGN_MULTILINE_FOR" value="false" />
|
|
45
|
+
<option name="METHOD_CALL_CHAIN_WRAP" value="2" />
|
|
46
|
+
<option name="IF_BRACE_FORCE" value="1" />
|
|
47
|
+
<option name="DOWHILE_BRACE_FORCE" value="1" />
|
|
48
|
+
<option name="WHILE_BRACE_FORCE" value="1" />
|
|
49
|
+
<option name="FOR_BRACE_FORCE" value="1" />
|
|
50
|
+
<indentOptions>
|
|
51
|
+
<option name="INDENT_SIZE" value="2" />
|
|
52
|
+
<option name="CONTINUATION_INDENT_SIZE" value="2" />
|
|
53
|
+
</indentOptions>
|
|
54
|
+
</codeStyleSettings>
|
|
55
|
+
</code_scheme>
|
|
56
|
+
</component>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<module type="WEB_MODULE" version="4">
|
|
3
|
+
<component name="NewModuleRootManager">
|
|
4
|
+
<content url="file://$MODULE_DIR$">
|
|
5
|
+
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
|
|
6
|
+
<excludeFolder url="file://$MODULE_DIR$/temp" />
|
|
7
|
+
<excludeFolder url="file://$MODULE_DIR$/tmp" />
|
|
8
|
+
</content>
|
|
9
|
+
<orderEntry type="inheritedJdk" />
|
|
10
|
+
<orderEntry type="sourceFolder" forTests="false" />
|
|
11
|
+
</component>
|
|
12
|
+
</module>
|
package/.idea/vcs.xml
ADDED
package/dist/api.d.ts
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Json 响应通用实体.
|
|
3
|
+
*/
|
|
4
|
+
export type JsonResponse<T> = {
|
|
5
|
+
success: boolean;
|
|
6
|
+
data: T;
|
|
7
|
+
code: string;
|
|
8
|
+
message?: string;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Antd Table 数据类型.
|
|
12
|
+
*/
|
|
13
|
+
export type RequestData<T> = {
|
|
14
|
+
data: T[];
|
|
15
|
+
page: number;
|
|
16
|
+
total: number;
|
|
17
|
+
success: boolean;
|
|
18
|
+
};
|
|
19
|
+
export default class Fetch {
|
|
20
|
+
/**
|
|
21
|
+
* 请求地址.
|
|
22
|
+
*/
|
|
23
|
+
private readonly pathPrefix;
|
|
24
|
+
private constructor();
|
|
25
|
+
/**
|
|
26
|
+
* 发送POST/JSON 请求.
|
|
27
|
+
* @param path 路径.
|
|
28
|
+
* @param params 参数.
|
|
29
|
+
* @param body 内容体.
|
|
30
|
+
*/
|
|
31
|
+
post<T>(path: string, params?: any, body?: any): Promise<JsonResponse<T>>;
|
|
32
|
+
/**
|
|
33
|
+
* 发送Get 请求.
|
|
34
|
+
* @param path 路径.
|
|
35
|
+
* @param params 参数.
|
|
36
|
+
*/
|
|
37
|
+
get<T>(path: string, params?: any): Promise<JsonResponse<T>>;
|
|
38
|
+
/**
|
|
39
|
+
* 缓存.
|
|
40
|
+
* @param key 缓存Key.
|
|
41
|
+
* @param callback 数据回执函数.
|
|
42
|
+
* @param minute 缓存时间 (分钟).
|
|
43
|
+
*/
|
|
44
|
+
cache<T>(key: string, callback: () => Promise<T>, minute: number): Promise<T>;
|
|
45
|
+
/**
|
|
46
|
+
* 默认授权方式.
|
|
47
|
+
*/
|
|
48
|
+
authorization(): {};
|
|
49
|
+
/**
|
|
50
|
+
* 默认响应数据解析方式.
|
|
51
|
+
* @param response 响应数据.
|
|
52
|
+
*/
|
|
53
|
+
responseJson<T>(response: Response): Promise<JsonResponse<T>>;
|
|
54
|
+
pageParams(params: any): any;
|
|
55
|
+
pageTable<T>(response: JsonResponse<any>): Promise<Partial<RequestData<T>>>;
|
|
56
|
+
sleep(value: number): Promise<unknown>;
|
|
57
|
+
}
|
package/dist/api.js
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const session_1 = require("./session");
|
|
4
|
+
class Fetch {
|
|
5
|
+
constructor(pathPrefix) {
|
|
6
|
+
this.pathPrefix = pathPrefix;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* 发送POST/JSON 请求.
|
|
10
|
+
* @param path 路径.
|
|
11
|
+
* @param params 参数.
|
|
12
|
+
* @param body 内容体.
|
|
13
|
+
*/
|
|
14
|
+
async post(path, params, body) {
|
|
15
|
+
const paramQuery = new URLSearchParams();
|
|
16
|
+
Object.keys(params || {})
|
|
17
|
+
.forEach(key => {
|
|
18
|
+
paramQuery.append(key, params[key]);
|
|
19
|
+
});
|
|
20
|
+
const response = await fetch(this.pathPrefix + path + (paramQuery.toString() === '' ? '' : '?') + paramQuery.toString(), {
|
|
21
|
+
method: 'POST',
|
|
22
|
+
headers: {
|
|
23
|
+
...this.authorization(),
|
|
24
|
+
'Content-Type': 'application/json'
|
|
25
|
+
},
|
|
26
|
+
body: JSON.stringify(body || {})
|
|
27
|
+
});
|
|
28
|
+
return this.responseJson(response);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* 发送Get 请求.
|
|
32
|
+
* @param path 路径.
|
|
33
|
+
* @param params 参数.
|
|
34
|
+
*/
|
|
35
|
+
async get(path, params) {
|
|
36
|
+
const paramQuery = new URLSearchParams();
|
|
37
|
+
Object.keys(params || {})
|
|
38
|
+
.forEach(key => {
|
|
39
|
+
paramQuery.append(key, params[key]);
|
|
40
|
+
});
|
|
41
|
+
const response = await fetch(this.pathPrefix + path + '?' + paramQuery.toString(), {
|
|
42
|
+
method: 'GET',
|
|
43
|
+
headers: {
|
|
44
|
+
...this.authorization()
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
return this.responseJson(response);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* 缓存.
|
|
51
|
+
* @param key 缓存Key.
|
|
52
|
+
* @param callback 数据回执函数.
|
|
53
|
+
* @param minute 缓存时间 (分钟).
|
|
54
|
+
*/
|
|
55
|
+
async cache(key, callback, minute) {
|
|
56
|
+
const cacheKey = 'CACHE_' + key;
|
|
57
|
+
const cacheValue = localStorage.getItem(cacheKey);
|
|
58
|
+
if (cacheValue !== null) {
|
|
59
|
+
const result = JSON.parse(cacheValue);
|
|
60
|
+
const { expireTime } = result;
|
|
61
|
+
if (expireTime !== undefined && expireTime >= new Date().getTime()) {
|
|
62
|
+
return result;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
const response = await callback();
|
|
66
|
+
if (response.code === '0') {
|
|
67
|
+
response.expireTime = new Date().getTime() + 60000 * minute;
|
|
68
|
+
localStorage.setItem(cacheKey, JSON.stringify(response));
|
|
69
|
+
}
|
|
70
|
+
return response;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* 默认授权方式.
|
|
74
|
+
*/
|
|
75
|
+
authorization() {
|
|
76
|
+
const bearer = session_1.Session.getBearer();
|
|
77
|
+
if (bearer === undefined || bearer === '') {
|
|
78
|
+
return {};
|
|
79
|
+
}
|
|
80
|
+
return { Authorization: 'Bearer ' + bearer };
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* 默认响应数据解析方式.
|
|
84
|
+
* @param response 响应数据.
|
|
85
|
+
*/
|
|
86
|
+
async responseJson(response) {
|
|
87
|
+
const result = await response.json();
|
|
88
|
+
if (result?.code === '401') {
|
|
89
|
+
setTimeout(() => window.location.replace('/auth/login'), 500);
|
|
90
|
+
return result;
|
|
91
|
+
}
|
|
92
|
+
return result;
|
|
93
|
+
}
|
|
94
|
+
pageParams(params) {
|
|
95
|
+
return {
|
|
96
|
+
...params,
|
|
97
|
+
currentPage: params.current,
|
|
98
|
+
current: undefined
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
async pageTable(response) {
|
|
102
|
+
return {
|
|
103
|
+
data: response.data.records || response.data,
|
|
104
|
+
page: response.data.currentPage || 1,
|
|
105
|
+
total: response.data.totalSize || response.data.length,
|
|
106
|
+
success: response.success
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
async sleep(value) {
|
|
110
|
+
return new Promise((resolve) => {
|
|
111
|
+
setTimeout(() => {
|
|
112
|
+
resolve(undefined);
|
|
113
|
+
}, value);
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
exports.default = Fetch;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ElementUtils = void 0;
|
|
4
|
+
class ElementUtils {
|
|
5
|
+
/**
|
|
6
|
+
* 选择文件本地文件.
|
|
7
|
+
*/
|
|
8
|
+
static selectFile() {
|
|
9
|
+
return new Promise((resolve) => {
|
|
10
|
+
const fileInput = document.createElement('input');
|
|
11
|
+
fileInput.type = 'file';
|
|
12
|
+
fileInput.style.display = 'none';
|
|
13
|
+
document.body.appendChild(fileInput);
|
|
14
|
+
fileInput.addEventListener('change', () => {
|
|
15
|
+
resolve(fileInput.files);
|
|
16
|
+
document.body.removeChild(fileInput);
|
|
17
|
+
});
|
|
18
|
+
fileInput.click();
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* 下载文件.
|
|
23
|
+
* @param url 文件下载地址.
|
|
24
|
+
* @param fileName 文件名称.
|
|
25
|
+
*/
|
|
26
|
+
static download(url, fileName) {
|
|
27
|
+
const link = document.createElement('a');
|
|
28
|
+
link.href = url;
|
|
29
|
+
link.download = fileName;
|
|
30
|
+
document.body.appendChild(link);
|
|
31
|
+
link.click();
|
|
32
|
+
document.body.removeChild(link);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
exports.ElementUtils = ElementUtils;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export declare class Session {
|
|
2
|
+
/**
|
|
3
|
+
* 获取令牌.
|
|
4
|
+
* <li>window.sessionKey 设置读取缓存用户信息的Key, 默认 login_user.</li>
|
|
5
|
+
* <li>window.accessTokenKey 读取用户令牌的字段, 默认 accessToken 或者 token.</li>
|
|
6
|
+
* <li>window.accessToken 设置身份令牌, 直接返回.</li>
|
|
7
|
+
*/
|
|
8
|
+
static getBearer(): string | undefined;
|
|
9
|
+
/**
|
|
10
|
+
* 检查令牌是否存在.
|
|
11
|
+
*/
|
|
12
|
+
static checkAccessTokenExist(): boolean;
|
|
13
|
+
/**
|
|
14
|
+
* 退出登录.
|
|
15
|
+
* @param url 退出之后的地址.
|
|
16
|
+
*/
|
|
17
|
+
static logout(url?: string): void;
|
|
18
|
+
}
|
package/dist/session.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Session = void 0;
|
|
4
|
+
class Session {
|
|
5
|
+
/**
|
|
6
|
+
* 获取令牌.
|
|
7
|
+
* <li>window.sessionKey 设置读取缓存用户信息的Key, 默认 login_user.</li>
|
|
8
|
+
* <li>window.accessTokenKey 读取用户令牌的字段, 默认 accessToken 或者 token.</li>
|
|
9
|
+
* <li>window.accessToken 设置身份令牌, 直接返回.</li>
|
|
10
|
+
*/
|
|
11
|
+
static getBearer() {
|
|
12
|
+
if (window.accessToken != undefined && window.accessToken !== '') {
|
|
13
|
+
return window.accessToken;
|
|
14
|
+
}
|
|
15
|
+
const key = window.sessionKey || 'login_user';
|
|
16
|
+
const loginUser = JSON.parse(localStorage.getItem(key) || '{}');
|
|
17
|
+
if (window.accessTokenKey != undefined && window.accessTokenKey !== '') {
|
|
18
|
+
return loginUser[window.accessTokenKey];
|
|
19
|
+
}
|
|
20
|
+
return loginUser.accessToken || loginUser.token || undefined;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* 检查令牌是否存在.
|
|
24
|
+
*/
|
|
25
|
+
static checkAccessTokenExist() {
|
|
26
|
+
const bearer = Session.getBearer();
|
|
27
|
+
return !(bearer === undefined || bearer === '');
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* 退出登录.
|
|
31
|
+
* @param url 退出之后的地址.
|
|
32
|
+
*/
|
|
33
|
+
static logout(url) {
|
|
34
|
+
localStorage.clear();
|
|
35
|
+
if (url !== undefined && url !== '') {
|
|
36
|
+
window.location.href = url;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
exports.Session = Session;
|
package/package.json
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "beer-network",
|
|
3
|
+
"private": false,
|
|
4
|
+
"version": "1.1.0",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
},
|
|
8
|
+
"dependencies": {
|
|
9
|
+
},
|
|
10
|
+
"devDependencies": {
|
|
11
|
+
"typescript": "^5.0.2",
|
|
12
|
+
"@babel/eslint-parser": "^7.22.15",
|
|
13
|
+
"@typescript-eslint/eslint-plugin": "^6.0.0",
|
|
14
|
+
"@typescript-eslint/parser": "^6.0.0",
|
|
15
|
+
"eslint": "^8.45.0",
|
|
16
|
+
"eslint-config-airbnb": "^19.0.4",
|
|
17
|
+
"eslint-config-ali": "^14.0.2",
|
|
18
|
+
"eslint-plugin-import": "^2.28.1",
|
|
19
|
+
"eslint-plugin-react": "^7.33.2",
|
|
20
|
+
"eslint-plugin-react-hooks": "^4.6.0",
|
|
21
|
+
"eslint-plugin-react-refresh": "^0.4.3"
|
|
22
|
+
}
|
|
23
|
+
}
|
package/src/api.ts
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { Session } from './session';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Json 响应通用实体.
|
|
5
|
+
*/
|
|
6
|
+
export type JsonResponse<T> = {
|
|
7
|
+
success: boolean;
|
|
8
|
+
data: T;
|
|
9
|
+
code: string;
|
|
10
|
+
message?: string;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Antd Table 数据类型.
|
|
15
|
+
*/
|
|
16
|
+
export type RequestData<T> = {
|
|
17
|
+
data: T[]
|
|
18
|
+
page: number
|
|
19
|
+
total: number
|
|
20
|
+
success: boolean
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export default class Fetch {
|
|
24
|
+
/**
|
|
25
|
+
* 请求地址.
|
|
26
|
+
*/
|
|
27
|
+
private readonly pathPrefix: string;
|
|
28
|
+
|
|
29
|
+
private constructor(pathPrefix: string) {
|
|
30
|
+
this.pathPrefix = pathPrefix;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* 发送POST/JSON 请求.
|
|
35
|
+
* @param path 路径.
|
|
36
|
+
* @param params 参数.
|
|
37
|
+
* @param body 内容体.
|
|
38
|
+
*/
|
|
39
|
+
async post<T>(path: string, params?: any, body?: any): Promise<JsonResponse<T>> {
|
|
40
|
+
const paramQuery = new URLSearchParams();
|
|
41
|
+
Object.keys(params || {})
|
|
42
|
+
.forEach(key => {
|
|
43
|
+
paramQuery.append(key, params[key]);
|
|
44
|
+
});
|
|
45
|
+
const response = await fetch(this.pathPrefix + path + (paramQuery.toString() === '' ? '' : '?') + paramQuery.toString(), {
|
|
46
|
+
method: 'POST',
|
|
47
|
+
headers: {
|
|
48
|
+
...this.authorization(),
|
|
49
|
+
'Content-Type': 'application/json'
|
|
50
|
+
},
|
|
51
|
+
body: JSON.stringify(body || {})
|
|
52
|
+
});
|
|
53
|
+
return this.responseJson<T>(response);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* 发送Get 请求.
|
|
58
|
+
* @param path 路径.
|
|
59
|
+
* @param params 参数.
|
|
60
|
+
*/
|
|
61
|
+
async get<T>(path: string, params?: any): Promise<JsonResponse<T>> {
|
|
62
|
+
const paramQuery = new URLSearchParams();
|
|
63
|
+
Object.keys(params || {})
|
|
64
|
+
.forEach(key => {
|
|
65
|
+
paramQuery.append(key, params[key]);
|
|
66
|
+
});
|
|
67
|
+
const response = await fetch(this.pathPrefix + path + '?' + paramQuery.toString(), {
|
|
68
|
+
method: 'GET',
|
|
69
|
+
headers: {
|
|
70
|
+
...this.authorization()
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
return this.responseJson<T>(response);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* 缓存.
|
|
78
|
+
* @param key 缓存Key.
|
|
79
|
+
* @param callback 数据回执函数.
|
|
80
|
+
* @param minute 缓存时间 (分钟).
|
|
81
|
+
*/
|
|
82
|
+
async cache<T>(key: string, callback: () => Promise<T>, minute: number) {
|
|
83
|
+
const cacheKey = 'CACHE_' + key;
|
|
84
|
+
const cacheValue = localStorage.getItem(cacheKey);
|
|
85
|
+
if (cacheValue !== null) {
|
|
86
|
+
const result = JSON.parse(cacheValue) as T;
|
|
87
|
+
const { expireTime } = (result as { expireTime: number });
|
|
88
|
+
if (expireTime !== undefined && expireTime >= new Date().getTime()) {
|
|
89
|
+
return result;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
const response = await callback();
|
|
93
|
+
if ((response as { code: string }).code === '0') {
|
|
94
|
+
(response as { expireTime: number }).expireTime = new Date().getTime() + 60000 * minute;
|
|
95
|
+
localStorage.setItem(cacheKey, JSON.stringify(response));
|
|
96
|
+
}
|
|
97
|
+
return response;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* 默认授权方式.
|
|
102
|
+
*/
|
|
103
|
+
authorization(): {} {
|
|
104
|
+
const bearer = Session.getBearer();
|
|
105
|
+
if (bearer === undefined || bearer === '') {
|
|
106
|
+
return {};
|
|
107
|
+
}
|
|
108
|
+
return { Authorization: 'Bearer ' + bearer };
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* 默认响应数据解析方式.
|
|
113
|
+
* @param response 响应数据.
|
|
114
|
+
*/
|
|
115
|
+
async responseJson<T>(response: Response): Promise<JsonResponse<T>> {
|
|
116
|
+
const result = await response.json() as JsonResponse<T>;
|
|
117
|
+
if (result?.code === '401') {
|
|
118
|
+
setTimeout(() => window.location.replace('/auth/login'), 500);
|
|
119
|
+
return result;
|
|
120
|
+
}
|
|
121
|
+
return result;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
pageParams(params: any) {
|
|
125
|
+
return {
|
|
126
|
+
...params,
|
|
127
|
+
currentPage: params.current,
|
|
128
|
+
current: undefined
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
async pageTable<T>(response: JsonResponse<any>): Promise<Partial<RequestData<T>>> {
|
|
133
|
+
return {
|
|
134
|
+
data: (response.data as { records: [] }).records || response.data,
|
|
135
|
+
page: response.data.currentPage || 1,
|
|
136
|
+
total: (response.data as { totalSize: number }).totalSize || response.data.length,
|
|
137
|
+
success: response.success
|
|
138
|
+
} as RequestData<T>;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
async sleep(value: number) {
|
|
142
|
+
return new Promise((resolve) => {
|
|
143
|
+
setTimeout(() => {
|
|
144
|
+
resolve(undefined);
|
|
145
|
+
}, value);
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export class ElementUtils {
|
|
2
|
+
/**
|
|
3
|
+
* 选择文件本地文件.
|
|
4
|
+
*/
|
|
5
|
+
public static selectFile(): Promise<FileList | null> {
|
|
6
|
+
return new Promise<FileList | null>((resolve) => {
|
|
7
|
+
const fileInput = document.createElement('input');
|
|
8
|
+
fileInput.type = 'file';
|
|
9
|
+
fileInput.style.display = 'none';
|
|
10
|
+
document.body.appendChild(fileInput);
|
|
11
|
+
fileInput.addEventListener('change', () => {
|
|
12
|
+
resolve(fileInput.files);
|
|
13
|
+
document.body.removeChild(fileInput);
|
|
14
|
+
});
|
|
15
|
+
fileInput.click();
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* 下载文件.
|
|
21
|
+
* @param url 文件下载地址.
|
|
22
|
+
* @param fileName 文件名称.
|
|
23
|
+
*/
|
|
24
|
+
public static download(url: string, fileName: string) {
|
|
25
|
+
const link = document.createElement('a');
|
|
26
|
+
link.href = url;
|
|
27
|
+
link.download = fileName;
|
|
28
|
+
|
|
29
|
+
document.body.appendChild(link);
|
|
30
|
+
link.click();
|
|
31
|
+
|
|
32
|
+
document.body.removeChild(link);
|
|
33
|
+
}
|
|
34
|
+
}
|
package/src/session.ts
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
declare const window: { location: any, sessionKey: string, accessTokenKey: string, accessToken: string };
|
|
2
|
+
|
|
3
|
+
export class Session {
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* 获取令牌.
|
|
7
|
+
* <li>window.sessionKey 设置读取缓存用户信息的Key, 默认 login_user.</li>
|
|
8
|
+
* <li>window.accessTokenKey 读取用户令牌的字段, 默认 accessToken 或者 token.</li>
|
|
9
|
+
* <li>window.accessToken 设置身份令牌, 直接返回.</li>
|
|
10
|
+
*/
|
|
11
|
+
public static getBearer() {
|
|
12
|
+
if (window.accessToken != undefined && window.accessToken !== '') {
|
|
13
|
+
return window.accessToken;
|
|
14
|
+
}
|
|
15
|
+
const key: string = window.sessionKey || 'login_user';
|
|
16
|
+
const loginUser: {
|
|
17
|
+
accessToken: string | undefined,
|
|
18
|
+
token: string | undefined
|
|
19
|
+
} = JSON.parse(localStorage.getItem(key) || '{}');
|
|
20
|
+
if (window.accessTokenKey != undefined && window.accessTokenKey !== '') {
|
|
21
|
+
return (loginUser as never)[window.accessTokenKey];
|
|
22
|
+
}
|
|
23
|
+
return loginUser.accessToken || loginUser.token || undefined;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* 检查令牌是否存在.
|
|
28
|
+
*/
|
|
29
|
+
public static checkAccessTokenExist() {
|
|
30
|
+
const bearer = Session.getBearer();
|
|
31
|
+
return !(bearer === undefined || bearer === '');
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* 退出登录.
|
|
36
|
+
* @param url 退出之后的地址.
|
|
37
|
+
*/
|
|
38
|
+
public static logout(url?: string) {
|
|
39
|
+
localStorage.clear();
|
|
40
|
+
if (url !== undefined && url !== '') {
|
|
41
|
+
window.location.href = url;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
package/tsconfig.json
ADDED