@james-zhang/elpis 1.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.
Files changed (86) hide show
  1. package/.eslintignore +3 -0
  2. package/.eslintrc +55 -0
  3. package/.tmp-check.js +47 -0
  4. package/README.md +287 -0
  5. package/app/controller/base.js +37 -0
  6. package/app/controller/project.js +76 -0
  7. package/app/controller/view.js +17 -0
  8. package/app/extend/logger.js +36 -0
  9. package/app/middleware/api-params-verify.js +78 -0
  10. package/app/middleware/api-sign-verify.js +31 -0
  11. package/app/middleware/error-handler.js +36 -0
  12. package/app/middleware/project-handler.js +26 -0
  13. package/app/middleware.js +69 -0
  14. package/app/pages/asserts/custom.css +10 -0
  15. package/app/pages/boot.js +44 -0
  16. package/app/pages/common/curl.js +76 -0
  17. package/app/pages/common/utils.js +2 -0
  18. package/app/pages/dashboard/complex-view/header-view/complex-view/sub-menu/sub-menu.vue +19 -0
  19. package/app/pages/dashboard/complex-view/header-view/header-view.vue +131 -0
  20. package/app/pages/dashboard/complex-view/iframe-view/iframe-view.vue +29 -0
  21. package/app/pages/dashboard/complex-view/schema-view/complex-view/search-pannel/search-pannel.vue +36 -0
  22. package/app/pages/dashboard/complex-view/schema-view/complex-view/table-pannel/table-pannel.vue +125 -0
  23. package/app/pages/dashboard/complex-view/schema-view/components/component-config.js +19 -0
  24. package/app/pages/dashboard/complex-view/schema-view/components/create-form/create-form.vue +119 -0
  25. package/app/pages/dashboard/complex-view/schema-view/components/detail-panel/detail-panel.vue +131 -0
  26. package/app/pages/dashboard/complex-view/schema-view/components/edit-form/edit-form.vue +149 -0
  27. package/app/pages/dashboard/complex-view/schema-view/hook/schema.js +126 -0
  28. package/app/pages/dashboard/complex-view/schema-view/schema-view.vue +111 -0
  29. package/app/pages/dashboard/complex-view/sider-view/complex-view/sub-menu/sub-menu.vue +28 -0
  30. package/app/pages/dashboard/complex-view/sider-view/sider-view.vue +138 -0
  31. package/app/pages/dashboard/dashboard.vue +121 -0
  32. package/app/pages/dashboard/entry.dashboard.js +52 -0
  33. package/app/pages/dashboard/router.js +3 -0
  34. package/app/pages/dashboard/todo/todo.vue +10 -0
  35. package/app/pages/store/index.js +3 -0
  36. package/app/pages/store/menu.js +71 -0
  37. package/app/pages/store/project.js +15 -0
  38. package/app/pages/widgets/header-container/asserts/avatar.png +0 -0
  39. package/app/pages/widgets/header-container/asserts/logo.png +0 -0
  40. package/app/pages/widgets/header-container/header-container.vue +118 -0
  41. package/app/pages/widgets/schema-form/complex-view/input/input.vue +165 -0
  42. package/app/pages/widgets/schema-form/complex-view/input-number/input-number.vue +164 -0
  43. package/app/pages/widgets/schema-form/complex-view/select/select.vue +138 -0
  44. package/app/pages/widgets/schema-form/form-item-config.js +20 -0
  45. package/app/pages/widgets/schema-form/schema-form.vue +154 -0
  46. package/app/pages/widgets/schema-search-bar/complex-view/date-range/date-range.vue +49 -0
  47. package/app/pages/widgets/schema-search-bar/complex-view/dynamic-select/dynamic-select.vue +65 -0
  48. package/app/pages/widgets/schema-search-bar/complex-view/input/input.vue +44 -0
  49. package/app/pages/widgets/schema-search-bar/complex-view/select/select.vue +50 -0
  50. package/app/pages/widgets/schema-search-bar/schema-search-bar.vue +134 -0
  51. package/app/pages/widgets/schema-search-bar/search-item-config.js +27 -0
  52. package/app/pages/widgets/schema-table/schema-table.vue +277 -0
  53. package/app/pages/widgets/sider-container/sider-container.vue +42 -0
  54. package/app/public/static/logo.png +0 -0
  55. package/app/public/static/normalize.css +239 -0
  56. package/app/router/project.js +7 -0
  57. package/app/router/view.js +7 -0
  58. package/app/router-schema/project.js +34 -0
  59. package/app/service/base.js +10 -0
  60. package/app/service/project.js +43 -0
  61. package/app/view/entry.tpl +31 -0
  62. package/app/webpack/config/webpack.base.js +224 -0
  63. package/app/webpack/config/webpack.dev.js +53 -0
  64. package/app/webpack/config/webpack.prod.js +104 -0
  65. package/app/webpack/dev.js +54 -0
  66. package/app/webpack/libs/blank.js +1 -0
  67. package/app/webpack/prod.js +17 -0
  68. package/config/config.default.js +3 -0
  69. package/docs/dashboard-model.js +150 -0
  70. package/elpis-core/env.js +21 -0
  71. package/elpis-core/index.js +82 -0
  72. package/elpis-core/loader/config.js +58 -0
  73. package/elpis-core/loader/controller.js +55 -0
  74. package/elpis-core/loader/extend.js +42 -0
  75. package/elpis-core/loader/middleware.js +50 -0
  76. package/elpis-core/loader/router-schema.js +28 -0
  77. package/elpis-core/loader/router.js +42 -0
  78. package/elpis-core/loader/service.js +51 -0
  79. package/index.js +37 -0
  80. package/logs/application.log +50 -0
  81. package/logs/application.log.2026-06-13 +159 -0
  82. package/model/index.js +119 -0
  83. package/package.json +88 -0
  84. package/scripts/generate-cover.py +93 -0
  85. package/scripts/generate-diagrams.js +80 -0
  86. package/test/controller/project.test.js +218 -0
