@gingkoo/base-server 0.0.1-alpha.0 → 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.
Files changed (122) hide show
  1. package/README.md +4 -0
  2. package/app.js +41 -40
  3. package/backend/common/entity.js +55 -0
  4. package/backend/common/enum.js +247 -0
  5. package/backend/common/fss/index.js +18 -0
  6. package/backend/common/fss/routers/attachment.js +45 -0
  7. package/backend/common/fss/routers/download.js +43 -0
  8. package/backend/common/fss/routers/import_export.js +113 -0
  9. package/backend/common/fss/routers/resources.js +149 -0
  10. package/backend/common/fss/routers/upload.js +81 -0
  11. package/backend/common/fss/services/import_export.js +159 -0
  12. package/backend/common/fss/services/index.js +92 -0
  13. package/backend/common/fss/utils.js +39 -0
  14. package/backend/common/ginfo/config.js +5 -0
  15. package/backend/common/ginfo/index.js +62 -0
  16. package/backend/common/index_template.html +28 -0
  17. package/backend/common/logger/index.js +96 -0
  18. package/backend/common/mapping.js +128 -0
  19. package/backend/common/middleware/auth.js +109 -0
  20. package/backend/common/middleware/cors.js +13 -0
  21. package/backend/common/middleware/response.js +25 -0
  22. package/backend/common/page_engine.js +487 -0
  23. package/backend/common/schedule.js +45 -0
  24. package/backend/common/services/dataCombine.js +67 -0
  25. package/backend/common/services/dept.js +37 -0
  26. package/backend/common/services/dict.js +488 -0
  27. package/backend/common/services/email.js +49 -0
  28. package/backend/common/services/generalConfig.js +137 -0
  29. package/backend/common/services/login.js +18 -0
  30. package/backend/common/services/notice.js +260 -0
  31. package/backend/common/services/permission.js +500 -0
  32. package/backend/common/services/roles.js +57 -0
  33. package/backend/common/services/send-notice.js +86 -0
  34. package/backend/common/services/task.js +259 -0
  35. package/backend/common/services/user.js +673 -0
  36. package/backend/common/socket.js +18 -0
  37. package/backend/common/sse/index.js +81 -0
  38. package/backend/common/sse/router.js +30 -0
  39. package/backend/common/task.js +75 -0
  40. package/backend/common/wechat/index.js +9 -0
  41. package/backend/common/wechat/routers/auth.js +238 -0
  42. package/{modules/user/frontend → backend/common/wechat/routers}/index.html +14 -7
  43. package/backend/common/wechat/services/auth.js +209 -0
  44. package/backend/common/wechat/services/notice.js +171 -0
  45. package/backend/config/index.js +61 -0
  46. package/backend/config/path.js +3 -0
  47. package/backend/router.js +100 -0
  48. package/backend/routers/app.js +222 -0
  49. package/backend/routers/automate.js +276 -0
  50. package/backend/routers/dict.js +370 -0
  51. package/backend/routers/email.js +85 -0
  52. package/backend/routers/generalConfig.js +276 -0
  53. package/backend/routers/idm.js +245 -0
  54. package/backend/routers/module.js +357 -0
  55. package/backend/routers/notice.js +138 -0
  56. package/backend/routers/pages.js +46 -0
  57. package/backend/routers/permission.js +985 -0
  58. package/backend/routers/setting.js +184 -0
  59. package/backend/routers/team/index.js +22 -0
  60. package/backend/routers/team/routers/mapping.js +29 -0
  61. package/backend/routers/team/routers/member.js +72 -0
  62. package/backend/routers/team/routers/membermanage.js +289 -0
  63. package/backend/routers/team/routers/pages.js +47 -0
  64. package/backend/routers/team/routers/roles.js +92 -0
  65. package/backend/routers/team/routers/teaminfo.js +27 -0
  66. package/backend/routers/team/routers/usergroup.js +213 -0
  67. package/backend/routers/team/services/mapping.js +101 -0
  68. package/backend/routers/team/services/member.js +206 -0
  69. package/backend/routers/team/services/roles.js +71 -0
  70. package/backend/routers/team/services/teaminfo.js +20 -0
  71. package/backend/routers/team/services/usergroup.js +128 -0
  72. package/backend/routers/user.js +436 -0
  73. package/backend/services/automate.js +60 -0
  74. package/backend/services/config.js +14 -0
  75. package/backend/services/module.js +298 -0
  76. package/backend/services/permission.js +192 -0
  77. package/backend/services/services.js +115 -0
  78. package/backend/services/setting.js +190 -0
  79. package/backend/services/token.js +42 -0
  80. package/backend/space.js +52 -0
  81. package/backend/space_mapping.js +22 -0
  82. package/backend/utils/avatar.js +48 -0
  83. package/backend/utils/color_gen_helper.js +20 -0
  84. package/backend/utils/date.js +66 -0
  85. package/backend/utils/excel.js +446 -0
  86. package/backend/utils/fs/doc.md +64 -0
  87. package/backend/utils/fs/index.js +127 -0
  88. package/backend/utils/jwt.js +54 -0
  89. package/backend/utils/modules/sequence.js +93 -0
  90. package/backend/utils/object.js +31 -0
  91. package/backend/utils/page-query-helper/index.js +61 -0
  92. package/backend/utils/path.js +123 -0
  93. package/backend/utils/run.js +25 -0
  94. package/backend/utils/tokenize.js +82 -0
  95. package/backend/utils/typeof.js +5 -0
  96. package/backend/utils/util.js +153 -0
  97. package/backend/views/api/index.js +32 -0
  98. package/backend/views/api/index.xml +49 -0
  99. package/backend/views/dict/index.js +80 -0
  100. package/backend/views/dict/index.xml +52 -0
  101. package/backend/views/index.js +32 -0
  102. package/backend/views/members_manage/index.js +68 -0
  103. package/backend/views/members_manage/index.xml +68 -0
  104. package/backend/views/roles/index.js +17 -0
  105. package/backend/views/roles/index.xml +47 -0
  106. package/backend/views/usergroup/index.js +68 -0
  107. package/backend/views/usergroup/index.xml +65 -0
  108. package/dist/base-assets/css/index-ffdb55a5.css +3 -0
  109. package/dist/base-assets/css/index-ffdb55a5.css.gz +0 -0
  110. package/dist/base-assets/js/index-b3998a47.js +762 -0
  111. package/dist/base-assets/js/index-b3998a47.js.gz +0 -0
  112. package/dist/base-assets/js/react-cropper.es-d5f06996.js +10 -0
  113. package/dist/base-assets/js/react-cropper.es-d5f06996.js.gz +0 -0
  114. package/dist/base-assets/png/u9-2348c304.png +0 -0
  115. package/dist/base-assets/woff2/materialicons-83be7b2f.woff2 +0 -0
  116. package/dist/index.html +162 -0
  117. package/package.json +62 -5
  118. package/common/router.js +0 -42
  119. package/modules/user/backend/index.js +0 -19
  120. package/modules/user/backend/routers/user.js +0 -11
  121. package/modules/user/frontend/index.js +0 -1
  122. package/serve.js +0 -9
