@gingkoo/base-server 0.0.1-alpha.1 → 0.0.1-alpha.10
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/README.md +1 -4
- package/app.js +12 -3
- package/backend/common/index_template.html +2 -2
- package/backend/common/mapping.js +39 -9
- package/backend/common/middleware/auth.js +24 -12
- package/backend/common/services/dict.js +1 -0
- package/backend/common/wechat/services/auth.js +2 -2
- package/backend/config/index.js +0 -2
- package/backend/router.js +37 -33
- package/backend/space_mapping.js +8 -1
- package/dist/base-assets/css/index-ffdb55a5.css +3 -0
- package/dist/base-assets/css/index-ffdb55a5.css.gz +0 -0
- package/dist/{assets/js/index-9eef7474.js → base-assets/js/index-b3998a47.js} +145 -145
- package/dist/base-assets/js/index-b3998a47.js.gz +0 -0
- package/dist/{assets/js/react-cropper.es-d3337769.js → base-assets/js/react-cropper.es-d5f06996.js} +1 -1
- package/dist/base-assets/js/react-cropper.es-d5f06996.js.gz +0 -0
- package/dist/index.html +4 -4
- package/package.json +3 -1
- package/dist/assets/css/index-cc834b52.css +0 -3
- package/dist/assets/css/index-cc834b52.css.gz +0 -0
- package/dist/assets/js/index-9eef7474.js.gz +0 -0
- package/dist/assets/js/react-cropper.es-d3337769.js.gz +0 -0
- /package/dist/{assets → base-assets}/png/u9-2348c304.png +0 -0
- /package/dist/{assets → base-assets}/woff2/materialicons-83be7b2f.woff2 +0 -0
package/README.md
CHANGED
package/app.js
CHANGED
|
@@ -15,7 +15,9 @@ const router = require('./backend/router');
|
|
|
15
15
|
class App {
|
|
16
16
|
/**
|
|
17
17
|
* @param {string} optinos.timeout 超时时间 默认 30s
|
|
18
|
-
* @param {(app: any) => void} optinos.
|
|
18
|
+
* @param {(app: any, express: any) => void} optinos.middleware 注册中间件
|
|
19
|
+
* @param {(app: any, express: any) => void} optinos.beforeRoutes 在前面注册路由
|
|
20
|
+
* @param {(app: any, express: any) => void} optinos.afterRoutes 在后面注册路由
|
|
19
21
|
*/
|
|
20
22
|
constructor(options = {}) {
|
|
21
23
|
this.options = options;
|
|
@@ -62,13 +64,20 @@ class App {
|
|
|
62
64
|
this.app.use((req, res, next) => {
|
|
63
65
|
if (!req.timedout) next();
|
|
64
66
|
});
|
|
67
|
+
|
|
68
|
+
if (this.options.middleware) {
|
|
69
|
+
this.options.middleware(this.app, express);
|
|
70
|
+
}
|
|
65
71
|
}
|
|
66
72
|
|
|
67
73
|
routes() {
|
|
68
|
-
if (this.options.
|
|
69
|
-
this.options.
|
|
74
|
+
if (this.options.beforeRoutes) {
|
|
75
|
+
this.options.beforeRoutes(this.app, express);
|
|
70
76
|
}
|
|
71
77
|
this.app.use('/', router);
|
|
78
|
+
if (this.options.afterRoutes) {
|
|
79
|
+
this.options.afterRoutes(this.app, express);
|
|
80
|
+
}
|
|
72
81
|
}
|
|
73
82
|
|
|
74
83
|
listenSocket() {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<!
|
|
1
|
+
<!doctype html>
|
|
2
2
|
<html>
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="UTF-8" />
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
<meta name="force-rendering" content="webkit" />
|
|
10
10
|
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
|
|
11
11
|
<link rel="stylesheet" href="https://cdn.gingkoo.com/pandora/1.0.1/pandora.min.css" />
|
|
12
|
-
<link rel="stylesheet" type="text/css" href="
|
|
12
|
+
<link rel="stylesheet" type="text/css" href="../../static/css/index.css" />
|
|
13
13
|
</head>
|
|
14
14
|
|
|
15
15
|
<body>
|
|
@@ -21,19 +21,31 @@ class MappingFactory {
|
|
|
21
21
|
|
|
22
22
|
async getMapping(module, dict_ids, extra) {
|
|
23
23
|
let mapping = {};
|
|
24
|
+
let list = {};
|
|
24
25
|
|
|
25
|
-
if (!Array.isArray(dict_ids))
|
|
26
|
-
|
|
26
|
+
if (!Array.isArray(dict_ids) || !dict_ids?.length) {
|
|
27
|
+
return {
|
|
28
|
+
dict: mapping,
|
|
29
|
+
list: list,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
27
32
|
|
|
28
33
|
let modulesMap = {
|
|
29
34
|
async USER_LIST() {
|
|
30
35
|
let res = await userService.getUsers();
|
|
31
|
-
|
|
36
|
+
let arr = [];
|
|
37
|
+
let dict = res.reduce((mo, item) => {
|
|
32
38
|
if (item.USER_ID) {
|
|
39
|
+
arr.push({ value: item.USER_ID, label: item.USER_NAME });
|
|
33
40
|
mo[item.USER_ID] = item.USER_NAME;
|
|
34
41
|
}
|
|
35
42
|
return mo;
|
|
36
43
|
}, {});
|
|
44
|
+
|
|
45
|
+
return {
|
|
46
|
+
dict,
|
|
47
|
+
list: arr,
|
|
48
|
+
};
|
|
37
49
|
},
|
|
38
50
|
};
|
|
39
51
|
|
|
@@ -68,6 +80,12 @@ class MappingFactory {
|
|
|
68
80
|
mo[value] = rest;
|
|
69
81
|
return mo;
|
|
70
82
|
}, {});
|
|
83
|
+
list[key] = value.map((item) => {
|
|
84
|
+
return {
|
|
85
|
+
label: item.label,
|
|
86
|
+
value: item.value,
|
|
87
|
+
};
|
|
88
|
+
});
|
|
71
89
|
}
|
|
72
90
|
});
|
|
73
91
|
}
|
|
@@ -76,18 +94,30 @@ class MappingFactory {
|
|
|
76
94
|
if (module_dict.length) {
|
|
77
95
|
await module_dict.myforeach(async (dict_id) => {
|
|
78
96
|
let fn = modulesMap[dict_id];
|
|
79
|
-
|
|
97
|
+
let result = {};
|
|
80
98
|
if (isAsync(fn)) {
|
|
81
|
-
|
|
99
|
+
result = await fn(extra);
|
|
82
100
|
} else if (typeof fn === 'function') {
|
|
83
|
-
|
|
84
|
-
} else
|
|
85
|
-
|
|
101
|
+
result = fn(extra);
|
|
102
|
+
} else {
|
|
103
|
+
result = fn;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (isPlainObject(result)) {
|
|
107
|
+
if (result['dict']) {
|
|
108
|
+
mapping[dict_id] = result['dict'];
|
|
109
|
+
}
|
|
110
|
+
if (result['list']) {
|
|
111
|
+
list[dict_id] = result['list'];
|
|
112
|
+
}
|
|
86
113
|
}
|
|
87
114
|
});
|
|
88
115
|
}
|
|
89
116
|
|
|
90
|
-
return
|
|
117
|
+
return {
|
|
118
|
+
dict: mapping,
|
|
119
|
+
list: list,
|
|
120
|
+
};
|
|
91
121
|
}
|
|
92
122
|
}
|
|
93
123
|
|
|
@@ -7,16 +7,22 @@ const { loginType, getLoginMethod } = require('../services/login');
|
|
|
7
7
|
async function authCheck(req, res, next) {
|
|
8
8
|
if (req.login) return next();
|
|
9
9
|
let token = req.cookies['X-Token'] || req.get('X-Token');
|
|
10
|
+
const authorization = req.headers.authorization;
|
|
11
|
+
if (!token && authorization) {
|
|
12
|
+
token = authorization?.split?.('Bearer ')?.[1] || '';
|
|
13
|
+
}
|
|
10
14
|
|
|
11
15
|
let data = jwt.token2data(token);
|
|
12
16
|
if (data) {
|
|
13
17
|
let { userid, exp } = data;
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
if (userid) {
|
|
19
|
+
req.headers['x-userid'] = userid;
|
|
20
|
+
let expires = new Date();
|
|
21
|
+
expires.setDate(expires.getDate() + 3);
|
|
22
|
+
if (exp + 30 * 60 > Math.floor(Date.now() / 1000)) {
|
|
23
|
+
let token = jwt.generateToken(tokenData);
|
|
24
|
+
res.cookie('X-Token', token, { expires });
|
|
25
|
+
}
|
|
20
26
|
}
|
|
21
27
|
return next();
|
|
22
28
|
}
|
|
@@ -39,16 +45,22 @@ async function authCheck(req, res, next) {
|
|
|
39
45
|
function checkLogin(req, res, next) {
|
|
40
46
|
let token = req.cookies['X-Token'] || req.get('X-Token');
|
|
41
47
|
const ip = req.ip;
|
|
48
|
+
const authorization = req.headers.authorization;
|
|
49
|
+
if (!token && authorization) {
|
|
50
|
+
token = authorization?.split?.('Bearer ')?.[1] || '';
|
|
51
|
+
}
|
|
42
52
|
|
|
43
53
|
let data = jwt.token2data(token);
|
|
44
54
|
if (data) {
|
|
45
55
|
let { userid, exp } = data;
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
56
|
+
if (userid) {
|
|
57
|
+
req.headers['x-userid'] = userid;
|
|
58
|
+
let expires = new Date();
|
|
59
|
+
expires.setDate(expires.getDate() + 3);
|
|
60
|
+
if (exp + 30 * 60 > Math.floor(Date.now() / 1000)) {
|
|
61
|
+
let token = jwt.generateToken(tokenData);
|
|
62
|
+
res.cookie('X-Token', token, { expires });
|
|
63
|
+
}
|
|
52
64
|
}
|
|
53
65
|
return next();
|
|
54
66
|
}
|
|
@@ -17,8 +17,8 @@ const getRedirectUrl = async (userAgent) => {
|
|
|
17
17
|
let auth_redirect_url = '';
|
|
18
18
|
let data = await configService.getFromConfig({ GROUP_ID: 'qywx' });
|
|
19
19
|
let { qywx_AgentID, qywx_APPID, qywx_REDIRECT } = data;
|
|
20
|
-
// qywx_REDIRECT = http://gingkoo.com
|
|
21
|
-
let redirect_uri = `${qywx_REDIRECT}/
|
|
20
|
+
// qywx_REDIRECT = http://gingkoo.com/teams
|
|
21
|
+
let redirect_uri = `${qywx_REDIRECT}/wechat/auth/oauth/qywx/callback`;
|
|
22
22
|
|
|
23
23
|
if (userAgent.indexOf('wxwork/') > -1) {
|
|
24
24
|
params = {
|
package/backend/config/index.js
CHANGED
|
@@ -18,10 +18,8 @@ function gConfig() {
|
|
|
18
18
|
return _.merge(
|
|
19
19
|
{
|
|
20
20
|
isProd: true, // 纯当前开发用, 通过 npm 包 使用该组件的时候 他应该永远是 true
|
|
21
|
-
orgid: 'GINGKOO',
|
|
22
21
|
allowedIPs: [], // 不校验登录的 ip
|
|
23
22
|
testUser: '', // 测试用户
|
|
24
|
-
|
|
25
23
|
ip: '0.0.0.0', // 服务 host
|
|
26
24
|
port: 8081, // 服务端口号
|
|
27
25
|
orgid: 'GINGKOO', // 组织 id
|
package/backend/router.js
CHANGED
|
@@ -17,16 +17,47 @@ var router = express.Router();
|
|
|
17
17
|
// 后端
|
|
18
18
|
router.get('/(:module/)?mapping', async (req, res) => {
|
|
19
19
|
let { module } = req.params;
|
|
20
|
-
let { list = '', ...extra } = req.query;
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
20
|
+
let { list = '', type = 'dict', ...extra } = req.query;
|
|
21
|
+
let data = await mapping.getMapping(module, list.split('|'), extra);
|
|
22
|
+
if (type === 'dict') {
|
|
23
|
+
Reflect.deleteProperty(data, 'list');
|
|
24
|
+
} else if (type === 'list') {
|
|
25
|
+
Reflect.deleteProperty(data, 'dict');
|
|
26
|
+
}
|
|
27
|
+
res.sendOk(data);
|
|
24
28
|
});
|
|
25
29
|
|
|
26
30
|
router.use('/fss', fss);
|
|
27
31
|
router.use('/wechat', wechat);
|
|
28
32
|
router.use('/space', space);
|
|
29
33
|
|
|
34
|
+
// 前端
|
|
35
|
+
router.use('/static', express.static(path.join(__dirname, '../static')));
|
|
36
|
+
|
|
37
|
+
if (config.isProd) {
|
|
38
|
+
router.use('/', express.static(path.join(__dirname, '../dist')));
|
|
39
|
+
} else {
|
|
40
|
+
router.use(
|
|
41
|
+
'/',
|
|
42
|
+
createProxyMiddleware({
|
|
43
|
+
target: 'http://127.0.0.1:2000',
|
|
44
|
+
changeOrigin: false,
|
|
45
|
+
ws: true,
|
|
46
|
+
pathRewrite: {
|
|
47
|
+
'^/': '',
|
|
48
|
+
},
|
|
49
|
+
onProxyReq: function (proxyReq, req, res) {
|
|
50
|
+
if (req.body) {
|
|
51
|
+
let bodyData = JSON.stringify(req.body);
|
|
52
|
+
proxyReq.setHeader('Content-Type', 'application/json');
|
|
53
|
+
proxyReq.setHeader('Content-Length', Buffer.byteLength(bodyData));
|
|
54
|
+
proxyReq.write(bodyData);
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
}),
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
|
|
30
61
|
// 反向代理
|
|
31
62
|
if (Array.isArray(config?.proxy?.targets)) {
|
|
32
63
|
config.proxy.targets.forEach((element) => {
|
|
@@ -46,8 +77,8 @@ if (Array.isArray(config?.proxy?.targets)) {
|
|
|
46
77
|
let tokenData = jwt.verifyToken(req.cookies['X-Token']);
|
|
47
78
|
if (tokenData) {
|
|
48
79
|
proxyReq.setHeader('X-Token', req.cookies['X-Token']);
|
|
49
|
-
proxyReq.setHeader('X-UserId', tokenData
|
|
50
|
-
proxyReq.setHeader('X-OrgId', tokenData['orgid']);
|
|
80
|
+
tokenData?.data?.userid && proxyReq.setHeader('X-UserId', tokenData.data.userid);
|
|
81
|
+
// proxyReq.setHeader('X-OrgId', tokenData['orgid']);
|
|
51
82
|
} else {
|
|
52
83
|
proxyReq.removeHeader('X-UserId');
|
|
53
84
|
}
|
|
@@ -66,31 +97,4 @@ if (Array.isArray(config?.proxy?.targets)) {
|
|
|
66
97
|
});
|
|
67
98
|
}
|
|
68
99
|
|
|
69
|
-
// 前端
|
|
70
|
-
router.use('/static', express.static(path.join(__dirname, '../static')));
|
|
71
|
-
|
|
72
|
-
if (config.isProd) {
|
|
73
|
-
router.use('/', express.static('dist'));
|
|
74
|
-
} else {
|
|
75
|
-
router.use(
|
|
76
|
-
'/',
|
|
77
|
-
createProxyMiddleware({
|
|
78
|
-
target: 'http://127.0.0.1:2000',
|
|
79
|
-
changeOrigin: false,
|
|
80
|
-
ws: true,
|
|
81
|
-
pathRewrite: {
|
|
82
|
-
'^/': '',
|
|
83
|
-
},
|
|
84
|
-
onProxyReq: function (proxyReq, req, res) {
|
|
85
|
-
if (req.body) {
|
|
86
|
-
let bodyData = JSON.stringify(req.body);
|
|
87
|
-
proxyReq.setHeader('Content-Type', 'application/json');
|
|
88
|
-
proxyReq.setHeader('Content-Length', Buffer.byteLength(bodyData));
|
|
89
|
-
proxyReq.write(bodyData);
|
|
90
|
-
}
|
|
91
|
-
},
|
|
92
|
-
}),
|
|
93
|
-
);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
100
|
module.exports = router;
|
package/backend/space_mapping.js
CHANGED
|
@@ -5,11 +5,18 @@ const deptService = require('./common/services/dept');
|
|
|
5
5
|
mapping.register('space', {
|
|
6
6
|
async DEPT_LIST() {
|
|
7
7
|
let res = await deptService.getDepts();
|
|
8
|
-
|
|
8
|
+
let list = [];
|
|
9
|
+
let dict = res.reduce((mo, item) => {
|
|
9
10
|
if (item.DEPT_NO) {
|
|
10
11
|
mo[item.DEPT_NO] = item.DEPT_NAME;
|
|
12
|
+
list.push({ value: item.DEPT_NO, label: item.DEPT_NAME });
|
|
11
13
|
}
|
|
12
14
|
return mo;
|
|
13
15
|
}, {});
|
|
16
|
+
|
|
17
|
+
return {
|
|
18
|
+
dict,
|
|
19
|
+
list,
|
|
20
|
+
};
|
|
14
21
|
},
|
|
15
22
|
});
|