@@ -0,0 +1,159 @@
1
+ [2026-06-13T18:00:41.558] [INFO] default - 项目列表请求成功
2
+ [2026-06-13T19:12:29.199] [INFO] default - 项目列表请求成功
3
+ [2026-06-13T19:13:05.127] [INFO] default - {"cause":{},"isOperational":true}
4
+ [2026-06-13T19:13:05.127] [ERROR] default - [--exception--]: OperationalError: template not found: output/entry.page3.tpl
5
+ at createTemplate (D:\CV_project\elpis-learning\node_modules\.store\nunjucks@3.2.4\node_modules\nunjucks\src\environment.js:234:15)
6
+ ... 14 lines matching cause stack trace ...
7
+ at new Promise (<anonymous>) {
8
+ cause: Error: template not found: output/entry.page3.tpl
9
+ at createTemplate (D:\CV_project\elpis-learning\node_modules\.store\nunjucks@3.2.4\node_modules\nunjucks\src\environment.js:234:15)
10
+ at next (D:\CV_project\elpis-learning\node_modules\.store\nunjucks@3.2.4\node_modules\nunjucks\src\lib.js:260:7)
11
+ at handle (D:\CV_project\elpis-learning\node_modules\.store\nunjucks@3.2.4\node_modules\nunjucks\src\environment.js:267:11)
12
+ at D:\CV_project\elpis-learning\node_modules\.store\nunjucks@3.2.4\node_modules\nunjucks\src\environment.js:276:9
13
+ at next (D:\CV_project\elpis-learning\node_modules\.store\nunjucks@3.2.4\node_modules\nunjucks\src\lib.js:258:7)
14
+ at Object.asyncIter (D:\CV_project\elpis-learning\node_modules\.store\nunjucks@3.2.4\node_modules\nunjucks\src\lib.js:263:3)
15
+ at Environment.getTemplate (D:\CV_project\elpis-learning\node_modules\.store\nunjucks@3.2.4\node_modules\nunjucks\src\environment.js:259:9)
16
+ at Environment.render (D:\CV_project\elpis-learning\node_modules\.store\nunjucks@3.2.4\node_modules\nunjucks\src\environment.js:295:10)
17
+ at Environment.promisified [as renderAsync] (D:\CV_project\elpis-learning\node_modules\.store\bluebird@3.7.2\node_modules\bluebird\js\release\promisify.js:223:16)
18
+ at _callee$ (D:\CV_project\elpis-learning\node_modules\.store\koa-nunjucks-2@3.0.2\node_modules\koa-nunjucks-2\compiled.js:109:64)
19
+ at tryCatch (D:\CV_project\elpis-learning\node_modules\.store\regenerator-runtime@0.11.1\node_modules\regenerator-runtime\runtime.js:62:40)
20
+ at Generator.invoke [as _invoke] (D:\CV_project\elpis-learning\node_modules\.store\regenerator-runtime@0.11.1\node_modules\regenerator-runtime\runtime.js:296:22)
21
+ at prototype.<computed> [as next] (D:\CV_project\elpis-learning\node_modules\.store\regenerator-runtime@0.11.1\node_modules\regenerator-runtime\runtime.js:114:21)
22
+ at step (D:\CV_project\elpis-learning\node_modules\.store\babel-runtime@6.26.0\node_modules\babel-runtime\helpers\asyncToGenerator.js:17:30)
23
+ at D:\CV_project\elpis-learning\node_modules\.store\babel-runtime@6.26.0\node_modules\babel-runtime\helpers\asyncToGenerator.js:35:14
24
+ at new Promise (<anonymous>),
25
+ isOperational: true
26
+ }
27
+ [2026-06-13T19:13:05.129] [ERROR] default - [--exception--]: undefined template not found: output/entry.page3.tpl undefined
28
+ [2026-06-13T19:41:44.950] [INFO] default - {}
29
+ [2026-06-13T19:41:44.951] [ERROR] default - [--exception--]: ReferenceError: methd is not defined
30
+ at D:\CV_project\elpis-learning\app\middleware\api-sign-verify.js:18:25
31
+ at dispatch (D:\CV_project\elpis-learning\node_modules\.store\koa-compose@4.1.0\node_modules\koa-compose\index.js:42:32)
32
+ at D:\CV_project\elpis-learning\app\middleware\error-handler.js:9:13
33
+ at dispatch (D:\CV_project\elpis-learning\node_modules\.store\koa-compose@4.1.0\node_modules\koa-compose\index.js:42:32)
34
+ at bodyParser (D:\CV_project\elpis-learning\node_modules\.store\koa-bodyparser@4.4.1\node_modules\koa-bodyparser\index.js:78:11)
35
+ [2026-06-13T19:41:44.952] [ERROR] default - [--exception--]: undefined methd is not defined undefined
36
+ [2026-06-13T19:41:51.000] [INFO] default - {}
37
+ [2026-06-13T19:41:51.001] [ERROR] default - [--exception--]: ReferenceError: methd is not defined
38
+ at D:\CV_project\elpis-learning\app\middleware\api-sign-verify.js:18:25
39
+ at dispatch (D:\CV_project\elpis-learning\node_modules\.store\koa-compose@4.1.0\node_modules\koa-compose\index.js:42:32)
40
+ at D:\CV_project\elpis-learning\app\middleware\error-handler.js:9:13
41
+ at dispatch (D:\CV_project\elpis-learning\node_modules\.store\koa-compose@4.1.0\node_modules\koa-compose\index.js:42:32)
42
+ at bodyParser (D:\CV_project\elpis-learning\node_modules\.store\koa-bodyparser@4.4.1\node_modules\koa-bodyparser\index.js:78:11)
43
+ [2026-06-13T19:41:51.002] [ERROR] default - [--exception--]: undefined methd is not defined undefined
44
+ [2026-06-13T19:42:13.186] [INFO] default - [GET $[path]] signature:dcd2070de24a192c439135a9b93a634d
45
+ [2026-06-13T19:42:13.190] [INFO] default - 项目列表请求成功
46
+ [2026-06-13T19:42:27.702] [INFO] default - [GET $[path]] signature:007a38570263b9931d6ce29e58d9cd3d
47
+ [2026-06-13T19:42:27.704] [INFO] default - 项目列表请求成功
48
+ [2026-06-13T19:42:34.413] [INFO] default - [GET $[path]] signature:da1bfef727e323257f8c15b6627ea902
49
+ [2026-06-13T20:21:56.515] [INFO] default - [GET $[path]] signature:44b1267325cc1f2cb38c5313dfa9d33c
50
+ [2026-06-13T20:21:56.516] [INFO] default - [GET] /api/project/list body:{}
51
+ [2026-06-13T20:21:56.517] [INFO] default - [GET] /api/project/list params:undefined
52
+ [2026-06-13T20:21:56.518] [INFO] default - [GET] /api/project/list headers:{"host":"localhost:8080","connection":"keep-alive","pragma":"no-cache","cache-control":"no-cache","s_t":"1781353316453","sec-ch-ua-platform":"\"Windows\"","sec-ch-ua":"\"Chromium\";v=\"148\", \"Google Chrome\";v=\"148\", \"Not/A)Brand\";v=\"99\"","sec-ch-ua-mobile":"?0","s_sign":"44b1267325cc1f2cb38c5313dfa9d33c","user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/148.0.0.0 Safari/537.36","accept":"application/json, text/plain, */*","content-type":"application/json","sec-fetch-site":"same-origin","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:8080/view/page1","accept-encoding":"gzip, deflate, br, zstd","accept-language":"zh-CN,zh;q=0.9","cookie":"_ga=GA1.1.952682400.1772029889; _ga_HT3DXHT6MN=GS2.1.s1775795289$o8$g1$t1775795391$j19$l0$h0; token=0bacd914-f9d5-4797-9f34-712bd3e7c925"}
53
+ [2026-06-13T20:21:56.518] [INFO] default - [GET] /api/project/list headers:{"host":"localhost:8080","connection":"keep-alive","pragma":"no-cache","cache-control":"no-cache","s_t":"1781353316453","sec-ch-ua-platform":"\"Windows\"","sec-ch-ua":"\"Chromium\";v=\"148\", \"Google Chrome\";v=\"148\", \"Not/A)Brand\";v=\"99\"","sec-ch-ua-mobile":"?0","s_sign":"44b1267325cc1f2cb38c5313dfa9d33c","user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/148.0.0.0 Safari/537.36","accept":"application/json, text/plain, */*","content-type":"application/json","sec-fetch-site":"same-origin","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:8080/view/page1","accept-encoding":"gzip, deflate, br, zstd","accept-language":"zh-CN,zh;q=0.9","cookie":"_ga=GA1.1.952682400.1772029889; _ga_HT3DXHT6MN=GS2.1.s1775795289$o8$g1$t1775795391$j19$l0$h0; token=0bacd914-f9d5-4797-9f34-712bd3e7c925"}
54
+ [2026-06-13T20:21:56.519] [INFO] default - {}
55
+ [2026-06-13T20:21:56.519] [ERROR] default - [--exception--]: TypeError: Cannot read properties of undefined (reading '/api/project/list')
56
+ at D:\CV_project\elpis-learning\app\middleware\api-params-verify.js:23:33
57
+ at dispatch (D:\CV_project\elpis-learning\node_modules\.store\koa-compose@4.1.0\node_modules\koa-compose\index.js:42:32)
58
+ at D:\CV_project\elpis-learning\app\middleware\api-sign-verify.js:29:11
59
+ at dispatch (D:\CV_project\elpis-learning\node_modules\.store\koa-compose@4.1.0\node_modules\koa-compose\index.js:42:32)
60
+ at D:\CV_project\elpis-learning\app\middleware\error-handler.js:9:13
61
+ at dispatch (D:\CV_project\elpis-learning\node_modules\.store\koa-compose@4.1.0\node_modules\koa-compose\index.js:42:32)
62
+ at bodyParser (D:\CV_project\elpis-learning\node_modules\.store\koa-bodyparser@4.4.1\node_modules\koa-bodyparser\index.js:78:11)
63
+ at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
64
+ [2026-06-13T20:21:56.520] [ERROR] default - [--exception--]: undefined Cannot read properties of undefined (reading '/api/project/list') undefined
65
+ [2026-06-13T20:22:57.604] [INFO] default - [GET $[path]] signature:b4c7f0e9d26ea2dfbefef599bf972d68
66
+ [2026-06-13T20:22:57.605] [INFO] default - [GET] /api/project/list body:{}
67
+ [2026-06-13T20:22:57.605] [INFO] default - [GET] /api/project/list params:undefined
68
+ [2026-06-13T20:22:57.606] [INFO] default - [GET] /api/project/list headers:{"host":"localhost:8080","connection":"keep-alive","pragma":"no-cache","cache-control":"no-cache","s_t":"1781353377595","sec-ch-ua-platform":"\"Windows\"","sec-ch-ua":"\"Chromium\";v=\"148\", \"Google Chrome\";v=\"148\", \"Not/A)Brand\";v=\"99\"","sec-ch-ua-mobile":"?0","s_sign":"b4c7f0e9d26ea2dfbefef599bf972d68","user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/148.0.0.0 Safari/537.36","accept":"application/json, text/plain, */*","content-type":"application/json","sec-fetch-site":"same-origin","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:8080/view/page1","accept-encoding":"gzip, deflate, br, zstd","accept-language":"zh-CN,zh;q=0.9","cookie":"_ga=GA1.1.952682400.1772029889; _ga_HT3DXHT6MN=GS2.1.s1775795289$o8$g1$t1775795391$j19$l0$h0; token=0bacd914-f9d5-4797-9f34-712bd3e7c925"}
69
+ [2026-06-13T20:22:57.606] [INFO] default - [GET] /api/project/list headers:{"host":"localhost:8080","connection":"keep-alive","pragma":"no-cache","cache-control":"no-cache","s_t":"1781353377595","sec-ch-ua-platform":"\"Windows\"","sec-ch-ua":"\"Chromium\";v=\"148\", \"Google Chrome\";v=\"148\", \"Not/A)Brand\";v=\"99\"","sec-ch-ua-mobile":"?0","s_sign":"b4c7f0e9d26ea2dfbefef599bf972d68","user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/148.0.0.0 Safari/537.36","accept":"application/json, text/plain, */*","content-type":"application/json","sec-fetch-site":"same-origin","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:8080/view/page1","accept-encoding":"gzip, deflate, br, zstd","accept-language":"zh-CN,zh;q=0.9","cookie":"_ga=GA1.1.952682400.1772029889; _ga_HT3DXHT6MN=GS2.1.s1775795289$o8$g1$t1775795391$j19$l0$h0; token=0bacd914-f9d5-4797-9f34-712bd3e7c925"}
70
+ [2026-06-13T20:22:57.607] [INFO] default - {}
71
+ [2026-06-13T20:22:57.607] [ERROR] default - [--exception--]: TypeError: Cannot read properties of undefined (reading '/api/project/list')
72
+ at D:\CV_project\elpis-learning\app\middleware\api-params-verify.js:23:33
73
+ at dispatch (D:\CV_project\elpis-learning\node_modules\.store\koa-compose@4.1.0\node_modules\koa-compose\index.js:42:32)
74
+ at D:\CV_project\elpis-learning\app\middleware\api-sign-verify.js:29:11
75
+ at dispatch (D:\CV_project\elpis-learning\node_modules\.store\koa-compose@4.1.0\node_modules\koa-compose\index.js:42:32)
76
+ at D:\CV_project\elpis-learning\app\middleware\error-handler.js:9:13
77
+ at dispatch (D:\CV_project\elpis-learning\node_modules\.store\koa-compose@4.1.0\node_modules\koa-compose\index.js:42:32)
78
+ at bodyParser (D:\CV_project\elpis-learning\node_modules\.store\koa-bodyparser@4.4.1\node_modules\koa-bodyparser\index.js:78:11)
79
+ at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
80
+ [2026-06-13T20:22:57.608] [ERROR] default - [--exception--]: undefined Cannot read properties of undefined (reading '/api/project/list') undefined
81
+ [2026-06-13T20:23:52.849] [INFO] default - [GET $[path]] signature:4f6e35907c6bdf55a9d12ed4f166b73c
82
+ [2026-06-13T20:23:52.851] [INFO] default - [GET] /api/project/list body:{}
83
+ [2026-06-13T20:23:52.851] [INFO] default - [GET] /api/project/list params:undefined
84
+ [2026-06-13T20:23:52.851] [INFO] default - [GET] /api/project/list headers:{"host":"localhost:8080","connection":"keep-alive","pragma":"no-cache","cache-control":"no-cache","s_t":"1781353432788","sec-ch-ua-platform":"\"Windows\"","sec-ch-ua":"\"Chromium\";v=\"148\", \"Google Chrome\";v=\"148\", \"Not/A)Brand\";v=\"99\"","sec-ch-ua-mobile":"?0","s_sign":"4f6e35907c6bdf55a9d12ed4f166b73c","user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/148.0.0.0 Safari/537.36","accept":"application/json, text/plain, */*","content-type":"application/json","sec-fetch-site":"same-origin","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:8080/view/page1","accept-encoding":"gzip, deflate, br, zstd","accept-language":"zh-CN,zh;q=0.9","cookie":"_ga=GA1.1.952682400.1772029889; _ga_HT3DXHT6MN=GS2.1.s1775795289$o8$g1$t1775795391$j19$l0$h0; token=0bacd914-f9d5-4797-9f34-712bd3e7c925"}
85
+ [2026-06-13T20:23:52.852] [INFO] default - [GET] /api/project/list headers:{"host":"localhost:8080","connection":"keep-alive","pragma":"no-cache","cache-control":"no-cache","s_t":"1781353432788","sec-ch-ua-platform":"\"Windows\"","sec-ch-ua":"\"Chromium\";v=\"148\", \"Google Chrome\";v=\"148\", \"Not/A)Brand\";v=\"99\"","sec-ch-ua-mobile":"?0","s_sign":"4f6e35907c6bdf55a9d12ed4f166b73c","user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/148.0.0.0 Safari/537.36","accept":"application/json, text/plain, */*","content-type":"application/json","sec-fetch-site":"same-origin","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:8080/view/page1","accept-encoding":"gzip, deflate, br, zstd","accept-language":"zh-CN,zh;q=0.9","cookie":"_ga=GA1.1.952682400.1772029889; _ga_HT3DXHT6MN=GS2.1.s1775795289$o8$g1$t1775795391$j19$l0$h0; token=0bacd914-f9d5-4797-9f34-712bd3e7c925"}
86
+ [2026-06-13T20:23:52.853] [INFO] default - 项目列表请求成功
87
+ [2026-06-13T20:25:31.598] [INFO] default - [GET $[path]] signature:b9ef3149b99cc69fafd975d7e80a3c6d
88
+ [2026-06-13T20:25:31.599] [INFO] default - [GET] /api/project/list body:{}
89
+ [2026-06-13T20:25:31.599] [INFO] default - [GET] /api/project/list params:undefined
90
+ [2026-06-13T20:25:31.600] [INFO] default - [GET] /api/project/list headers:{"host":"localhost:8080","connection":"keep-alive","pragma":"no-cache","cache-control":"no-cache","s_t":"1781353531585","sec-ch-ua-platform":"\"Windows\"","sec-ch-ua":"\"Chromium\";v=\"148\", \"Google Chrome\";v=\"148\", \"Not/A)Brand\";v=\"99\"","sec-ch-ua-mobile":"?0","s_sign":"b9ef3149b99cc69fafd975d7e80a3c6d","user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/148.0.0.0 Safari/537.36","accept":"application/json, text/plain, */*","content-type":"application/json","sec-fetch-site":"same-origin","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:8080/view/page1","accept-encoding":"gzip, deflate, br, zstd","accept-language":"zh-CN,zh;q=0.9","cookie":"_ga=GA1.1.952682400.1772029889; _ga_HT3DXHT6MN=GS2.1.s1775795289$o8$g1$t1775795391$j19$l0$h0; token=0bacd914-f9d5-4797-9f34-712bd3e7c925"}
91
+ [2026-06-13T20:25:31.600] [INFO] default - [GET] /api/project/list headers:{"host":"localhost:8080","connection":"keep-alive","pragma":"no-cache","cache-control":"no-cache","s_t":"1781353531585","sec-ch-ua-platform":"\"Windows\"","sec-ch-ua":"\"Chromium\";v=\"148\", \"Google Chrome\";v=\"148\", \"Not/A)Brand\";v=\"99\"","sec-ch-ua-mobile":"?0","s_sign":"b9ef3149b99cc69fafd975d7e80a3c6d","user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/148.0.0.0 Safari/537.36","accept":"application/json, text/plain, */*","content-type":"application/json","sec-fetch-site":"same-origin","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:8080/view/page1","accept-encoding":"gzip, deflate, br, zstd","accept-language":"zh-CN,zh;q=0.9","cookie":"_ga=GA1.1.952682400.1772029889; _ga_HT3DXHT6MN=GS2.1.s1775795289$o8$g1$t1775795391$j19$l0$h0; token=0bacd914-f9d5-4797-9f34-712bd3e7c925"}
92
+ [2026-06-13T20:25:31.601] [INFO] default - 项目列表请求成功
93
+ [2026-06-13T20:26:32.752] [INFO] default - [GET $[path]] signature:bc86ee5543d501c14d9bbb5d6cb6a4e8
94
+ [2026-06-13T20:26:32.753] [INFO] default - [GET] /api/project/list body:{}
95
+ [2026-06-13T20:26:32.754] [INFO] default - [GET] /api/project/list params:undefined
96
+ [2026-06-13T20:26:32.754] [INFO] default - [GET] /api/project/list headers:{"host":"localhost:8080","connection":"keep-alive","pragma":"no-cache","cache-control":"no-cache","s_t":"1781353592742","s_sign":"bc86ee5543d501c14d9bbb5d6cb6a4e8","sec-ch-ua-platform":"\"Windows\"","user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/148.0.0.0 Safari/537.36","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Chromium\";v=\"148\", \"Google Chrome\";v=\"148\", \"Not/A)Brand\";v=\"99\"","sec-ch-ua-mobile":"?0","sec-fetch-site":"same-origin","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:8080/view/page1","accept-encoding":"gzip, deflate, br, zstd","accept-language":"zh-CN,zh;q=0.9","cookie":"_ga=GA1.1.952682400.1772029889; _ga_HT3DXHT6MN=GS2.1.s1775795289$o8$g1$t1775795391$j19$l0$h0; token=0bacd914-f9d5-4797-9f34-712bd3e7c925"}
97
+ [2026-06-13T20:26:32.755] [INFO] default - [GET] /api/project/list headers:{"host":"localhost:8080","connection":"keep-alive","pragma":"no-cache","cache-control":"no-cache","s_t":"1781353592742","s_sign":"bc86ee5543d501c14d9bbb5d6cb6a4e8","sec-ch-ua-platform":"\"Windows\"","user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/148.0.0.0 Safari/537.36","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Chromium\";v=\"148\", \"Google Chrome\";v=\"148\", \"Not/A)Brand\";v=\"99\"","sec-ch-ua-mobile":"?0","sec-fetch-site":"same-origin","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:8080/view/page1","accept-encoding":"gzip, deflate, br, zstd","accept-language":"zh-CN,zh;q=0.9","cookie":"_ga=GA1.1.952682400.1772029889; _ga_HT3DXHT6MN=GS2.1.s1775795289$o8$g1$t1775795391$j19$l0$h0; token=0bacd914-f9d5-4797-9f34-712bd3e7c925"}
98
+ [2026-06-13T20:26:32.756] [INFO] default - {}
99
+ [2026-06-13T20:26:32.756] [ERROR] default - [--exception--]: TypeError: Cannot set properties of undefined (setting '$schema')
100
+ at D:\CV_project\elpis-learning\app\middleware\api-params-verify.js:32:24
101
+ at dispatch (D:\CV_project\elpis-learning\node_modules\.store\koa-compose@4.1.0\node_modules\koa-compose\index.js:42:32)
102
+ at D:\CV_project\elpis-learning\app\middleware\api-sign-verify.js:29:11
103
+ at dispatch (D:\CV_project\elpis-learning\node_modules\.store\koa-compose@4.1.0\node_modules\koa-compose\index.js:42:32)
104
+ at D:\CV_project\elpis-learning\app\middleware\error-handler.js:9:13
105
+ at dispatch (D:\CV_project\elpis-learning\node_modules\.store\koa-compose@4.1.0\node_modules\koa-compose\index.js:42:32)
106
+ at bodyParser (D:\CV_project\elpis-learning\node_modules\.store\koa-bodyparser@4.4.1\node_modules\koa-bodyparser\index.js:78:11)
107
+ [2026-06-13T20:26:32.757] [ERROR] default - [--exception--]: undefined Cannot set properties of undefined (setting '$schema') undefined
108
+ [2026-06-13T20:28:23.994] [INFO] default - [GET $[path]] signature:d66ae8f887d5007f34dc13dad75867e4
109
+ [2026-06-13T20:28:23.996] [INFO] default - [GET] /api/project/list body:{}
110
+ [2026-06-13T20:28:23.996] [INFO] default - [GET] /api/project/list params:undefined
111
+ [2026-06-13T20:28:23.997] [INFO] default - [GET] /api/project/list headers:{"host":"localhost:8080","connection":"keep-alive","pragma":"no-cache","cache-control":"no-cache","s_t":"1781353703983","s_sign":"d66ae8f887d5007f34dc13dad75867e4","sec-ch-ua-platform":"\"Windows\"","user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/148.0.0.0 Safari/537.36","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Chromium\";v=\"148\", \"Google Chrome\";v=\"148\", \"Not/A)Brand\";v=\"99\"","sec-ch-ua-mobile":"?0","sec-fetch-site":"same-origin","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:8080/view/page1","accept-encoding":"gzip, deflate, br, zstd","accept-language":"zh-CN,zh;q=0.9","cookie":"_ga=GA1.1.952682400.1772029889; _ga_HT3DXHT6MN=GS2.1.s1775795289$o8$g1$t1775795391$j19$l0$h0; token=0bacd914-f9d5-4797-9f34-712bd3e7c925"}
112
+ [2026-06-13T20:28:23.997] [INFO] default - [GET] /api/project/list headers:{"host":"localhost:8080","connection":"keep-alive","pragma":"no-cache","cache-control":"no-cache","s_t":"1781353703983","s_sign":"d66ae8f887d5007f34dc13dad75867e4","sec-ch-ua-platform":"\"Windows\"","user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/148.0.0.0 Safari/537.36","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Chromium\";v=\"148\", \"Google Chrome\";v=\"148\", \"Not/A)Brand\";v=\"99\"","sec-ch-ua-mobile":"?0","sec-fetch-site":"same-origin","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:8080/view/page1","accept-encoding":"gzip, deflate, br, zstd","accept-language":"zh-CN,zh;q=0.9","cookie":"_ga=GA1.1.952682400.1772029889; _ga_HT3DXHT6MN=GS2.1.s1775795289$o8$g1$t1775795391$j19$l0$h0; token=0bacd914-f9d5-4797-9f34-712bd3e7c925"}
113
+ [2026-06-13T20:28:50.878] [INFO] default - [GET $[path]] signature:c876d6a33ad422e8359eef3b723e4985
114
+ [2026-06-13T20:28:50.879] [INFO] default - [GET] /api/project/list body:{}
115
+ [2026-06-13T20:28:50.879] [INFO] default - [GET] /api/project/list params:undefined
116
+ [2026-06-13T20:28:50.880] [INFO] default - [GET] /api/project/list headers:{"host":"localhost:8080","connection":"keep-alive","pragma":"no-cache","cache-control":"no-cache","s_t":"1781353730870","s_sign":"c876d6a33ad422e8359eef3b723e4985","sec-ch-ua-platform":"\"Windows\"","user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/148.0.0.0 Safari/537.36","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Chromium\";v=\"148\", \"Google Chrome\";v=\"148\", \"Not/A)Brand\";v=\"99\"","sec-ch-ua-mobile":"?0","sec-fetch-site":"same-origin","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:8080/view/page1","accept-encoding":"gzip, deflate, br, zstd","accept-language":"zh-CN,zh;q=0.9","cookie":"_ga=GA1.1.952682400.1772029889; _ga_HT3DXHT6MN=GS2.1.s1775795289$o8$g1$t1775795391$j19$l0$h0; token=0bacd914-f9d5-4797-9f34-712bd3e7c925"}
117
+ [2026-06-13T20:28:50.881] [INFO] default - [GET] /api/project/list headers:{"host":"localhost:8080","connection":"keep-alive","pragma":"no-cache","cache-control":"no-cache","s_t":"1781353730870","s_sign":"c876d6a33ad422e8359eef3b723e4985","sec-ch-ua-platform":"\"Windows\"","user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/148.0.0.0 Safari/537.36","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Chromium\";v=\"148\", \"Google Chrome\";v=\"148\", \"Not/A)Brand\";v=\"99\"","sec-ch-ua-mobile":"?0","sec-fetch-site":"same-origin","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:8080/view/page1","accept-encoding":"gzip, deflate, br, zstd","accept-language":"zh-CN,zh;q=0.9","cookie":"_ga=GA1.1.952682400.1772029889; _ga_HT3DXHT6MN=GS2.1.s1775795289$o8$g1$t1775795391$j19$l0$h0; token=0bacd914-f9d5-4797-9f34-712bd3e7c925"}
118
+ [2026-06-13T20:29:07.122] [INFO] default - [GET $[path]] signature:5f0c7545af12639cd4e157e6b6721216
119
+ [2026-06-13T20:29:07.122] [INFO] default - [GET] /api/project/list body:{}
120
+ [2026-06-13T20:29:07.122] [INFO] default - [GET] /api/project/list params:undefined
121
+ [2026-06-13T20:29:07.123] [INFO] default - [GET] /api/project/list headers:{"host":"localhost:8080","connection":"keep-alive","pragma":"no-cache","cache-control":"no-cache","s_t":"1781353747111","s_sign":"5f0c7545af12639cd4e157e6b6721216","sec-ch-ua-platform":"\"Windows\"","user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/148.0.0.0 Safari/537.36","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Chromium\";v=\"148\", \"Google Chrome\";v=\"148\", \"Not/A)Brand\";v=\"99\"","sec-ch-ua-mobile":"?0","sec-fetch-site":"same-origin","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:8080/view/page1","accept-encoding":"gzip, deflate, br, zstd","accept-language":"zh-CN,zh;q=0.9","cookie":"_ga=GA1.1.952682400.1772029889; _ga_HT3DXHT6MN=GS2.1.s1775795289$o8$g1$t1775795391$j19$l0$h0; token=0bacd914-f9d5-4797-9f34-712bd3e7c925"}
122
+ [2026-06-13T20:29:07.123] [INFO] default - [GET] /api/project/list headers:{"host":"localhost:8080","connection":"keep-alive","pragma":"no-cache","cache-control":"no-cache","s_t":"1781353747111","s_sign":"5f0c7545af12639cd4e157e6b6721216","sec-ch-ua-platform":"\"Windows\"","user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/148.0.0.0 Safari/537.36","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Chromium\";v=\"148\", \"Google Chrome\";v=\"148\", \"Not/A)Brand\";v=\"99\"","sec-ch-ua-mobile":"?0","sec-fetch-site":"same-origin","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:8080/view/page1","accept-encoding":"gzip, deflate, br, zstd","accept-language":"zh-CN,zh;q=0.9","cookie":"_ga=GA1.1.952682400.1772029889; _ga_HT3DXHT6MN=GS2.1.s1775795289$o8$g1$t1775795391$j19$l0$h0; token=0bacd914-f9d5-4797-9f34-712bd3e7c925"}
123
+ [2026-06-13T20:29:24.296] [INFO] default - [GET $[path]] signature:97c407052225d565afa8615c4dca81fb
124
+ [2026-06-13T20:29:24.297] [INFO] default - [GET] /api/project/list body:{}
125
+ [2026-06-13T20:29:24.297] [INFO] default - [GET] /api/project/list params:undefined
126
+ [2026-06-13T20:29:24.298] [INFO] default - [GET] /api/project/list headers:{"host":"localhost:8080","connection":"keep-alive","pragma":"no-cache","cache-control":"no-cache","s_t":"1781353764287","s_sign":"97c407052225d565afa8615c4dca81fb","sec-ch-ua-platform":"\"Windows\"","user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/148.0.0.0 Safari/537.36","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Chromium\";v=\"148\", \"Google Chrome\";v=\"148\", \"Not/A)Brand\";v=\"99\"","sec-ch-ua-mobile":"?0","sec-fetch-site":"same-origin","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:8080/view/page1","accept-encoding":"gzip, deflate, br, zstd","accept-language":"zh-CN,zh;q=0.9","cookie":"_ga=GA1.1.952682400.1772029889; _ga_HT3DXHT6MN=GS2.1.s1775795289$o8$g1$t1775795391$j19$l0$h0; token=0bacd914-f9d5-4797-9f34-712bd3e7c925"}
127
+ [2026-06-13T20:29:24.298] [INFO] default - [GET] /api/project/list headers:{"host":"localhost:8080","connection":"keep-alive","pragma":"no-cache","cache-control":"no-cache","s_t":"1781353764287","s_sign":"97c407052225d565afa8615c4dca81fb","sec-ch-ua-platform":"\"Windows\"","user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/148.0.0.0 Safari/537.36","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Chromium\";v=\"148\", \"Google Chrome\";v=\"148\", \"Not/A)Brand\";v=\"99\"","sec-ch-ua-mobile":"?0","sec-fetch-site":"same-origin","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:8080/view/page1","accept-encoding":"gzip, deflate, br, zstd","accept-language":"zh-CN,zh;q=0.9","cookie":"_ga=GA1.1.952682400.1772029889; _ga_HT3DXHT6MN=GS2.1.s1775795289$o8$g1$t1775795391$j19$l0$h0; token=0bacd914-f9d5-4797-9f34-712bd3e7c925"}
128
+ [2026-06-13T20:29:53.545] [INFO] default - [GET $[path]] signature:e7a0d8fc4797a4ae2ae312535fdbfaee
129
+ [2026-06-13T20:29:53.545] [INFO] default - [GET] /api/project/list body:{}
130
+ [2026-06-13T20:29:53.545] [INFO] default - [GET] /api/project/list params:undefined
131
+ [2026-06-13T20:29:53.546] [INFO] default - [GET] /api/project/list headers:{"host":"localhost:8080","connection":"keep-alive","pragma":"no-cache","cache-control":"no-cache","s_t":"1781353793538","s_sign":"e7a0d8fc4797a4ae2ae312535fdbfaee","sec-ch-ua-platform":"\"Windows\"","user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/148.0.0.0 Safari/537.36","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Chromium\";v=\"148\", \"Google Chrome\";v=\"148\", \"Not/A)Brand\";v=\"99\"","sec-ch-ua-mobile":"?0","sec-fetch-site":"same-origin","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:8080/view/page1","accept-encoding":"gzip, deflate, br, zstd","accept-language":"zh-CN,zh;q=0.9","cookie":"_ga=GA1.1.952682400.1772029889; _ga_HT3DXHT6MN=GS2.1.s1775795289$o8$g1$t1775795391$j19$l0$h0; token=0bacd914-f9d5-4797-9f34-712bd3e7c925"}
132
+ [2026-06-13T20:29:53.546] [INFO] default - [GET] /api/project/list headers:{"host":"localhost:8080","connection":"keep-alive","pragma":"no-cache","cache-control":"no-cache","s_t":"1781353793538","s_sign":"e7a0d8fc4797a4ae2ae312535fdbfaee","sec-ch-ua-platform":"\"Windows\"","user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/148.0.0.0 Safari/537.36","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Chromium\";v=\"148\", \"Google Chrome\";v=\"148\", \"Not/A)Brand\";v=\"99\"","sec-ch-ua-mobile":"?0","sec-fetch-site":"same-origin","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:8080/view/page1","accept-encoding":"gzip, deflate, br, zstd","accept-language":"zh-CN,zh;q=0.9","cookie":"_ga=GA1.1.952682400.1772029889; _ga_HT3DXHT6MN=GS2.1.s1775795289$o8$g1$t1775795391$j19$l0$h0; token=0bacd914-f9d5-4797-9f34-712bd3e7c925"}
133
+ [2026-06-13T20:30:29.901] [INFO] default - [GET $[path]] signature:040cffc112fa427e94f1c94079759cf5
134
+ [2026-06-13T20:30:29.901] [INFO] default - [GET] /api/project/list body:{}
135
+ [2026-06-13T20:30:29.902] [INFO] default - [GET] /api/project/list params:undefined
136
+ [2026-06-13T20:30:29.902] [INFO] default - [GET] /api/project/list headers:{"host":"localhost:8080","connection":"keep-alive","pragma":"no-cache","cache-control":"no-cache","s_t":"1781353829893","s_sign":"040cffc112fa427e94f1c94079759cf5","sec-ch-ua-platform":"\"Windows\"","user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/148.0.0.0 Safari/537.36","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Chromium\";v=\"148\", \"Google Chrome\";v=\"148\", \"Not/A)Brand\";v=\"99\"","sec-ch-ua-mobile":"?0","sec-fetch-site":"same-origin","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:8080/view/page1","accept-encoding":"gzip, deflate, br, zstd","accept-language":"zh-CN,zh;q=0.9","cookie":"_ga=GA1.1.952682400.1772029889; _ga_HT3DXHT6MN=GS2.1.s1775795289$o8$g1$t1775795391$j19$l0$h0; token=0bacd914-f9d5-4797-9f34-712bd3e7c925"}
137
+ [2026-06-13T20:30:29.902] [INFO] default - [GET] /api/project/list headers:{"host":"localhost:8080","connection":"keep-alive","pragma":"no-cache","cache-control":"no-cache","s_t":"1781353829893","s_sign":"040cffc112fa427e94f1c94079759cf5","sec-ch-ua-platform":"\"Windows\"","user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/148.0.0.0 Safari/537.36","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Chromium\";v=\"148\", \"Google Chrome\";v=\"148\", \"Not/A)Brand\";v=\"99\"","sec-ch-ua-mobile":"?0","sec-fetch-site":"same-origin","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:8080/view/page1","accept-encoding":"gzip, deflate, br, zstd","accept-language":"zh-CN,zh;q=0.9","cookie":"_ga=GA1.1.952682400.1772029889; _ga_HT3DXHT6MN=GS2.1.s1775795289$o8$g1$t1775795391$j19$l0$h0; token=0bacd914-f9d5-4797-9f34-712bd3e7c925"}
138
+ [2026-06-13T20:30:36.733] [INFO] default - [GET $[path]] signature:8d40038c657893d43a3b164bc48aa386
139
+ [2026-06-13T20:30:36.733] [INFO] default - [GET] /api/project/list body:{}
140
+ [2026-06-13T20:30:36.733] [INFO] default - [GET] /api/project/list params:undefined
141
+ [2026-06-13T20:30:36.733] [INFO] default - [GET] /api/project/list headers:{"host":"localhost:8080","connection":"keep-alive","pragma":"no-cache","cache-control":"no-cache","s_t":"1781353836726","s_sign":"8d40038c657893d43a3b164bc48aa386","sec-ch-ua-platform":"\"Windows\"","user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/148.0.0.0 Safari/537.36","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Chromium\";v=\"148\", \"Google Chrome\";v=\"148\", \"Not/A)Brand\";v=\"99\"","sec-ch-ua-mobile":"?0","sec-fetch-site":"same-origin","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:8080/view/page1","accept-encoding":"gzip, deflate, br, zstd","accept-language":"zh-CN,zh;q=0.9","cookie":"_ga=GA1.1.952682400.1772029889; _ga_HT3DXHT6MN=GS2.1.s1775795289$o8$g1$t1775795391$j19$l0$h0; token=0bacd914-f9d5-4797-9f34-712bd3e7c925"}
142
+ [2026-06-13T20:30:36.734] [INFO] default - [GET] /api/project/list headers:{"host":"localhost:8080","connection":"keep-alive","pragma":"no-cache","cache-control":"no-cache","s_t":"1781353836726","s_sign":"8d40038c657893d43a3b164bc48aa386","sec-ch-ua-platform":"\"Windows\"","user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/148.0.0.0 Safari/537.36","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Chromium\";v=\"148\", \"Google Chrome\";v=\"148\", \"Not/A)Brand\";v=\"99\"","sec-ch-ua-mobile":"?0","sec-fetch-site":"same-origin","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:8080/view/page1","accept-encoding":"gzip, deflate, br, zstd","accept-language":"zh-CN,zh;q=0.9","cookie":"_ga=GA1.1.952682400.1772029889; _ga_HT3DXHT6MN=GS2.1.s1775795289$o8$g1$t1775795391$j19$l0$h0; token=0bacd914-f9d5-4797-9f34-712bd3e7c925"}
143
+ [2026-06-13T20:33:44.269] [INFO] default - [GET $[path]] signature:37172913afde22ef031e215d06b2d59d
144
+ [2026-06-13T20:33:44.270] [INFO] default - [GET] /api/project/list body:{}
145
+ [2026-06-13T20:33:44.270] [INFO] default - [GET] /api/project/list params:undefined
146
+ [2026-06-13T20:33:44.270] [INFO] default - [GET] /api/project/list headers:{"host":"localhost:8080","connection":"keep-alive","pragma":"no-cache","cache-control":"no-cache","s_t":"1781354024256","s_sign":"37172913afde22ef031e215d06b2d59d","sec-ch-ua-platform":"\"Windows\"","user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/148.0.0.0 Safari/537.36","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Chromium\";v=\"148\", \"Google Chrome\";v=\"148\", \"Not/A)Brand\";v=\"99\"","sec-ch-ua-mobile":"?0","sec-fetch-site":"same-origin","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:8080/view/page1","accept-encoding":"gzip, deflate, br, zstd","accept-language":"zh-CN,zh;q=0.9","cookie":"_ga=GA1.1.952682400.1772029889; _ga_HT3DXHT6MN=GS2.1.s1775795289$o8$g1$t1775795391$j19$l0$h0; token=0bacd914-f9d5-4797-9f34-712bd3e7c925"}
147
+ [2026-06-13T20:33:44.270] [INFO] default - [GET] /api/project/list headers:{"host":"localhost:8080","connection":"keep-alive","pragma":"no-cache","cache-control":"no-cache","s_t":"1781354024256","s_sign":"37172913afde22ef031e215d06b2d59d","sec-ch-ua-platform":"\"Windows\"","user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/148.0.0.0 Safari/537.36","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Chromium\";v=\"148\", \"Google Chrome\";v=\"148\", \"Not/A)Brand\";v=\"99\"","sec-ch-ua-mobile":"?0","sec-fetch-site":"same-origin","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:8080/view/page1","accept-encoding":"gzip, deflate, br, zstd","accept-language":"zh-CN,zh;q=0.9","cookie":"_ga=GA1.1.952682400.1772029889; _ga_HT3DXHT6MN=GS2.1.s1775795289$o8$g1$t1775795391$j19$l0$h0; token=0bacd914-f9d5-4797-9f34-712bd3e7c925"}
148
+ [2026-06-13T20:36:50.920] [INFO] default - [GET $[path]] signature:69b95942f7777344e36f4d48a94b4f20
149
+ [2026-06-13T20:36:50.922] [INFO] default - [GET] /api/project/list body:{}
150
+ [2026-06-13T20:36:50.922] [INFO] default - [GET] /api/project/list query:{"proj_key":"123456"}
151
+ [2026-06-13T20:36:50.922] [INFO] default - [GET] /api/project/list params:undefined
152
+ [2026-06-13T20:36:50.922] [INFO] default - [GET] /api/project/list headers:{"s_t":"1781354210896","s_sign":"69b95942f7777344e36f4d48a94b4f20","host":"127.0.0.1:8080","connection":"keep-alive"}
153
+ [2026-06-13T20:36:50.952] [INFO] default - 项目列表请求成功
154
+ [2026-06-13T20:37:49.719] [INFO] default - [GET $[path]] signature:141eaeaf44e35a70437908982c0c233c
155
+ [2026-06-13T20:37:49.719] [INFO] default - [GET] /api/project/list body:{}
156
+ [2026-06-13T20:37:49.719] [INFO] default - [GET] /api/project/list query:{"proj_key":"123456"}
157
+ [2026-06-13T20:37:49.719] [INFO] default - [GET] /api/project/list params:undefined
158
+ [2026-06-13T20:37:49.720] [INFO] default - [GET] /api/project/list headers:{"host":"localhost:8080","connection":"keep-alive","pragma":"no-cache","cache-control":"no-cache","s_t":"1781354269710","s_sign":"141eaeaf44e35a70437908982c0c233c","sec-ch-ua-platform":"\"Windows\"","user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/148.0.0.0 Safari/537.36","accept":"application/json, text/plain, */*","sec-ch-ua":"\"Chromium\";v=\"148\", \"Google Chrome\";v=\"148\", \"Not/A)Brand\";v=\"99\"","sec-ch-ua-mobile":"?0","sec-fetch-site":"same-origin","sec-fetch-mode":"cors","sec-fetch-dest":"empty","referer":"http://localhost:8080/view/page1","accept-encoding":"gzip, deflate, br, zstd","accept-language":"zh-CN,zh;q=0.9","cookie":"_ga=GA1.1.952682400.1772029889; _ga_HT3DXHT6MN=GS2.1.s1775795289$o8$g1$t1775795391$j19$l0$h0; token=0bacd914-f9d5-4797-9f34-712bd3e7c925"}
159
+ [2026-06-13T20:37:49.720] [INFO] default - 项目列表请求成功
package/model/index.js ADDED
@@ -0,0 +1,119 @@
1
+ const glob = require('glob')
2
+ const path = require('path')
3
+ const {sep} = path
4
+
5
+ //project继承model,project的配置会覆盖model的配置
6
+ const ProjectExtendModel=(model,project)=>{
7
+ if(project===undefined || project===null){
8
+ return model
9
+ }
10
+ if(model===undefined || model===null){
11
+ return project
12
+ }
13
+ // 数组合并:如果数组项都有 key,按 key 合并;否则 project 数组整体覆盖 model
14
+ if(Array.isArray(model) && Array.isArray(project)){
15
+ const allHaveKey = project.every(item=>item && typeof item==='object' && item.key) &&
16
+ model.every(item=>item && typeof item==='object' && item.key)
17
+ if(!allHaveKey){
18
+ return project
19
+ }
20
+
21
+ const result=[]
22
+ const usedProjectKeys=new Set()
23
+ for(const modelItem of model){
24
+ const projectItem=project.find(item=>item && item.key===modelItem.key)
25
+ if(projectItem){
26
+ usedProjectKeys.add(projectItem.key)
27
+ result.push(ProjectExtendModel(modelItem,projectItem))
28
+ continue
29
+ }
30
+ result.push(modelItem)
31
+ }
32
+ for(const projectItem of project){
33
+ if(!usedProjectKeys.has(projectItem.key)){
34
+ result.push(projectItem)
35
+ }
36
+ }
37
+ return result
38
+ }
39
+ // 对象深度合并
40
+ if(typeof model==='object' && typeof project==='object'){
41
+ const result={...model}
42
+ for(const key in project){
43
+ if(project[key]!==undefined){
44
+ result[key]=ProjectExtendModel(model[key],project[key])
45
+ }
46
+ }
47
+ return result
48
+ }
49
+ return project
50
+ }
51
+
52
+
53
+ /**
54
+ * 解析model配置,并返回组织并继承后的数据结构
55
+ * [{
56
+ * model : ${model}
57
+ * project:{
58
+ * project1Key: ${project1}
59
+ * project2Key: ${project2}
60
+ * }
61
+ * }...]
62
+ */
63
+
64
+ module.exports=(app)=>{
65
+ const modelList=[]
66
+
67
+ //遍历当前文件夹,构造模型数据结构,挂载到modelList上
68
+ const modelPath=path.resolve(app.baseDir,`.${sep}model`)
69
+ const fileList=glob.sync(path.resolve(modelPath,`.${sep}**${sep}**.js`))
70
+ fileList.forEach((file)=>{
71
+ //跳过index.js文件
72
+ if(file.indexOf('index.js')>-1){
73
+ return
74
+ }
75
+ //区分配置类型(model/project)
76
+ //注意:glob.sync() 返回的路径总是使用正斜杠 /,即使在 Windows 上
77
+ const type=file.indexOf('/project/')>-1?'project':'model'
78
+ if(type==='project'){
79
+ //egg:/src/model/user/project.js => modelKey=user,projectKey=project
80
+ const modelKey=file.match(/\/model\/(.*?)\/project/)?.[1]
81
+ const projectKey=file.match(/\/project\/(.*?)\.js/)?.[1]
82
+ let modelItem=modelList.find(item=>item.model?.key===modelKey)
83
+
84
+ if(!modelItem){ //初始化model数据结构
85
+ modelItem={}
86
+ modelList.push(modelItem)
87
+ }
88
+ if(!modelItem.project){
89
+ modelItem.project={}
90
+ }
91
+ modelItem.project[projectKey]=require(path.resolve(file))
92
+ modelItem.project[projectKey].key=projectKey //注入projectKey到project对象中
93
+ modelItem.project[projectKey].modelKey=modelKey //注入modelKey到project对象中
94
+ }
95
+
96
+ if(type==='model'){
97
+ //egg:/src/model/user/model.js => modelKey=user
98
+ const modelKey=file.match(/\/model\/(.*?)\/model\.js/)?.[1]
99
+ let modelItem=modelList.find(item=>item.model?.key===modelKey)
100
+ if(!modelItem){ //初始化model数据结构
101
+ modelItem={}
102
+ modelList.push(modelItem)
103
+ }
104
+ modelItem.model=require(path.resolve(file))
105
+ modelItem.model.key=modelKey //注入modelKey到model对象中
106
+ }
107
+
108
+ })
109
+
110
+ //数据进一步整理
111
+ modelList.forEach(item=>{
112
+ const {model,project}=item
113
+ for(const key in project){
114
+ project[key]=ProjectExtendModel(model,project[key])
115
+ }
116
+ })
117
+
118
+ return modelList
119
+ }
package/package.json ADDED
@@ -0,0 +1,88 @@
1
+ {
2
+ "name": "@james-zhang/elpis",
3
+ "version": "1.0.0",
4
+ "description": "这是一个elpis框架学习项目\r 一个企业级的elpis框架项目",
5
+ "main": "index.js",
6
+ "scripts": {
7
+ "lint": "eslint . --quiet --ext .js,.jsx,.vue",
8
+ "test": "set _ENV=local && mocha 'test/**/*.js'"
9
+ },
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "https://cnb.cool/James-study/elpis-learning"
13
+ },
14
+ "author": "JAMES",
15
+ "license": "ISC",
16
+ "dependencies": {
17
+ "@babel/core": "^7.24.0",
18
+ "@babel/runtime": "^7.29.7",
19
+ "@element-plus/icons-vue": "^2.3.2",
20
+ "ajv": "^6.10.2",
21
+ "axios": "^0.19.2",
22
+ "echarts": "^5.5.0",
23
+ "element-plus": "^2.3.7",
24
+ "generate-password": "^1.7.1",
25
+ "glob": "^7.1.4",
26
+ "jsonwebtoken": "^9.0.2",
27
+ "knex": "^0.19.0",
28
+ "koa": "^2.7.0",
29
+ "koa-bodyparser": "^4.2.1",
30
+ "koa-nunjucks-2": "^3.0.2",
31
+ "koa-router": "^7.4.0",
32
+ "koa-static": "^5.0.0",
33
+ "koa-useragent": "2.0.0",
34
+ "koa2-cors": "^2.0.6",
35
+ "less": "^3.8.1",
36
+ "lodash": "^4.17.21",
37
+ "log4js": "^6.9.1",
38
+ "md5": "^2.2.1",
39
+ "moment": "^2.29.4",
40
+ "mysql": "^2.18.1",
41
+ "node-schedule": "^2.1.1",
42
+ "nodemon": "^1.19.2",
43
+ "path": "^0.12.7",
44
+ "pinia": "^2.1.6",
45
+ "superagent": "^8.1.2",
46
+ "vue": "^3.3.4",
47
+ "vue-json-viewer": "^3.0.4",
48
+ "vue-router": "^4.2.4",
49
+ "vuex": "^4.1.0",
50
+
51
+ "@babel/plugin-transform-runtime": "^7.1.0",
52
+ "@babel/preset-env": "^7.4.5",
53
+ "babel-loader": "^8.0.4",
54
+ "clean-webpack-plugin": "^0.1.19",
55
+ "consoler": "^0.2.0",
56
+ "css-loader": "^0.23.1",
57
+ "css-minimizer-webpack-plugin": "^5.0.1",
58
+ "directory-named-webpack-plugin": "^4.0.1",
59
+ "express": "^4.18.2",
60
+ "file-loader": "^6.2.0",
61
+ "happypack": "^5.0.1",
62
+ "html-webpack-inject-attributes-plugin": "^1.0.1",
63
+ "html-webpack-plugin": "^5.5.3",
64
+ "less-loader": "^11.1.3",
65
+ "mini-css-extract-plugin": "^2.7.6",
66
+ "style-loader": "^0.14.1",
67
+ "terser-webpack-plugin": "^2.3.5",
68
+ "url-loader": "^4.1.1",
69
+ "vue-loader": "^17.2.2",
70
+ "vue-style-loader": "^4.1.2",
71
+ "webpack": "^5.88.1",
72
+ "webpack-dev-middleware": "^6.1.1",
73
+ "webpack-hot-middleware": "^2.25.4",
74
+ "webpack-merge": "^4.2.1"
75
+ },
76
+ "devDependencies": {
77
+ "assert": "^2.0.0",
78
+ "babel-eslint": "^10.0.2",
79
+ "eslint": "^7.32.0",
80
+ "eslint-plugin-import": "^2.28.1",
81
+ "eslint-plugin-vue": "^9.17.0",
82
+ "ghooks": "~1.0.3",
83
+ "mocha": "^6.1.4",
84
+ "supertest": "^4.0.2",
85
+ "validate-commit-msg": "~2.14.0"
86
+
87
+ }
88
+ }
@@ -0,0 +1,93 @@
1
+ from PIL import Image, ImageDraw, ImageFont, ImageFilter
2
+
3
+ W, H = 1200, 630
4
+
5
+ # 基础背景
6
+ img = Image.new('RGB', (W, H), '#0b1120')
7
+ draw = ImageDraw.Draw(img)
8
+
9
+ # 纵向渐变
10
+ for y in range(H):
11
+ t = y / H
12
+ r = int(11 + (20 - 11) * t)
13
+ g = int(17 + (35 - 17) * t)
14
+ b = int(32 + (65 - 32) * t)
15
+ draw.line([(0, y), (W, y)], fill=(r, g, b))
16
+
17
+ # 柔和光斑
18
+ def glow(size, color, blur=130):
19
+ g = Image.new('RGBA', size, (0, 0, 0, 0))
20
+ gd = ImageDraw.Draw(g)
21
+ gd.ellipse([0, 0, size[0], size[1]], fill=(*color, 180))
22
+ return g.filter(ImageFilter.GaussianBlur(blur))
23
+
24
+ img.paste(glow((400, 400), (99, 102, 241), 130), (-120, -80), glow((400, 400), (99, 102, 241), 130))
25
+ img.paste(glow((360, 360), (14, 165, 233), 130), (W - 280, H - 300), glow((360, 360), (14, 165, 233), 130))
26
+ img.paste(glow((260, 260), (139, 92, 246), 120), (W - 230, 20), glow((260, 260), (139, 92, 246), 120))
27
+
28
+ # 网格线(半透明叠加)
29
+ grid = Image.new('RGBA', (W, H), (0, 0, 0, 0))
30
+ gd = ImageDraw.Draw(grid)
31
+ for x in range(0, W, 60):
32
+ gd.line([(x, 0), (x, H)], fill=(255, 255, 255, 16), width=1)
33
+ for y in range(0, H, 60):
34
+ gd.line([(0, y), (W, y)], fill=(255, 255, 255, 16), width=1)
35
+ img = Image.alpha_composite(img.convert('RGBA'), grid).convert('RGB')
36
+
37
+ # 字体
38
+ try:
39
+ title_font = ImageFont.truetype('/c/Windows/Fonts/msyhbd.ttc', 48)
40
+ sub_font = ImageFont.truetype('/c/Windows/Fonts/msyhl.ttc', 28)
41
+ tag_font = ImageFont.truetype('/c/Windows/Fonts/msyh.ttc', 22)
42
+ except Exception as e:
43
+ print(e)
44
+ title_font = ImageFont.load_default()
45
+ sub_font = ImageFont.load_default()
46
+ tag_font = ImageFont.load_default()
47
+
48
+ # 标题区域暗色衬底
49
+ base = img.convert('RGBA')
50
+ overlay = Image.new('RGBA', base.size, (0, 0, 0, 0))
51
+ od = ImageDraw.Draw(overlay)
52
+ od.rectangle([40, 145, 1010, 390], fill=(2, 6, 23, 150))
53
+ overlay = overlay.filter(ImageFilter.GaussianBlur(50))
54
+ img = Image.alpha_composite(base, overlay).convert('RGB')
55
+
56
+ draw = ImageDraw.Draw(img)
57
+
58
+ # 标题(三行,避免与右侧层级图重叠)
59
+ title_lines = ['从重复 CRUD 到领域模型 DSL', 'Elpis 配置化 Dashboard', '设计实践']
60
+ x, y = 70, 165
61
+ line_gap = 66
62
+ for line in title_lines:
63
+ draw.text((x + 2, y + 2), line, font=title_font, fill='#020617')
64
+ draw.text((x, y), line, font=title_font, fill='#f8fafc')
65
+ y += line_gap
66
+
67
+ # 副标题
68
+ draw.text((70, 365), '模型驱动 · 约定优于配置 · 前后端分层 · 组件可扩展', font=sub_font, fill='#94a3b8')
69
+
70
+ # 右下角标签
71
+ tag = '技术文章 / 知乎 · 掘金'
72
+ tw = draw.textbbox((0, 0), tag, font=tag_font)[2]
73
+ draw.text((W - tw - 70, H - 60), tag, font=tag_font, fill='#64748b')
74
+
75
+ # 右上角 DSL 层级示意
76
+ box_w, box_h = 150, 46
77
+ start_x, start_y = 1040, 120
78
+ layer_colors = ['#6366f1', '#8b5cf6', '#0ea5e9']
79
+ layer_texts = ['Domain Model', 'Project', 'Schema Config']
80
+ for i, (color, text) in enumerate(zip(layer_colors, layer_texts)):
81
+ bx = start_x - i * 18
82
+ by = start_y + i * 68
83
+ draw.rectangle([bx + 3, by + 3, bx + box_w, by + box_h], fill=(0, 0, 0, 120))
84
+ draw.rectangle([bx, by, bx + box_w, by + box_h], fill=color, outline='#ffffff', width=2)
85
+ tw, th = draw.textbbox((0, 0), text, font=tag_font)[2], draw.textbbox((0, 0), text, font=tag_font)[3]
86
+ draw.text((bx + (box_w - tw) // 2, by + (box_h - th) // 2 - 2), text, font=tag_font, fill='white')
87
+ if i < 2:
88
+ ax, ay = bx + box_w // 2, by + box_h
89
+ draw.polygon([(ax, ay + 10), (ax - 7, ay), (ax + 7, ay)], fill='white')
90
+
91
+ out = 'docs/cover.png'
92
+ img.save(out, 'PNG')
93
+ print(f'cover saved: {out} ({W}x{H})')
@@ -0,0 +1,80 @@
1
+ const fs = require('fs')
2
+ const path = require('path')
3
+ const https = require('https')
4
+
5
+ const articlePath = path.resolve(process.cwd(), 'docs/technical-article.md')
6
+ const outputDir = path.resolve(process.cwd(), 'docs/diagrams')
7
+
8
+ const article = fs.readFileSync(articlePath, 'utf8')
9
+
10
+ // 提取 mermaid 代码块及其后的“图 N:...”说明
11
+ const matches = [...article.matchAll(/```mermaid\n([\s\S]*?)```\n*\n*(> 图 \d+[^\n]*)\n/g)]
12
+
13
+ console.log(`found ${matches.length} mermaid blocks`)
14
+
15
+ if (!fs.existsSync(outputDir)) {
16
+ fs.mkdirSync(outputDir, { recursive: true })
17
+ }
18
+
19
+ function fetchPng(source, index) {
20
+ return new Promise((resolve, reject) => {
21
+ const encoded = Buffer.from(source, 'utf8').toString('base64url')
22
+ const url = `https://mermaid.ink/img/${encoded}`
23
+ const fileName = `diagram-${index + 1}.png`
24
+ const filePath = path.join(outputDir, fileName)
25
+
26
+ console.log(`[${index + 1}] fetching ${url.substring(0, 80)}...`)
27
+
28
+ https.get(url, { family: 4 }, (res) => {
29
+ if (res.statusCode !== 200) {
30
+ let body = ''
31
+ res.on('data', (chunk) => body += chunk)
32
+ res.on('end', () => reject(new Error(`status ${res.statusCode}: ${body.substring(0, 200)}`)))
33
+ return
34
+ }
35
+ const chunks = []
36
+ res.on('data', (chunk) => chunks.push(chunk))
37
+ res.on('end', () => {
38
+ const buffer = Buffer.concat(chunks)
39
+ fs.writeFileSync(filePath, buffer)
40
+ console.log(`[${index + 1}] saved ${fileName} (${buffer.length} bytes)`)
41
+ resolve(fileName)
42
+ })
43
+ }).on('error', reject)
44
+ })
45
+ }
46
+
47
+ ;(async () => {
48
+ const names = []
49
+ for (let i = 0; i < matches.length; i++) {
50
+ try {
51
+ const name = await fetchPng(matches[i][1], i)
52
+ names.push(name)
53
+ } catch (err) {
54
+ console.error(`[${i + 1}] failed: ${err.message}`)
55
+ names.push(null)
56
+ }
57
+ }
58
+
59
+ // 按原文顺序替换为图片引用
60
+ let newArticle = ''
61
+ let lastIndex = 0
62
+ for (let i = 0; i < matches.length; i++) {
63
+ const match = matches[i]
64
+ const name = names[i]
65
+ const caption = match[2].replace(/^> /, '')
66
+
67
+ newArticle += article.slice(lastIndex, match.index)
68
+ if (name) {
69
+ newArticle += `![${caption}](./diagrams/${name})\n`
70
+ } else {
71
+ // 失败时保留原代码块和说明
72
+ newArticle += match[0]
73
+ }
74
+ lastIndex = match.index + match[0].length
75
+ }
76
+ newArticle += article.slice(lastIndex)
77
+
78
+ fs.writeFileSync(articlePath, newArticle)
79
+ console.log('article updated with images')
80
+ })()