@@ -0,0 +1,149 @@
1
+ 'use strict';
2
+ const express = require('express');
3
+ const { fileExist, join, mkdirPath, saveFile } = require('../../../utils/path');
4
+ const config = require('../../../config/index');
5
+ const generateAvatar = require('../../../utils/avatar');
6
+ const userService = require('../../services/user');
7
+ const { resourcePath } = require('../utils');
8
+
9
+ var router = express.Router();
10
+
11
+ /**
12
+ * @api {post} /fss/resources/avatar/:username 根据用户名显示 用户头像
13
+ * @apiVersion 1.0.0
14
+ * @apiGroup fss
15
+ *
16
+ * @apiQuery {string} username 用户名
17
+ */
18
+ router.get('/avatar/:username', async function (req, res, next) {
19
+ let userid = req.get('X-UserId');
20
+ let { username } = req.params;
21
+ let user = await userService.getUserInfo(username === 'currentUser' ? userid : username);
22
+ if (user) {
23
+ let avatar = user?.AVATAR;
24
+ if (avatar) {
25
+ let filePath = '';
26
+ if (avatar.split('/').slice(-2)[0] !== 'avatars') {
27
+ //兼容下老版头像
28
+ filePath = resourcePath(userid, 'share', avatar.split('/').slice(-1)[0]);
29
+ } else {
30
+ filePath = resourcePath(userid, 'avatars', avatar.split('/').slice(-1)[0]);
31
+ }
32
+
33
+ if (!filePath) {
34
+ return res.sendErr('resource not found');
35
+ }
36
+ filePath = decodeURIComponent(filePath);
37
+
38
+ let isExist = await fileExist(filePath);
39
+ if (isExist) {
40
+ var options = {
41
+ headers: {
42
+ 'x-timestamp': Date.now(),
43
+ 'x-sent': true,
44
+ },
45
+ };
46
+
47
+ res.sendFile(filePath, options);
48
+ } else {
49
+ res.sendErr('resource not found');
50
+ }
51
+ } else {
52
+ // 头像 附件存放位置
53
+ const attachmentPath = join(
54
+ config.app.home,
55
+ 'storage',
56
+ global.orgid.toLowerCase(),
57
+ 'avatars',
58
+ );
59
+
60
+ mkdirPath(attachmentPath);
61
+
62
+ let data = await generateAvatar.generate();
63
+
64
+ let localUrl = join(attachmentPath, username + '.svg');
65
+ await saveFile(localUrl, data);
66
+
67
+ let url = `/fss/resources/avatars/${username + '.svg'}`;
68
+ await userService.operTeamMember(username, {
69
+ AVATAR: url,
70
+ });
71
+
72
+ var options = {
73
+ headers: {
74
+ 'x-timestamp': Date.now(),
75
+ 'x-sent': true,
76
+ },
77
+ };
78
+
79
+ res.sendFile(localUrl, options);
80
+ }
81
+ } else {
82
+ res.sendErr('resource not found');
83
+ }
84
+ });
85
+
86
+ /**
87
+ * @api {post} /fss/resources/share/* 查看 share图片
88
+ * @apiGroup fss
89
+ *
90
+ */
91
+ router.get('/share/*', async function (req, res, next) {
92
+ let userid = req.get('X-UserId');
93
+ let filePath = resourcePath(userid, 'share', req.path.split('/').slice(-1)[0]);
94
+ if (!filePath) {
95
+ res.sendErr('resource not found');
96
+ return;
97
+ }
98
+ filePath = decodeURIComponent(filePath);
99
+
100
+ let isExist = await fileExist(filePath);
101
+ if (isExist) {
102
+ var options = {
103
+ headers: {
104
+ 'x-timestamp': Date.now(),
105
+ 'x-sent': true,
106
+ },
107
+ };
108
+
109
+ res.sendFile(filePath, options);
110
+ } else {
111
+ res.sendErr('resource not found');
112
+ }
113
+ });
114
+
115
+ // 图片查看 /fss/resources/share/1.png
116
+ // 图片头像 /fss/resources/avatar/1.png
117
+ /**
118
+ * @api {post} /fss/resources/:fileFolder/* 查看图片
119
+ * @apiVersion 1.0.0
120
+ * @apiGroup fss
121
+ *
122
+ * @apiQuery {string} fileFolder 文件存放文件夹 share | avatar
123
+ */
124
+ router.get('/:fileFolder/*', async function (req, res, next) {
125
+ let userid = req.get('X-UserId');
126
+ let { fileFolder } = req.params;
127
+ let filePath = resourcePath(userid, fileFolder, req.path.split('/').slice(-1)[0]);
128
+ if (!filePath) {
129
+ res.sendErr('resource not found');
130
+ return;
131
+ }
132
+ filePath = decodeURIComponent(filePath);
133
+
134
+ let isExist = await fileExist(filePath);
135
+ if (isExist) {
136
+ var options = {
137
+ headers: {
138
+ 'x-timestamp': Date.now(),
139
+ 'x-sent': true,
140
+ },
141
+ };
142
+
143
+ res.sendFile(filePath, options);
144
+ } else {
145
+ res.sendErr('resource not found');
146
+ }
147
+ });
148
+
149
+ module.exports = router;
@@ -0,0 +1,81 @@
1
+ 'use strict';
2
+ const { v4: uuidv4 } = require('uuid');
3
+ const express = require('express');
4
+ const multer = require('multer');
5
+ const sizeOf = require('image-size');
6
+ const { mkdirPath } = require('../../../utils/path');
7
+ const { resourcePath } = require('../utils');
8
+
9
+ var router = express.Router();
10
+
11
+ const multerUpload = multer({
12
+ storage: multer.diskStorage({
13
+ // 设置存储路径
14
+ destination(req, res, cb) {
15
+ const { fileFolder = 'share' } = req.query;
16
+ // 附件存放位置
17
+ let attachmentPath = resourcePath('', fileFolder, '');
18
+ let dest = mkdirPath(attachmentPath);
19
+ cb(null, dest);
20
+ },
21
+ // 设置存储的文件名
22
+ filename(req, file, cb) {
23
+ let fileName = file.originalname;
24
+ let fileNameLen = fileName.length;
25
+ let lastPointIndex = fileName.lastIndexOf('.');
26
+ let pointIndex = ~lastPointIndex ? lastPointIndex : fileNameLen;
27
+ let suffixLen = fileNameLen - pointIndex; // 没有后缀为 0
28
+ let suffixStr = fileName.slice(pointIndex); // 带.
29
+
30
+ // 去掉后缀,并限制带上后缀 不超过 56 个字符
31
+ fileName = fileName.slice(0, Math.min(fileNameLen, 56) - suffixLen);
32
+
33
+ function sStr() {
34
+ return uuidv4()
35
+ .replaceAll('-', '')
36
+ .match(/(\w{6})/g)[1];
37
+ }
38
+
39
+ cb(null, `${fileName}__${sStr()}${suffixStr}`);
40
+ },
41
+ }),
42
+ });
43
+
44
+ /**
45
+ * @api {post} /fss/upload/attachment 文件上传
46
+ * @apiVersion 1.0.0
47
+ * @apiGroup fss
48
+ * @apiDescription 图片,文件都行
49
+ *
50
+ */
51
+ router.post('/attachment', multerUpload.any(), async (req, res) => {
52
+ req.clearTimeout();
53
+ const { fileFolder = 'share' } = req.query;
54
+ let filesInfo = req.files.map((file) => {
55
+ return {
56
+ FILE_NAME: file['filename'],
57
+ FILE_TYPE: file['mimetype'],
58
+ path: file['path'],
59
+ size: file['size'],
60
+ };
61
+ })[0];
62
+
63
+ let width = 0,
64
+ height = 0;
65
+ try {
66
+ const dimensions = sizeOf(filesInfo['path']);
67
+ width = dimensions.width;
68
+ height = dimensions.height;
69
+ } catch (error) {}
70
+
71
+ res.sendOk({
72
+ value: `/fss/resources/${fileFolder}/${filesInfo.FILE_NAME}`,
73
+ width,
74
+ height,
75
+ size: filesInfo.size,
76
+ type: filesInfo.FILE_TYPE,
77
+ name: filesInfo.FILE_NAME,
78
+ });
79
+ });
80
+
81
+ module.exports = router;
@@ -0,0 +1,159 @@
1
+ const { v4: uuidv4 } = require('uuid');
2
+ const path = require('path');
3
+ const fs = require('fs');
4
+ const dayjs = require('dayjs');
5
+ const { format: timeFormat } = require('date-fns');
6
+ const { creatTask } = require('../../services/task');
7
+ const { sse, bgTaskEnum } = require('../../sse');
8
+ const tasks = require('../../task');
9
+
10
+ module.exports = {
11
+ /**
12
+ * 上传文件 - 插入表
13
+ * @param {string} USER_ID 当前登录用户
14
+ * @param {any[]} filesInfo 文件信息
15
+ * @param {object} options 参数
16
+ */
17
+ async uploadFiles(USER_ID, filesInfo, options) {
18
+ let { FWD, MODULE_ID, ...rest } = options;
19
+ let strUUID = uuidv4().replaceAll('-', '');
20
+ let taskId = '';
21
+
22
+ for (let i in filesInfo) {
23
+ let params = {
24
+ ORG_ID: global.orgid,
25
+ REQ_ID: strUUID,
26
+ USER_ID,
27
+ STATUS: '00',
28
+ };
29
+
30
+ for (let k in filesInfo[i]) {
31
+ if (k in params) {
32
+ continue;
33
+ }
34
+
35
+ params[k] = filesInfo[i][k];
36
+ }
37
+
38
+ let TASK_NAME = await tasks.getTaskName(MODULE_ID, FWD, rest, 'Excel文件导入');
39
+
40
+ let curDate = timeFormat(new Date(), 'yyyyMMdd');
41
+ let curTime = timeFormat(new Date(), 'yyyyMMddHHmmssSSSS');
42
+
43
+ let [err, taskResult] = await creatTask({
44
+ USER_ID,
45
+ FILE_NAME: params['FILE_NAME'],
46
+ FILE_DIR: params['UPLOAD_DIR'],
47
+ TASK_TYPE: 'excelImport',
48
+ TASK_NAME,
49
+ MODULE_ID: 'import',
50
+ TASK_SERVICE: FWD,
51
+ DATA_CRT_DATE: curDate,
52
+ DATA_CRT_TIME: curTime,
53
+ DATA_UPD_DATE: curDate,
54
+ DATA_UPD_TIME: curTime,
55
+ defaultDate: false,
56
+ });
57
+
58
+ if (err) {
59
+ return [err];
60
+ }
61
+
62
+ taskId = taskResult.TASK;
63
+ sse.addBgTasks(
64
+ {
65
+ USER_ID,
66
+ FILE_NAME: params['FILE_NAME'],
67
+ FILE_DIR: params['UPLOAD_DIR'],
68
+ TASK_TYPE: 'excelImport',
69
+ TASK_NAME,
70
+ MODULE_ID: 'import',
71
+ TASK_SERVICE: FWD,
72
+ TASK_ID: result?.TASK,
73
+ taskProgressStatus: bgTaskEnum.taskProgressStatus.dataLoading,
74
+ STATUS: 'Pending',
75
+ DATA_CRT_DATE: curDate,
76
+ DATA_CRT_TIME: curTime,
77
+ },
78
+ USER_ID,
79
+ );
80
+
81
+ let FILE_PATH = path.join(params['UPLOAD_DIR'], params['FILE_NAME']);
82
+ tasks.run(MODULE_ID, FWD, USER_ID, taskId, { ...rest, FILE_PATH });
83
+ }
84
+
85
+ return [
86
+ false,
87
+ {
88
+ TASK: taskId,
89
+ },
90
+ ];
91
+ },
92
+
93
+ /**
94
+ * 下载文件
95
+ * @param {string} USER_ID 当前登录用户
96
+ * @param {string} moduleId 模块id
97
+ * @param {object} options 参数
98
+ */
99
+ async downloadFile(USER_ID, moduleId, options) {
100
+ let { FWD, ...rest } = options;
101
+
102
+ let curTime = dayjs().format('YYYYMMDDHHmmss');
103
+ let FILE_NAME = moduleId + '_' + curTime + '.xlsx';
104
+ let storageDir = path.join(config['app']['home'], 'storage');
105
+ let dir = path.join(global.orgid.toLowerCase(), 'users', USER_ID);
106
+ let FILE_DIR = path.join(storageDir, dir);
107
+
108
+ // 创建目录 - TODO.这里不应该先判断存不存在吗
109
+ fs.mkdirSync(FILE_DIR, { recursive: true });
110
+
111
+ let TASK_NAME = await tasks.getTaskName(MODULE_ID, FWD, rest, 'Excel文件导出');
112
+
113
+ let curDate = timeFormat(new Date(), 'yyyyMMdd');
114
+ let curTime1 = timeFormat(new Date(), 'yyyyMMddHHmmssSSSS');
115
+
116
+ let [err, result] = await creatTask({
117
+ USER_ID,
118
+ FILE_NAME,
119
+ FILE_DIR: dir, // 这里为什么不拼上 storageDir,这里不拼,那下载不也得拼吗?
120
+ TASK_TYPE: 'excelExport',
121
+ TASK_NAME,
122
+ MODULE_ID: moduleId,
123
+ TASK_SERVICE: FWD,
124
+ DATA_CRT_DATE: curDate,
125
+ DATA_CRT_TIME: curTime1,
126
+ DATA_UPD_DATE: curDate,
127
+ DATA_UPD_TIME: curTime1,
128
+ defaultDate: false,
129
+ });
130
+
131
+ if (err) {
132
+ return [err];
133
+ }
134
+
135
+ // 添加后台任务
136
+ sse.addBgTasks(
137
+ {
138
+ USER_ID,
139
+ FILE_NAME,
140
+ FILE_DIR: dir, // 这里为什么不拼上 storageDir,这里不拼,那下载不也得拼吗?
141
+ TASK_TYPE: 'excelExport',
142
+ TASK_NAME,
143
+ MODULE_ID: moduleId,
144
+ TASK_SERVICE: FWD,
145
+ TASK_ID: result.TASK,
146
+ taskProgressStatus: bgTaskEnum.taskProgressStatus.exportOutData,
147
+ STATUS: 'Pending',
148
+ DATA_CRT_TIME: curTime1,
149
+ DATA_CRT_DATE: curDate,
150
+ },
151
+ USER_ID,
152
+ );
153
+
154
+ let FILE_PATH = path.join(FILE_DIR, FILE_NAME);
155
+ tasks.run(MODULE_ID, FWD, USER_ID, result.TASK, { ...rest, FILE_PATH });
156
+
157
+ return [false, result];
158
+ },
159
+ };
@@ -0,0 +1,92 @@
1
+ const { v4: uuidv4 } = require('uuid');
2
+ const { insertSqlBuilder, sqlExecutor, queryParamsBuilder } = require('@gingkoo/node-tools');
3
+ const entity = require('../../entity');
4
+ const { cleanUselessKey } = require('../../../utils/util');
5
+
6
+ /**
7
+ * 查询附件
8
+ * @param {*} orgid
9
+ * @param {string?} OBJECT_ID 附件绑定对象id
10
+ * @param {string?} REF_ID 关联id
11
+ * @param {image | doc ?} FILE_KIND 文件类型
12
+ * @returns { FILE_KIND: 'image', FILE_NAME: '1102-001__440a25.png' }[]
13
+ */
14
+ async function findAttachment({ OBJECT_ID, REF_ID, FILE_KIND }) {
15
+ let sql = `select * from ${entity.BASE_ATTACHMENTS} where `;
16
+ let filter = cleanUselessKey({
17
+ ORG_ID: global.orgid,
18
+ OBJECT_ID,
19
+ REF_ID,
20
+ FILE_KIND,
21
+ STATUS: '00',
22
+ });
23
+
24
+ let sqlResult = queryParamsBuilder(filter);
25
+ sql += sqlResult.sql;
26
+ let dbResult = await sqlExecutor(sql, sqlResult.params);
27
+ if (dbResult.error) {
28
+ return [];
29
+ }
30
+
31
+ return dbResult.results.map((v) => {
32
+ return { FILE_KIND: v.FILE_KIND, FILE_NAME: v.FILE_NAME };
33
+ });
34
+ }
35
+
36
+ /**
37
+ * 根据条件 删除附件
38
+ * @param {string?} DATA_ID 附件ID
39
+ * @param {string?} OBJECT_ID 附件绑定对象id
40
+ * @param {string?} REF_ID 关联id
41
+ * @param {string?} FILE_NAME 文件名
42
+ * @param {image | doc ?} FILE_KIND 文件类型
43
+ */
44
+ async function discardAttachment({ OBJECT_ID, DATA_ID, REF_ID, FILE_NAME, FILE_KIND }) {
45
+ let sql = `update ${entity.BASE_ATTACHMENTS} set STATUS = '01' WHERE `;
46
+ let filter = cleanUselessKey({
47
+ ORG_ID: global.orgid,
48
+ OBJECT_ID,
49
+ DATA_ID,
50
+ REF_ID,
51
+ FILE_NAME,
52
+ FILE_KIND,
53
+ });
54
+ let sqlResult = queryParamsBuilder(filter);
55
+ sql += sqlResult.sql;
56
+ await sqlExecutor(sql, sqlResult.params);
57
+ }
58
+
59
+ /**
60
+ * 添加附件
61
+ * @param {string} orgid
62
+ * @param {string} userid
63
+ * @param {object} filesInfo {FILE_NAME: 文件名, FILE_TYPE: 文件类型 也就是文件后缀}
64
+ * @param {string} options.MODULE_ID 模块ID project user
65
+ * @param {image | doc} options.FILE_KIND 文件种类
66
+ * @param {string} options.OBJECT_ID: 附件绑定对象id
67
+ * @param {string} options.REF_ID: 关联id
68
+ * @param {string} options.FSS_PATH: storage中的路径
69
+ * @param {'00' | '01'} options.STATUS: 状态 (00正常 01已删除)
70
+ */
71
+ async function addAttachment(userid, filesInfo, options) {
72
+ let strUUID = uuidv4().replaceAll('-', '');
73
+
74
+ let params = Object.assign(
75
+ {
76
+ ORG_ID: global.orgid,
77
+ DATA_ID: strUUID,
78
+ USER_ID: userid,
79
+ },
80
+ filesInfo,
81
+ options,
82
+ );
83
+ let sqlResult = insertSqlBuilder(entity.BASE_ATTACHMENTS, params);
84
+ let res = await sqlExecutor(sqlResult.sql, sqlResult.params);
85
+ return res;
86
+ }
87
+
88
+ module.exports = {
89
+ findAttachment,
90
+ addAttachment,
91
+ discardAttachment,
92
+ };
@@ -0,0 +1,39 @@
1
+ const path = require('path');
2
+ const config = require('../../config/index');
3
+ /**
4
+ * 获取文件位置
5
+ * 一个是通过类型来 获取文件存放位置
6
+ * resourcePath('', fileFolder, '')
7
+ * 获取文件存放位置
8
+ * resourcePath('', fileFolder, filename)
9
+ * @param {*} userid 暂时没用
10
+ * @param {*} fileFolder //文件通过类型,判断文件存放位置
11
+ * @param {string} filePath //文件名称
12
+ * @returns
13
+ */
14
+ function resourcePath(userid = '', fileFolder, filePath = '') {
15
+ let basePath = path.join(config.app.home, 'storage');
16
+ let fileRealPath = path.join(basePath, global.orgid.toLowerCase(), filePath);
17
+
18
+ if (fileFolder == 'users') {
19
+ filePath = filePath.split('/').slice(-2, -1)[0];
20
+ } else if (fileFolder == 'depts') {
21
+ } else if (fileFolder == 'groups') {
22
+ } else if (fileFolder == 'share') {
23
+ } else if (fileFolder == 'public') {
24
+ } else if (fileFolder == 'avatars') {
25
+ fileRealPath = path.join(basePath, global.orgid.toLowerCase(), 'avatars', filePath);
26
+ } else if (fileFolder == 'chat') {
27
+ fileRealPath = path.join(basePath, global.orgid.toLowerCase(), 'chat', filePath);
28
+ } else if (fileFolder == 'avatar') {
29
+ } else if (fileFolder == 'upload') {
30
+ fileRealPath = path.join(config.app.home, filePath);
31
+ } else {
32
+ return null;
33
+ }
34
+ return fileRealPath;
35
+ }
36
+
37
+ module.exports = {
38
+ resourcePath,
39
+ };
@@ -0,0 +1,5 @@
1
+ module.exports = Ginfo = {
2
+ app_id: 'worklog',
3
+ app_key: '05a91881361b923b79cc9f885b7dd976',
4
+ host: 'http://10.1.2.21:5000',
5
+ };
@@ -0,0 +1,62 @@
1
+ var httpclient = require('node-httpclient');
2
+ var { logger } = require('../logger/index');
3
+ var config = require('./config');
4
+
5
+ async function getAccessToken() {
6
+ url = '{host}/api/auth/gettoken?app_id={app_id}&app_key={app_key}'.format(config);
7
+
8
+ const resp = await httpclient.get(url);
9
+ const json_data = resp.data;
10
+
11
+ if (json_data['ret_code'] != '0') {
12
+ logger.error('error:{0}'.format(json_data['ret_msg']));
13
+ return null;
14
+ }
15
+
16
+ const accessToken = json_data['access_token'];
17
+
18
+ return accessToken;
19
+ }
20
+
21
+ async function apiRequest(url_path, method, data) {
22
+ const accessToken = await getAccessToken();
23
+ const url = config['host'] + url_path;
24
+
25
+ try {
26
+ resp = await httpclient.ajax(url, {
27
+ method: method,
28
+ contentType: 'application/json',
29
+ data: data,
30
+ headers: {
31
+ Authorization: 'Bearer {0}'.format(accessToken),
32
+ },
33
+ });
34
+ } catch (e) {
35
+ console.log(e);
36
+ return null;
37
+ }
38
+
39
+ json_data = resp.data;
40
+
41
+ return json_data;
42
+ }
43
+
44
+ async function getUserInfo(qywxuserid) {
45
+ const url = '/api/users/{0}'.format(qywxuserid);
46
+ const ginfo_data = await apiRequest(url, 'GET', {});
47
+ if (ginfo_data == null || ginfo_data['ret_code'] != '0') {
48
+ return null;
49
+ }
50
+
51
+ const user_id = ginfo_data['data']['USER_NAME'];
52
+ if (user_id == null || user_id.length == 0) {
53
+ return null;
54
+ }
55
+
56
+ return ginfo_data['data'];
57
+ }
58
+
59
+ module.exports = Ginfo = {
60
+ getUserInfo,
61
+ apiRequest,
62
+ };
@@ -0,0 +1,28 @@
1
+ <!doctype html>
2
+ <html>
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <title>{title}</title>
6
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
7
+ <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
8
+ <meta name="renderer" content="webkit" />
9
+ <meta name="force-rendering" content="webkit" />
10
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
11
+ <link rel="stylesheet" href="https://cdn.gingkoo.com/pandora/1.0.1/pandora.min.css" />
12
+ <link rel="stylesheet" type="text/css" href="../../static/css/index.css" />
13
+ </head>
14
+
15
+ <body>
16
+ <div id="root" class="app-wrapper"></div>
17
+
18
+ <script src="https://cdn.gingkoo.com/pandora/1.0.1/pandora.min.js"></script>
19
+ <script>
20
+ let schema = '{{schema}}';
21
+ let props = {};
22
+ let env = {
23
+ baseURL: '',
24
+ };
25
+ Pandora.embed('#root', schema, props, env);
26
+ </script>
27
+ </body>
28
+ </html>