@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,446 @@
1
+ 'use strict';
2
+ const ExcelJS = require('exceljs');
3
+ const { sse, bgTaskEnum } = require('../common/sse');
4
+
5
+ /**
6
+ * 解析excel
7
+ * @param {string} filePath 本地文件路径
8
+ * @param {object} dataModel 字段信息
9
+ * e.g dataModel = {
10
+ * ISSUE_ID: { label: '工作项ID', component: 'text', source: undefined },
11
+ * PROJECT_ID: { label: '项目', component: 'dropdown', source: '$dict.PROJECT_LIST' },
12
+ * }
13
+ * @param {object} mappingData 数据字典
14
+ * e.g mappingData = {
15
+ * CUST: {
16
+ * label: '客户',
17
+ * data: {
18
+ * DB: '德意志',
19
+ * ABN: '荷兰',
20
+ * }
21
+ * }
22
+ * }
23
+ */
24
+ async function _excelImport(filePath, dataModel, mappingData) {
25
+ let result = {
26
+ data: [],
27
+ };
28
+
29
+ // e.g {状态:字段信息}
30
+ let colsMap = {};
31
+
32
+ // e.g {A: 字段信息, C: 字段信息}
33
+ let colIndex = {};
34
+
35
+ // e.g {ISSUE_TAGS: {label: '}, width: undeinfed, data: {未开始: nostart}}
36
+ let mappingData2 = {};
37
+
38
+ for (let col in dataModel) {
39
+ colsMap[dataModel[col].label] = col;
40
+ }
41
+
42
+ for (let k in mappingData) {
43
+ mappingData2[k] = { label: mappingData[k].label, width: mappingData.width, data: {} };
44
+ for (let j in mappingData[k].data) {
45
+ mappingData2[k].data[mappingData[k].data[j]] = j;
46
+ }
47
+ }
48
+
49
+ var workbook = new ExcelJS.Workbook();
50
+ await workbook.xlsx.readFile(filePath);
51
+ var worksheet = workbook.getWorksheet(1);
52
+ let titleRow = worksheet.getRow(1);
53
+ titleRow.eachCell((cell, colNumber) => {
54
+ if (cell.value in colsMap) {
55
+ let colId = cell.address.match(/[a-zA-Z]+/g)[0];
56
+ colIndex[colId] = colsMap[cell.value];
57
+ }
58
+ });
59
+
60
+ for (let i = 2; i < worksheet.rowCount + 1; i++) {
61
+ let row = worksheet.getRow(i);
62
+ let rec = {};
63
+ row.eachCell((cell, colNumber) => {
64
+ let colId = cell.address.match(/[a-zA-Z]+/g)[0];
65
+ if (colId in colIndex) {
66
+ let fieldId = colIndex[colId];
67
+ if (dataModel[fieldId]['source']) {
68
+ //数据字典字段
69
+ let mappingId = dataModel[fieldId]['source']?.split('.')[1];
70
+ if (mappingData2?.[mappingId]?.data?.[cell.value]) {
71
+ rec[colIndex[colId]] = mappingData2?.[mappingId]?.data?.[cell.value];
72
+ } else {
73
+ //数据字典匹配不到
74
+ rec[colIndex[colId]] = cell.value;
75
+ }
76
+ } else {
77
+ //非数据字典字段
78
+ rec[colIndex[colId]] = cell.value;
79
+ }
80
+ }
81
+ });
82
+ result.data.push(rec);
83
+ }
84
+ return result;
85
+ }
86
+
87
+ /**
88
+ * 生成excel
89
+ * @param {string} filePath 文件地址
90
+
91
+ * @param {object} dataModel 字段信息
92
+ * e.g dataModel = {
93
+ * ISSUE_ID: { label: '工作项ID', component: 'text', source: undefined },
94
+ * PROJECT_ID: { label: '项目', component: 'dropdown', source: '$dict.PROJECT_LIST' },
95
+ * }
96
+ * @param {object} mappingData 数据字典
97
+ * e.g mappingData = {
98
+ * CUST: {
99
+ * label: '客户',
100
+ * data: {
101
+ * DB: '德意志',
102
+ * ABN: '荷兰',
103
+ * }
104
+ * }
105
+ * }
106
+ * @param {Array} cols 表查询的数据
107
+ * @param {string} data 表查询的数据
108
+ */
109
+ async function _excelExport(filePath, dataModel, mappingData, cols, data, TASK_ID, USER_ID) {
110
+ var workbook = new ExcelJS.Workbook();
111
+ const worksheet = workbook.addWorksheet('问题');
112
+ const mappingsheet = workbook.addWorksheet('字典');
113
+ let titles = [];
114
+ let columns = [];
115
+ let mapColIndex = {};
116
+ const fillHeader = { type: 'pattern', pattern: 'solid', fgColor: { argb: 'ff4576B5' } };
117
+ const fontHeader = {
118
+ name: 'Arial Black',
119
+ color: { argb: '00FFFFFF' },
120
+ family: 2,
121
+ size: 14,
122
+ italic: false,
123
+ };
124
+ const borderHeader = {
125
+ top: { style: 'thin' },
126
+ left: { style: 'thin' },
127
+ bottom: { style: 'thin' },
128
+ right: { style: 'thin' },
129
+ };
130
+ let mappingTitles = [];
131
+ let mappingColumns = [];
132
+ //处理头
133
+ for (let k in mappingData) {
134
+ let colinfo = {
135
+ header: mappingData[k].label,
136
+ key: k,
137
+ width: mappingData[k].width || 20,
138
+ };
139
+ mappingColumns.push(colinfo);
140
+ }
141
+
142
+ // cols.forEach((elem) => {
143
+ // titles.push(dataModel[elem].label);
144
+ // let colinfo = {
145
+ // header: dataModel[elem].label,
146
+ // key: elem,
147
+ // width: dataModel[elem].width || 20,
148
+ // };
149
+ // columns.push(colinfo);
150
+ // });
151
+ for (let k in dataModel) {
152
+ if (dataModel && dataModel[k] && dataModel[k].label) {
153
+ titles.push(dataModel[k].label);
154
+ let colinfo = {
155
+ header: dataModel[k].label,
156
+ key: k,
157
+ width: dataModel[k].width || 20,
158
+ };
159
+ columns.push(colinfo);
160
+ }
161
+ }
162
+
163
+ worksheet.columns = columns;
164
+ mappingsheet.columns = mappingColumns;
165
+ //row = worksheet.getRow(1);
166
+ //row.values = titles;
167
+
168
+ //转换数据字典
169
+ data.forEach((rec, i) => {
170
+ sse.changeBgTaskSatus(
171
+ {
172
+ TASK_ID,
173
+ taskProgressStatus: bgTaskEnum.taskProgressStatus.fileBuilding,
174
+ REC_NUM: data.length,
175
+ OPER_NUM: Number(i) + 1,
176
+ },
177
+ USER_ID,
178
+ );
179
+
180
+ let rec2 = {};
181
+ for (let k in rec) {
182
+ rec2[k] = rec[k];
183
+ if (rec[k] && k in dataModel && dataModel[k]['source']) {
184
+ let mappingId = dataModel[k]['source']?.split('.')[1];
185
+
186
+ if (mappingId in mappingData && mappingData[mappingId].data[rec[k]]) {
187
+ rec2[k] = mappingData[mappingId].data[rec[k]];
188
+ }
189
+ }
190
+ }
191
+
192
+ worksheet.addRow(rec2);
193
+ });
194
+
195
+ let firstRow = worksheet.getRow(1);
196
+ firstRow.eachCell((cell, colNumber) => {
197
+ cell.font = fontHeader;
198
+ cell.fill = fillHeader;
199
+ cell.border = borderHeader;
200
+ });
201
+
202
+ //字典处理
203
+ for (let k in mappingData) {
204
+ let excelCol = mappingsheet.getColumn(k);
205
+ let mapList = [];
206
+ mapList.push(mappingData[k].label);
207
+ for (let x in mappingData[k].data) {
208
+ mapList.push(mappingData[k].data[x]);
209
+ }
210
+ excelCol.values = mapList;
211
+ }
212
+ firstRow = mappingsheet.getRow(1);
213
+ firstRow.eachCell((cell, colNumber) => {
214
+ cell.font = fontHeader;
215
+ cell.fill = fillHeader;
216
+ cell.border = borderHeader;
217
+ let colObj = mappingsheet.getColumn(cell.col);
218
+ let colId = cell.address.match(/[a-zA-Z]+/g)[0];
219
+ mapColIndex[colObj.key] = colId;
220
+ });
221
+
222
+ //添加校验
223
+ // cols.forEach((k) => {
224
+ // if (dataModel[k]['source']) {
225
+ // let mappingId = dataModel[k]['source']?.split('.')[1];
226
+ // if (mappingData?.[mappingId]?.data) {
227
+ // let colObj = worksheet.getColumn(k);
228
+ // let mapRowCount = (Object.keys(mappingData[mappingId].data).length + 1).toString();
229
+ // let mapColId = mapColIndex[mappingId];
230
+ // let valiFormula = '字典!$' + mapColId + '$2' + ':$' + mapColId + '$' + mapRowCount;
231
+
232
+ // colObj.eachCell((cell, rowNumber) => {
233
+ // if (rowNumber == 1) {
234
+ // return;
235
+ // }
236
+
237
+ // cell.dataValidation = {
238
+ // type: 'list',
239
+ // allowBlank: true,
240
+ // formulae: [valiFormula],
241
+ // };
242
+ // });
243
+ // }
244
+ // }
245
+ // });
246
+
247
+ for (let k in dataModel) {
248
+ let mappingId = dataModel[k]['source']?.split('.')[1];
249
+ if (mappingData?.[mappingId]?.data) {
250
+ let colObj = worksheet.getColumn(k);
251
+ let mapRowCount = (Object.keys(mappingData[mappingId].data).length + 1).toString();
252
+ let mapColId = mapColIndex[mappingId];
253
+ let valiFormula = '字典!$' + mapColId + '$2' + ':$' + mapColId + '$' + mapRowCount;
254
+
255
+ colObj.eachCell((cell, rowNumber) => {
256
+ if (rowNumber == 1) {
257
+ return;
258
+ }
259
+
260
+ cell.dataValidation = {
261
+ type: 'list',
262
+ allowBlank: true,
263
+ formulae: [valiFormula],
264
+ };
265
+ });
266
+ }
267
+ }
268
+
269
+ let ret = await workbook.xlsx.writeFile(filePath);
270
+ return ret;
271
+ }
272
+
273
+ /**
274
+ * excel 帮助方法
275
+ */
276
+ class ExcelHelper {
277
+ constructor() {
278
+ // 工作簿
279
+ this.workbook = null;
280
+ }
281
+
282
+ createWorkBook(workBookName) {
283
+ this.workbook = new ExcelJS.Workbook();
284
+ return this;
285
+ }
286
+
287
+ createSheet(sheetName) {
288
+ let sheet = this.workbook.addWorksheet(sheetName);
289
+ return sheet;
290
+ }
291
+
292
+ writeFile(filePath) {
293
+ this.workbook.xlsx.writeFile(filePath);
294
+ }
295
+
296
+ setCell(sheet, data) {
297
+ data.forEach((v) => {
298
+ sheet.getCell(v.cell).value = v.value;
299
+ });
300
+ return this;
301
+ }
302
+
303
+ setMergeCell(sheet, start, end) {
304
+ sheet.mergeCells(`${start}:${end}`);
305
+ return this;
306
+ }
307
+
308
+ // 合并单元格
309
+ setMerge(rows, columns) {
310
+ let char = String.fromCharCode(64 + columns);
311
+ for (let i = 1; i <= rows; i++) {
312
+ sheet.mergeCells(`A${i}:${char}${i}`);
313
+ }
314
+ return this;
315
+ }
316
+
317
+ // 设置header
318
+ setHeader(sheet, numberLines, value) {
319
+ let keys = [];
320
+
321
+ for (let i = 0, length = value.length; i < length; i++) {
322
+ let currentLines = numberLines ? numberLines : sheet.rowCount + 1;
323
+ let columnsChar = String.fromCharCode(64 + i + 1);
324
+ let cellNumbers = `${columnsChar}${currentLines}`;
325
+ let item = value[i];
326
+
327
+ keys.push({
328
+ key: item.id,
329
+ width: 18,
330
+ });
331
+ sheet.getCell(cellNumbers).value = item.name;
332
+ }
333
+ sheet.columns = keys;
334
+ return this;
335
+ }
336
+
337
+ setColumnsWidth(sheet, header) {
338
+ header.map((v, i) => {
339
+ sheet.getColumn(i + 1).width = v.width;
340
+ });
341
+ return this;
342
+ }
343
+
344
+ // 设置内容
345
+ setContent(sheet, value) {
346
+ sheet.addRows(value);
347
+ return this;
348
+ }
349
+
350
+ // 设置字体是否居中
351
+ setAlignment(sheet, cell, verticalValue, horizontalValue) {
352
+ sheet.getCell(cell).alignment = { vertical: verticalValue, horizontal: horizontalValue };
353
+ return this;
354
+ }
355
+
356
+ // 设置一行全部居中
357
+ setRowAlignment(sheet, columns, row, verticalValue, horizontalValue) {
358
+ for (var i = 1; i <= columns; i++) {
359
+ let cell = `${String.fromCharCode(64 + i)}2`;
360
+ this.setAlignment(sheet, cell, verticalValue, horizontalValue);
361
+ }
362
+ return this;
363
+ }
364
+
365
+ // 设置字体大小
366
+ setFontSize(cell, option) {
367
+ let { size = 14, color = 'FF0000', bold = true, family = 2 } = option;
368
+ sheet.getCell(cell).font = {
369
+ color: { argb: color },
370
+ family,
371
+ size,
372
+ bold,
373
+ };
374
+ return this;
375
+ }
376
+
377
+ // 设置背景色
378
+ setBackgroundColor(cell, color) {
379
+ sheet.getCell(cell).fill = {
380
+ type: 'pattern',
381
+ pattern: 'solid',
382
+ fgColor: {
383
+ argb: `FF${color}`,
384
+ },
385
+ };
386
+ return this;
387
+ }
388
+
389
+ // 设置表格边框
390
+ setBorderStyle(sheet, columns, rows, color = '000000') {
391
+ for (let i = 1; i <= columns; i++) {
392
+ let char = String.fromCharCode(64 + i);
393
+ sheet.getCell(`${char}${rows}`).border = {
394
+ top: {
395
+ style: 'thin',
396
+ color: {
397
+ argb: `FF${color}`,
398
+ },
399
+ },
400
+ left: {
401
+ style: 'thin',
402
+ color: {
403
+ argb: `FF${color}`,
404
+ },
405
+ },
406
+ bottom: {
407
+ style: 'thin',
408
+ color: {
409
+ argb: `FF${color}`,
410
+ },
411
+ },
412
+ right: {
413
+ style: 'thin',
414
+ color: {
415
+ argb: `FF${color}`,
416
+ },
417
+ },
418
+ };
419
+ }
420
+ return this;
421
+ }
422
+ setBorderRightStyle() {
423
+ for (let i = 1; i <= 5; i++) {
424
+ sheet.getCell(`A${i}`).border = {
425
+ right: {
426
+ style: 'thin',
427
+ color: {
428
+ argb: `FF000000`,
429
+ },
430
+ },
431
+ };
432
+ }
433
+ return this;
434
+ }
435
+
436
+ autoWrap(sheet, row) {
437
+ sheet.getRow(row).alignment = { wrapText: true, vertical: 'middle' };
438
+ return this;
439
+ }
440
+ }
441
+
442
+ module.exports = {
443
+ _excelImport,
444
+ _excelExport,
445
+ ExcelHelper,
446
+ };
@@ -0,0 +1,64 @@
1
+ # fs 模块
2
+
3
+
4
+ ## 根据文件路径获取文件内容
5
+
6
+ ```js
7
+ const { getFileContent } = require('@gingkoo/node-tools')
8
+ /**
9
+ * @param {string} filePath 文件路径
10
+ * @param {string?} charset 字符集
11
+ * @returns
12
+ */
13
+ const fileContent = getFileContent(filePath, charset='utf8')
14
+ ```
15
+
16
+ ## 判断文件是否存在
17
+
18
+ ```js
19
+ const { fileExist } = require('@gingkoo/node-tools')
20
+
21
+ /**
22
+ * @param {string} path 文件路径
23
+ * @returns boolean
24
+ */
25
+ const isExist = fileExist(path)
26
+ ```
27
+
28
+ ## 保存文件
29
+
30
+ ```js
31
+ const { saveFile } = require('@gingkoo/node-tools')
32
+
33
+ /**
34
+ * @param {string} path
35
+ * @param {string} content
36
+ * @returns
37
+ */
38
+ const isSave = saveFile(path, content)
39
+ ```
40
+
41
+ ## 删除文件
42
+
43
+ ```js
44
+ const { delFile } = require('@gingkoo/node-tools')
45
+
46
+ /**
47
+ * @param {string} path
48
+ * @returns
49
+ */
50
+ const isDel = delFile(path)
51
+ ```
52
+
53
+ ## 判读路径是否存在,如不存在创建文件夹
54
+
55
+ ```js
56
+ const { mkdirPath } = require('@gingkoo/node-tools')
57
+
58
+ /**
59
+ * @param {string} pathStr
60
+ * @param {{unlink: boolean}?} optinos
61
+ * @returns
62
+ */
63
+ const projectPath = mkdirPath(pathStr, optinos)
64
+ ```
@@ -0,0 +1,127 @@
1
+ 'use strict';
2
+ var { readFileSync, writeFile, access, unlink, constants } = require('fs');
3
+
4
+ /**
5
+ * 根据文件路径获取文件内容
6
+ * @param {string} filePath 文件路径
7
+ * @param {string?} charset 字符集
8
+ * @returns
9
+ */
10
+ const getFileContent = (filePath, charset = 'utf8') => {
11
+ let fileContent = readFileSync(filePath, charset);
12
+ return fileContent || '';
13
+ };
14
+
15
+ /**
16
+ * 判断文件是否存在
17
+ * @param {string} path 文件路径
18
+ * @returns boolean
19
+ */
20
+ const fileExist = (path) => {
21
+ return new Promise((resolve, reject) => {
22
+ access(path, constants.F_OK, (err) => {
23
+ if (err) {
24
+ resolve(false);
25
+ } else {
26
+ resolve(true);
27
+ }
28
+ });
29
+ });
30
+ };
31
+
32
+ /**
33
+ * 保存文件
34
+ * @param {string} path
35
+ * @param {string} content
36
+ * @returns
37
+ */
38
+ const saveFile = (path, content) => {
39
+ return new Promise((resolve) => {
40
+ writeFile(path, content, (err) => {
41
+ if (err) {
42
+ console.error(err);
43
+ return resolve(false);
44
+ }
45
+ resolve(true);
46
+ });
47
+ });
48
+ };
49
+
50
+ /**
51
+ * 删除文件
52
+ * @param {string} path
53
+ * @returns
54
+ */
55
+ const delFile = (path) => {
56
+ return new Promise((resolve) => {
57
+ unlink(path, (err) => {
58
+ if (err) {
59
+ console.error(err);
60
+ return resolve(false);
61
+ }
62
+ resolve(true);
63
+ });
64
+ });
65
+ };
66
+
67
+ /**
68
+ * 判读路径是否存在,如不存在创建文件夹
69
+ * @param {string} pathStr
70
+ * @param {boolean} optinos.unlink
71
+ * @returns
72
+ */
73
+ const mkdirPath = (pathStr, optinos) => {
74
+ optinos = optinos || { unlink: true };
75
+ let { unlink } = optinos;
76
+
77
+ var tempDirArray;
78
+ if (pathStr.indexOf('\\') !== -1) {
79
+ tempDirArray = pathStr.split('\\');
80
+ }
81
+ if (pathStr.indexOf('/') !== -1) {
82
+ tempDirArray = pathStr.split('/');
83
+ }
84
+ var projectPath = '';
85
+ for (var i = 0; i < tempDirArray.length; i++) {
86
+ projectPath += '/' + tempDirArray[i];
87
+
88
+ if (fs.existsSync(projectPath)) {
89
+ var tempstats = fs.statSync(projectPath);
90
+ if (!tempstats.isDirectory()) {
91
+ fs.unlinkSync(projectPath); // 如果存在同名文件 要不要删除?
92
+ fs.mkdirSync(projectPath);
93
+ }
94
+ } else {
95
+ fs.mkdirSync(projectPath);
96
+ }
97
+ }
98
+
99
+ return projectPath;
100
+ };
101
+
102
+ /**
103
+ * @api {get} /explorer/fileDownload?fileType= 文件下载
104
+ * @apiBody {array} dataArr 路径.
105
+ * @apiBody {array} fileType 压缩格式eg: zip.
106
+ *
107
+ */
108
+ router.get('/fileDownload', async function (req, res) {
109
+ const { path: filePath } = req.query;
110
+ req.clearTimeout();
111
+ let fileName = filePath.split('/')?.slice(-1)?.[0] || '';
112
+ setTimeout(() => {
113
+ res.download(filePath, fileName, function (err) {
114
+ if (err) {
115
+ return res.send(err);
116
+ }
117
+ });
118
+ }, 1e3);
119
+ });
120
+
121
+ module.exports = {
122
+ getFileContent,
123
+ fileExist,
124
+ saveFile,
125
+ delFile,
126
+ mkdirPath,
127
+ };
@@ -0,0 +1,54 @@
1
+ const jwt = require('jsonwebtoken');
2
+ const config = require('../config');
3
+
4
+ // 生成token
5
+ function generateToken(data, forever = false, cert = config?.jwt?.auth_cert) {
6
+ let created = Math.floor(Date.now() / 1000);
7
+ let exp = created + config.jwt.exp;
8
+ if (forever) {
9
+ exp = created + 60 * 60 * 24 * 365 * 10; // 10 年
10
+ }
11
+ let token = jwt.sign({ data, exp, iat: created }, cert);
12
+
13
+ return token;
14
+ }
15
+
16
+ // 校验token
17
+ function verifyToken(token, cert = config?.jwt?.auth_cert) {
18
+ let res = null;
19
+ if (token) {
20
+ try {
21
+ let result = jwt.verify(token, cert) || {};
22
+ let { exp = 0 } = result;
23
+ let current = Math.floor(Date.now() / 1000);
24
+ if (current <= exp) {
25
+ res = result || {};
26
+ }
27
+ } catch (e) {
28
+ console.log('token check failed.');
29
+ res = null;
30
+ }
31
+ }
32
+ return res;
33
+ }
34
+
35
+ // token 换 数据
36
+ function token2data(token, key = null, cert = config?.jwt?.auth_cert) {
37
+ if (token) {
38
+ var tokenResult = verifyToken(token, cert);
39
+ if (tokenResult) {
40
+ let tokenData = tokenResult['data'];
41
+ if (key) {
42
+ return tokenData[key];
43
+ }
44
+ return tokenData;
45
+ }
46
+ }
47
+ return null;
48
+ }
49
+
50
+ module.exports = Jwt = {
51
+ generateToken,
52
+ verifyToken,
53
+ token2data,
54
+ };