From 48aa4015532d668c705af98d8a22eeffe79c7568 Mon Sep 17 00:00:00 2001 From: COOL Date: Thu, 9 Jan 2025 16:30:35 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B8=85=E7=A9=BA=E4=BB=93=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .DS_Store | Bin 0 -> 8196 bytes .gitattributes | 4 - .gitignore | 19 - README.md | 6 - cloud/.editorconfig | 11 - cloud/.eslintrc.json | 20 - cloud/.gitignore | 15 - cloud/.prettierrc.js | 3 - cloud/LICENSE | 21 - cloud/index.d.ts | 10 - cloud/jest.config.js | 7 - cloud/jest.setup.js | 1 - cloud/package.json | 49 -- cloud/src/LICENSE | 21 - cloud/src/README.md | 27 - cloud/src/config/config.default.ts | 4 - cloud/src/configuration.ts | 22 - cloud/src/db/index.ts | 131 ---- cloud/src/db/source.ts | 10 - cloud/src/func/crud.ts | 525 -------------- cloud/src/func/index.ts | 17 - cloud/src/index.ts | 10 - cloud/src/interface.ts | 11 - cloud/src/package.json | 45 -- cloud/src/util.ts | 1 - cloud/tsconfig.json | 25 - core/LICENSE | 21 - core/README.md | 3 - core/_.editorconfig | 11 - core/_.eslintrc.json | 7 - core/_.gitignore | 15 - core/_.prettierrc.js | 3 - core/index.d.ts | 10 - core/jest.config.js | 7 - core/jest.setup.js | 1 - core/package.json | 64 -- core/src/LICENSE | 21 - core/src/README.md | 27 - core/src/cache/store.ts | 64 -- core/src/config/config.default.ts | 22 - core/src/configuration.ts | 79 --- core/src/constant/global.ts | 84 --- core/src/controller/base.ts | 220 ------ core/src/decorator/cache.ts | 8 - core/src/decorator/controller.ts | 212 ------ core/src/decorator/event.ts | 54 -- core/src/decorator/index.ts | 112 --- core/src/decorator/tag.ts | 50 -- core/src/decorator/transaction.ts | 19 - core/src/entity/base.ts | 26 - core/src/entity/mongo.ts | 25 - core/src/entity/typeorm.ts | 3 - core/src/event/index.ts | 190 ------ core/src/exception/base.ts | 13 - core/src/exception/comm.ts | 16 - core/src/exception/core.ts | 16 - core/src/exception/filter.ts | 21 - core/src/exception/validate.ts | 16 - core/src/index.ts | 52 -- core/src/interface.ts | 447 ------------ core/src/module/config.ts | 100 --- core/src/module/import.ts | 260 ------- core/src/module/menu.ts | 186 ----- core/src/package.json | 62 -- core/src/rest/eps.ts | 169 ----- core/src/service/base.ts | 287 -------- core/src/service/mysql.ts | 499 -------------- core/src/service/postgres.ts | 639 ------------------ core/src/service/sqlite.ts | 532 --------------- core/src/tag/data.ts | 89 --- core/src/util/func.ts | 27 - core/src/util/location.ts | 52 -- core/tsconfig.json | 25 - es/.editorconfig | 11 - es/.eslintrc.json | 28 - es/.gitignore | 15 - es/.prettierrc.js | 3 - es/README.md | 3 - es/index.d.ts | 10 - es/jest.config.js | 7 - es/jest.setup.js | 1 - es/package.json | 43 -- es/src/README.md | 27 - es/src/base.ts | 615 ----------------- es/src/config/config.default.ts | 4 - es/src/configuration.ts | 19 - es/src/decorator/elasticsearch.ts | 41 -- es/src/elasticsearch.ts | 154 ----- es/src/index.ts | 18 - es/src/package.json | 41 -- es/tsconfig.json | 24 - file/.editorconfig | 11 - file/.eslintrc.json | 20 - file/.gitignore | 15 - file/.prettierrc.js | 3 - file/LICENSE | 21 - file/index.d.ts | 10 - file/jest.config.js | 7 - file/jest.setup.js | 1 - file/package.json | 54 -- file/src/README.md | 27 - file/src/config/config.default.ts | 16 - file/src/configuration.ts | 21 - file/src/file.ts | 568 ---------------- file/src/index.ts | 5 - file/src/interface.ts | 132 ---- file/src/package.json | 54 -- file/tsconfig.json | 25 - iot/.editorconfig | 11 - iot/.eslintrc.json | 28 - iot/.gitignore | 15 - iot/.prettierrc.js | 3 - iot/README.md | 3 - iot/index.d.ts | 10 - iot/jest.config.js | 7 - iot/jest.setup.js | 1 - iot/package.json | 52 -- iot/src/README.md | 27 - iot/src/config/config.default.ts | 13 - iot/src/configuration.ts | 18 - iot/src/decorator/mqtt.ts | 42 -- iot/src/index.ts | 7 - iot/src/interface.ts | 34 - iot/src/mqtt.ts | 163 ----- iot/src/package.json | 52 -- iot/tsconfig.json | 24 - other/cache-manager-fs-hash/LICENSE | 21 - other/cache-manager-fs-hash/README.md | 27 - other/cache-manager-fs-hash/index.js | 1 - other/cache-manager-fs-hash/package.json | 37 - other/cache-manager-fs-hash/src/index.js | 260 ------- .../src/json-file-store.js | 118 ---- .../src/wrap-callback.js | 21 - other/mqemitter-redis/.github/dependabot.yml | 7 - .../mqemitter-redis/.github/workflows/ci.yml | 35 - other/mqemitter-redis/.gitignore | 33 - other/mqemitter-redis/.travis.yml | 9 - other/mqemitter-redis/LICENSE | 21 - other/mqemitter-redis/README.md | 27 - other/mqemitter-redis/mqemitter-redis.js | 250 ------- other/mqemitter-redis/package.json | 44 -- other/mqemitter-redis/types/index.d.ts | 37 - pay/.editorconfig | 11 - pay/.eslintrc.json | 28 - pay/.gitignore | 15 - pay/.prettierrc.js | 3 - pay/index.d.ts | 10 - pay/jest.config.js | 7 - pay/jest.setup.js | 1 - pay/package.json | 49 -- pay/src/README.md | 27 - pay/src/ali.ts | 56 -- pay/src/config/config.default.ts | 4 - pay/src/configuration.ts | 21 - pay/src/index.ts | 7 - pay/src/interface.ts | 77 --- pay/src/package.json | 49 -- pay/src/wx.ts | 68 -- pay/tsconfig.json | 24 - plugin-cli/.gitignore | 2 - plugin-cli/.npmignore | 3 - plugin-cli/README.md | 27 - plugin-cli/package.json | 36 - plugin-cli/scripts/build.js | 47 -- plugin-cli/scripts/index.js | 12 - plugin-cli/scripts/release.js | 48 -- plugin-cli/src/cache/store.ts | 64 -- plugin-cli/src/constant/global.ts | 84 --- plugin-cli/src/exception/base.ts | 13 - plugin-cli/src/exception/comm.ts | 16 - plugin-cli/src/exception/core.ts | 16 - plugin-cli/src/exception/validate.ts | 16 - plugin-cli/src/hook/upload.ts | 67 -- plugin-cli/src/index.ts | 158 ----- plugin-cli/tsconfig.json | 15 - rpc/.editorconfig | 11 - rpc/.eslintrc.json | 29 - rpc/.gitignore | 15 - rpc/.prettierrc.js | 3 - rpc/index.d.ts | 10 - rpc/jest.config.js | 7 - rpc/jest.setup.js | 1 - rpc/package.json | 47 -- rpc/src/README.md | 27 - rpc/src/config/config.default.ts | 6 - rpc/src/configuration.ts | 26 - rpc/src/decorator/event/event.ts | 19 - rpc/src/decorator/event/handler.ts | 23 - rpc/src/decorator/index.ts | 101 --- rpc/src/decorator/rpc.ts | 84 --- rpc/src/decorator/transaction.ts | 22 - rpc/src/index.ts | 25 - rpc/src/package.json | 47 -- rpc/src/rpc.ts | 275 -------- rpc/src/service/base.ts | 406 ----------- rpc/src/test.ts | 25 - rpc/src/transaction/event.ts | 40 -- rpc/tsconfig.json | 24 - sms/.editorconfig | 11 - sms/.eslintrc.json | 28 - sms/.gitignore | 15 - sms/.prettierrc.js | 3 - sms/index.d.ts | 10 - sms/jest.config.js | 7 - sms/jest.setup.js | 1 - sms/package.json | 50 -- sms/src/README.md | 27 - sms/src/ali.ts | 68 -- sms/src/aws.ts | 50 -- sms/src/config/config.default.ts | 5 - sms/src/configuration.ts | 17 - sms/src/index.ts | 10 - sms/src/interface.ts | 103 --- sms/src/package.json | 50 -- sms/src/sms.ts | 97 --- sms/src/tx.ts | 74 -- sms/src/yp.ts | 90 --- sms/tsconfig.json | 24 - task/.editorconfig | 11 - task/.eslintrc.json | 28 - task/.gitignore | 15 - task/.prettierrc.js | 3 - task/README.md | 3 - task/index.d.ts | 10 - task/jest.config.js | 7 - task/jest.setup.js | 1 - task/package.json | 50 -- task/src/README.md | 27 - task/src/base.ts | 118 ---- task/src/config/config.default.ts | 6 - task/src/configuration.ts | 19 - task/src/decorator/queue.ts | 26 - task/src/index.ts | 7 - task/src/package.json | 50 -- task/src/queue.ts | 142 ---- task/tsconfig.json | 24 - tsconfig.json | 25 - 237 files changed, 13059 deletions(-) create mode 100644 .DS_Store delete mode 100644 .gitattributes delete mode 100644 .gitignore delete mode 100644 README.md delete mode 100644 cloud/.editorconfig delete mode 100644 cloud/.eslintrc.json delete mode 100644 cloud/.gitignore delete mode 100644 cloud/.prettierrc.js delete mode 100644 cloud/LICENSE delete mode 100644 cloud/index.d.ts delete mode 100644 cloud/jest.config.js delete mode 100644 cloud/jest.setup.js delete mode 100644 cloud/package.json delete mode 100644 cloud/src/LICENSE delete mode 100644 cloud/src/README.md delete mode 100644 cloud/src/config/config.default.ts delete mode 100644 cloud/src/configuration.ts delete mode 100644 cloud/src/db/index.ts delete mode 100644 cloud/src/db/source.ts delete mode 100644 cloud/src/func/crud.ts delete mode 100644 cloud/src/func/index.ts delete mode 100644 cloud/src/index.ts delete mode 100644 cloud/src/interface.ts delete mode 100644 cloud/src/package.json delete mode 100644 cloud/src/util.ts delete mode 100644 cloud/tsconfig.json delete mode 100644 core/LICENSE delete mode 100644 core/README.md delete mode 100644 core/_.editorconfig delete mode 100644 core/_.eslintrc.json delete mode 100644 core/_.gitignore delete mode 100644 core/_.prettierrc.js delete mode 100644 core/index.d.ts delete mode 100644 core/jest.config.js delete mode 100644 core/jest.setup.js delete mode 100644 core/package.json delete mode 100644 core/src/LICENSE delete mode 100644 core/src/README.md delete mode 100644 core/src/cache/store.ts delete mode 100644 core/src/config/config.default.ts delete mode 100644 core/src/configuration.ts delete mode 100644 core/src/constant/global.ts delete mode 100644 core/src/controller/base.ts delete mode 100644 core/src/decorator/cache.ts delete mode 100644 core/src/decorator/controller.ts delete mode 100644 core/src/decorator/event.ts delete mode 100644 core/src/decorator/index.ts delete mode 100644 core/src/decorator/tag.ts delete mode 100644 core/src/decorator/transaction.ts delete mode 100644 core/src/entity/base.ts delete mode 100644 core/src/entity/mongo.ts delete mode 100644 core/src/entity/typeorm.ts delete mode 100644 core/src/event/index.ts delete mode 100644 core/src/exception/base.ts delete mode 100644 core/src/exception/comm.ts delete mode 100644 core/src/exception/core.ts delete mode 100644 core/src/exception/filter.ts delete mode 100644 core/src/exception/validate.ts delete mode 100644 core/src/index.ts delete mode 100644 core/src/interface.ts delete mode 100644 core/src/module/config.ts delete mode 100644 core/src/module/import.ts delete mode 100644 core/src/module/menu.ts delete mode 100644 core/src/package.json delete mode 100644 core/src/rest/eps.ts delete mode 100644 core/src/service/base.ts delete mode 100644 core/src/service/mysql.ts delete mode 100644 core/src/service/postgres.ts delete mode 100644 core/src/service/sqlite.ts delete mode 100644 core/src/tag/data.ts delete mode 100644 core/src/util/func.ts delete mode 100644 core/src/util/location.ts delete mode 100644 core/tsconfig.json delete mode 100644 es/.editorconfig delete mode 100644 es/.eslintrc.json delete mode 100644 es/.gitignore delete mode 100644 es/.prettierrc.js delete mode 100644 es/README.md delete mode 100644 es/index.d.ts delete mode 100644 es/jest.config.js delete mode 100644 es/jest.setup.js delete mode 100644 es/package.json delete mode 100644 es/src/README.md delete mode 100644 es/src/base.ts delete mode 100644 es/src/config/config.default.ts delete mode 100644 es/src/configuration.ts delete mode 100644 es/src/decorator/elasticsearch.ts delete mode 100644 es/src/elasticsearch.ts delete mode 100644 es/src/index.ts delete mode 100644 es/src/package.json delete mode 100644 es/tsconfig.json delete mode 100644 file/.editorconfig delete mode 100644 file/.eslintrc.json delete mode 100644 file/.gitignore delete mode 100644 file/.prettierrc.js delete mode 100644 file/LICENSE delete mode 100644 file/index.d.ts delete mode 100644 file/jest.config.js delete mode 100644 file/jest.setup.js delete mode 100644 file/package.json delete mode 100644 file/src/README.md delete mode 100644 file/src/config/config.default.ts delete mode 100644 file/src/configuration.ts delete mode 100644 file/src/file.ts delete mode 100644 file/src/index.ts delete mode 100644 file/src/interface.ts delete mode 100644 file/src/package.json delete mode 100644 file/tsconfig.json delete mode 100644 iot/.editorconfig delete mode 100644 iot/.eslintrc.json delete mode 100644 iot/.gitignore delete mode 100644 iot/.prettierrc.js delete mode 100644 iot/README.md delete mode 100644 iot/index.d.ts delete mode 100644 iot/jest.config.js delete mode 100644 iot/jest.setup.js delete mode 100644 iot/package.json delete mode 100644 iot/src/README.md delete mode 100644 iot/src/config/config.default.ts delete mode 100644 iot/src/configuration.ts delete mode 100644 iot/src/decorator/mqtt.ts delete mode 100644 iot/src/index.ts delete mode 100644 iot/src/interface.ts delete mode 100644 iot/src/mqtt.ts delete mode 100644 iot/src/package.json delete mode 100644 iot/tsconfig.json delete mode 100644 other/cache-manager-fs-hash/LICENSE delete mode 100644 other/cache-manager-fs-hash/README.md delete mode 100644 other/cache-manager-fs-hash/index.js delete mode 100644 other/cache-manager-fs-hash/package.json delete mode 100644 other/cache-manager-fs-hash/src/index.js delete mode 100644 other/cache-manager-fs-hash/src/json-file-store.js delete mode 100644 other/cache-manager-fs-hash/src/wrap-callback.js delete mode 100644 other/mqemitter-redis/.github/dependabot.yml delete mode 100644 other/mqemitter-redis/.github/workflows/ci.yml delete mode 100644 other/mqemitter-redis/.gitignore delete mode 100644 other/mqemitter-redis/.travis.yml delete mode 100644 other/mqemitter-redis/LICENSE delete mode 100644 other/mqemitter-redis/README.md delete mode 100644 other/mqemitter-redis/mqemitter-redis.js delete mode 100644 other/mqemitter-redis/package.json delete mode 100644 other/mqemitter-redis/types/index.d.ts delete mode 100644 pay/.editorconfig delete mode 100644 pay/.eslintrc.json delete mode 100644 pay/.gitignore delete mode 100644 pay/.prettierrc.js delete mode 100644 pay/index.d.ts delete mode 100644 pay/jest.config.js delete mode 100644 pay/jest.setup.js delete mode 100644 pay/package.json delete mode 100644 pay/src/README.md delete mode 100644 pay/src/ali.ts delete mode 100644 pay/src/config/config.default.ts delete mode 100644 pay/src/configuration.ts delete mode 100644 pay/src/index.ts delete mode 100644 pay/src/interface.ts delete mode 100644 pay/src/package.json delete mode 100644 pay/src/wx.ts delete mode 100644 pay/tsconfig.json delete mode 100644 plugin-cli/.gitignore delete mode 100644 plugin-cli/.npmignore delete mode 100644 plugin-cli/README.md delete mode 100644 plugin-cli/package.json delete mode 100644 plugin-cli/scripts/build.js delete mode 100644 plugin-cli/scripts/index.js delete mode 100644 plugin-cli/scripts/release.js delete mode 100644 plugin-cli/src/cache/store.ts delete mode 100644 plugin-cli/src/constant/global.ts delete mode 100644 plugin-cli/src/exception/base.ts delete mode 100644 plugin-cli/src/exception/comm.ts delete mode 100644 plugin-cli/src/exception/core.ts delete mode 100644 plugin-cli/src/exception/validate.ts delete mode 100644 plugin-cli/src/hook/upload.ts delete mode 100644 plugin-cli/src/index.ts delete mode 100644 plugin-cli/tsconfig.json delete mode 100644 rpc/.editorconfig delete mode 100644 rpc/.eslintrc.json delete mode 100644 rpc/.gitignore delete mode 100644 rpc/.prettierrc.js delete mode 100644 rpc/index.d.ts delete mode 100644 rpc/jest.config.js delete mode 100644 rpc/jest.setup.js delete mode 100644 rpc/package.json delete mode 100644 rpc/src/README.md delete mode 100644 rpc/src/config/config.default.ts delete mode 100644 rpc/src/configuration.ts delete mode 100644 rpc/src/decorator/event/event.ts delete mode 100644 rpc/src/decorator/event/handler.ts delete mode 100644 rpc/src/decorator/index.ts delete mode 100644 rpc/src/decorator/rpc.ts delete mode 100644 rpc/src/decorator/transaction.ts delete mode 100644 rpc/src/index.ts delete mode 100644 rpc/src/package.json delete mode 100644 rpc/src/rpc.ts delete mode 100644 rpc/src/service/base.ts delete mode 100644 rpc/src/test.ts delete mode 100644 rpc/src/transaction/event.ts delete mode 100644 rpc/tsconfig.json delete mode 100644 sms/.editorconfig delete mode 100644 sms/.eslintrc.json delete mode 100644 sms/.gitignore delete mode 100644 sms/.prettierrc.js delete mode 100644 sms/index.d.ts delete mode 100644 sms/jest.config.js delete mode 100644 sms/jest.setup.js delete mode 100644 sms/package.json delete mode 100644 sms/src/README.md delete mode 100644 sms/src/ali.ts delete mode 100644 sms/src/aws.ts delete mode 100644 sms/src/config/config.default.ts delete mode 100644 sms/src/configuration.ts delete mode 100644 sms/src/index.ts delete mode 100644 sms/src/interface.ts delete mode 100644 sms/src/package.json delete mode 100644 sms/src/sms.ts delete mode 100644 sms/src/tx.ts delete mode 100644 sms/src/yp.ts delete mode 100644 sms/tsconfig.json delete mode 100644 task/.editorconfig delete mode 100644 task/.eslintrc.json delete mode 100644 task/.gitignore delete mode 100644 task/.prettierrc.js delete mode 100644 task/README.md delete mode 100644 task/index.d.ts delete mode 100644 task/jest.config.js delete mode 100644 task/jest.setup.js delete mode 100644 task/package.json delete mode 100644 task/src/README.md delete mode 100644 task/src/base.ts delete mode 100644 task/src/config/config.default.ts delete mode 100644 task/src/configuration.ts delete mode 100644 task/src/decorator/queue.ts delete mode 100644 task/src/index.ts delete mode 100644 task/src/package.json delete mode 100644 task/src/queue.ts delete mode 100644 task/tsconfig.json delete mode 100644 tsconfig.json diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..6c1eec729964d1096635cf194b1ddcda59bbf988 GIT binary patch literal 8196 zcmeHM!EVz)6nq=I)M-_eLy-y+!V=d|l2F~ukS{W6R@$*7SG<4!8IE!E)_z2bi9)_7d2Rw`w`wy}9y_Q%!QcD3wp zZET&M7QGvH??2w#KaNh~b2p&uBuqK>Ea7wk>%=tHX?M@f8$Hs)VHbA;M7z^4y) z0vckkOR3?~H}JDAElsr{T#YG#x|`RC+lFR=4k!Y1NF9Uu$zZx*o;Tv3dAv-leq4I2 zZjQ&*hufQo)mDXL^{9rpZ9LdCLd7?UGB;El%IS?8p(@OVq`+a!hQy_J2w-G}q43M# zIbbE`GH`Yb)&g_r2s~jnQ}#W_c^% zrEwtCO>N_CZW~t<8 literal 0 HcmV?d00001 diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index 0b909d8..0000000 --- a/.gitattributes +++ /dev/null @@ -1,4 +0,0 @@ -*.js text eol=lf -*.json text eol=lf -*.ts text eol=lf -*.code-snippets text eol=lf \ No newline at end of file diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 6830170..0000000 --- a/.gitignore +++ /dev/null @@ -1,19 +0,0 @@ -logs/ -npm-debug.log -yarn-error.log -node_modules/ -package-lock.json -yarn.lock -coverage/ -dist/ -.idea/ -run/ -.DS_Store -launch.json -*.sw* -*.un~ -.tsbuildinfo -.tsbuildinfo.* -data/* -pnpm-lock.yaml -public/uploads/* diff --git a/README.md b/README.md deleted file mode 100644 index 30bfa49..0000000 --- a/README.md +++ /dev/null @@ -1,6 +0,0 @@ -# cool-admin-midway-packages -cool-admin midway 后端核心包 - -- 为了不和src代码相互影响,7.0的核心依赖包单独成一个项目 - -- 7.0之前的在cool-admin-midway这个项目的packages目录下 \ No newline at end of file diff --git a/cloud/.editorconfig b/cloud/.editorconfig deleted file mode 100644 index 4c7f8a8..0000000 --- a/cloud/.editorconfig +++ /dev/null @@ -1,11 +0,0 @@ -# 🎨 editorconfig.org - -root = true - -[*] -charset = utf-8 -end_of_line = lf -indent_style = space -indent_size = 2 -trim_trailing_whitespace = true -insert_final_newline = true \ No newline at end of file diff --git a/cloud/.eslintrc.json b/cloud/.eslintrc.json deleted file mode 100644 index 93e32bd..0000000 --- a/cloud/.eslintrc.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "extends": "./node_modules/mwts/", - "ignorePatterns": ["node_modules", "dist", "test", "jest.config.js", "typings"], - "env": { - "jest": true - }, - "rules": { - "@typescript-eslint/explicit-module-boundary-types": "off", - "@typescript-eslint/no-unused-vars": "off", - "@typescript-eslint/ban-ts-comment": "off", - "node/no-extraneous-import": "off", - "no-empty": "off", - "node/no-extraneous-require": "off", - "eqeqeq": "off", - "node/no-unsupported-features/node-builtins": "off", - "@typescript-eslint/ban-types": "off", - "no-control-regex": "off", - "prefer-const": "off" - } -} diff --git a/cloud/.gitignore b/cloud/.gitignore deleted file mode 100644 index 13bc3a6..0000000 --- a/cloud/.gitignore +++ /dev/null @@ -1,15 +0,0 @@ -logs/ -npm-debug.log -yarn-error.log -node_modules/ -package-lock.json -yarn.lock -coverage/ -dist/ -.idea/ -run/ -.DS_Store -*.sw* -*.un~ -.tsbuildinfo -.tsbuildinfo.* diff --git a/cloud/.prettierrc.js b/cloud/.prettierrc.js deleted file mode 100644 index b964930..0000000 --- a/cloud/.prettierrc.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - ...require('mwts/.prettierrc.json') -} diff --git a/cloud/LICENSE b/cloud/LICENSE deleted file mode 100644 index 5a739ee..0000000 --- a/cloud/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2013 - Now midwayjs - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/cloud/index.d.ts b/cloud/index.d.ts deleted file mode 100644 index e0065de..0000000 --- a/cloud/index.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -export * from './dist/index'; - -declare module '@midwayjs/core/dist/interface' { - interface MidwayConfig { - book?: PowerPartial<{ - a: number; - b: string; - }>; - } -} diff --git a/cloud/jest.config.js b/cloud/jest.config.js deleted file mode 100644 index 82a8b85..0000000 --- a/cloud/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = { - preset: 'ts-jest', - testEnvironment: 'node', - testPathIgnorePatterns: ['/test/fixtures'], - coveragePathIgnorePatterns: ['/test/'], - setupFilesAfterEnv: ['./jest.setup.js'] -}; diff --git a/cloud/jest.setup.js b/cloud/jest.setup.js deleted file mode 100644 index 1399c91..0000000 --- a/cloud/jest.setup.js +++ /dev/null @@ -1 +0,0 @@ -jest.setTimeout(30000); diff --git a/cloud/package.json b/cloud/package.json deleted file mode 100644 index b246876..0000000 --- a/cloud/package.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "name": "@cool-midway/cloud", - "version": "7.1.0", - "description": "", - "main": "dist/index.js", - "typings": "index.d.ts", - "scripts": { - "build": "cross-env midway-bin build -c", - "cov": "cross-env midway-bin cov --ts", - "lint": "mwts check", - "lint:fix": "mwts fix" - }, - "keywords": [ - "cool", - "cool-admin", - "cooljs" - ], - "author": "COOL", - "files": [ - "dist/**/*.js", - "dist/**/*.d.ts", - "index.d.ts" - ], - "license": "MIT", - "repository": { - "type": "git", - "url": "https://cool-js.com" - }, - "devDependencies": { - "@cool-midway/core": "^7.1.19", - "@midwayjs/cli": "^2.0.0", - "@midwayjs/core": "^3.16.0", - "@midwayjs/decorator": "^3.9.0", - "@midwayjs/mock": "^3.9.0", - "@midwayjs/typeorm": "^3.9.0", - "@types/jest": "^29.2.4", - "@types/node": "^18.11.15", - "cross-env": "^7.0.3", - "jest": "^29.3.1", - "lodash": "^4.17.21", - "mwts": "^1.3.0", - "ts-jest": "^29.0.3", - "typeorm": "^0.3.11", - "typescript": "^4.9.4" - }, - "dependencies": { - "sqlstring": "^2.3.3" - } -} diff --git a/cloud/src/LICENSE b/cloud/src/LICENSE deleted file mode 100644 index 5a739ee..0000000 --- a/cloud/src/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2013 - Now midwayjs - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/cloud/src/README.md b/cloud/src/README.md deleted file mode 100644 index 7edd966..0000000 --- a/cloud/src/README.md +++ /dev/null @@ -1,27 +0,0 @@ -### COOL-ADMIN - -cool-admin一个很酷的后台权限管理系统,开源免费,模块化、插件化、极速开发CRUD,方便快速构建迭代后台管理系统 - -大数据、微服务、AI编码快速开发!!! - - -### 技术栈 - -- 后端:node.js midway.js koa.js mysql typescript -- 前端:vue.js element-plus jsx pinia vue-router - -### 官网 - -[https://cool-js.com](https://cool-js.com) - - -### 演示地址 - -[https://show.cool-admin.com](https://show.cool-admin.com) - -- 账户:admin -- 密码:123456 - -### 项目地址 - -[https://github.com/cool-team-official/cool-admin-midway](https://github.com/cool-team-official/cool-admin-midway) \ No newline at end of file diff --git a/cloud/src/config/config.default.ts b/cloud/src/config/config.default.ts deleted file mode 100644 index 03ef2cd..0000000 --- a/cloud/src/config/config.default.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * cool的配置 - */ -export default {}; diff --git a/cloud/src/configuration.ts b/cloud/src/configuration.ts deleted file mode 100644 index ee7447f..0000000 --- a/cloud/src/configuration.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { ILifeCycle, ILogger, IMidwayContainer, Logger } from '@midwayjs/core'; -import { Configuration } from '@midwayjs/decorator'; -import * as DefaultConfig from './config/config.default'; -import { CoolCloudDb } from './db'; - -@Configuration({ - namespace: 'cloud', - importConfigs: [ - { - default: DefaultConfig, - }, - ], -}) -export class CoolCloudConfiguration implements ILifeCycle { - @Logger() - coreLogger: ILogger; - - async onReady(container: IMidwayContainer) { - await container.getAsync(CoolCloudDb); - this.coreLogger.info('\x1B[36m [cool:cloud] ready \x1B[0m'); - } -} diff --git a/cloud/src/db/index.ts b/cloud/src/db/index.ts deleted file mode 100644 index fa9fac4..0000000 --- a/cloud/src/db/index.ts +++ /dev/null @@ -1,131 +0,0 @@ -import { CoolCommException } from '@cool-midway/core'; -import { CoolDataSource } from './source'; -import { - ALL, - Config, - ILogger, - Init, - Logger, - Provide, - Scope, - ScopeEnum, -} from '@midwayjs/core'; -import { Repository } from 'typeorm'; -import * as ts from 'typescript'; -import * as _ from 'lodash'; -/** - * 数据库 - */ -@Provide() -@Scope(ScopeEnum.Singleton) -export class CoolCloudDb { - @Logger() - coreLogger: ILogger; - - coolDataSource: CoolDataSource; - - @Config(ALL) - config; - - @Init() - async init() { - const config = this.config.typeorm.dataSource.default; - if (!config) { - throw new CoolCommException('未配置数据库default信息'); - } - this.coolDataSource = new CoolDataSource({ - ...this.config.typeorm.dataSource.default, - entities: [], - }); - // 连接数据库 - await this.coolDataSource.initialize(); - } - - /** - * 获得数据库操作实例 - * @param tableClass 表类 - * @param appId 应用ID - * @returns - */ - getRepository(tableClass: string, appId = 'CLOUD'): Repository { - return this.coolDataSource.getRepository(`${tableClass}${appId}`); - } - - /** - * 创建表 - * @param table 表结构,元函数,字符串 - * @param appId 应用ID,确保每个应用的数据隔离 - * @param synchronize 是否同步表结构 - */ - async createTable(table: string, synchronize = false, appId = 'CLOUD') { - if (!table || !appId) { - throw new CoolCommException('table、appId不能为空'); - } - const { newCode, className } = this.parseCode(table, appId); - const entities = this.coolDataSource.options.entities; - // @ts-ignore - this.coolDataSource.options.entities = _.dropWhile(entities, { - name: className, - }); - const code = ts.transpile( - `${newCode} - this.coolDataSource.options.entities.push(${className}) - - this.coolDataSource.buildMetadatas().then(() => { - if(synchronize){ - this.coolDataSource.synchronize(); - } - }); - `, - { - emitDecoratorMetadata: true, - module: ts.ModuleKind.CommonJS, - target: ts.ScriptTarget.ES2018, - removeComments: true, - experimentalDecorators: true, - noImplicitThis: true, - noUnusedLocals: true, - stripInternal: true, - skipLibCheck: true, - pretty: true, - declaration: true, - noImplicitAny: false, - } - ); - eval(code); - } - - /** - * 根据字符串查找并生成一个跟appId相关的类名 - * @param code 代码 - * @param appId - */ - parseCode(code: string, appId = 'CLOUD') { - try { - const oldClassName = code - .match('class(.*)extends')[1] - .replace(/\s*/g, ''); - const oldTableStart = code.indexOf('@Entity('); - const oldTableEnd = code.indexOf(')'); - - const oldTableName = code - .substring(oldTableStart + 9, oldTableEnd - 1) - .replace(/\s*/g, '') - // eslint-disable-next-line no-useless-escape - .replace(/\"/g, '') - // eslint-disable-next-line no-useless-escape - .replace(/\'/g, ''); - const className = `${oldClassName}${appId}`; - return { - newCode: code - .replace(oldClassName, className) - .replace(oldTableName, `func_${oldTableName}`), - className, - tableName: `func_${oldTableName}`, - }; - } catch (err) { - this.coreLogger.error(err); - throw new CoolCommException('代码结构不正确,请检查'); - } - } -} diff --git a/cloud/src/db/source.ts b/cloud/src/db/source.ts deleted file mode 100644 index f5c13af..0000000 --- a/cloud/src/db/source.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { DataSource } from 'typeorm'; - -export class CoolDataSource extends DataSource { - /** - * 重新构造元数据 - */ - async buildMetadatas() { - await super.buildMetadatas(); - } -} diff --git a/cloud/src/func/crud.ts b/cloud/src/func/crud.ts deleted file mode 100644 index 842c4cd..0000000 --- a/cloud/src/func/crud.ts +++ /dev/null @@ -1,525 +0,0 @@ -import { CloudReq } from './../interface'; -import { IMidwayApplication } from '@midwayjs/core'; -import { - CoolConfig, - CoolEventManager, - CoolValidateException, - CurdOption, - ERRINFO, - EVENT, -} from '@cool-midway/core'; -import { Brackets, In, Repository, SelectQueryBuilder } from 'typeorm'; -import { CoolCloudDb } from '../db'; -import * as _ from 'lodash'; -import * as SqlString from 'sqlstring'; - -export abstract class CloudCrud { - ctx; - - curdOption: CurdOption; - - coolCloudDb: CoolCloudDb; - - coolConfig: CoolConfig; - - entity: Repository; - - app: IMidwayApplication; - - req: CloudReq; - - coolEventManager: CoolEventManager; - - protected sqlParams; - - setCurdOption(curdOption: CurdOption) { - this.curdOption = curdOption; - } - - /** - * 设置实体 - * @param entityModel - */ - async setEntity() { - this.entity = this.coolCloudDb.getRepository( - this.curdOption.entity, - 'CLOUD' - ); - } - - abstract main(req: CloudReq): Promise; - - async init(req: CloudReq) { - this.sqlParams = []; - // 执行主函数 - await this.main(req); - // 操作之前 - await this.before(); - // // 设置实体 - await this.setEntity(); - } - - /** - * 参数安全性检查 - * @param params - */ - async paramSafetyCheck(params) { - const lp = params.toLowerCase(); - return !( - lp.indexOf('update ') > -1 || - lp.indexOf('select ') > -1 || - lp.indexOf('delete ') > -1 || - lp.indexOf('insert ') > -1 - ); - } - - /** - * 非分页查询 - * @param query 查询条件 - * @param option 查询配置 - */ - async list(query): Promise { - if (!this.entity) throw new CoolValidateException(ERRINFO.NOENTITY); - const sql = await this.getOptionFind(query, this.curdOption.listQueryOp); - return this.nativeQuery(sql, []); - } - - /** - * 执行SQL并获得分页数据 - * @param sql 执行的sql语句 - * @param query 分页查询条件 - * @param autoSort 是否自动排序 - */ - async sqlRenderPage(sql, query, autoSort = true) { - const { - size = this.coolConfig.crud.pageSize, - page = 1, - order = 'createTime', - sort = 'desc', - isExport = false, - maxExportLimit, - } = query; - if (order && sort && autoSort) { - if (!(await this.paramSafetyCheck(order + sort))) { - throw new CoolValidateException('非法传参~'); - } - sql += ` ORDER BY ${SqlString.escapeId(order)} ${this.checkSort(sort)}`; - } - if (isExport && maxExportLimit > 0) { - this.sqlParams.push(parseInt(maxExportLimit)); - sql += ' LIMIT ? '; - } - if (!isExport) { - this.sqlParams.push((page - 1) * size); - this.sqlParams.push(parseInt(size)); - sql += ' LIMIT ?,? '; - } - - let params = []; - params = params.concat(this.sqlParams); - const result = await this.nativeQuery(sql, params); - const countResult = await this.nativeQuery(this.getCountSql(sql), params); - return { - list: result, - pagination: { - page: parseInt(page), - size: parseInt(size), - total: parseInt(countResult[0] ? countResult[0].count : 0), - }, - }; - } - - /** - * 分页查询 - * @param connectionName 连接名 - */ - async page(query) { - if (!this.entity) throw new CoolValidateException(ERRINFO.NOENTITY); - const sql = await this.getOptionFind(query, this.curdOption.pageQueryOp); - return this.sqlRenderPage(sql, query, false); - } - - /** - * 获得查询个数的SQL - * @param sql - */ - getCountSql(sql) { - sql = sql - .replace(new RegExp('LIMIT', 'gm'), 'limit ') - .replace(new RegExp('\n', 'gm'), ' '); - if (sql.includes('limit')) { - const sqlArr = sql.split('limit '); - sqlArr.pop(); - sql = sqlArr.join('limit '); - } - return `select count(*) as count from (${sql}) a`; - } - - /** - * 操作entity获得分页数据,不用写sql - * @param find QueryBuilder - * @param query - * @param autoSort - * @param connectionName - */ - async entityRenderPage( - find: SelectQueryBuilder, - query, - autoSort = true - ) { - const { - size = this.coolConfig.crud.pageSize, - page = 1, - order = 'createTime', - sort = 'desc', - isExport = false, - maxExportLimit, - } = query; - const count = await find.getCount(); - let dataFind: SelectQueryBuilder; - if (isExport && maxExportLimit > 0) { - dataFind = find.limit(maxExportLimit); - } else { - dataFind = find.offset((page - 1) * size).limit(size); - } - if (autoSort) { - find.addOrderBy(order, sort.toUpperCase()); - } - return { - list: await dataFind.getRawMany(), - pagination: { - page: parseInt(page), - size: parseInt(size), - total: count, - }, - }; - } - - /** - * 检查排序 - * @param sort 排序 - * @returns - */ - private checkSort(sort) { - if (!['desc', 'asc'].includes(sort.toLowerCase())) { - throw new CoolValidateException('sort 非法传参~'); - } - return sort; - } - - /** - * 原生查询 - * @param sql - * @param params - */ - async nativeQuery(sql, params?) { - if (_.isEmpty(params)) { - params = this.sqlParams; - } - let newParams = []; - newParams = newParams.concat(params); - this.sqlParams = []; - for (const param of newParams) { - SqlString.escape(param); - } - return await this.getOrmManager().query(sql, newParams || []); - } - - /** - * 获得ORM管理 - * @param connectionName 连接名称 - */ - getOrmManager() { - return this.coolCloudDb.coolDataSource; - } - - private async before() { - if (!this.curdOption?.before) { - return; - } - await this.curdOption.before(this.ctx, this.app); - } - - /** - * 插入参数值 - * @param curdOption 配置 - */ - private async insertParam(param) { - if (!this.curdOption?.insertParam) { - return param; - } - return { - ...param, - ...(await this.curdOption.insertParam(this.ctx, this.app)), - }; - } - - /** - * 新增|修改|删除 之后的操作 - * @param data 对应数据 - */ - async modifyAfter( - data: any, - type: 'delete' | 'update' | 'add' - ): Promise {} - - /** - * 新增|修改|删除 之前的操作 - * @param data 对应数据 - */ - async modifyBefore( - data: any, - type: 'delete' | 'update' | 'add' - ): Promise {} - - /** - * 新增 - * @param param - * @returns - */ - async add(param) { - param = await this.insertParam(param); - if (!this.entity) throw new CoolValidateException(ERRINFO.NOENTITY); - await this.modifyBefore(param, 'add'); - await this.addOrUpdate(param); - await this.modifyAfter(param, 'add'); - return { - id: - param instanceof Array - ? param.map(e => { - return e.id ? e.id : e._id; - }) - : param.id - ? param.id - : param._id, - }; - } - - /** - * 新增|修改 - * @param param 数据 - */ - async addOrUpdate(param: any | any[]) { - if (!this.entity) throw new CoolValidateException(ERRINFO.NOENTITY); - delete param.createTime; - if (param.id) { - param.updateTime = new Date(); - await this.entity.update(param.id, param); - } else { - param.createTime = new Date(); - param.updateTime = new Date(); - await this.entity.insert(param); - } - } - - /** - * 删除 - * @param ids 删除的ID集合 如:[1,2,3] 或者 1,2,3 - */ - async delete(ids: any) { - if (!this.entity) throw new CoolValidateException(ERRINFO.NOENTITY); - await this.modifyBefore(ids, 'delete'); - if (ids instanceof String) { - ids = ids.split(','); - } - if (this.coolConfig.crud?.softDelete) { - this.softDelete(ids); - } - await this.entity.delete(ids); - await this.modifyAfter(ids, 'delete'); - } - - /** - * 软删除 - * @param ids 删除的ID数组 - * @param entity 实体 - */ - async softDelete(ids: string[], entity?: Repository, userId?: string) { - const data = await this.entity.find({ - where: { - id: In(ids), - }, - }); - if (_.isEmpty(data)) return; - const _entity = entity ? entity : this.entity; - const params = { - data, - ctx: this.ctx, - entity: _entity, - }; - if (data.length > 0) { - this.coolEventManager.emit(EVENT.SOFT_DELETE, params); - } - } - - /** - * 修改 - * @param param 数据 - */ - async update(param: any) { - if (!this.entity) throw new CoolValidateException(ERRINFO.NOENTITY); - await this.modifyBefore(param, 'update'); - if (!param.id && !(param instanceof Array)) - throw new CoolValidateException(ERRINFO.NOID); - await this.addOrUpdate(param); - await this.modifyAfter(param, 'update'); - } - - /** - * 获得单个ID - * @param id ID - */ - async info(id: any): Promise { - if (!this.entity) throw new CoolValidateException(ERRINFO.NOENTITY); - if (!id) { - throw new CoolValidateException(ERRINFO.NOID); - } - const info = await this.entity.findBy({ id }); - if (info && this.curdOption?.infoIgnoreProperty) { - for (const property of this.curdOption?.infoIgnoreProperty) { - delete info[property]; - } - } - return info; - } - - /** - * 构建查询配置 - * @param query 前端查询 - * @param option - */ - private async getOptionFind(query, option) { - let { order = 'createTime', sort = 'desc', keyWord = '' } = query; - const sqlArr = ['SELECT']; - const selects = ['a.*']; - const find = this.entity.createQueryBuilder('a'); - if (option) { - if (typeof option == 'function') { - // @ts-ignore - option = await option(this.baseCtx, this.baseApp); - } - // 判断是否有关联查询,有的话取个别名 - if (!_.isEmpty(option.join)) { - for (const item of option.join) { - selects.push(`${item.alias}.*`); - find[item.type || 'leftJoin']( - item.entity, - item.alias, - item.condition - ); - } - } - // 默认条件 - if (option.where) { - const wheres = - typeof option.where == 'function' - ? await option.where(this.ctx, this.app) - : option.where; - if (!_.isEmpty(wheres)) { - for (const item of wheres) { - if ( - item.length == 2 || - (item.length == 3 && - (item[2] || (item[2] === 0 && item[2] != ''))) - ) { - for (const key in item[1]) { - this.sqlParams.push(item[1][key]); - } - find.andWhere(item[0], item[1]); - } - } - } - } - // 附加排序 - if (!_.isEmpty(option.addOrderBy)) { - for (const key in option.addOrderBy) { - if (order && order == key) { - sort = option.addOrderBy[key].toUpperCase(); - } - find.addOrderBy( - SqlString.escapeId(key), - this.checkSort(option.addOrderBy[key].toUpperCase()) - ); - } - } - // 关键字模糊搜索 - if (keyWord || (keyWord == 0 && keyWord != '')) { - keyWord = `%${keyWord}%`; - find.andWhere( - new Brackets(qb => { - const keyWordLikeFields = option.keyWordLikeFields; - for (let i = 0; i < option.keyWordLikeFields?.length || 0; i++) { - qb.orWhere(`${keyWordLikeFields[i]} like :keyWord`, { - keyWord, - }); - this.sqlParams.push(keyWord); - } - }) - ); - } - // 筛选字段 - if (!_.isEmpty(option.select)) { - sqlArr.push(option.select.join(',')); - find.select(option.select); - } else { - sqlArr.push(selects.join(',')); - } - // 字段全匹配 - if (!_.isEmpty(option.fieldEq)) { - for (const key of option.fieldEq) { - const c = {}; - // 单表字段无别名的情况下操作 - if (typeof key === 'string') { - if (query[key] || (query[key] == 0 && query[key] == '')) { - c[key] = query[key]; - const eq = query[key] instanceof Array ? 'in' : '='; - if (eq === 'in') { - find.andWhere(`${key} ${eq} (:${key})`, c); - } else { - find.andWhere(`${key} ${eq} :${key}`, c); - } - this.sqlParams.push(query[key]); - } - } else { - if ( - query[key.requestParam] || - (query[key.requestParam] == 0 && query[key.requestParam] !== '') - ) { - c[key.column] = query[key.requestParam]; - const eq = query[key.requestParam] instanceof Array ? 'in' : '='; - if (eq === 'in') { - find.andWhere(`${key.column} ${eq} (:${key.column})`, c); - } else { - find.andWhere(`${key.column} ${eq} :${key.column}`, c); - } - this.sqlParams.push(query[key.requestParam]); - } - } - } - } - } else { - sqlArr.push(selects.join(',')); - } - // 接口请求的排序 - if (sort && order) { - const sorts = sort.toUpperCase().split(','); - const orders = order.split(','); - if (sorts.length != orders.length) { - throw new CoolValidateException(ERRINFO.SORTFIELD); - } - for (const i in sorts) { - find.addOrderBy( - SqlString.escapeId(orders[i]), - this.checkSort(sorts[i]) - ); - } - } - if (option?.extend) { - await option?.extend(find, this.ctx, this.app); - } - const sqls = find.getSql().split('FROM'); - sqlArr.push('FROM'); - sqlArr.push(sqls[1]); - return sqlArr.join(' '); - } -} diff --git a/cloud/src/func/index.ts b/cloud/src/func/index.ts deleted file mode 100644 index 94da053..0000000 --- a/cloud/src/func/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { Provide, Scope, ScopeEnum } from '@midwayjs/core'; - -/** - * 云函数 - */ -@Provide() -@Scope(ScopeEnum.Singleton) -export class CoolCloudFunc { - /** - * 获得类名 - * @param code - * @returns - */ - getClassName(code: string) { - return code.match('class(.*)extends')[1].replace(/\s*/g, ''); - } -} diff --git a/cloud/src/index.ts b/cloud/src/index.ts deleted file mode 100644 index b95e149..0000000 --- a/cloud/src/index.ts +++ /dev/null @@ -1,10 +0,0 @@ -export { CoolCloudConfiguration as Configuration } from './configuration'; - -export * from './interface'; - -// 云数据库 -export * from './db/index'; - -// 云函数 -export * from './func/index'; -export * from './func/crud'; diff --git a/cloud/src/interface.ts b/cloud/src/interface.ts deleted file mode 100644 index 3c36af0..0000000 --- a/cloud/src/interface.ts +++ /dev/null @@ -1,11 +0,0 @@ -/** - * 云函数请求 - */ -export interface CloudReq { - // 云函数名称 - name: string; - // 请求参数 - params: any; - // 调用方法 - method: string; -} diff --git a/cloud/src/package.json b/cloud/src/package.json deleted file mode 100644 index d07f131..0000000 --- a/cloud/src/package.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "name": "@cool-midway/cloud", - "version": "7.1.0", - "description": "", - "main": "index.js", - "typings": "index.d.ts", - "scripts": { - "build": "cross-env midway-bin build -c", - "cov": "cross-env midway-bin cov --ts", - "lint": "mwts check", - "lint:fix": "mwts fix" - }, - "keywords": ["cool","cool-admin","cooljs"], - "author": "COOL", - "files": [ - "**/*.js", - "**/*.d.ts", - "index.d.ts" - ], - "license": "MIT", - "repository": { - "type": "git", - "url": "https://cool-js.com" - }, - "devDependencies": { - "@cool-midway/core": "^7.1.19", - "@midwayjs/cli": "^2.0.0", - "@midwayjs/core": "^3.16.0", - "@midwayjs/decorator": "^3.9.0", - "@midwayjs/mock": "^3.9.0", - "@midwayjs/typeorm": "^3.9.0", - "@types/jest": "^29.2.4", - "@types/node": "^18.11.15", - "cross-env": "^7.0.3", - "jest": "^29.3.1", - "lodash": "^4.17.21", - "mwts": "^1.3.0", - "ts-jest": "^29.0.3", - "typeorm": "^0.3.11", - "typescript": "^4.9.4" - }, - "dependencies": { - "sqlstring": "^2.3.3" - } -} diff --git a/cloud/src/util.ts b/cloud/src/util.ts deleted file mode 100644 index f98361e..0000000 --- a/cloud/src/util.ts +++ /dev/null @@ -1 +0,0 @@ -export class CoolCloudUtil {} diff --git a/cloud/tsconfig.json b/cloud/tsconfig.json deleted file mode 100644 index 9bb4ab7..0000000 --- a/cloud/tsconfig.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "compileOnSave": true, - "compilerOptions": { - "target": "es2018", - "module": "commonjs", - "moduleResolution": "node", - "experimentalDecorators": true, - "emitDecoratorMetadata": true, - "inlineSourceMap":false, - "noImplicitThis": true, - "noUnusedLocals": true, - "stripInternal": true, - "skipLibCheck": true, - "noImplicitReturns": false, - "pretty": true, - "declaration": true, - "forceConsistentCasingInFileNames": true, - "outDir": "dist" - }, - "exclude": [ - "dist", - "node_modules", - "test" - ] -} diff --git a/core/LICENSE b/core/LICENSE deleted file mode 100644 index 5a739ee..0000000 --- a/core/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2013 - Now midwayjs - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/core/README.md b/core/README.md deleted file mode 100644 index 610c3db..0000000 --- a/core/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# cool-admin - -https://cool-js.com diff --git a/core/_.editorconfig b/core/_.editorconfig deleted file mode 100644 index 4c7f8a8..0000000 --- a/core/_.editorconfig +++ /dev/null @@ -1,11 +0,0 @@ -# 🎨 editorconfig.org - -root = true - -[*] -charset = utf-8 -end_of_line = lf -indent_style = space -indent_size = 2 -trim_trailing_whitespace = true -insert_final_newline = true \ No newline at end of file diff --git a/core/_.eslintrc.json b/core/_.eslintrc.json deleted file mode 100644 index 8d20e22..0000000 --- a/core/_.eslintrc.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "extends": "./node_modules/mwts/", - "ignorePatterns": ["node_modules", "dist", "test", "jest.config.js", "typings"], - "env": { - "jest": true - } -} diff --git a/core/_.gitignore b/core/_.gitignore deleted file mode 100644 index 13bc3a6..0000000 --- a/core/_.gitignore +++ /dev/null @@ -1,15 +0,0 @@ -logs/ -npm-debug.log -yarn-error.log -node_modules/ -package-lock.json -yarn.lock -coverage/ -dist/ -.idea/ -run/ -.DS_Store -*.sw* -*.un~ -.tsbuildinfo -.tsbuildinfo.* diff --git a/core/_.prettierrc.js b/core/_.prettierrc.js deleted file mode 100644 index b964930..0000000 --- a/core/_.prettierrc.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - ...require('mwts/.prettierrc.json') -} diff --git a/core/index.d.ts b/core/index.d.ts deleted file mode 100644 index e0065de..0000000 --- a/core/index.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -export * from './dist/index'; - -declare module '@midwayjs/core/dist/interface' { - interface MidwayConfig { - book?: PowerPartial<{ - a: number; - b: string; - }>; - } -} diff --git a/core/jest.config.js b/core/jest.config.js deleted file mode 100644 index 82a8b85..0000000 --- a/core/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = { - preset: 'ts-jest', - testEnvironment: 'node', - testPathIgnorePatterns: ['/test/fixtures'], - coveragePathIgnorePatterns: ['/test/'], - setupFilesAfterEnv: ['./jest.setup.js'] -}; diff --git a/core/jest.setup.js b/core/jest.setup.js deleted file mode 100644 index 1399c91..0000000 --- a/core/jest.setup.js +++ /dev/null @@ -1 +0,0 @@ -jest.setTimeout(30000); diff --git a/core/package.json b/core/package.json deleted file mode 100644 index 8c7e83e..0000000 --- a/core/package.json +++ /dev/null @@ -1,64 +0,0 @@ -{ - "name": "@cool-midway/core", - "version": "7.1.25", - "description": "", - "main": "dist/index.js", - "typings": "index.d.ts", - "scripts": { - "build": "cross-env midway-bin build -c", - "cov": "cross-env midway-bin cov --ts", - "lint": "mwts check", - "lint:fix": "mwts fix" - }, - "keywords": [ - "cool", - "cool-admin", - "cooljs" - ], - "author": "COOL", - "files": [ - "dist/**/*.js", - "dist/**/*.d.ts", - "index.d.ts" - ], - "readme": "README.md", - "license": "MIT", - "repository": { - "type": "git", - "url": "https://cool-js.com" - }, - "devDependencies": { - "@midwayjs/cli": "2.1.1", - "@midwayjs/core": "^3.15.0", - "@midwayjs/decorator": "^3.15.0", - "@midwayjs/koa": "^3.15.2", - "@midwayjs/mock": "^3.15.2", - "@midwayjs/typeorm": "^3.15.2", - "@types/download": "^8.0.5", - "@types/jest": "^29.5.12", - "@types/node": "^20.11.30", - "aedes": "^0.51.0", - "cross-env": "^7.0.3", - "jest": "^29.7.0", - "mwts": "^1.3.0", - "ts-jest": "^29.1.2", - "typeorm": "^0.3.20", - "typescript": "~5.4.2" - }, - "dependencies": { - "@cool-midway/cache-manager-fs-hash": "^7.0.0", - "@midwayjs/cache": "^3.14.0", - "@midwayjs/cache-manager": "^3.15.2", - "axios": "^1.6.8", - "decompress": "^4.2.1", - "download": "^8.0.0", - "jsonwebtoken": "^9.0.2", - "lodash": "^4.17.21", - "md5": "^2.3.0", - "moment": "^2.30.1", - "pm2": "^5.3.1", - "sqlstring": "^2.3.3", - "uuid": "^9.0.1", - "ws": "^8.16.0" - } -} \ No newline at end of file diff --git a/core/src/LICENSE b/core/src/LICENSE deleted file mode 100644 index 5a739ee..0000000 --- a/core/src/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2013 - Now midwayjs - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/core/src/README.md b/core/src/README.md deleted file mode 100644 index 7edd966..0000000 --- a/core/src/README.md +++ /dev/null @@ -1,27 +0,0 @@ -### COOL-ADMIN - -cool-admin一个很酷的后台权限管理系统,开源免费,模块化、插件化、极速开发CRUD,方便快速构建迭代后台管理系统 - -大数据、微服务、AI编码快速开发!!! - - -### 技术栈 - -- 后端:node.js midway.js koa.js mysql typescript -- 前端:vue.js element-plus jsx pinia vue-router - -### 官网 - -[https://cool-js.com](https://cool-js.com) - - -### 演示地址 - -[https://show.cool-admin.com](https://show.cool-admin.com) - -- 账户:admin -- 密码:123456 - -### 项目地址 - -[https://github.com/cool-team-official/cool-admin-midway](https://github.com/cool-team-official/cool-admin-midway) \ No newline at end of file diff --git a/core/src/cache/store.ts b/core/src/cache/store.ts deleted file mode 100644 index f52b23b..0000000 --- a/core/src/cache/store.ts +++ /dev/null @@ -1,64 +0,0 @@ -import * as FsStore from "@cool-midway/cache-manager-fs-hash"; - -/** - * cool 基于磁盘的缓存 - */ -class FsCacheStore { - options: any; - - store: FsStore; - - constructor(options = {}) { - options = { - ...options, - path: "cache", - ttl: -1, - }; - this.options = options; - this.store = FsStore.create(options); - } - - /** - * 获得 - * @param key - * @returns - */ - async get(key: string): Promise { - return await this.store.get(key); - } - - /** - * 设置 - * @param key - * @param value - * @param ttl - */ - async set(key: string, value: T, ttl: number): Promise { - let t = ttl ? ttl : this.options.ttl; - if (t > 0) { - t = t / 1000; - } - await this.store.set(key, value, { - ttl: t, - }); - } - - /** - * 删除 - * @param key - */ - async del(key: string): Promise { - await this.store.del(key); - } - - /** - * 重置 - */ - async reset(): Promise { - await this.store.reset(); - } -} - -export const CoolCacheStore = function (options = {}) { - return new FsCacheStore(options); -}; diff --git a/core/src/config/config.default.ts b/core/src/config/config.default.ts deleted file mode 100644 index b8f7858..0000000 --- a/core/src/config/config.default.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { CoolConfig } from "../interface"; - -/** - * cool的配置 - */ -export default { - cool: { - // 是否自动导入数据库 - initDB: false, - // 是否自动导入模块菜单 - initMenu: true, - // 判断是否初始化的方式 - initJudge: "file", - // crud配置 - crud: { - // 软删除 - softDelete: true, - // 分页查询每页条数 - pageSize: 15, - }, - } as CoolConfig, -}; diff --git a/core/src/configuration.ts b/core/src/configuration.ts deleted file mode 100644 index 4dc389c..0000000 --- a/core/src/configuration.ts +++ /dev/null @@ -1,79 +0,0 @@ -import { - App, - Context, - ILifeCycle, - ILogger, - IMidwayBaseApplication, - IMidwayContainer, - Inject, - Logger, -} from "@midwayjs/core"; -import { Configuration } from "@midwayjs/decorator"; -import * as DefaultConfig from "./config/config.default"; -import { CoolExceptionFilter } from "./exception/filter"; -import { FuncUtil } from "./util/func"; -import * as koa from "@midwayjs/koa"; -import { CoolModuleConfig } from "./module/config"; -import { CoolModuleImport } from "./module/import"; -import { CoolEventManager } from "./event"; -import { CoolEps } from "./rest/eps"; -import { CoolDecorator } from "./decorator"; -import * as cache from "@midwayjs/cache-manager"; -import * as _cache from "@midwayjs/cache"; - -@Configuration({ - namespace: "cool", - imports: [_cache, cache], - importConfigs: [ - { - default: DefaultConfig, - }, - ], -}) -export class CoolConfiguration implements ILifeCycle { - @Logger() - coreLogger: ILogger; - - @App() - app: koa.Application; - - @Inject() - coolEventManager: CoolEventManager; - - async onReady(container: IMidwayContainer) { - this.coolEventManager.emit("onReady"); - // 处理模块配置 - await container.getAsync(CoolModuleConfig); - // 常用函数处理 - await container.getAsync(FuncUtil); - // 异常处理 - this.app.useFilter([CoolExceptionFilter]); - // 装饰器 - await container.getAsync(CoolDecorator); - - // 缓存设置为全局 - // global["COOL-CACHE"] = await container.getAsync(CacheManager); - // // 清除 location - // setTimeout(() => { - // location.clean(); - // this.coreLogger.info("\x1B[36m [cool:core] location clean \x1B[0m"); - // }, 10000); - } - - async onConfigLoad( - container: IMidwayContainer, - mainApp?: IMidwayBaseApplication - ) {} - - async onServerReady(container: IMidwayContainer) { - // 事件 - await (await container.getAsync(CoolEventManager)).init(); - // 导入模块数据 - (await container.getAsync(CoolModuleImport)).init(); - // 实体与路径 - const eps: CoolEps = await container.getAsync(CoolEps); - eps.init(); - this.coolEventManager.emit("onServerReady"); - // location.clean(); - } -} diff --git a/core/src/constant/global.ts b/core/src/constant/global.ts deleted file mode 100644 index ad18ebe..0000000 --- a/core/src/constant/global.ts +++ /dev/null @@ -1,84 +0,0 @@ -/** - * 返回码 - */ -export enum RESCODE { - // 成功 - SUCCESS = 1000, - // 失败 - COMMFAIL = 1001, - // 参数验证失败 - VALIDATEFAIL = 1002, - // 参数验证失败 - COREFAIL = 1003, -} - -/** - * 返回信息 - */ -export enum RESMESSAGE { - // 成功 - SUCCESS = "success", - // 失败 - COMMFAIL = "comm fail", - // 参数验证失败 - VALIDATEFAIL = "validate fail", - // 核心异常 - COREFAIL = "core fail", -} - -/** - * 错误提示 - */ -export enum ERRINFO { - NOENTITY = "未设置操作实体", - NOID = "查询参数[id]不存在", - SORTFIELD = "排序参数不正确", -} - -/** - * 事件 - */ -export enum EVENT { - // 软删除 - SOFT_DELETE = "onSoftDelete", - // 服务成功启动 - SERVER_READY = "onServerReady", - // 服务就绪 - READY = "onReady", - // ES 数据改变 - ES_DATA_CHANGE = "esDataChange", -} - - -export class GlobalConfig { - private static instance: GlobalConfig; - - RESCODE = { - SUCCESS: 1000, - COMMFAIL: 1001, - VALIDATEFAIL: 1002, - COREFAIL: 1003, - }; - - RESMESSAGE = { - SUCCESS: "success", - COMMFAIL: "comm fail", - VALIDATEFAIL: "validate fail", - COREFAIL: "core fail", - }; - - // ... 其他的配置 ... - - private constructor() {} - - static getInstance(): GlobalConfig { - if (!GlobalConfig.instance) { - GlobalConfig.instance = new GlobalConfig(); - } - return GlobalConfig.instance; - } -} - - - - diff --git a/core/src/controller/base.ts b/core/src/controller/base.ts deleted file mode 100644 index da76d52..0000000 --- a/core/src/controller/base.ts +++ /dev/null @@ -1,220 +0,0 @@ -import { - App, - CONTROLLER_KEY, - getClassMetadata, - Init, - Inject, - Provide, -} from "@midwayjs/decorator"; -import { GlobalConfig } from "../constant/global"; -import { ControllerOption, CurdOption } from "../decorator/controller"; -import { BaseService } from "../service/base"; -import { IMidwayApplication } from "@midwayjs/core"; -import { Context } from "@midwayjs/koa"; -import { TypeORMDataSourceManager } from "@midwayjs/typeorm"; - -/** - * 控制器基类 - */ -@Provide() -export abstract class BaseController { - @Inject("ctx") - baseCtx: Context; - - @Inject() - service: BaseService; - - @App() - baseApp: IMidwayApplication; - - curdOption: CurdOption; - - @Inject() - typeORMDataSourceManager: TypeORMDataSourceManager; - - connectionName; - - @Init() - async init() { - const option: ControllerOption = getClassMetadata(CONTROLLER_KEY, this); - const curdOption: CurdOption = option.curdOption; - this.curdOption = curdOption; - if (!this.curdOption) { - return; - } - // 操作之前 - await this.before(curdOption); - // 设置service - await this.setService(curdOption); - // 设置实体 - await this.setEntity(curdOption); - } - - private async before(curdOption: CurdOption) { - if (!curdOption?.before) { - return; - } - await curdOption.before(this.baseCtx, this.baseApp); - } - - /** - * 插入参数值 - * @param curdOption 配置 - */ - private async insertParam(curdOption: CurdOption) { - if (!curdOption?.insertParam) { - return; - } - const body = this.baseCtx.request.body; - if (body) { - // 判断body是否是数组 - if (Array.isArray(body)) { - for (let i = 0; i < body.length; i++) { - body[i] = { - ...body[i], - ...(await curdOption.insertParam(this.baseCtx, this.baseApp)), - }; - } - this.baseCtx.request.body = body; - return; - } - this.baseCtx.request.body = { - // @ts-ignore - ...this.baseCtx.request.body, - ...(await curdOption.insertParam(this.baseCtx, this.baseApp)), - }; - } - } - - /** - * 设置实体 - * @param curdOption 配置 - */ - private async setEntity(curdOption: CurdOption) { - const entity = curdOption?.entity; - if (entity) { - const dataSourceName = - this.typeORMDataSourceManager.getDataSourceNameByModel(entity); - this.connectionName = dataSourceName; - let entityModel = this.typeORMDataSourceManager - .getDataSource(dataSourceName) - .getRepository(entity); - this.service.setEntity(entityModel); - } - } - - /** - * 设置service - * @param curdOption - */ - private async setService(curdOption: CurdOption) { - if (curdOption.service) { - this.service = await this.baseCtx.requestContext.getAsync( - curdOption.service - ); - } - } - - /** - * 新增 - * @returns - */ - async add() { - // 插入参数 - await this.insertParam(this.curdOption); - const { body } = this.baseCtx.request; - return this.ok(await this.service.add(body)); - } - - /** - * 删除 - * @returns - */ - async delete() { - // @ts-ignore - const { ids } = this.baseCtx.request.body; - return this.ok(await this.service.delete(ids)); - } - - /** - * 更新 - * @returns - */ - async update() { - const { body } = this.baseCtx.request; - return this.ok(await this.service.update(body)); - } - - /** - * 分页查询 - * @returns - */ - async page() { - const { body } = this.baseCtx.request; - return this.ok( - await this.service.page( - body, - this.curdOption.pageQueryOp, - this.connectionName - ) - ); - } - - /** - * 列表查询 - * @returns - */ - async list() { - const { body } = this.baseCtx.request; - return this.ok( - await this.service.list( - body, - this.curdOption.listQueryOp, - this.connectionName - ) - ); - } - - /** - * 根据ID查询信息 - * @returns - */ - async info() { - const { id } = this.baseCtx.query; - return this.ok( - await this.service.info(id, this.curdOption.infoIgnoreProperty) - ); - } - - /** - * 成功返回 - * @param data 返回数据 - */ - ok(data?: any) { - const { RESCODE, RESMESSAGE } = GlobalConfig.getInstance(); - const res = { - code: RESCODE.SUCCESS, - message: RESMESSAGE.SUCCESS, - }; - if (data || data == 0) { - res["data"] = data; - } - return res; - } - - /** - * 失败返回 - * @param message - */ - fail(message?: string, code?: number) { - const { RESCODE, RESMESSAGE } = GlobalConfig.getInstance(); - return { - code: code ? code : RESCODE.COMMFAIL, - message: message - ? message - : code == RESCODE.VALIDATEFAIL - ? RESMESSAGE.VALIDATEFAIL - : RESMESSAGE.COMMFAIL, - }; - } -} diff --git a/core/src/decorator/cache.ts b/core/src/decorator/cache.ts deleted file mode 100644 index f8195f0..0000000 --- a/core/src/decorator/cache.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { createCustomMethodDecorator } from "@midwayjs/decorator"; - -// 装饰器内部的唯一 id -export const COOL_CACHE = "decorator:cool_cache"; - -export function CoolCache(ttl?: number): MethodDecorator { - return createCustomMethodDecorator(COOL_CACHE, ttl); -} diff --git a/core/src/decorator/controller.ts b/core/src/decorator/controller.ts deleted file mode 100644 index b0166b7..0000000 --- a/core/src/decorator/controller.ts +++ /dev/null @@ -1,212 +0,0 @@ -import { ModuleConfig } from "./../interface"; -import { - Scope, - ScopeEnum, - saveClassMetadata, - saveModule, - CONTROLLER_KEY, - MiddlewareParamArray, - WEB_ROUTER_KEY, - attachClassMetadata, -} from "@midwayjs/decorator"; -import * as fs from "fs"; -import * as _ from "lodash"; -import location from "../util/location"; - -export type ApiTypes = "add" | "delete" | "update" | "page" | "info" | "list"; -// Crud配置 - -export interface CurdOption { - // 路由前缀,不配置默认是按Controller下的文件夹路径 - prefix?: string; - // curd api接口 - api: ApiTypes[]; - // 分页查询配置 - pageQueryOp?: QueryOp | Function; - // 非分页查询配置 - listQueryOp?: QueryOp | Function; - // 插入参数 - insertParam?: Function; - // 操作之前 - before?: Function; - // info 忽略返回属性 - infoIgnoreProperty?: string[]; - // 实体 - entity: any; - // 服务 - service?: any; - // api标签 - urlTag?: { - name: "ignoreToken" | string; - url: ApiTypes[]; - }; -} -export interface JoinOp { - // 实体 - entity: any; - // 别名 - alias: string; - // 关联条件 - condition: string; - // 关联类型 - type?: "innerJoin" | "leftJoin"; -} - -// 字段匹配 -export interface FieldEq { - // 字段 - column: string; - // 请求参数 - requestParam: string; -} -// 查询配置 -export interface QueryOp { - // 需要模糊查询的字段 - keyWordLikeFields?: string[]; - // 查询条件 - where?: Function; - // 查询字段 - select?: string[]; - // 字段相等 - fieldEq?: string[] | FieldEq[] | (string | FieldEq)[]; - // 添加排序条件 - addOrderBy?: {}; - // 关联配置 - join?: JoinOp[]; - // 其他条件 - extend?: Function; -} - -// Controller 配置 -export interface ControllerOption { - // crud配置 如果是字符串则为路由前缀,不配置默认是按Controller下的文件夹路径 - curdOption?: CurdOption & string; - // 路由配置 - routerOptions?: { - // 是否敏感 - sensitive?: boolean; - // 路由中间件 - middleware?: MiddlewareParamArray; - // 别名 - alias?: string[]; - // 描述 - description?: string; - // 标签名称 - tagName?: string; - }; -} - -// 路由配置 -export interface RouterOptions { - sensitive?: boolean; - middleware?: MiddlewareParamArray; - description?: string; - tagName?: string; - ignoreGlobalPrefix?: boolean; -} - -// COOL的装饰器 -export function CoolController( - curdOption?: CurdOption | string | RouterOptions, - routerOptions: RouterOptions = { middleware: [], sensitive: true } -): ClassDecorator { - return (target: any) => { - // 将装饰的类,绑定到该装饰器,用于后续能获取到 class - saveModule(CONTROLLER_KEY, target); - let prefix; - if (curdOption) { - // 判断 curdOption 的类型 - if (typeof curdOption === "string") { - prefix = curdOption; - } else if (curdOption && "api" in curdOption) { - // curdOption 是 CurdOption 类型 - prefix = curdOption.prefix || ""; - } else { - // curdOption 是 RouterOptions 类型 合并到 routerOptions - routerOptions = { ...curdOption, ...routerOptions }; - } - } - // 如果不存在路由前缀,那么自动根据当前文件夹路径 - location.scriptPath(target).then(async (res: any) => { - const pathSps = res.path.split("."); - const paths = pathSps[pathSps.length - 2].split(/[/\\]/); - const pathArr = []; - let module = null; - for (const path of paths.reverse()) { - if (path != "controller" && !module) { - pathArr.push(path); - } - if (path == "controller" && !paths.includes("modules")) { - break; - } - if (path == "controller" && paths.includes("modules")) { - module = "ready"; - } - if (module && path != "controller") { - module = `${path}`; - break; - } - } - if (module) { - pathArr.reverse(); - pathArr.splice(1, 0, module); - // 追加模块中间件 - let path = `${res.path.split(new RegExp(`modules[/\\\\]${module}`))[0]}modules/${module}/config.${_.endsWith(res.path, "ts") ? "ts" : "js"}`; - if (fs.existsSync(path)) { - const config: ModuleConfig = require(path).default(); - routerOptions.middleware = (config.middlewares || []).concat( - routerOptions.middleware || [] - ); - } - } - if (!prefix) { - prefix = `/${pathArr.join("/")}`; - } - saveMetadata(prefix, routerOptions, target, curdOption, module); - }); - }; -} - -export const apiDesc = { - add: "新增", - delete: "删除", - update: "修改", - page: "分页查询", - list: "列表查询", - info: "单个信息", -}; - -// 保存一些元数据信息,任意你希望存的东西 -function saveMetadata(prefix, routerOptions, target, curdOption, module) { - if (module && !routerOptions.tagName) { - routerOptions = routerOptions || {}; - routerOptions.tagName = module; - } - saveClassMetadata( - CONTROLLER_KEY, - { - prefix, - routerOptions, - curdOption, - module, - } as ControllerOption, - target - ); - // 追加CRUD路由 - if (!_.isEmpty(curdOption?.api)) { - curdOption?.api.forEach((path) => { - attachClassMetadata( - WEB_ROUTER_KEY, - { - path: `/${path}`, - requestMethod: path == "info" ? "get" : "post", - method: path, - summary: apiDesc[path], - description: "", - }, - target - ); - }); - Scope(ScopeEnum.Request)(target); - } -} diff --git a/core/src/decorator/event.ts b/core/src/decorator/event.ts deleted file mode 100644 index b773570..0000000 --- a/core/src/decorator/event.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { - saveClassMetadata, - saveModule, - attachClassMetadata, -} from "@midwayjs/decorator"; -import { Scope, ScopeEnum } from "@midwayjs/core"; - -export const COOL_CLS_EVENT_KEY = "decorator:cool:cls:event"; - -/** - * 事件配置 - */ -export interface CoolEventOptions { - /** 是否全局 */ - isGlobal: boolean; -} - -/** - * 事件 - * @param options - * @returns - */ -export function CoolEvent(options = {} as CoolEventOptions): ClassDecorator { - return (target: any) => { - // 将装饰的类,绑定到该装饰器,用于后续能获取到 class - saveModule(COOL_CLS_EVENT_KEY, target); - // 保存一些元数据信息,任意你希望存的东西 - saveClassMetadata(COOL_CLS_EVENT_KEY, options, target); - // 指定 IoC 容器创建实例的作用域,这里注册为请求作用域,这样能取到 ctx - Scope(ScopeEnum.Singleton)(target); - }; -} - -export const COOL_EVENT_KEY = "decorator:cool:event"; - -/** - * 事件 - * @param eventName - * @returns - */ -export function Event(eventName?: string): MethodDecorator { - return (target: any, propertyKey: string, descriptor: PropertyDescriptor) => { - // 将装饰的类,绑定到该装饰器,用于后续能获取到 class - attachClassMetadata( - COOL_EVENT_KEY, - { - eventName, - propertyKey, - descriptor, - }, - target - ); - }; -} diff --git a/core/src/decorator/index.ts b/core/src/decorator/index.ts deleted file mode 100644 index 64d65f2..0000000 --- a/core/src/decorator/index.ts +++ /dev/null @@ -1,112 +0,0 @@ -import { COOL_CACHE } from "./cache"; -import { CachingFactory, MidwayCache } from "@midwayjs/cache-manager"; -import { - Init, - Inject, - InjectClient, - JoinPoint, - MidwayDecoratorService, - Provide, - Scope, - ScopeEnum, -} from "@midwayjs/core"; -import { TypeORMDataSourceManager } from "@midwayjs/typeorm"; -import { CoolCommException } from "../exception/comm"; -import { COOL_TRANSACTION, TransactionOptions } from "./transaction"; -import * as md5 from "md5"; -import { CoolUrlTagData } from "../tag/data"; - -/** - * 装饰器 - */ -@Provide() -@Scope(ScopeEnum.Singleton) -export class CoolDecorator { - @Inject() - typeORMDataSourceManager: TypeORMDataSourceManager; - - @Inject() - decoratorService: MidwayDecoratorService; - - @InjectClient(CachingFactory, "default") - midwayCache: MidwayCache; - - @Inject() - coolUrlTagData: CoolUrlTagData; - - @Init() - async init() { - // 事务 - await this.transaction(); - // 缓存 - await this.cache(); - // URL标签 - await this.coolUrlTagData.init(); - } - - /** - * 缓存 - */ - async cache() { - this.decoratorService.registerMethodHandler(COOL_CACHE, (options) => { - return { - around: async (joinPoint: JoinPoint) => { - const key = md5( - joinPoint.target.constructor.name + - joinPoint.methodName + - JSON.stringify(joinPoint.args) - ); - // 缓存有数据就返回 - let data: any = await this.midwayCache.get(key); - if (data) { - return JSON.parse(data); - } else { - // 执行原始方法 - data = await joinPoint.proceed(...joinPoint.args); - await this.midwayCache.set( - key, - JSON.stringify(data), - options.metadata - ); - } - return data; - }, - }; - }); - } - - /** - * 事务 - */ - async transaction() { - this.decoratorService.registerMethodHandler(COOL_TRANSACTION, (options) => { - return { - around: async (joinPoint: JoinPoint) => { - const option: TransactionOptions = options.metadata; - const dataSource = this.typeORMDataSourceManager.getDataSource( - option?.connectionName || "default" - ); - const queryRunner = dataSource.createQueryRunner(); - await queryRunner.connect(); - if (option && option.isolation) { - await queryRunner.startTransaction(option.isolation); - } else { - await queryRunner.startTransaction(); - } - let data; - try { - joinPoint.args.push(queryRunner); - data = await joinPoint.proceed(...joinPoint.args); - await queryRunner.commitTransaction(); - } catch (error) { - await queryRunner.rollbackTransaction(); - throw new CoolCommException(error.message); - } finally { - await queryRunner.release(); - } - return data; - }, - }; - }); - } -} diff --git a/core/src/decorator/tag.ts b/core/src/decorator/tag.ts deleted file mode 100644 index a2a94ab..0000000 --- a/core/src/decorator/tag.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { saveClassMetadata, savePropertyDataToClass, saveModule } from "@midwayjs/decorator"; - -export const COOL_URL_TAG_KEY = "decorator:cool:url:tag"; - -export const COOL_METHOD_TAG_KEY = "decorator:cool:method:tag"; - -export enum TagTypes { - IGNORE_TOKEN = "ignoreToken", - IGNORE_SIGN = "ignoreSign", -} - -export interface CoolUrlTagConfig { - key: TagTypes | string; - value?: string[]; -} - -/** - * 打标记 - * @param data - * @returns - */ -export function CoolUrlTag(data?: CoolUrlTagConfig): ClassDecorator { - return (target: any) => { - // 将装饰的类,绑定到该装饰器,用于后续能获取到 class - saveModule(COOL_URL_TAG_KEY, target); - // 保存一些元数据信息,任意你希望存的东西 - saveClassMetadata(COOL_URL_TAG_KEY, data, target); - }; -} - - -/** - * 方法打标记 - * @param data - * @returns - */ -export function CoolTag(tag: TagTypes | string): MethodDecorator { - return (target, key, descriptor: PropertyDescriptor) => { - savePropertyDataToClass( - COOL_METHOD_TAG_KEY, - { - key, - tag - }, - target, - key - ); - return descriptor; - }; -} \ No newline at end of file diff --git a/core/src/decorator/transaction.ts b/core/src/decorator/transaction.ts deleted file mode 100644 index 5922dc3..0000000 --- a/core/src/decorator/transaction.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { createCustomMethodDecorator } from "@midwayjs/decorator"; - -type IsolationLevel = - | "READ UNCOMMITTED" - | "READ COMMITTED" - | "REPEATABLE READ" - | "SERIALIZABLE"; - -export interface TransactionOptions { - connectionName?: string; - isolation?: IsolationLevel; -} - -// 装饰器内部的唯一 id -export const COOL_TRANSACTION = "decorator:cool_transaction"; - -export function CoolTransaction(option?: TransactionOptions): MethodDecorator { - return createCustomMethodDecorator(COOL_TRANSACTION, option); -} diff --git a/core/src/entity/base.ts b/core/src/entity/base.ts deleted file mode 100644 index a2d97fe..0000000 --- a/core/src/entity/base.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { - Index, - UpdateDateColumn, - CreateDateColumn, - PrimaryGeneratedColumn, -} from "typeorm"; -import { CoolBaseEntity } from "./typeorm"; - -/** - * 模型基类 - */ -export abstract class BaseEntity extends CoolBaseEntity { - // 默认自增 - @PrimaryGeneratedColumn("increment", { - comment: "ID", - }) - id: number; - - @Index() - @CreateDateColumn({ comment: "创建时间" }) - createTime: Date; - - @Index() - @UpdateDateColumn({ comment: "更新时间" }) - updateTime: Date; -} diff --git a/core/src/entity/mongo.ts b/core/src/entity/mongo.ts deleted file mode 100644 index f17dec5..0000000 --- a/core/src/entity/mongo.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { - Index, - UpdateDateColumn, - CreateDateColumn, - // @ts-ignore - ObjectID, - ObjectIdColumn, -} from "typeorm"; -import { CoolBaseEntity } from "./typeorm"; - -/** - * 模型基类 - */ -export abstract class BaseMongoEntity extends CoolBaseEntity { - @ObjectIdColumn({ comment: "id" }) - id: ObjectID; - - @Index() - @CreateDateColumn({ comment: "创建时间" }) - createTime: Date; - - @Index() - @UpdateDateColumn({ comment: "更新时间" }) - updateTime: Date; -} diff --git a/core/src/entity/typeorm.ts b/core/src/entity/typeorm.ts deleted file mode 100644 index f9c1c8b..0000000 --- a/core/src/entity/typeorm.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { BaseEntity } from "typeorm"; - -export abstract class CoolBaseEntity extends BaseEntity {} diff --git a/core/src/event/index.ts b/core/src/event/index.ts deleted file mode 100644 index e348627..0000000 --- a/core/src/event/index.ts +++ /dev/null @@ -1,190 +0,0 @@ -import { - App, - getClassMetadata, - listModule, - Provide, -} from "@midwayjs/decorator"; -import * as Events from "events"; -import { Scope, ScopeEnum, IMidwayApplication, Config } from "@midwayjs/core"; -import { COOL_CLS_EVENT_KEY, COOL_EVENT_KEY } from "../decorator/event"; -import * as pm2 from "pm2"; -import * as _ from "lodash"; - -export const COOL_EVENT_MESSAGE = "cool:event:message"; - -/** - * 事件 - */ -@Provide() -@Scope(ScopeEnum.Singleton) -export class CoolEventManager extends Events { - @App() - app: IMidwayApplication; - - @Config("keys") - keys: string; - - // 事件数据 某个事件对应的模块对应的方法 - eventData = {} as { - [key: string]: { - module: any; - method: string; - }[]; - }; - - /** - * 初始化 - */ - async init() { - const eventModules = listModule(COOL_CLS_EVENT_KEY); - for (const module of eventModules) { - await this.handlerEvent(module); - } - await this.commEvent(); - await this.globalEvent(); - } - - /** - * 发送事件 - * @param event - * @param args - * @returns - */ - emit(event: string | symbol, ...args: any[]): boolean { - return super.emit(COOL_EVENT_MESSAGE, { - type: COOL_EVENT_MESSAGE, - data: { - event, - args, - }, - }); - } - - /** - * 发送全局事件 - * @param event 事件 - * @param random 是否随机一个 - * @param args 参数 - * @returns - */ - async globalEmit(event: string, random: boolean = false, ...args) { - // 如果是本地运行还是转普通模式 - if (this.app.getEnv() === "local") { - this.emit(event, ...args); - return; - } - pm2.connect(() => { - pm2.list((err, list) => { - const ps = list.map((e) => { - return { - id: e.pm_id, - name: e.name, - }; - }); - // random 为 true 时随机发给同名称的一个进程 - if (random) { - // 按名称分组 - const group = _.groupBy(ps, "name"); - const names = Object.keys(group); - // 遍历名称 - names.forEach((name) => { - const pss = group[name]; - // 随机一个 - const index = _.random(0, pss.length - 1); - const ps = pss[index]; - // 发给这个进程 - // @ts-ignore - pm2.sendDataToProcessId( - { - type: "process:msg", - data: { - type: `${COOL_EVENT_MESSAGE}@${this.keys}`, - event, - args, - }, - id: ps.id, - topic: "cool:event:topic", - }, - (err, res) => {} - ); - }); - } else { - // 发给所有进程 - ps.forEach((e) => { - // @ts-ignore - pm2.sendDataToProcessId( - { - type: "process:msg", - data: { - type: `${COOL_EVENT_MESSAGE}@${this.keys}`, - event, - args, - }, - id: e.id, - topic: "cool:event:topic", - }, - (err, res) => {} - ); - }); - } - }); - }); - } - - /** - * 处理事件 - * @param module - */ - async handlerEvent(module) { - const events = getClassMetadata(COOL_EVENT_KEY, module); - for (const event of events) { - const listen = event.eventName ? event.eventName : event.propertyKey; - if (!this.eventData[listen]) { - this.eventData[listen] = []; - } - this.eventData[listen].push({ - module, - method: event.propertyKey, - }); - } - } - - /** - * 全局事件 - */ - async globalEvent() { - process.on("message", async (message: any) => { - const data = message?.data; - if (!data) return; - if (data.type != `${COOL_EVENT_MESSAGE}@${this.keys}`) return; - await this.doAction(message); - }); - } - - /** - * 普通事件 - */ - async commEvent() { - this.on(COOL_EVENT_MESSAGE, async (message: any) => { - await this.doAction(message); - }); - } - - /** - * 执行事件 - * @param message - */ - async doAction(message) { - const data = message.data; - const method = data.event; - const args = data.args; - if (this.eventData[method]) { - for (const event of this.eventData[method]) { - const moduleInstance = await this.app - .getApplicationContext() - .getAsync(event.module); - moduleInstance[event.method](...args); - } - } - } -} diff --git a/core/src/exception/base.ts b/core/src/exception/base.ts deleted file mode 100644 index 177b46b..0000000 --- a/core/src/exception/base.ts +++ /dev/null @@ -1,13 +0,0 @@ -/** - * 异常基类 - */ -export class BaseException extends Error { - status: number; - - constructor(name: string, code: number, message: string) { - super(message); - - this.name = name; - this.status = code; - } -} diff --git a/core/src/exception/comm.ts b/core/src/exception/comm.ts deleted file mode 100644 index d2c9525..0000000 --- a/core/src/exception/comm.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { GlobalConfig } from '../constant/global'; -import { BaseException } from './base'; - -/** - * 通用异常 - */ -export class CoolCommException extends BaseException { - constructor(message: string) { - const { RESCODE, RESMESSAGE } = GlobalConfig.getInstance(); - super( - 'CoolCommException', - RESCODE.COMMFAIL, - message ? message : RESMESSAGE.COMMFAIL - ); - } -} diff --git a/core/src/exception/core.ts b/core/src/exception/core.ts deleted file mode 100644 index 9dc3a7e..0000000 --- a/core/src/exception/core.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { GlobalConfig } from '../constant/global'; -import { BaseException } from './base'; - -/** - * 核心异常 - */ -export class CoolCoreException extends BaseException { - constructor(message: string) { - const { RESCODE, RESMESSAGE } = GlobalConfig.getInstance(); - super( - 'CoolCoreException', - RESCODE.COREFAIL, - message ? message : RESMESSAGE.COREFAIL - ); - } -} diff --git a/core/src/exception/filter.ts b/core/src/exception/filter.ts deleted file mode 100644 index 170ddc3..0000000 --- a/core/src/exception/filter.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { ILogger } from '@midwayjs/core'; -import { Catch, Logger } from '@midwayjs/decorator'; -import { GlobalConfig } from '../constant/global'; - -/** - * 全局异常处理 - */ -@Catch() -export class CoolExceptionFilter { - @Logger() - coreLogger: ILogger; - - async catch(err) { - const { RESCODE } = GlobalConfig.getInstance(); - this.coreLogger.error(err); - return { - code: err.status || RESCODE.COMMFAIL, - message: err.message, - }; - } -} diff --git a/core/src/exception/validate.ts b/core/src/exception/validate.ts deleted file mode 100644 index da023ca..0000000 --- a/core/src/exception/validate.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { GlobalConfig } from '../constant/global'; -import { BaseException } from './base'; - -/** - * 校验异常 - */ -export class CoolValidateException extends BaseException { - constructor(message: string) { - const { RESCODE, RESMESSAGE } = GlobalConfig.getInstance(); - super( - 'CoolValidateException', - RESCODE.VALIDATEFAIL, - message ? message : RESMESSAGE.VALIDATEFAIL - ); - } -} diff --git a/core/src/index.ts b/core/src/index.ts deleted file mode 100644 index 6b6e89c..0000000 --- a/core/src/index.ts +++ /dev/null @@ -1,52 +0,0 @@ -export { CoolConfiguration as Configuration } from "./configuration"; - -// 异常处理 -export * from "./exception/filter"; -export * from "./exception/core"; -export * from "./exception/base"; -export * from "./exception/comm"; -export * from "./exception/validate"; - -// cache -export * from "./cache/store"; - -// entity -export * from "./entity/base"; -export * from "./entity/typeorm"; -export * from "./entity/mongo"; - -// service -export * from "./service/base"; -export * from "./service/mysql"; -export * from "./service/postgres"; -export * from "./service/sqlite"; - -// controller -export * from "./controller/base"; - -// 事件 -export * from "./event/index"; - -// 装饰器 -export * from "./decorator/controller"; -export * from "./decorator/cache"; -export * from "./decorator/event"; -export * from "./decorator/transaction"; -export * from "./decorator/tag"; -export * from "./decorator/index"; - -// rest -export * from "./rest/eps"; - -// tag -export * from "./tag/data"; - -// 模块 -export * from "./module/config"; -export * from "./module/import"; -export * from "./module/menu"; - -// 其他 -export * from "./interface"; -export * from "./util/func"; -export * from "./constant/global"; diff --git a/core/src/interface.ts b/core/src/interface.ts deleted file mode 100644 index 64ab288..0000000 --- a/core/src/interface.ts +++ /dev/null @@ -1,447 +0,0 @@ -import { MiddlewareParamArray } from "@midwayjs/core"; -import { AedesOptions } from "aedes"; -// @ts-ignore -import { PublishPacket } from "packet"; - -/** - * 模块配置 - */ -export interface ModuleConfig { - /** 名称 */ - name: string; - /** 描述 */ - description: string; - /** 模块中间件 */ - middlewares?: MiddlewareParamArray; - /** 全局中间件 */ - globalMiddlewares?: MiddlewareParamArray; - /** 模块加载顺序,默认为0,值越大越优先加载 */ - order?: number; -} - -export interface CoolConfig { - /** 短信 */ - sms?: CoolSmsConfig; - /** 是否自动导入数据库 */ - initDB?: boolean; - /** Eps */ - eps?: boolean; - /** 是否自动导入模块菜单 */ - initMenu?: boolean; - /** 判断是否初始化的方式 */ - initJudge: "file" | "db"; - // 实体配置 - // entity?: { - // primaryType: "uuid" | "increment" | "rowid" | "identity"; - // }; - /** crud配置 */ - crud?: { - /** 软删除 */ - softDelete: boolean; - /** 分页查询每页条数 */ - pageSize: number; - /** 插入方式 */ - upsert: "normal" | "save"; - // 多租户 - // tenant: boolean; - }; - /** elasticsearch配置 */ - es?: { - nodes: string[]; - options?: any; - }; - /** pay */ - pay?: { - /** 微信支付 */ - wx?: CoolWxPayConfig; - /** 支付宝支付 */ - ali?: CoolAliPayConfig; - }; - /** rpc */ - rpc?: CoolRpcConfig; - /** redis */ - redis?: RedisConfig | RedisConfig[]; - /** 文件上传 */ - file?: { - /** 上传模式 */ - mode: MODETYPE; - /** 本地上传 文件地址前缀 */ - domain?: string; - /** oss */ - oss?: OSSConfig; - /** cos */ - cos?: COSConfig; - /** qiniu */ - qiniu?: QINIUConfig; - /** aws */ - aws: AWSConfig; - }; - /** IOT 配置 */ - iot?: CoolIotConfig; -} - -export interface CoolRpcConfig { - /** 服务名称 */ - name: string; - /** redis */ - redis: RedisConfig & RedisConfig[] & unknown; -} - -export interface RedisConfig { - /** host */ - host: string; - /** password */ - password: string; - /** port */ - port: number; - /** db */ - db: number; -} - -// 模式 -export enum MODETYPE { - /** 本地 */ - LOCAL = "local", - /** 云存储 */ - CLOUD = "cloud", - /** 其他 */ - OTHER = "other", -} - -export enum CLOUDTYPE { - /** 阿里云存储 */ - OSS = "oss", - /** 腾讯云存储 */ - COS = "cos", - /** 七牛云存储 */ - QINIU = "qiniu", - /** AWS S3 */ - AWS = "aws", -} - -/** - * 上传模式 - */ -export interface Mode { - /** 模式 */ - mode: MODETYPE; - /** 类型 */ - type: string; -} - -/** - * 模块配置 - */ -export interface CoolFileConfig { - /** 上传模式 */ - mode: MODETYPE; - /** 阿里云oss 配置 */ - oss: OSSConfig; - /** 腾讯云 cos配置 */ - cos: COSConfig; - /** 七牛云 配置 */ - qiniu: QINIUConfig; - /** AWS s3 配置 */ - aws: AWSConfig; - /** 文件前缀 */ - domain: string; -} - -/** - * OSS 配置 - */ -export interface OSSConfig { - /** 阿里云accessKeyId */ - accessKeyId: string; - /** 阿里云accessKeySecret */ - accessKeySecret: string; - /** 阿里云oss的bucket */ - bucket: string; - /** 阿里云oss的endpoint */ - endpoint: string; - /** 阿里云oss的timeout */ - timeout: string; - /** 签名失效时间,毫秒 */ - expAfter?: number; - /** 文件最大的 size */ - maxSize?: number; - // host - host?: string; - // 阿里云oss的公网访问地址 - publicDomain?: string; -} - -/** - * COS 配置 - */ -export interface COSConfig { - /** 腾讯云accessKeyId */ - accessKeyId: string; - /** 腾讯云accessKeySecret */ - accessKeySecret: string; - /** 腾讯云cos的bucket */ - bucket: string; - /** 腾讯云cos的区域 */ - region: string; - /** 腾讯云cos的公网访问地址 */ - publicDomain: string; - /** 上传持续时间 */ - durationSeconds?: number; - /** 允许操作(上传)的对象前缀 */ - allowPrefix?: string; - /** 密钥的权限列表 */ - allowActions?: string[]; -} - -export interface QINIUConfig { - /** 七牛云accessKeyId */ - accessKeyId: string; - /** 七牛云accessKeySecret */ - accessKeySecret: string; - /** 七牛云cos的bucket */ - bucket: string; - /** 七牛云cos的区域 */ - region: string; - /** 七牛云cos的公网访问地址 */ - publicDomain: string; - /** 上传地址 */ - uploadUrl?: string; - /** 上传fileKey */ - fileKey?: string; -} - -export interface AWSConfig { - /** accessKeyId */ - accessKeyId: string; - /** secretAccessKey */ - secretAccessKey: string; - /** bucket */ - bucket: string; - /** region */ - region: string; - /** fields */ - fields?: any; - /** conditions */ - conditions?: any[]; - /** expires */ - expires?: number; - /** publicDomain */ - publicDomain?: string; - /** forcePathStyle */ - forcePathStyle?: boolean; -} - -/** - * 微信支付配置 - */ -export interface CoolWxPayConfig { - /** 直连商户申请的公众号或移动应用appid。 */ - appid: string; - /** 商户号 */ - mchid: string; - /** 可选参数 证书序列号 */ - serial_no?: string; - /** 回调链接 */ - notify_url: string; - /** 公钥 */ - publicKey: Buffer; - /** 私钥 */ - privateKey: Buffer; - /** 可选参数 认证类型,目前为WECHATPAY2-SHA256-RSA2048 */ - authType?: string; - /** 可选参数 User-Agent */ - userAgent?: string; - /** 可选参数 APIv3密钥 */ - key?: string; -} - -/** - * 支付宝支付配置 - */ -export interface CoolAliPayConfig { - /** 支付回调地址 */ - notifyUrl: string; - /** 应用ID */ - appId: string; - /** - * 应用私钥字符串 - * RSA签名验签工具:https://docs.open.alipay.com/291/106097) - * 密钥格式一栏请选择 “PKCS1(非JAVA适用)” - */ - privateKey: string; - /** 签名类型 */ - signType?: "RSA2" | "RSA"; - /** 支付宝公钥(需要对返回值做验签时候必填) */ - alipayPublicKey?: string; - /** 网关 */ - gateway?: string; - /** 网关超时时间(单位毫秒,默认 5s) */ - timeout?: number; - /** 是否把网关返回的下划线 key 转换为驼峰写法 */ - camelcase?: boolean; - /** 编码(只支持 utf-8) */ - charset?: "utf-8"; - /** api版本 */ - version?: "1.0"; - urllib?: any; - /** 指定private key类型, 默认: PKCS1, PKCS8: PRIVATE KEY, PKCS1: RSA PRIVATE KEY */ - keyType?: "PKCS1" | "PKCS8"; - /** 应用公钥证书文件路径 */ - appCertPath?: string; - /** 应用公钥证书文件内容 */ - appCertContent?: string | Buffer; - /** 应用公钥证书sn */ - appCertSn?: string; - /** 支付宝根证书文件路径 */ - alipayRootCertPath?: string; - /** 支付宝根证书文件内容 */ - alipayRootCertContent?: string | Buffer; - /** 支付宝根证书sn */ - alipayRootCertSn?: string; - /** 支付宝公钥证书文件路径 */ - alipayPublicCertPath?: string; - /** 支付宝公钥证书文件内容 */ - alipayPublicCertContent?: string | Buffer; - /** 支付宝公钥证书sn */ - alipayCertSn?: string; - /** AES密钥,调用AES加解密相关接口时需要 */ - encryptKey?: string; - /** 服务器地址 */ - wsServiceUrl?: string; -} - -/** - * IOT配置 - */ -export interface CoolIotConfig { - /** MQTT服务端口 */ - port: number; - /** MQTT Websocket服务端口 */ - wsPort: number; - /** redis 配置 mqtt cluster下必须要配置 */ - redis?: { - /** host */ - host: string; - /** port */ - port: number; - /** password */ - password: string; - /** db */ - db: number; - }; - /** 发布消息配置 */ - publish?: PublishPacket; - /** 认证 */ - auth?: { - /** 用户 */ - username: string; - /** 密码 */ - password: string; - }; - /** 服务配置 */ - serve?: AedesOptions; -} - -export interface CoolSmsConfig { - /** - * 阿里云短信配置 - */ - ali: CoolSmsAliConfig; - /** - * 腾讯云短信配置 - */ - tx: CoolSmsTxConfig; - /** - * 云片短信配置 - */ - yp: CoolSmsYpConfig; - /** - * aws短信配置 - */ - aws: CoolSmsAwsConfig; -} - -export interface CoolSmsAwsConfig { - /** - * 区域 - */ - region: string; - /** - * accessKeyId - */ - accessKeyId: string; - /** - * secretAccessKey - */ - secretAccessKey: string; - /** - * 扩展配置 - */ - extend?: any; -} - -/** - * 阿里云配置 - */ -export interface CoolSmsAliConfig { - /** - * 阿里云accessKeyId - */ - accessKeyId: string; - /** - * 阿里云accessKeySecret - */ - accessKeySecret: string; - /** - * 签名,非必填,调用时可以传入 - */ - signName?: string; - /** - * 模板,非必填,调用时可以传入 - */ - template?: string; -} - -/** - * 腾讯云配置 - */ -export interface CoolSmsTxConfig { - /** - * 应用ID - */ - appId: string; - /** - * 腾讯云secretId - */ - secretId: string; - /** - * 腾讯云secretKey - */ - secretKey: string; - /** - * 签名,非必填,调用时可以传入 - */ - signName?: string; - /** - * 模板,非必填,调用时可以传入 - */ - template?: string; -} - -/** - * 云片短信配置 - */ -export interface CoolSmsYpConfig { - /** - * 云片apikey - */ - apikey: string; - /** - * 签名,非必填,调用时可以传入 - */ - signName?: string; - /** - * 模板,非必填,调用时可以传入 - */ - template?: string; -} diff --git a/core/src/module/config.ts b/core/src/module/config.ts deleted file mode 100644 index 3f579ef..0000000 --- a/core/src/module/config.ts +++ /dev/null @@ -1,100 +0,0 @@ -import { IMidwayApplication } from "@midwayjs/core"; -import { - ALL, - App, - Config, - Init, - Provide, - Scope, - ScopeEnum, -} from "@midwayjs/decorator"; -import * as fs from "fs"; -import { CoolCoreException } from "../exception/core"; -import { ModuleConfig } from "../interface"; -import * as _ from "lodash"; - -/** - * 模块配置 - */ -@Provide() -@Scope(ScopeEnum.Singleton) -export class CoolModuleConfig { - @App() - app: IMidwayApplication; - - @Config(ALL) - allConfig; - - modules; - - @Init() - async init() { - let modules = []; - // 模块路径 - const moduleBasePath = `${this.app.getBaseDir()}/modules/`; - if (!fs.existsSync(moduleBasePath)) { - return; - } - if (!this.allConfig["module"]) { - this.allConfig["module"] = {}; - } - // 全局中间件 - const globalMiddlewareArr = []; - for (const module of fs.readdirSync(moduleBasePath)) { - const modulePath = `${moduleBasePath}/${module}`; - const dirStats = fs.statSync(modulePath); - if (dirStats.isDirectory()) { - const configPath = fs.existsSync(`${modulePath}/config.ts`) - ? `${modulePath}/config.ts` - : `${modulePath}/config.js`; - if (fs.existsSync(configPath)) { - const moduleConfig: ModuleConfig = require(configPath).default({ - app: this.app, - env: this.app.getEnv(), - }); - modules.push({ - order: moduleConfig.order || 0, - module: module, - }); - await this.moduleConfig(module, moduleConfig); - // 处理全局中间件 - if (!_.isEmpty(moduleConfig.globalMiddlewares)) { - globalMiddlewareArr.push({ - order: moduleConfig.order || 0, - data: moduleConfig.globalMiddlewares, - }); - } - } else { - throw new CoolCoreException(`模块【${module}】缺少config.ts配置文件`); - } - } - } - this.modules = _.orderBy(modules, ["order"], ["desc"]).map((e) => { - return e.module; - }); - await this.globalMiddlewareArr(globalMiddlewareArr); - } - - /** - * 模块配置 - * @param module 模块 - * @param config 配置 - */ - async moduleConfig(module, config) { - // 追加配置 - this.allConfig["module"][module] = config; - } - - /** - * 全局中间件 - * @param middleware 中间件 - */ - async globalMiddlewareArr(middlewares: any[]) { - middlewares = _.orderBy(middlewares, ["order"], ["desc"]); - for (const middleware of middlewares) { - for (const item of middleware.data) { - this.app.getMiddleware().insertLast(item); - } - } - } -} diff --git a/core/src/module/import.ts b/core/src/module/import.ts deleted file mode 100644 index 1295aae..0000000 --- a/core/src/module/import.ts +++ /dev/null @@ -1,260 +0,0 @@ -import { ILogger, IMidwayApplication, Scope, ScopeEnum } from "@midwayjs/core"; -import { App, Config, Inject, Logger, Provide } from "@midwayjs/decorator"; -import { InjectDataSource, TypeORMDataSourceManager } from "@midwayjs/typeorm"; -import * as fs from "fs"; -import * as _ from "lodash"; -import * as path from "path"; -import { DataSource, Equal } from "typeorm"; -import { CoolEventManager } from "../event"; -import { CoolModuleConfig } from "./config"; -import { CoolModuleMenu } from "./menu"; - -/** - * 模块sql - */ -@Provide() -@Scope(ScopeEnum.Singleton) -export class CoolModuleImport { - @Config("typeorm.dataSource") - ormConfig; - - @InjectDataSource("default") - defaultDataSource: DataSource; - - @Inject() - typeORMDataSourceManager: TypeORMDataSourceManager; - - @Config("cool") - coolConfig; - - @Logger() - coreLogger: ILogger; - - @Inject() - coolModuleConfig: CoolModuleConfig; - - @Inject() - coolEventManager: CoolEventManager; - - @App() - app: IMidwayApplication; - - @Inject() - coolModuleMenu: CoolModuleMenu; - - initJudge: "file" | "db"; - - /** - * 初始化 - */ - async init() { - this.initJudge = this.coolConfig.initJudge; - if (!this.initJudge) { - this.initJudge = "file"; - } - // 是否需要导入 - if (this.coolConfig.initDB) { - const modules = this.coolModuleConfig.modules; - const metadatas = await this.getDbMetadatas(); - setTimeout(async () => { - for (const module of modules) { - if (this.initJudge == "file") { - const { exist, lockPath } = this.checkFileExist(module); - if (!exist) { - await this.initDataBase(module, metadatas, lockPath); - } - } - if (this.initJudge == "db") { - const exist = await this.checkDbExist(module, metadatas); - if (!exist) { - await this.initDataBase(module, metadatas); - } - } - } - this.coolEventManager.emit("onDBInit", {}); - this.coolModuleMenu.init(); - }, 2000); - } - } - - /** - * 获取数据库元数据 - */ - async getDbMetadatas() { - // 获得所有的实体 - const entityMetadatas = this.defaultDataSource.entityMetadatas; - const metadatas = _.mapValues( - _.keyBy(entityMetadatas, "tableName"), - "target" - ); - return metadatas; - } - - /** - * 检查数据是否存在 - * @param module - * @param metadatas - */ - async checkDbExist(module: string, metadatas) { - const cKey = `init_db_${module}`; - const repository = this.defaultDataSource.getRepository( - metadatas["base_sys_conf"] - ); - const data = await repository.findOneBy({ cKey: Equal(cKey) }); - return !!data; - } - - /** - * 检查文件是否存在 - * @param module - */ - checkFileExist(module: string) { - const importLockPath = path.join( - `${this.app.getBaseDir()}`, - "..", - "lock", - "db" - ); - if (!fs.existsSync(importLockPath)) { - fs.mkdirSync(importLockPath, { recursive: true }); - } - const lockPath = path.join(importLockPath, module + ".db.lock"); - return { - exist: fs.existsSync(lockPath), - lockPath, - }; - } - - /** - * 导入数据库 - * @param module - * @param lockPath 锁定导入 - */ - async initDataBase(module: string, metadatas, lockPath?: string) { - // 计算耗时 - const startTime = new Date().getTime(); - // 模块路径 - const modulePath = `${this.app.getBaseDir()}/modules/${module}`; - // 数据路径 - const dataPath = `${modulePath}/db.json`; - // 判断文件是否存在 - if (fs.existsSync(dataPath)) { - // 读取数据 - const data = JSON.parse(fs.readFileSync(dataPath).toString() || "{}"); - // 导入数据 - for (const key in data) { - try { - for (const item of data[key]) { - await this.importData(metadatas, item, key); - } - } catch (e) { - this.coreLogger.error( - "\x1B[36m [cool:core] midwayjs cool core init " + - module + - " database err \x1B[0m" - ); - continue; - } - } - const endTime = new Date().getTime(); - await this.lockImportData( - module, - metadatas, - lockPath, - endTime - startTime - ); - this.coreLogger.info( - "\x1B[36m [cool:core] midwayjs cool core init " + - module + - " database complete \x1B[0m" - ); - } - } - - /** - * 锁定导入 - * @param module - * @param metadatas - * @param lockPath - * @param time - */ - async lockImportData( - module: string, - metadatas, - lockPath: string, - time: number - ) { - if (this.initJudge == "file") { - fs.writeFileSync(lockPath, `time consuming:${time}ms`); - } - if (this.initJudge == "db") { - const repository = this.defaultDataSource.getRepository( - metadatas["base_sys_conf"] - ); - if (this.ormConfig.default.type == "postgres") { - await repository.save( - repository.create({ - cKey: `init_db_${module}`, - cValue: `time consuming:${time}ms`, - }) - ); - } else { - await repository.insert({ - cKey: `init_db_${module}`, - cValue: `time consuming:${time}ms`, - }); - } - } - } - - /** - * 导入数据 - * @param metadatas - * @param datas - * @param tableName - */ - async importData( - metadatas: any[], - item: any, - tableName: string, - parentItem: any = null - ) { - const repository = this.defaultDataSource.getRepository( - metadatas[tableName] - ); - // 处理当前项中的引用 - if (parentItem) { - for (const key in item) { - if (typeof item[key] === "string" && item[key].startsWith("@")) { - const parentKey = item[key].substring(1); // 移除"@"符号 - if (parentItem.hasOwnProperty(parentKey)) { - item[key] = parentItem[parentKey]; - } - } - } - } - // 插入当前项到数据库 - let insertedItem; - if (this.ormConfig.default.type == "postgres") { - insertedItem = await repository.save(repository.create(item)); - if (item.id) { - await repository.update(insertedItem.id, { id: item.id }); - await this.defaultDataSource.query( - `SELECT setval('${tableName}_id_seq', (SELECT MAX(id) FROM ${tableName}));` - ); - } - } else { - insertedItem = await repository.insert(item); - } - // 递归处理@childDatas - if (!_.isEmpty(item["@childDatas"])) { - const childDatas = item["@childDatas"]; - delete item["@childDatas"]; - for (const childKey in childDatas) { - for (const childItem of childDatas[childKey]) { - await this.importData(metadatas, childItem, childKey, item); - } - } - } - } -} diff --git a/core/src/module/menu.ts b/core/src/module/menu.ts deleted file mode 100644 index 2370a54..0000000 --- a/core/src/module/menu.ts +++ /dev/null @@ -1,186 +0,0 @@ -import { - App, - Config, - ILogger, - IMidwayApplication, - Inject, - Logger, - Provide, - Scope, - ScopeEnum, -} from "@midwayjs/core"; -import { InjectDataSource, TypeORMDataSourceManager } from "@midwayjs/typeorm"; -import * as fs from "fs"; -import * as _ from "lodash"; -import * as path from "path"; -import { DataSource, Equal } from "typeorm"; -import { CoolEventManager } from "../event"; -import { CoolConfig } from "../interface"; -import { CoolModuleConfig } from "./config"; - -/** - * 菜单 - */ -@Provide() -@Scope(ScopeEnum.Singleton) -export class CoolModuleMenu { - @Inject() - coolModuleConfig: CoolModuleConfig; - - @Config("cool") - coolConfig: CoolConfig; - - @App() - app: IMidwayApplication; - - @Logger() - coreLogger: ILogger; - - @Inject() - coolEventManager: CoolEventManager; - - initJudge: "file" | "db"; - - @Config("typeorm.dataSource") - ormConfig; - - @InjectDataSource("default") - defaultDataSource: DataSource; - - @Inject() - typeORMDataSourceManager: TypeORMDataSourceManager; - - datas = {}; - - async init() { - this.initJudge = this.coolConfig.initJudge; - if (!this.initJudge) { - this.initJudge = "file"; - } - // 是否需要导入 - if (this.coolConfig.initMenu) { - const modules = this.coolModuleConfig.modules; - const metadatas = await this.getDbMetadatas(); - for (const module of modules) { - if (this.initJudge == "file") { - const { exist, lockPath } = this.checkFileExist(module); - if (!exist) { - await this.importMenu(module, metadatas, lockPath); - } - } - if (this.initJudge == "db") { - const exist = await this.checkDbExist(module, metadatas); - if (!exist) { - await this.importMenu(module, metadatas); - } - } - } - this.coolEventManager.emit("onMenuImport", this.datas); - } - } - - /** - * 导入菜单 - * @param module - * @param lockPath - */ - async importMenu(module: string, metadatas, lockPath?: string) { - // 模块路径 - const modulePath = `${this.app.getBaseDir()}/modules/${module}`; - // json 路径 - const menuPath = `${modulePath}/menu.json`; - // 导入 - if (fs.existsSync(menuPath)) { - const data = fs.readFileSync(menuPath); - try { - // this.coolEventManager.emit("onMenuImport", module, JSON.parse(data.toString())); - this.datas[module] = JSON.parse(data.toString()); - await this.lockImportData(module, metadatas, lockPath); - } catch (error) { - this.coreLogger.error(error); - this.coreLogger.error( - `自动初始化模块[${module}]菜单失败,请检查对应的数据结构是否正确` - ); - } - } - } - - /** - * 获取数据库元数据 - */ - async getDbMetadatas() { - // 获得所有的实体 - const entityMetadatas = this.defaultDataSource.entityMetadatas; - const metadatas = _.mapValues( - _.keyBy(entityMetadatas, "tableName"), - "target" - ); - return metadatas; - } - - /** - * 检查数据是否存在 - * @param module - * @param metadatas - */ - async checkDbExist(module: string, metadatas) { - const cKey = `init_menu_${module}`; - const repository = this.defaultDataSource.getRepository( - metadatas["base_sys_conf"] - ); - const data = await repository.findOneBy({ cKey: Equal(cKey) }); - return !!data; - } - - /** - * 检查文件是否存在 - * @param module - */ - checkFileExist(module: string) { - const importLockPath = path.join( - `${this.app.getBaseDir()}`, - "..", - "lock", - "menu" - ); - if (!fs.existsSync(importLockPath)) { - fs.mkdirSync(importLockPath, { recursive: true }); - } - const lockPath = path.join(importLockPath, module + ".menu.lock"); - return { - exist: fs.existsSync(lockPath), - lockPath, - }; - } - - /** - * 锁定导入 - * @param module - * @param metadatas - * @param lockPath - * @param time - */ - async lockImportData(module: string, metadatas, lockPath: string) { - if (this.initJudge == "file") { - fs.writeFileSync(lockPath, `success`); - } - if (this.initJudge == "db") { - const repository = this.defaultDataSource.getRepository( - metadatas["base_sys_conf"] - ); - if (this.ormConfig.default.type == "postgres") { - await repository.save( - repository.create({ - cKey: `init_menu_${module}`, - cValue: `success`, - }) - ); - } else { - await repository.insert({ - cKey: `init_menu_${module}`, - cValue: `success`, - }); - } - } - } -} diff --git a/core/src/package.json b/core/src/package.json deleted file mode 100644 index 8e59e6a..0000000 --- a/core/src/package.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "name": "@cool-midway/core", - "version": "7.1.25", - "description": "", - "main": "index.js", - "typings": "index.d.ts", - "scripts": { - "build": "cross-env midway-bin build -c", - "cov": "cross-env midway-bin cov --ts", - "lint": "mwts check", - "lint:fix": "mwts fix" - }, - "keywords": [ - "cool", - "cool-admin", - "cooljs" - ], - "readme": "README.md", - "author": "COOL", - "files": [ - "**/*.js", - "**/*.d.ts", - "index.d.ts" - ], - "license": "MIT", - "repository": { - "type": "git", - "url": "https://cool-js.com" - }, - "devDependencies": { - "@midwayjs/cli": "1.3.21", - "@midwayjs/core": "^3.9.0", - "@midwayjs/decorator": "^3.9.0", - "@midwayjs/koa": "^3.9.0", - "@midwayjs/mock": "^3.9.0", - "@midwayjs/typeorm": "^3.9.0", - "@types/jest": "^29.2.4", - "@types/node": "^18.11.15", - "cross-env": "^7.0.3", - "jest": "^29.3.1", - "mwts": "^1.3.0", - "ts-jest": "^29.0.3", - "typeorm": "^0.3.19", - "typescript": "~4.9.4" - }, - "dependencies": { - "@midwayjs/cache": "^3.14.0", - "@midwayjs/cache-manager": "^3.15.0", - "@cool-midway/cache-manager-fs-hash": "^7.0.0", - "axios": "^1.6.5", - "decompress": "^4.2.1", - "download": "^8.0.0", - "jsonwebtoken": "^9.0.2", - "lodash": "^4.17.21", - "md5": "^2.3.0", - "moment": "^2.30.1", - "sqlstring": "^2.3.3", - "uuid": "^9.0.1", - "ws": "^8.16.0", - "pm2": "^5.3.1" - } -} \ No newline at end of file diff --git a/core/src/rest/eps.ts b/core/src/rest/eps.ts deleted file mode 100644 index 26c9694..0000000 --- a/core/src/rest/eps.ts +++ /dev/null @@ -1,169 +0,0 @@ -import { - CONTROLLER_KEY, - getClassMetadata, - listModule, - Provide, -} from "@midwayjs/decorator"; -import * as _ from "lodash"; -import { - Scope, - ScopeEnum, - Config, - Inject, - MidwayWebRouterService, -} from "@midwayjs/core"; -import { TypeORMDataSourceManager } from "@midwayjs/typeorm"; -import { CoolUrlTagData } from "../tag/data"; -import { TagTypes } from "../decorator/tag"; - -/** - * 实体路径 - */ -@Provide() -@Scope(ScopeEnum.Singleton) -export class CoolEps { - admin = {}; - - app = {}; - - module = {}; - - @Inject() - midwayWebRouterService: MidwayWebRouterService; - - @Inject() - typeORMDataSourceManager: TypeORMDataSourceManager; - - @Config("cool.eps") - epsConfig: boolean; - - @Config("module") - moduleConfig: any; - - @Inject() - coolUrlTagData: CoolUrlTagData; - - // @Init() - async init() { - if (!this.epsConfig) return; - const entitys = await this.entity(); - const controllers = await this.controller(); - const routers = await this.router(); - await this.modules(); - const adminArr = []; - const appArr = []; - for (const controller of controllers) { - const { prefix, module, curdOption, routerOptions } = controller; - const name = curdOption?.entity?.name; - (_.startsWith(prefix, "/admin/") ? adminArr : appArr).push({ - module, - info: { - type: { - name: prefix.split("/").pop(), - description: routerOptions?.description || "", - }, - }, - api: routers[prefix], - name, - columns: entitys[name] || [], - prefix, - }); - } - this.admin = _.groupBy(adminArr, "module"); - this.app = _.groupBy(appArr, "module"); - } - - /** - * 模块信息 - * @param module - */ - async modules(module?: string) { - for (const key in this.moduleConfig) { - const config = this.moduleConfig[key]; - this.module[key] = { - name: config.name, - description: config.description, - }; - } - return module ? this.module[module] : this.module; - } - - /** - * 所有controller - * @returns - */ - async controller() { - const result = []; - const controllers = listModule(CONTROLLER_KEY); - for (const controller of controllers) { - result.push(getClassMetadata(CONTROLLER_KEY, controller)); - } - return result; - } - - /** - * 所有路由 - * @returns - */ - async router() { - let ignoreUrls: string[] = this.coolUrlTagData.byKey(TagTypes.IGNORE_TOKEN); - if (_.isEmpty(ignoreUrls)) { - ignoreUrls = []; - } - return _.groupBy( - (await this.midwayWebRouterService.getFlattenRouterTable()).map( - (item) => { - return { - method: item.requestMethod, - path: item.url, - summary: item.summary, - dts: {}, - tag: "", - prefix: item.prefix, - ignoreToken: ignoreUrls.includes(item.prefix + item.url), - }; - } - ), - "prefix" - ); - } - - /** - * 所有实体 - * @returns - */ - async entity() { - const result = {}; - const dataSourceNames = this.typeORMDataSourceManager.getDataSourceNames(); - for (const dataSourceName of dataSourceNames) { - const entityMetadatas = await this.typeORMDataSourceManager.getDataSource( - dataSourceName - ).entityMetadatas; - for (const entityMetadata of entityMetadatas) { - const commColums = []; - let columns = entityMetadata.columns; - if (entityMetadata.tableType != "regular") continue; - columns = _.filter( - columns.map((e) => { - return { - propertyName: e.propertyName, - type: - typeof e.type == "string" ? e.type : e.type.name.toLowerCase(), - length: e.length, - comment: e.comment, - nullable: e.isNullable, - }; - }), - (o) => { - if (["createTime", "updateTime"].includes(o.propertyName)) { - commColums.push(o); - } - return o && !["createTime", "updateTime"].includes(o.propertyName); - } - ).concat(commColums); - result[entityMetadata.name] = columns; - } - } - return result; - } -} diff --git a/core/src/service/base.ts b/core/src/service/base.ts deleted file mode 100644 index d1534e6..0000000 --- a/core/src/service/base.ts +++ /dev/null @@ -1,287 +0,0 @@ -import { App, Config, Init, Inject, Provide } from "@midwayjs/decorator"; -import { Scope, ScopeEnum } from "@midwayjs/core"; -import { BaseMysqlService } from "./mysql"; -import { BasePgService } from "./postgres"; -import { CoolValidateException } from "../exception/validate"; -import { ERRINFO } from "../constant/global"; -import { Application, Context } from "@midwayjs/koa"; -import { TypeORMDataSourceManager } from "@midwayjs/typeorm"; -import { Repository, SelectQueryBuilder } from "typeorm"; -import { QueryOp } from "../decorator/controller"; -import * as _ from "lodash"; -import { CoolEventManager } from "../event"; -import { CoolCoreException } from "../exception/core"; -import { BaseSqliteService } from "./sqlite"; - -/** - * 服务基类 - */ -@Provide() -@Scope(ScopeEnum.Request, { allowDowngrade: true }) -export abstract class BaseService { - // mysql的基类 - @Inject() - baseMysqlService: BaseMysqlService; - - // postgres的基类 - @Inject() - basePgService: BasePgService; - - @Inject() - baseSqliteService: BaseSqliteService; - - // 数据库类型 - @Config("typeorm.dataSource.default.type") - ormType; - - // 当前服务名称 - service: BaseMysqlService | BasePgService | BaseSqliteService; - - // 模型 - protected entity: Repository; - - protected sqlParams; - - @Inject() - typeORMDataSourceManager: TypeORMDataSourceManager; - - @Inject() - coolEventManager: CoolEventManager; - - @Inject("ctx") - baseCtx: Context; - - @App() - baseApp: Application; - - @Init() - async init() { - const services = { - mysql: this.baseMysqlService, - mariadb: this.baseMysqlService, - postgres: this.basePgService, - sqlite: this.baseSqliteService, - }; - this.service = services[this.ormType]; - if (!this.service) throw new CoolCoreException("暂不支持当前数据库类型"); - this.sqlParams = this.service.sqlParams; - await this.service.init(); - } - - // 设置模型 - setEntity(entity: any) { - this.entity = entity; - this.service.setEntity(entity); - } - - // 设置请求上下文 - setCtx(ctx: Context) { - this.baseCtx = ctx; - this.service.setCtx(ctx); - } - - // 设置应用对象 - setApp(app: Application) { - this.baseApp = app; - this.service.setApp(app); - } - - /** - * 设置sql - * @param condition 条件是否成立 - * @param sql sql语句 - * @param params 参数 - */ - setSql(condition, sql, params) { - return this.service.setSql(condition, sql, params); - } - - /** - * 获得查询个数的SQL - * @param sql - */ - getCountSql(sql) { - return this.service.getCountSql(sql); - } - - /** - * 参数安全性检查 - * @param params - */ - async paramSafetyCheck(params) { - return await this.service.paramSafetyCheck(params); - } - - /** - * 原生查询 - * @param sql - * @param params - * @param connectionName - */ - async nativeQuery(sql, params?, connectionName?) { - return await this.service.nativeQuery(sql, params, connectionName); - } - - /** - * 获得ORM管理 - * @param connectionName 连接名称 - */ - getOrmManager(connectionName = "default") { - return this.service.getOrmManager(connectionName); - } - - /** - * 操作entity获得分页数据,不用写sql - * @param find QueryBuilder - * @param query - * @param autoSort - * @param connectionName - */ - async entityRenderPage( - find: SelectQueryBuilder, - query, - autoSort = true - ) { - return await this.service.entityRenderPage(find, query, autoSort); - } - - /** - * 执行SQL并获得分页数据 - * @param sql 执行的sql语句 - * @param query 分页查询条件 - * @param autoSort 是否自动排序 - * @param connectionName 连接名称 - */ - async sqlRenderPage(sql, query, autoSort = true, connectionName?) { - return await this.service.sqlRenderPage( - sql, - query, - autoSort, - connectionName - ); - } - - /** - * 获得单个ID - * @param id ID - * @param infoIgnoreProperty 忽略返回属性 - */ - async info(id: any, infoIgnoreProperty?: string[]) { - this.service.setEntity(this.entity); - return await this.service.info(id, infoIgnoreProperty); - } - - /** - * 删除 - * @param ids 删除的ID集合 如:[1,2,3] 或者 1,2,3 - */ - async delete(ids: any) { - this.service.setEntity(this.entity); - await this.modifyBefore(ids, "delete"); - await this.service.delete(ids); - await this.modifyAfter(ids, "delete"); - } - - /** - * 软删除 - * @param ids 删除的ID数组 - * @param entity 实体 - */ - async softDelete(ids: number[], entity?: Repository) { - this.service.setEntity(this.entity); - await this.service.softDelete(ids, entity); - } - - /** - * 修改 - * @param param 数据 - */ - async update(param: any) { - this.service.setEntity(this.entity); - if (!this.entity) throw new CoolValidateException(ERRINFO.NOENTITY); - if (!param.id && !(param instanceof Array)) - throw new CoolValidateException(ERRINFO.NOID); - await this.addOrUpdate(param, "update"); - } - - /** - * 新增 - * @param param 数据 - */ - async add(param: any | any[]): Promise { - if (!this.entity) throw new CoolValidateException(ERRINFO.NOENTITY); - delete param.id; - await this.addOrUpdate(param, "add"); - return { - id: - param instanceof Array - ? param.map((e) => { - return e.id ? e.id : e._id; - }) - : param.id - ? param.id - : param._id, - }; - } - - /** - * 新增|修改 - * @param param 数据 - */ - async addOrUpdate(param: any | any[], type: "add" | "update" = "add") { - this.service.setEntity(this.entity); - await this.modifyBefore(param, type); - await this.service.addOrUpdate(param, type); - await this.modifyAfter(param, type); - } - - /** - * 非分页查询 - * @param query 查询条件 - * @param option 查询配置 - * @param connectionName 连接名 - */ - async list(query, option, connectionName?): Promise { - this.service.setEntity(this.entity); - return await this.service.list(query, option, connectionName); - } - - /** - * 分页查询 - * @param query 查询条件 - * @param option 查询配置 - * @param connectionName 连接名 - */ - async page(query, option, connectionName?) { - this.service.setEntity(this.entity); - return await this.service.page(query, option, connectionName); - } - - /** - * 构建查询配置 - * @param query 前端查询 - * @param option - */ - async getOptionFind(query, option: QueryOp) { - this.service.setEntity(this.entity); - return await this.service.getOptionFind(query, option); - } - - /** - * 新增|修改|删除 之后的操作 - * @param data 对应数据 - */ - async modifyAfter( - data: any, - type: "delete" | "update" | "add" - ): Promise {} - - /** - * 新增|修改|删除 之前的操作 - * @param data 对应数据 - */ - async modifyBefore( - data: any, - type: "delete" | "update" | "add" - ): Promise {} -} diff --git a/core/src/service/mysql.ts b/core/src/service/mysql.ts deleted file mode 100644 index cd9764f..0000000 --- a/core/src/service/mysql.ts +++ /dev/null @@ -1,499 +0,0 @@ -import { Init, Provide, Inject, App, Config } from "@midwayjs/decorator"; -import { Scope, ScopeEnum } from "@midwayjs/core"; -import { CoolValidateException } from "../exception/validate"; -import { ERRINFO, EVENT } from "../constant/global"; -import { Application, Context } from "@midwayjs/koa"; -import * as SqlString from "sqlstring"; -import { CoolConfig } from "../interface"; -import { TypeORMDataSourceManager } from "@midwayjs/typeorm"; -import { Brackets, Equal, In, Repository, SelectQueryBuilder } from "typeorm"; -import { QueryOp } from "../decorator/controller"; -import * as _ from "lodash"; -import { CoolEventManager } from "../event"; - -/** - * 服务基类 - */ -@Provide() -@Scope(ScopeEnum.Request, { allowDowngrade: true }) -export abstract class BaseMysqlService { - // 分页配置 - @Config("cool") - private _coolConfig: CoolConfig; - - // 模型 - entity: Repository; - - sqlParams; - - @Inject() - typeORMDataSourceManager: TypeORMDataSourceManager; - - @Inject() - coolEventManager: CoolEventManager; - - // 设置模型 - setEntity(entity: any) { - this.entity = entity; - } - - // 设置请求上下文 - setCtx(ctx: Context) { - this.baseCtx = ctx; - } - - @App() - baseApp: Application; - - // 设置应用对象 - setApp(app: Application) { - this.baseApp = app; - } - - @Inject("ctx") - baseCtx: Context; - - // 初始化 - @Init() - init() { - this.sqlParams = []; - } - - /** - * 设置sql - * @param condition 条件是否成立 - * @param sql sql语句 - * @param params 参数 - */ - setSql(condition, sql, params) { - let rSql = false; - if (condition || condition === 0) { - rSql = true; - this.sqlParams = this.sqlParams.concat(params); - } - return rSql ? sql : ""; - } - - /** - * 获得查询个数的SQL - * @param sql - */ - getCountSql(sql) { - sql = sql - .replace(new RegExp("LIMIT", "gm"), "limit ") - .replace(new RegExp("\n", "gm"), " "); - if (sql.includes("limit")) { - const sqlArr = sql.split("limit "); - sqlArr.pop(); - sql = sqlArr.join("limit "); - } - return `select count(*) as count from (${sql}) a`; - } - - /** - * 参数安全性检查 - * @param params - */ - async paramSafetyCheck(params) { - const lp = params.toLowerCase(); - return !( - lp.indexOf("update ") > -1 || - lp.indexOf("select ") > -1 || - lp.indexOf("delete ") > -1 || - lp.indexOf("insert ") > -1 - ); - } - - /** - * 原生查询 - * @param sql - * @param params - * @param connectionName - */ - async nativeQuery(sql, params?, connectionName?) { - if (_.isEmpty(params)) { - params = this.sqlParams; - } - let newParams = []; - newParams = newParams.concat(params); - this.sqlParams = []; - for (const param of newParams) { - SqlString.escape(param); - } - return await this.getOrmManager(connectionName).query(sql, newParams || []); - } - - /** - * 获得ORM管理 - * @param connectionName 连接名称 - */ - getOrmManager(connectionName = "default") { - return this.typeORMDataSourceManager.getDataSource(connectionName); - } - - /** - * 操作entity获得分页数据,不用写sql - * @param find QueryBuilder - * @param query - * @param autoSort - * @param connectionName - */ - async entityRenderPage( - find: SelectQueryBuilder, - query, - autoSort = true - ) { - const { - size = this._coolConfig.crud.pageSize, - page = 1, - order = "createTime", - sort = "desc", - isExport = false, - maxExportLimit, - } = query; - const count = await find.getCount(); - let dataFind: SelectQueryBuilder; - if (isExport && maxExportLimit > 0) { - dataFind = find.limit(maxExportLimit); - } else { - dataFind = find.offset((page - 1) * size).limit(size); - } - if (autoSort) { - find.addOrderBy(order, sort.toUpperCase()); - } - return { - list: await dataFind.getMany(), - pagination: { - page: parseInt(page), - size: parseInt(size), - total: count, - }, - }; - } - - /** - * 执行SQL并获得分页数据 - * @param sql 执行的sql语句 - * @param query 分页查询条件 - * @param autoSort 是否自动排序 - * @param connectionName 连接名称 - */ - async sqlRenderPage(sql, query, autoSort = true, connectionName?) { - const { - size = this._coolConfig.crud.pageSize, - page = 1, - order = "createTime", - sort = "desc", - isExport = false, - maxExportLimit, - } = query; - if (order && sort && autoSort) { - if (!(await this.paramSafetyCheck(order + sort))) { - throw new CoolValidateException("非法传参~"); - } - sql += ` ORDER BY ${SqlString.escapeId(order)} ${this.checkSort(sort)}`; - } - if (isExport && maxExportLimit > 0) { - this.sqlParams.push(parseInt(maxExportLimit)); - sql += " LIMIT ? "; - } - if (!isExport) { - this.sqlParams.push((page - 1) * size); - this.sqlParams.push(parseInt(size)); - sql += " LIMIT ?,? "; - } - - let params = []; - params = params.concat(this.sqlParams); - const result = await this.nativeQuery(sql, params, connectionName); - const countResult = await this.nativeQuery( - this.getCountSql(sql), - params, - connectionName - ); - return { - list: result, - pagination: { - page: parseInt(page), - size: parseInt(size), - total: parseInt(countResult[0] ? countResult[0].count : 0), - }, - }; - } - - /** - * 检查排序 - * @param sort 排序 - * @returns - */ - checkSort(sort) { - if (!["desc", "asc"].includes(sort.toLowerCase())) { - throw new CoolValidateException("sort 非法传参~"); - } - return sort; - } - - /** - * 获得单个ID - * @param id ID - * @param infoIgnoreProperty 忽略返回属性 - */ - async info(id: any, infoIgnoreProperty?: string[]) { - if (!this.entity) throw new CoolValidateException(ERRINFO.NOENTITY); - if (!id) { - throw new CoolValidateException(ERRINFO.NOID); - } - const info = await this.entity.findOneBy({ id: Equal(id) }); - if (info && infoIgnoreProperty) { - for (const property of infoIgnoreProperty) { - delete info[property]; - } - } - return info; - } - - /** - * 删除 - * @param ids 删除的ID集合 如:[1,2,3] 或者 1,2,3 - */ - async delete(ids: any) { - if (!this.entity) throw new CoolValidateException(ERRINFO.NOENTITY); - if (ids instanceof String) { - ids = ids.split(","); - } - // 启动软删除发送事件 - if (this._coolConfig.crud?.softDelete) { - this.softDelete(ids); - } - await this.entity.delete(ids); - } - - /** - * 软删除 - * @param ids 删除的ID数组 - * @param entity 实体 - */ - async softDelete(ids: number[], entity?: Repository) { - const data = await this.entity.find({ - where: { - id: In(ids), - }, - }); - if (_.isEmpty(data)) return; - const _entity = entity ? entity : this.entity; - const params = { - data, - ctx: this.baseCtx, - entity: _entity, - }; - if (data.length > 0) { - this.coolEventManager.emit(EVENT.SOFT_DELETE, params); - } - } - - /** - * 新增|修改 - * @param param 数据 - */ - async addOrUpdate(param: any | any[], type: "add" | "update" = "add") { - if (!this.entity) throw new CoolValidateException(ERRINFO.NOENTITY); - delete param.createTime; - // 判断是否是批量操作 - if (param instanceof Array) { - param.forEach((item) => { - item.updateTime = new Date(); - item.createTime = new Date(); - }); - await this.entity.save(param); - } else { - const upsert = this._coolConfig.crud?.upsert || "normal"; - if (type == "update") { - if (upsert == "save") { - const info = await this.entity.findOneBy({ id: param.id }); - param = { - ...info, - ...param, - }; - } - param.updateTime = new Date(); - upsert == "normal" - ? await this.entity.update(param.id, param) - : await this.entity.save(param); - } - if (type == "add") { - param.createTime = new Date(); - param.updateTime = new Date(); - upsert == "normal" - ? await this.entity.insert(param) - : await this.entity.save(param); - } - } - } - - /** - * 非分页查询 - * @param query 查询条件 - * @param option 查询配置 - * @param connectionName 连接名 - */ - async list(query, option, connectionName?): Promise { - if (!this.entity) throw new CoolValidateException(ERRINFO.NOENTITY); - const sql = await this.getOptionFind(query, option); - return this.nativeQuery(sql, [], connectionName); - } - - /** - * 分页查询 - * @param query 查询条件 - * @param option 查询配置 - * @param connectionName 连接名 - */ - async page(query, option, connectionName?) { - if (!this.entity) throw new CoolValidateException(ERRINFO.NOENTITY); - const sql = await this.getOptionFind(query, option); - return this.sqlRenderPage(sql, query, false, connectionName); - } - - /** - * 构建查询配置 - * @param query 前端查询 - * @param option - */ - async getOptionFind(query, option: QueryOp) { - let { order = "createTime", sort = "desc", keyWord = "" } = query; - const sqlArr = ["SELECT"]; - const selects = ["a.*"]; - const find = this.entity.createQueryBuilder("a"); - if (option) { - if (typeof option == "function") { - // @ts-ignore - option = await option(this.baseCtx, this.baseApp); - } - // 判断是否有关联查询,有的话取个别名 - if (!_.isEmpty(option.join)) { - for (const item of option.join) { - selects.push(`${item.alias}.*`); - find[item.type || "leftJoin"]( - item.entity, - item.alias, - item.condition - ); - } - } - // 默认条件 - if (option.where) { - const wheres = - typeof option.where == "function" - ? await option.where(this.baseCtx, this.baseApp) - : option.where; - if (!_.isEmpty(wheres)) { - for (const item of wheres) { - if ( - item.length == 2 || - (item.length == 3 && (item[2] || item[2] === 0)) - ) { - for (const key in item[1]) { - this.sqlParams.push(item[1][key]); - } - find.andWhere(item[0], item[1]); - } - } - } - } - // 附加排序 - if (!_.isEmpty(option.addOrderBy)) { - for (const key in option.addOrderBy) { - if (order && order == key) { - sort = option.addOrderBy[key].toUpperCase(); - } - find.addOrderBy( - SqlString.escapeId(key), - this.checkSort(option.addOrderBy[key].toUpperCase()) - ); - } - } - // 关键字模糊搜索 - if (keyWord || keyWord === 0) { - keyWord = `%${keyWord}%`; - find.andWhere( - new Brackets((qb) => { - const keyWordLikeFields = option.keyWordLikeFields || []; - for (let i = 0; i < option.keyWordLikeFields?.length || 0; i++) { - qb.orWhere(`${keyWordLikeFields[i]} like :keyWord`, { - keyWord, - }); - this.sqlParams.push(keyWord); - } - }) - ); - } - // 筛选字段 - if (!_.isEmpty(option.select)) { - sqlArr.push(option.select.join(",")); - find.select(option.select); - } else { - sqlArr.push(selects.join(",")); - } - // 字段全匹配 - if (!_.isEmpty(option.fieldEq)) { - for (let key of option.fieldEq) { - const c = {}; - // 如果key有包含.的情况下操作 - if (typeof key === "string" && key.includes(".")) { - const keys = key.split("."); - const lastKey = keys.pop(); - key = { requestParam: lastKey, column: key }; - } - // 单表字段无别名的情况下操作 - if (typeof key === "string") { - if (query[key] || query[key] === 0) { - c[key] = query[key]; - const eq = query[key] instanceof Array ? "in" : "="; - if (eq === "in") { - find.andWhere(`${key} ${eq} (:${key})`, c); - } else { - find.andWhere(`${key} ${eq} :${key}`, c); - } - this.sqlParams.push(query[key]); - } - } else { - if (query[key.requestParam] || query[key.requestParam] === 0) { - c[key.column] = query[key.requestParam]; - const eq = query[key.requestParam] instanceof Array ? "in" : "="; - if (eq === "in") { - find.andWhere(`${key.column} ${eq} (:${key.column})`, c); - } else { - find.andWhere(`${key.column} ${eq} :${key.column}`, c); - } - this.sqlParams.push(query[key.requestParam]); - } - } - } - } - } else { - sqlArr.push(selects.join(",")); - } - // 接口请求的排序 - if (sort && order) { - const sorts = sort.toUpperCase().split(","); - const orders = order.split(","); - if (sorts.length != orders.length) { - throw new CoolValidateException(ERRINFO.SORTFIELD); - } - for (const i in sorts) { - find.addOrderBy( - SqlString.escapeId(orders[i]), - this.checkSort(sorts[i]) - ); - } - } - if (option?.extend) { - await option?.extend(find, this.baseCtx, this.baseApp); - } - const sqls = find.getSql().split("FROM"); - sqlArr.push("FROM"); - // 取sqls的最后一个 - sqlArr.push(sqls[sqls.length - 1]); - return sqlArr.join(" "); - } -} diff --git a/core/src/service/postgres.ts b/core/src/service/postgres.ts deleted file mode 100644 index 51cd387..0000000 --- a/core/src/service/postgres.ts +++ /dev/null @@ -1,639 +0,0 @@ -import { Init, Provide, Inject, App, Config } from "@midwayjs/decorator"; -import { CoolValidateException } from "../exception/validate"; -import { ERRINFO, EVENT } from "../constant/global"; -import { Application, Context } from "@midwayjs/koa"; -import { Scope, ScopeEnum } from "@midwayjs/core"; -import { CoolConfig } from "../interface"; -import { TypeORMDataSourceManager } from "@midwayjs/typeorm"; -import { Brackets, In, Repository, SelectQueryBuilder } from "typeorm"; -import { QueryOp } from "../decorator/controller"; -import * as _ from "lodash"; -import { CoolEventManager } from "../event"; - -/** - * 服务基类 - */ -@Provide() -@Scope(ScopeEnum.Request, { allowDowngrade: true }) -export abstract class BasePgService { - // 分页配置 - @Config("cool") - private _coolConfig: CoolConfig; - - // 模型 - entity: Repository; - - sqlParams; - - @Inject() - typeORMDataSourceManager: TypeORMDataSourceManager; - - @Inject() - coolEventManager: CoolEventManager; - - // 设置模型 - setEntity(entity: any) { - this.entity = entity; - } - - // 设置请求上下文 - setCtx(ctx: Context) { - this.baseCtx = ctx; - } - - @App() - baseApp: Application; - - // 设置应用对象 - setApp(app: Application) { - this.baseApp = app; - } - - @Inject("ctx") - baseCtx: Context; - - // 初始化 - @Init() - init() { - this.sqlParams = []; - } - - /** - * 设置sql - * @param condition 条件是否成立 - * @param sql sql语句 - * @param params 参数 - */ - setSql(condition, sql, params) { - let rSql = false; - if (condition || condition === 0) { - rSql = true; - for (let i = 0; i < params.length; i++) { - const param = params[i]; - if (param instanceof Array) { - // 将这个? 替换成 $1,$2,$3 - const replaceStr = []; - for (let j = 0; j < param.length; j++) { - replaceStr.push("$" + (this.sqlParams.length + j + 1)); - } - this.sqlParams = this.sqlParams.concat(...params); - sql = sql.replace("?", replaceStr.join(",")); - } else { - sql = sql.replace("?", "$" + (this.sqlParams.length + 1)); - this.sqlParams.push(param); - } - } - } - return rSql ? sql : ""; - } - - /** - * 获得查询个数的SQL - * @param sql - */ - getCountSql(sql) { - sql = sql - .replace(new RegExp("LIMIT", "gm"), "limit ") - .replace(new RegExp("\n", "gm"), " "); - if (sql.includes("limit")) { - const sqlArr = sql.split("limit "); - sqlArr.pop(); - sql = sqlArr.join("limit "); - } - return `select count(*) as count from (${sql}) a`; - } - - /** - * 参数安全性检查 - * @param params - */ - async paramSafetyCheck(params) { - const lp = params.toLowerCase(); - return !( - lp.indexOf("update ") > -1 || - lp.indexOf("select ") > -1 || - lp.indexOf("delete ") > -1 || - lp.indexOf("insert ") > -1 - ); - } - - /** - * 原生查询 - * @param sql - * @param params - * @param connectionName - */ - async nativeQuery(sql, params?, connectionName?) { - sql = this.convertToPostgres(sql); - if (_.isEmpty(params)) { - params = this.sqlParams; - } - let newParams = []; - // sql没处理过?的情况下 - if (sql.includes("?")) { - for (const item of params) { - // 如果是数组,将这个? 替换成 $1,$2,$3 - if (item instanceof Array) { - const replaceStr = []; - for (let i = 0; i < item.length; i++) { - replaceStr.push("$" + (newParams.length + i + 1)); - } - newParams.push(...item); - sql = sql.replace("?", replaceStr.join(",")); - } else { - sql = sql.replace("?", "$" + (newParams.length + 1)); - newParams.push(item); - } - } - } else { - newParams = params; - } - this.sqlParams = []; - return await this.getOrmManager(connectionName).query(sql, newParams || []); - } - - /** - * 获得ORM管理 - * @param connectionName 连接名称 - */ - getOrmManager(connectionName = "default") { - return this.typeORMDataSourceManager.getDataSource(connectionName); - } - - /** - * 操作entity获得分页数据,不用写sql - * @param find QueryBuilder - * @param query - * @param autoSort - * @param connectionName - */ - async entityRenderPage( - find: SelectQueryBuilder, - query, - autoSort = true - ) { - const { - size = this._coolConfig.crud.pageSize, - page = 1, - order = "createTime", - sort = "desc", - isExport = false, - maxExportLimit, - } = query; - const count = await find.getCount(); - let dataFind: SelectQueryBuilder; - if (isExport && maxExportLimit > 0) { - dataFind = find.limit(maxExportLimit); - } else { - dataFind = find.offset((page - 1) * size).limit(size); - } - if (autoSort) { - find.addOrderBy(order, sort.toUpperCase()); - } - return { - list: await dataFind.getMany(), - pagination: { - page: parseInt(page), - size: parseInt(size), - total: count, - }, - }; - } - - /** - * 将mysql语句转换为postgres语句 - * @param sql - * @returns - */ - protected convertToPostgres(sql) { - // 首先确保表名被正确引用 - sql = sql.replace(/(? 0) { - this.sqlParams.push(parseInt(maxExportLimit)); - cutParams = 1; - sql += ` LIMIT $${paramCount + 1}`; - } - if (!isExport) { - this.sqlParams.push(parseInt(size)); - this.sqlParams.push((page - 1) * size); - cutParams = 2; - sql += ` LIMIT $${paramCount + 1} OFFSET $${paramCount + 2}`; - } - let params = []; - params = params.concat(this.sqlParams); - const result = await this.nativeQuery(sql, params, connectionName); - params = params.slice(0, -cutParams); - const countResult = await this.nativeQuery( - this.getCountSql(sql), - params, - connectionName - ); - return { - list: result, - pagination: { - page: parseInt(page), - size: parseInt(size), - total: parseInt(countResult[0] ? countResult[0].count : 0), - }, - }; - } - - /** - * 检查排序 - * @param sort 排序 - * @returns - */ - checkSort(sort) { - if (!["desc", "asc"].includes(sort.toLowerCase())) { - throw new CoolValidateException("sort 非法传参~"); - } - return sort; - } - - /** - * 获得单个ID - * @param id ID - * @param infoIgnoreProperty 忽略返回属性 - */ - async info(id: any, infoIgnoreProperty?: string[]) { - if (!this.entity) throw new CoolValidateException(ERRINFO.NOENTITY); - if (!id) { - throw new CoolValidateException(ERRINFO.NOID); - } - const info = await this.entity.findOneBy({ id }); - if (info && infoIgnoreProperty) { - for (const property of infoIgnoreProperty) { - delete info[property]; - } - } - return info; - } - - /** - * 删除 - * @param ids 删除的ID集合 如:[1,2,3] 或者 1,2,3 - */ - async delete(ids: any) { - if (!this.entity) throw new CoolValidateException(ERRINFO.NOENTITY); - if (ids instanceof String) { - ids = ids.split(","); - } - // 启动软删除发送事件 - if (this._coolConfig.crud?.softDelete) { - this.softDelete(ids); - } - await this.entity.delete(ids); - } - - /** - * 软删除 - * @param ids 删除的ID数组 - * @param entity 实体 - */ - async softDelete(ids: number[], entity?: Repository) { - const data = await this.entity.find({ - where: { - id: In(ids), - }, - }); - if (_.isEmpty(data)) return; - const _entity = entity ? entity : this.entity; - const params = { - data, - ctx: this.baseCtx, - entity: _entity, - }; - if (data.length > 0) { - this.coolEventManager.emit(EVENT.SOFT_DELETE, params); - } - } - - /** - * 新增|修改 - * @param param 数据 - */ - async addOrUpdate(param: any | any[], type: "add" | "update" = "add") { - if (!this.entity) throw new CoolValidateException(ERRINFO.NOENTITY); - delete param.createTime; - // 判断是否是批量操作 - if (param instanceof Array) { - param.forEach((item) => { - item.updateTime = new Date(); - item.createTime = new Date(); - }); - await this.entity.save(param); - } else { - const upsert = this._coolConfig.crud?.upsert || "normal"; - if (type == "update") { - if (upsert == "save") { - const info = await this.entity.findOneBy({ id: param.id }); - param = { - ...info, - ...param, - }; - } - param.updateTime = new Date(); - upsert == "normal" - ? await this.entity.update(param.id, param) - : await this.entity.save(param); - } - if (type == "add") { - param.createTime = new Date(); - param.updateTime = new Date(); - upsert == "normal" - ? await this.entity.insert(param) - : await this.entity.save(param); - } - } - } - - /** - * 非分页查询 - * @param query 查询条件 - * @param option 查询配置 - * @param connectionName 连接名 - */ - async list(query, option, connectionName?): Promise { - if (!this.entity) throw new CoolValidateException(ERRINFO.NOENTITY); - const sql = await this.getOptionFind(query, option); - return this.nativeQuery(sql, [], connectionName); - } - - /** - * 分页查询 - * @param query 查询条件 - * @param option 查询配置 - * @param connectionName 连接名 - */ - async page(query, option, connectionName?) { - if (!this.entity) throw new CoolValidateException(ERRINFO.NOENTITY); - const sql = await this.getOptionFind(query, option); - return this.sqlRenderPage(sql, query, false, connectionName); - } - - /** - * 构建查询配置 - * @param query 前端查询 - * @param option - */ - async getOptionFind(query, option: QueryOp) { - let { order = "createTime", sort = "desc", keyWord = "" } = query; - const sqlArr = ["SELECT"]; - const selects = ["a.*"]; - const find = this.entity.createQueryBuilder("a"); - if (option) { - if (typeof option == "function") { - // @ts-ignore - option = await option(this.baseCtx, this.baseApp); - } - // 判断是否有关联查询,有的话取个别名 - if (!_.isEmpty(option.join)) { - for (const item of option.join) { - selects.push(`${item.alias}.*`); - find[item.type || "leftJoin"]( - item.entity, - item.alias, - item.condition - ); - } - } - // 默认条件 - if (option.where) { - const wheres = - typeof option.where == "function" - ? await option.where(this.baseCtx, this.baseApp) - : option.where; - if (!_.isEmpty(wheres)) { - for (const item of wheres) { - if ( - item.length == 2 || - (item.length == 3 && (item[2] || item[2] === 0)) - ) { - for (const key in item[1]) { - this.sqlParams.push(item[1][key]); - } - find.andWhere(item[0], item[1]); - } - } - } - } - // 附加排序 - if (!_.isEmpty(option.addOrderBy)) { - for (const key in option.addOrderBy) { - if (order && order == key) { - sort = option.addOrderBy[key].toUpperCase(); - } - find.addOrderBy( - `${this.matchColumn(option?.select, key)}.${key}`, - this.checkSort(option.addOrderBy[key].toUpperCase()) - ); - } - } - // 关键字模糊搜索 - if (keyWord || keyWord == 0) { - keyWord = `%${keyWord}%`; - find.andWhere( - new Brackets((qb) => { - const keyWordLikeFields = option.keyWordLikeFields || []; - for (let i = 0; i < option.keyWordLikeFields?.length || 0; i++) { - let column = keyWordLikeFields[i]; - column = column.includes(".") ? column : `a.${column}`; - const values = {}; - values[`keyWord${i}`] = keyWord; - qb.orWhere(`${column} like :keyWord${i}`, values); - this.sqlParams.push(keyWord); - } - }) - ); - } - // 筛选字段 - if (!_.isEmpty(option.select)) { - sqlArr.push(option.select.join(",")); - find.select(option.select); - } else { - sqlArr.push(selects.join(",")); - } - // 字段全匹配 - if (!_.isEmpty(option.fieldEq)) { - for (let key of option.fieldEq) { - const c = {}; - let column; - // 如果key有包含.的情况下操作 - if (typeof key === "string" && key.includes(".")) { - const keys = key.split("."); - const lastKey = keys.pop(); - key = { requestParam: lastKey, column: key }; - column = key; - } else { - column = `a.${key}`; - } - // 单表字段无别名的情况下操作 - if (typeof key === "string") { - if (query[key] || query[key] == 0) { - c[key] = query[key]; - const eq = query[key] instanceof Array ? "in" : "="; - if (eq === "in") { - find.andWhere(`${column} ${eq} (:...${key})`, c); - } else { - find.andWhere(`${column} ${eq} :${key}`, c); - } - this.sqlParams.push(query[key]); - } - } else { - if (query[key.requestParam] || query[key.requestParam] == 0) { - c[key.column] = query[key.requestParam]; - const eq = query[key.requestParam] instanceof Array ? "in" : "="; - if (eq === "in") { - find.andWhere(`${key.column} ${eq} (:${key.column})`, c); - } else { - find.andWhere(`${key.column} ${eq} :${key.column}`, c); - } - this.sqlParams.push(query[key.requestParam]); - } - } - } - } - } else { - sqlArr.push(selects.join(",")); - } - // 接口请求的排序 - if (sort && order) { - const sorts = sort.toUpperCase().split(","); - const orders = order.split(","); - if (sorts.length != orders.length) { - throw new CoolValidateException(ERRINFO.SORTFIELD); - } - for (const i in sorts) { - find.addOrderBy( - `${this.matchColumn(option?.select, orders[i])}.${orders[i]}`, - this.checkSort(sorts[i]) - ); - } - } - if (option?.extend) { - await option?.extend(find, this.baseCtx, this.baseApp); - } - const sqls = find.getSql().split("FROM"); - sqlArr.push("FROM"); - // 取sqls的最后一个 - sqlArr.push(sqls[sqls.length - 1]); - sqlArr.forEach((item, index) => { - if (item.includes("ORDER BY")) { - sqlArr[index] = this.replaceOrderByPrefix(item); - } - }); - return sqlArr.join(" "); - } - - /** - * 替换sql中的表别名 - * @param sql - * @returns - */ - replaceOrderByPrefix(sql) { - // 使用正则表达式匹配 ORDER BY 后面的部分 - // 这里假设 ORDER BY 后面跟着的是由空格分隔的字段名,且字段名由双引号包围 - const orderByRegex = - /ORDER BY\s+("[^"]+_[^"]+")(\s*(ASC|DESC)?\s*(,\s*"[^"]+_[^"]+")*)/gi; - - // 定义替换函数 - // @ts-ignore - function replaceMatch(match, p1, p2) { - // 将 p1 中的 "a_" 替换为 "a." - const replacedField = p1.replace(/a_([^"]+)/g, "a.$1"); - // 如果有其他字段,递归调用替换函数 - const replacedRest = p2.replace(/("[^"]+_)/g, (m, p) => - p.replace("a_", "a.") - ); - // 组合替换后的字段和其他部分 - return `ORDER BY ${replacedField.replace(/"/g, "")}${replacedRest.replace( - /"/g, - "" - )}`; - } - - // 使用替换函数替换匹配到的内容 - const replacedOrderBySql = sql.replace(orderByRegex, replaceMatch); - - // 移除所有双引号 - const sqlWithoutQuotes = replacedOrderBySql.replace(/"/g, ""); - - return sqlWithoutQuotes; - } - - /** - * 筛选的字段匹配 - * @param select 筛选的字段 - * @param field 字段 - * @returns 字段在哪个表中 - */ - protected matchColumn(select: string[] = [], field: string) { - for (const column of select) { - // 检查字段是否有别名,考虑 'AS' 关键字的不同大小写形式 - const aliasPattern = new RegExp(`\\b\\w+\\s+as\\s+${field}\\b`, "i"); - const aliasMatch = column.match(aliasPattern); - if (aliasMatch) { - // 提取别名前的字段和表名 - const fieldPattern = new RegExp( - `(\\w+)\\.(\\w+)\\s+as\\s+${field}`, - "i" - ); - const fieldMatch = column.match(fieldPattern); - if (fieldMatch) { - // 返回匹配到的表名 - return fieldMatch[1]; - } - } - - // 检查字段是否直接在选择列表中 - const fieldPattern = new RegExp(`\\b(\\w+)\\.${field}\\b`, "i"); - const fieldMatch = column.match(fieldPattern); - if (fieldMatch) { - // 如果直接匹配到字段,返回字段所属的表名 - return fieldMatch[1]; - } - } - - // 如果没有匹配到任何特定的表或别名,返回默认的 'a' 表 - return "a"; - } -} diff --git a/core/src/service/sqlite.ts b/core/src/service/sqlite.ts deleted file mode 100644 index 43dd440..0000000 --- a/core/src/service/sqlite.ts +++ /dev/null @@ -1,532 +0,0 @@ -import { Init, Provide, Inject, App, Config } from "@midwayjs/decorator"; -import { Scope, ScopeEnum } from "@midwayjs/core"; -import { CoolValidateException } from "../exception/validate"; -import { ERRINFO, EVENT } from "../constant/global"; -import { Application, Context } from "@midwayjs/koa"; -import * as SqlString from "sqlstring"; -import { CoolConfig } from "../interface"; -import { TypeORMDataSourceManager } from "@midwayjs/typeorm"; -import { Brackets, In, Repository, SelectQueryBuilder } from "typeorm"; -import { QueryOp } from "../decorator/controller"; -import * as _ from "lodash"; -import { CoolEventManager } from "../event"; - -/** - * 服务基类 - */ -@Provide() -@Scope(ScopeEnum.Request, { allowDowngrade: true }) -export abstract class BaseSqliteService { - // 分页配置 - @Config("cool") - private _coolConfig: CoolConfig; - - // 模型 - entity: Repository; - - sqlParams; - - @Inject() - typeORMDataSourceManager: TypeORMDataSourceManager; - - @Inject() - coolEventManager: CoolEventManager; - - // 设置模型 - setEntity(entity: any) { - this.entity = entity; - } - - // 设置请求上下文 - setCtx(ctx: Context) { - this.baseCtx = ctx; - } - - @App() - baseApp: Application; - - // 设置应用对象 - setApp(app: Application) { - this.baseApp = app; - } - - @Inject("ctx") - baseCtx: Context; - - // 初始化 - @Init() - init() { - this.sqlParams = []; - } - - /** - * 设置sql - * @param condition 条件是否成立 - * @param sql sql语句 - * @param params 参数 - */ - setSql(condition, sql, params) { - let rSql = false; - if (condition || condition === 0) { - rSql = true; - for (let i = 0; i < params.length; i++) { - const param = params[i]; - if (param instanceof Array) { - // 将这个? 替换成 $1,$2,$3 - const replaceStr = []; - for (let j = 0; j < param.length; j++) { - replaceStr.push("$" + (this.sqlParams.length + j + 1)); - } - this.sqlParams = this.sqlParams.concat(...params); - sql = sql.replace("?", replaceStr.join(",")); - } else { - sql = sql.replace("?", "$" + (this.sqlParams.length + 1)); - this.sqlParams.push(param); - } - } - } - return (rSql ? sql : "").replace(/\$\d+/g, "?"); - } - - /** - * 获得查询个数的SQL - * @param sql - */ - getCountSql(sql) { - sql = sql - .replace(new RegExp("LIMIT", "gm"), "limit ") - .replace(new RegExp("\n", "gm"), " "); - if (sql.includes("limit")) { - const sqlArr = sql.split("limit "); - sqlArr.pop(); - sql = sqlArr.join("limit "); - } - return `select count(*) as count from (${sql}) a`; - } - - /** - * 参数安全性检查 - * @param params - */ - async paramSafetyCheck(params) { - const lp = params.toLowerCase(); - return !( - lp.indexOf("update ") > -1 || - lp.indexOf("select ") > -1 || - lp.indexOf("delete ") > -1 || - lp.indexOf("insert ") > -1 - ); - } - - /** - * 原生查询 - * @param sql - * @param params - * @param connectionName - */ - async nativeQuery(sql, params?, connectionName?) { - if (_.isEmpty(params)) { - params = this.sqlParams; - } - let newParams = []; - // sql没处理过?的情况下 - for (const item of params) { - // 如果是数组,将这个? 替换成 $1,$2,$3 - if (item instanceof Array) { - const replaceStr = []; - for (let i = 0; i < item.length; i++) { - replaceStr.push("$" + (newParams.length + i + 1)); - } - newParams.push(...item); - sql = sql.replace("?", replaceStr.join(",")); - } else { - sql = sql.replace("?", "$" + (newParams.length + 1)); - newParams.push(item); - } - } - this.sqlParams = []; - return await this.getOrmManager(connectionName).query( - sql.replace(/\$\d+/g, "?"), - newParams || [] - ); - } - - /** - * 获得ORM管理 - * @param connectionName 连接名称 - */ - getOrmManager(connectionName = "default") { - return this.typeORMDataSourceManager.getDataSource(connectionName); - } - - /** - * 操作entity获得分页数据,不用写sql - * @param find QueryBuilder - * @param query - * @param autoSort - * @param connectionName - */ - async entityRenderPage( - find: SelectQueryBuilder, - query, - autoSort = true - ) { - const { - size = this._coolConfig.crud.pageSize, - page = 1, - order = "createTime", - sort = "desc", - isExport = false, - maxExportLimit, - } = query; - const count = await find.getCount(); - let dataFind: SelectQueryBuilder; - if (isExport && maxExportLimit > 0) { - dataFind = find.limit(maxExportLimit); - } else { - dataFind = find.offset((page - 1) * size).limit(size); - } - if (autoSort) { - find.addOrderBy(order, sort.toUpperCase()); - } - return { - list: await dataFind.getMany(), - pagination: { - page: parseInt(page), - size: parseInt(size), - total: count, - }, - }; - } - - /** - * 执行SQL并获得分页数据 - * @param sql 执行的sql语句 - * @param query 分页查询条件 - * @param autoSort 是否自动排序 - * @param connectionName 连接名称 - */ - async sqlRenderPage(sql, query, autoSort = true, connectionName?) { - const { - size = this._coolConfig.crud.pageSize, - page = 1, - order = "createTime", - sort = "desc", - isExport = false, - maxExportLimit, - } = query; - sql = `SELECT * FROM (${sql}) a`; - if (order && sort && autoSort) { - if (!(await this.paramSafetyCheck(order + sort))) { - throw new CoolValidateException("非法传参~"); - } - sql += ` ORDER BY a.${SqlString.escapeId(order)} ${this.checkSort(sort)}`; - } - let cutParams = 0; - if (isExport && maxExportLimit > 0) { - this.sqlParams.push(parseInt(maxExportLimit)); - cutParams = 1; - sql += " LIMIT ? "; - } - if (!isExport) { - this.sqlParams.push((page - 1) * size); - this.sqlParams.push(parseInt(size)); - cutParams = 2; - sql += " LIMIT ?,? "; - } - - let params = []; - params = params.concat(this.sqlParams); - const result = await this.nativeQuery(sql, params, connectionName); - params = params.slice(0, -cutParams); - const countResult = await this.nativeQuery( - this.getCountSql(sql), - params, - connectionName - ); - return { - list: result, - pagination: { - page: parseInt(page), - size: parseInt(size), - total: parseInt(countResult[0] ? countResult[0].count : 0), - }, - }; - } - - /** - * 检查排序 - * @param sort 排序 - * @returns - */ - checkSort(sort) { - if (!["desc", "asc"].includes(sort.toLowerCase())) { - throw new CoolValidateException("sort 非法传参~"); - } - return sort; - } - - /** - * 获得单个ID - * @param id ID - * @param infoIgnoreProperty 忽略返回属性 - */ - async info(id: any, infoIgnoreProperty?: string[]) { - if (!this.entity) throw new CoolValidateException(ERRINFO.NOENTITY); - if (!id) { - throw new CoolValidateException(ERRINFO.NOID); - } - const info = await this.entity.findOneBy({ id }); - if (info && infoIgnoreProperty) { - for (const property of infoIgnoreProperty) { - delete info[property]; - } - } - return info; - } - - /** - * 删除 - * @param ids 删除的ID集合 如:[1,2,3] 或者 1,2,3 - */ - async delete(ids: any) { - if (!this.entity) throw new CoolValidateException(ERRINFO.NOENTITY); - if (ids instanceof String) { - ids = ids.split(","); - } - // 启动软删除发送事件 - if (this._coolConfig.crud?.softDelete) { - this.softDelete(ids); - } - await this.entity.delete(ids); - } - - /** - * 软删除 - * @param ids 删除的ID数组 - * @param entity 实体 - */ - async softDelete(ids: number[], entity?: Repository) { - const data = await this.entity.find({ - where: { - id: In(ids), - }, - }); - if (_.isEmpty(data)) return; - const _entity = entity ? entity : this.entity; - const params = { - data, - ctx: this.baseCtx, - entity: _entity, - }; - if (data.length > 0) { - this.coolEventManager.emit(EVENT.SOFT_DELETE, params); - } - } - - /** - * 新增|修改 - * @param param 数据 - */ - async addOrUpdate(param: any | any[], type: "add" | "update" = "add") { - if (!this.entity) throw new CoolValidateException(ERRINFO.NOENTITY); - delete param.createTime; - // 判断是否是批量操作 - if (param instanceof Array) { - param.forEach((item) => { - item.updateTime = new Date(); - item.createTime = new Date(); - }); - await this.entity.save(param); - } else { - const upsert = this._coolConfig.crud?.upsert || "normal"; - if (type == "update") { - if (upsert == "save") { - const info = await this.entity.findOneBy({ id: param.id }); - param = { - ...info, - ...param, - }; - } - param.updateTime = new Date(); - upsert == "normal" - ? await this.entity.update(param.id, param) - : await this.entity.save(param); - } - if (type == "add") { - param.createTime = new Date(); - param.updateTime = new Date(); - upsert == "normal" - ? await this.entity.insert(param) - : await this.entity.save(param); - } - } - } - - /** - * 非分页查询 - * @param query 查询条件 - * @param option 查询配置 - * @param connectionName 连接名 - */ - async list(query, option, connectionName?): Promise { - if (!this.entity) throw new CoolValidateException(ERRINFO.NOENTITY); - const sql = await this.getOptionFind(query, option); - return this.nativeQuery(sql, [], connectionName); - } - - /** - * 分页查询 - * @param query 查询条件 - * @param option 查询配置 - * @param connectionName 连接名 - */ - async page(query, option, connectionName?) { - if (!this.entity) throw new CoolValidateException(ERRINFO.NOENTITY); - const sql = await this.getOptionFind(query, option); - return this.sqlRenderPage(sql, query, false, connectionName); - } - - /** - * 构建查询配置 - * @param query 前端查询 - * @param option - */ - async getOptionFind(query, option: QueryOp) { - let { order = "createTime", sort = "desc", keyWord = "" } = query; - const sqlArr = ["SELECT"]; - const selects = ["a.*"]; - const find = this.entity.createQueryBuilder("a"); - if (option) { - if (typeof option == "function") { - // @ts-ignore - option = await option(this.baseCtx, this.baseApp); - } - // 判断是否有关联查询,有的话取个别名 - if (!_.isEmpty(option.join)) { - for (const item of option.join) { - selects.push(`${item.alias}.*`); - find[item.type || "leftJoin"]( - item.entity, - item.alias, - item.condition - ); - } - } - // 默认条件 - if (option.where) { - const wheres = - typeof option.where == "function" - ? await option.where(this.baseCtx, this.baseApp) - : option.where; - if (!_.isEmpty(wheres)) { - for (const item of wheres) { - if ( - item.length == 2 || - (item.length == 3 && (item[2] || item[2] === 0)) - ) { - for (const key in item[1]) { - this.sqlParams.push(item[1][key]); - } - find.andWhere(item[0], item[1]); - } - } - } - } - // 附加排序 - if (!_.isEmpty(option.addOrderBy)) { - for (const key in option.addOrderBy) { - if (order && order == key) { - sort = option.addOrderBy[key].toUpperCase(); - } - find.addOrderBy( - SqlString.escapeId(key), - this.checkSort(option.addOrderBy[key].toUpperCase()) - ); - } - } - // 关键字模糊搜索 - if (keyWord || keyWord === 0) { - keyWord = `%${keyWord}%`; - find.andWhere( - new Brackets((qb) => { - const keyWordLikeFields = option.keyWordLikeFields || []; - for (let i = 0; i < option.keyWordLikeFields?.length || 0; i++) { - qb.orWhere(`${keyWordLikeFields[i]} like :keyWord`, { - keyWord, - }); - this.sqlParams.push(keyWord); - } - }) - ); - } - // 筛选字段 - if (!_.isEmpty(option.select)) { - sqlArr.push(option.select.join(",")); - find.select(option.select); - } else { - sqlArr.push(selects.join(",")); - } - // 字段全匹配 - if (!_.isEmpty(option.fieldEq)) { - for (let key of option.fieldEq) { - const c = {}; - // 如果key有包含.的情况下操作 - if (typeof key === "string" && key.includes(".")) { - const keys = key.split("."); - const lastKey = keys.pop(); - key = { requestParam: lastKey, column: key }; - } - // 单表字段无别名的情况下操作 - if (typeof key === "string") { - if (query[key] || query[key] == 0) { - c[key] = query[key]; - const eq = query[key] instanceof Array ? "in" : "="; - if (eq === "in") { - find.andWhere(`${key} ${eq} (:${key})`, c); - } else { - find.andWhere(`${key} ${eq} :${key}`, c); - } - // this.sqlParams.push(query[key]); - } - } else { - if (query[key.requestParam] || query[key.requestParam] == 0) { - c[key.column] = query[key.requestParam]; - const eq = query[key.requestParam] instanceof Array ? "in" : "="; - if (eq === "in") { - find.andWhere(`${key.column} ${eq} (:${key.column})`, c); - } else { - find.andWhere(`${key.column} ${eq} :${key.column}`, c); - } - // this.sqlParams.push(query[key.requestParam]); - } - } - } - } - } else { - sqlArr.push(selects.join(",")); - } - // 接口请求的排序 - if (sort && order) { - const sorts = sort.toUpperCase().split(","); - const orders = order.split(","); - if (sorts.length != orders.length) { - throw new CoolValidateException(ERRINFO.SORTFIELD); - } - for (const i in sorts) { - find.addOrderBy( - SqlString.escapeId(orders[i]), - this.checkSort(sorts[i]) - ); - } - } - if (option?.extend) { - await option?.extend(find, this.baseCtx, this.baseApp); - } - const sqls = find.getSql().split("FROM"); - sqlArr.push("FROM"); - // 取sqls的最后一个 - sqlArr.push(sqls[sqls.length - 1]); - return sqlArr.join(" "); - } -} diff --git a/core/src/tag/data.ts b/core/src/tag/data.ts deleted file mode 100644 index 9d9bff6..0000000 --- a/core/src/tag/data.ts +++ /dev/null @@ -1,89 +0,0 @@ -import { COOL_METHOD_TAG_KEY, CoolUrlTagConfig } from './../decorator/tag'; -import { - CONTROLLER_KEY, - getClassMetadata, - listPropertyDataFromClass, - listModule, - Provide, - Scope, - ScopeEnum, - WEB_ROUTER_KEY, -} from '@midwayjs/decorator'; -import { COOL_URL_TAG_KEY } from '../decorator/tag'; -import * as _ from 'lodash'; - -/** - * URL标签 - */ -@Provide() -@Scope(ScopeEnum.Singleton) -export class CoolUrlTagData { - data = {}; - - /** - * 初始化 - */ - async init() { - // 类标记 - await this.classTag(); - // 方法标记 - await this.methodTag(); - } - - /** - * 类标记 - */ - async classTag() { - const tags = listModule(COOL_URL_TAG_KEY); - for (const controller of tags) { - // class的标记 - const controllerOption = getClassMetadata(CONTROLLER_KEY, controller); - const tagOption: CoolUrlTagConfig = getClassMetadata( - COOL_URL_TAG_KEY, - controller - ); - if(tagOption?.key){ - const data: string[] = this.data[tagOption.key] || []; - this.data[tagOption.key] = _.uniq(data.concat( - (tagOption?.value || []).map(e => { - return controllerOption.prefix + '/' + e; - })) - ); - } - } - } - - /** - * 方法标记 - */ - async methodTag() { - const controllers = listModule(CONTROLLER_KEY); - for (const controller of controllers) { - const controllerOption = getClassMetadata(CONTROLLER_KEY, controller); - // 方法标记 - const listPropertyMetas = listPropertyDataFromClass(COOL_METHOD_TAG_KEY, controller); - const requestMetas = getClassMetadata(WEB_ROUTER_KEY, controller); - for (const propertyMeta of listPropertyMetas) { - const _data = this.data[propertyMeta.tag] || []; - const requestMeta = _.find(requestMetas, { method: propertyMeta.key }) - if(requestMeta){ - this.data[propertyMeta.tag] = _.uniq(_data.concat( - controllerOption.prefix + requestMeta.path - )) - } - } - } - } - - /** - * 根据键获得 - * @param key - * @param type - * @returns - */ - byKey(key: string, type?: 'app' | 'admin'): string[] { - return this.data[key].filter(e => { - return type? _.startsWith(e, `/${type}/`): true; - }); - } -} diff --git a/core/src/util/func.ts b/core/src/util/func.ts deleted file mode 100644 index f796bbc..0000000 --- a/core/src/util/func.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { ILogger } from '@midwayjs/core'; -import { Init, Logger, Provide, Scope, ScopeEnum } from '@midwayjs/decorator'; -import * as moment from 'moment'; - -/** - * 常用函数处理 - */ -@Provide() -@Scope(ScopeEnum.Singleton) -export class FuncUtil { - @Logger() - coreLogger: ILogger; - - @Init() - async init() { - Date.prototype.toJSON = function () { - return moment(this).format('YYYY-MM-DD HH:mm:ss'); - }; - // 新增String支持replaceAll方法 - String.prototype['replaceAll'] = function (s1, s2) { - return this.replace(new RegExp(s1, 'gm'), s2); - }; - this.coreLogger.info( - '\x1B[36m [cool:core] midwayjs cool core func handler \x1B[0m' - ); - } -} diff --git a/core/src/util/location.ts b/core/src/util/location.ts deleted file mode 100644 index 3be2890..0000000 --- a/core/src/util/location.ts +++ /dev/null @@ -1,52 +0,0 @@ -/** - * Location 工具类 - */ -class LocationUtil { - private locationCache = new Map(); - - /** - * 获取目标类的定义位置 - * @param target 目标类 - * @returns 目标类的定义位置 - */ - async scriptPath(target: any) { - const targetName = target.name; - - // 检查缓存 - if (this.locationCache.has(targetName)) { - return this.locationCache.get(targetName); - } - - const originalPrepareStackTrace = Error.prepareStackTrace; - let targetFile; - - try { - Error.prepareStackTrace = (error, stack) => stack; - const stack = new Error().stack as any; - - for (const site of stack) { - const fileName = site.getFileName(); - if (!fileName) continue; - - const content = require('fs').readFileSync(fileName, 'utf-8'); - if (content.includes(`class ${targetName}`)) { - targetFile = { - path: fileName, - line: site.getLineNumber(), - column: site.getColumnNumber(), - source: `file://${fileName}` - }; - this.locationCache.set(targetName, targetFile); - break; - } - } - } finally { - Error.prepareStackTrace = originalPrepareStackTrace; - } - - return targetFile; - } -} - -// 不再需要单例模式,直接导出实例即可 -export default new LocationUtil(); diff --git a/core/tsconfig.json b/core/tsconfig.json deleted file mode 100644 index 9bb4ab7..0000000 --- a/core/tsconfig.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "compileOnSave": true, - "compilerOptions": { - "target": "es2018", - "module": "commonjs", - "moduleResolution": "node", - "experimentalDecorators": true, - "emitDecoratorMetadata": true, - "inlineSourceMap":false, - "noImplicitThis": true, - "noUnusedLocals": true, - "stripInternal": true, - "skipLibCheck": true, - "noImplicitReturns": false, - "pretty": true, - "declaration": true, - "forceConsistentCasingInFileNames": true, - "outDir": "dist" - }, - "exclude": [ - "dist", - "node_modules", - "test" - ] -} diff --git a/es/.editorconfig b/es/.editorconfig deleted file mode 100644 index 4c7f8a8..0000000 --- a/es/.editorconfig +++ /dev/null @@ -1,11 +0,0 @@ -# 🎨 editorconfig.org - -root = true - -[*] -charset = utf-8 -end_of_line = lf -indent_style = space -indent_size = 2 -trim_trailing_whitespace = true -insert_final_newline = true \ No newline at end of file diff --git a/es/.eslintrc.json b/es/.eslintrc.json deleted file mode 100644 index aad9755..0000000 --- a/es/.eslintrc.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "extends": "./node_modules/mwts/", - "ignorePatterns": [ - "node_modules", - "dist", - "test", - "jest.config.js", - "typings", - "public/**/**", - "view/**/**" - ], - "env": { - "jest": true - }, - "rules": { - "@typescript-eslint/explicit-module-boundary-types": "off", - "@typescript-eslint/no-unused-vars": "off", - "@typescript-eslint/ban-ts-comment": "off", - "node/no-extraneous-import": "off", - "no-empty": "off", - "node/no-extraneous-require": "off", - "eqeqeq": "off", - "node/no-unsupported-features/node-builtins": "off", - "@typescript-eslint/ban-types": "off", - "no-control-regex": "off", - "prefer-const": "off" - } -} \ No newline at end of file diff --git a/es/.gitignore b/es/.gitignore deleted file mode 100644 index 13bc3a6..0000000 --- a/es/.gitignore +++ /dev/null @@ -1,15 +0,0 @@ -logs/ -npm-debug.log -yarn-error.log -node_modules/ -package-lock.json -yarn.lock -coverage/ -dist/ -.idea/ -run/ -.DS_Store -*.sw* -*.un~ -.tsbuildinfo -.tsbuildinfo.* diff --git a/es/.prettierrc.js b/es/.prettierrc.js deleted file mode 100644 index b964930..0000000 --- a/es/.prettierrc.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - ...require('mwts/.prettierrc.json') -} diff --git a/es/README.md b/es/README.md deleted file mode 100644 index 610c3db..0000000 --- a/es/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# cool-admin - -https://cool-js.com diff --git a/es/index.d.ts b/es/index.d.ts deleted file mode 100644 index e0065de..0000000 --- a/es/index.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -export * from './dist/index'; - -declare module '@midwayjs/core/dist/interface' { - interface MidwayConfig { - book?: PowerPartial<{ - a: number; - b: string; - }>; - } -} diff --git a/es/jest.config.js b/es/jest.config.js deleted file mode 100644 index 82a8b85..0000000 --- a/es/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = { - preset: 'ts-jest', - testEnvironment: 'node', - testPathIgnorePatterns: ['/test/fixtures'], - coveragePathIgnorePatterns: ['/test/'], - setupFilesAfterEnv: ['./jest.setup.js'] -}; diff --git a/es/jest.setup.js b/es/jest.setup.js deleted file mode 100644 index 1399c91..0000000 --- a/es/jest.setup.js +++ /dev/null @@ -1 +0,0 @@ -jest.setTimeout(30000); diff --git a/es/package.json b/es/package.json deleted file mode 100644 index f12ab63..0000000 --- a/es/package.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "name": "@cool-midway/es", - "version": "7.0.0", - "description": "cool-js.com elasticsearch", - "main": "dist/index.js", - "typings": "index.d.ts", - "scripts": { - "build": "cross-env midway-bin build -c", - "cov": "cross-env midway-bin cov --ts", - "lint": "mwts check", - "lint:fix": "mwts fix" - }, - "keywords": [ - "cool", - "cool-admin", - "cooljs" - ], - "author": "COOL", - "readme": "README.md", - "files": [ - "dist/**/*.js", - "dist/**/*.d.ts", - "index.d.ts" - ], - "license": "MIT", - "devDependencies": { - "@cool-midway/core": "^7.0.0", - "@midwayjs/cli": "^2.0.9", - "@midwayjs/core": "^3.9.0", - "@midwayjs/decorator": "^3.9.0", - "@midwayjs/mock": "^3.9.0", - "@types/jest": "^29.2.5", - "@types/node": "^18.11.18", - "cross-env": "^7.0.3", - "jest": "^29.3.1", - "mwts": "^1.3.0", - "ts-jest": "^29.0.3", - "typescript": "^4.9.4" - }, - "dependencies": { - "@elastic/elasticsearch": "^8.5.0" - } -} diff --git a/es/src/README.md b/es/src/README.md deleted file mode 100644 index 7edd966..0000000 --- a/es/src/README.md +++ /dev/null @@ -1,27 +0,0 @@ -### COOL-ADMIN - -cool-admin一个很酷的后台权限管理系统,开源免费,模块化、插件化、极速开发CRUD,方便快速构建迭代后台管理系统 - -大数据、微服务、AI编码快速开发!!! - - -### 技术栈 - -- 后端:node.js midway.js koa.js mysql typescript -- 前端:vue.js element-plus jsx pinia vue-router - -### 官网 - -[https://cool-js.com](https://cool-js.com) - - -### 演示地址 - -[https://show.cool-admin.com](https://show.cool-admin.com) - -- 账户:admin -- 密码:123456 - -### 项目地址 - -[https://github.com/cool-team-official/cool-admin-midway](https://github.com/cool-team-official/cool-admin-midway) \ No newline at end of file diff --git a/es/src/base.ts b/es/src/base.ts deleted file mode 100644 index f6d83af..0000000 --- a/es/src/base.ts +++ /dev/null @@ -1,615 +0,0 @@ -import { CoolEventManager } from '@cool-midway/core'; -import { Client } from '@elastic/elasticsearch'; -import { WaitForActiveShards } from '@elastic/elasticsearch/lib/api/types'; -import { Inject, Logger } from '@midwayjs/decorator'; -import { ILogger } from '@midwayjs/logger'; -import { EsConfig } from '.'; - -/** - * Es索引基类 - */ -export class BaseEsIndex { - // 索引 - public index: string; - // es客户端 - public client: Client; - // 日志 - @Logger() - coreLogger: ILogger; - // 事件 - @Inject('cool:coolEventManager') - coolEventManager: CoolEventManager; - - /** - * 设置索引 - * @param index - */ - setIndex(index: string) { - this.index = index; - } - - /** - * 处理es数据变更事件,主要用于同步数据 - * @param method - * @param data - */ - async handleDataChange(index, method, data) { - this.index = index; - const { - id, - ids, - bodys, - body, - type, - refresh, - waitForActiveShards, - properties, - config, - } = data; - switch (method) { - case 'upsert': - await this.upsert(body, refresh, waitForActiveShards); - break; - case 'batchIndex': - await this.batchIndex(bodys, type, refresh, waitForActiveShards); - break; - case 'deleteById': - await this.deleteById(id, refresh, waitForActiveShards); - break; - case 'deleteByIds': - await this.deleteByIds(ids, refresh, waitForActiveShards); - break; - case 'deleteByQuery': - await this.deleteByQuery(body, refresh, waitForActiveShards); - break; - case 'updateById': - await this.updateById(body, refresh, waitForActiveShards); - break; - case 'updateByQuery': - await this.updateByQuery(body, refresh, waitForActiveShards); - break; - case 'createIndex': - await this.updateByQuery(properties, config); - break; - } - } - - /** - * 数据更新事件 - * @param method - * @param data - */ - async esDataChange(method, data) { - this.coolEventManager?.emit('esDataChange', this.index, method, data); - } - - /** - * 设置客户端 - * @param client - */ - setClient(client: Client) { - this.client = client; - } - - /** - * 对象转body - * @param condition - */ - async objToBody(condition: any){ - const body = { - query: { - bool: { - must: [], - }, - } - } - for(const key in condition){ - body.query.bool.must.push({ - term: { - [key]: condition[key] - } - }) - } - return body; - } - - /** - * 按字段值查找 - * @param condition - * @param size - * @returns - */ - async findBy(condition: any, size?: number){ - const body = await this.objToBody(condition) - return this.find(body, size); - } - - /** - * 按字段值分页查找 - * @param condition - * @param page - * @param size - */ - async findPageBy(condition: any, page?: number, size?: number){ - const body = await this.objToBody(condition) - return this.findPage(body, page, size); - } - - /** - * 查询 - * @param body - */ - async find(body?: any, size?: number) { - if (!body) { - body = {}; - } - if(!body.size){ - body.size = size ? size : 10000; - } - return this.client - .search({ - index: this.index, - body, - }) - .then(res => { - return ( - res.hits.hits.map(e => { - e._source['id'] = e._id; - const _source: any = e._source; - ['_id', '_index', '_score', '_source'].forEach(key => { - delete e[key]; - }); - return { - ..._source, - ...e, - }; - }) || [] - ); - }); - } - - /** - * 分页查询 - * @param body - * @param page - * @param size - */ - async findPage(body?: any, page?: number, size?: number) { - if (!page) { - page = 1; - } - if (!body) { - body = {}; - } - if (!size && !body.size) { - size = 20; - body.size = size; - } - const total = await this.findCount(body); - body.from = (page - 1) * size; - return this.client.search({ index: this.index, body }).then(res => { - const result = - res.hits.hits.map(e => { - e._source['id'] = e._id; - const _source: any = e._source; - ['_id', '_index', '_score', '_source'].forEach(key => { - delete e[key]; - }); - return { - ..._source, - ...e, - }; - }) || []; - return { - list: result, - pagination: { - page, - size, - total, - }, - }; - }); - } - - /** - * 根据ID查询 - * @param id - * @returns - */ - async findById(id) { - return this.client - .get({ - index: this.index, - id, - }) - .then(res => { - res._source['id'] = res._id; - return res._source || undefined; - }) - .catch(e => { - return undefined; - }); - } - - /** - * 根据多个ID查询 - * @param ids - * @returns - */ - async findByIds(ids: string[]) { - return this.client - .mget({ index: this.index, body: { ids } }) - .then(res => { - const result = res.docs.map((e: any) => { - e._source.id = e._id; - return e._source || 'undefined'; - }); - return result.filter(e => { - return e !== 'undefined'; - }); - }) - .catch(e => { - return undefined; - }); - } - - /** - * 插入与更新 - * @param body - * @param refresh - * @param waitForActiveShards - * @returns - */ - async upsert( - body: any, - refresh?: boolean | 'wait_for', - waitForActiveShards?: WaitForActiveShards - ) { - if (refresh == undefined) { - refresh = true; - } - if (body.id) { - this.esDataChange('upsert', { - body, - refresh, - waitForActiveShards, - }); - const id = body.id; - delete body.id; - return this.client.index({ - id, - index: this.index, - wait_for_active_shards: waitForActiveShards, - refresh, - body, - }); - } else { - return this.client - .index({ - index: this.index, - wait_for_active_shards: waitForActiveShards, - refresh, - body, - }) - .then(res => { - this.esDataChange('upsert', { - body: { - ...body, - id: res._id, - }, - refresh, - waitForActiveShards, - }); - return res; - }); - } - } - - /** - * 批量插入更新 - * @param bodys - * @param type - * @param refresh - * @param waitForActiveShards - * @returns - */ - async batchIndex( - bodys: any[], - type: 'index' | 'create' | 'delete' | 'update', - refresh?: boolean | 'wait_for', - waitForActiveShards?: WaitForActiveShards - ) { - this.esDataChange('batchIndex', { - bodys, - type, - refresh, - waitForActiveShards, - }); - if (refresh == undefined) { - refresh = true; - } - const list = []; - for (const body of bodys) { - const typeO = {}; - typeO[type] = { _index: this.index, _id: body.id }; - if (body.id) { - delete body.id; - } - list.push(typeO); - if (type !== 'delete') { - if (type == 'update') { - list.push({ doc: body }); - } else { - list.push(body); - } - } - } - return this.client.bulk({ - wait_for_active_shards: waitForActiveShards, - index: this.index, - refresh, - body: list, - }); - } - - /** - * 删除索引 - * @param id - * @param refresh - * @param waitForActiveShards - * @returns - */ - async deleteById( - id, - refresh?: boolean | 'wait_for', - waitForActiveShards?: WaitForActiveShards - ) { - this.esDataChange('deleteById', { - id, - refresh, - waitForActiveShards, - }); - if (refresh == undefined) { - refresh = true; - } - try { - return this.client.delete({ - index: this.index, - refresh, - wait_for_active_shards: waitForActiveShards, - id, - }); - } catch {} - } - - /** - * 删除文档 - * @param ids - * @param refresh - * @param waitForActiveShards - * @returns - */ - async deleteByIds( - ids: string[], - refresh?: boolean, - waitForActiveShards?: WaitForActiveShards - ) { - this.esDataChange('deleteByIds', { - ids, - refresh, - waitForActiveShards, - }); - if (refresh == undefined) { - refresh = true; - } - const body = { - query: { - bool: { - must: [ - { - terms: { - _id: ids, - }, - }, - ], - }, - }, - }; - return this.client.deleteByQuery({ - index: this.index, - refresh, - wait_for_active_shards: waitForActiveShards, - body, - }); - } - - /** - * 根据条件批量删除 - * @param body - * @param refresh - * @param waitForActiveShards - * @returns - */ - async deleteByQuery( - body, - refresh?: boolean, - waitForActiveShards?: WaitForActiveShards - ) { - this.esDataChange('deleteByQuery', { - body, - refresh, - waitForActiveShards, - }); - if (refresh == undefined) { - refresh = true; - } - return this.client.deleteByQuery({ - index: this.index, - refresh, - wait_for_active_shards: waitForActiveShards, - body, - }); - } - - /** - * 更新索引 - * @param body - * @param refresh - * @param waitForActiveShards - * @returns - */ - async updateById( - body, - refresh?: boolean | 'wait_for', - waitForActiveShards?: WaitForActiveShards - ) { - this.esDataChange('updateById', { - body, - refresh, - waitForActiveShards, - }); - if (refresh == undefined) { - refresh = true; - } - const id = body.id; - delete body.id; - return this.client.update({ - wait_for_active_shards: waitForActiveShards, - index: this.index, - id: id, - refresh, - body: { - doc: body, - }, - }); - } - - /** - * 根据条件更新 - * @param body - * @param refresh - * @param waitForActiveShards - */ - async updateByQuery( - body, - refresh?: boolean, - waitForActiveShards?: WaitForActiveShards - ) { - this.esDataChange('updateByQuery', { - body, - refresh, - waitForActiveShards, - }); - if (refresh == undefined) { - refresh = true; - } - return this.client.updateByQuery({ - index: this.index, - refresh, - wait_for_active_shards: waitForActiveShards, - body, - }); - } - - /** - * 查询条数 - * @param body - */ - async findCount(body?: any) { - let _body = Object.assign({}, body || {}); - delete _body.from; - delete _body.size; - delete _body.sort; - return this.client - .count({ - index: this.index, - body: _body, - }) - .then(res => { - return res.count; - }) - .catch(e => { - return undefined; - }); - } - - /** - * 创建更新索引 - * @param config 配置 - */ - async createIndex( - properties: {}, - config: EsConfig = { - name: '', - replicas: 1, - shards: 8, - analyzers: [], - } - ) { - this.esDataChange('createIndex', { - properties, - config, - }); - const body = { - settings: { - number_of_shards: config.shards, - number_of_replicas: config.replicas, - analysis: { - analyzer: { - comma: { type: 'pattern', pattern: ',' }, - blank: { type: 'pattern', pattern: ' ' }, - }, - }, - mapping: { - nested_fields: { - limit: 100, - }, - }, - }, - mappings: { - properties: {}, - }, - }; - if (config.analyzers) { - for (const analyzer of config.analyzers) { - for (const key in analyzer) { - body.settings.analysis.analyzer[key] = analyzer[key]; - } - } - } - const param = { - index: this.index, - body, - }; - param.body = body; - param.body.mappings.properties = properties; - - this.client.indices.exists({ index: this.index }).then(async res => { - if (!res) { - await this.client.indices.create(param).then(res => { - if (res.acknowledged) { - console.info( - '\x1B[36m [cool:core] midwayjs cool elasticsearch ES索引创建成功: ' + - this.index + - ' \x1B[0m' - ); - } - }); - } else { - const updateParam = { - index: this.index, - body: param.body.mappings, - }; - await this.client.indices.putMapping(updateParam).then(res => { - if (res.acknowledged) { - console.info( - '\x1B[36m [cool:core] midwayjs cool elasticsearch ES索引更新成功: ' + - this.index + - ' \x1B[0m' - ); - } - }); - } - }); - } -} diff --git a/es/src/config/config.default.ts b/es/src/config/config.default.ts deleted file mode 100644 index d8324ca..0000000 --- a/es/src/config/config.default.ts +++ /dev/null @@ -1,4 +0,0 @@ -export const customKey = { - a: 1, - b: 'hello', -}; diff --git a/es/src/configuration.ts b/es/src/configuration.ts deleted file mode 100644 index 93d6842..0000000 --- a/es/src/configuration.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { Configuration } from '@midwayjs/decorator'; -import * as DefaultConfig from './config/config.default'; -import { IMidwayContainer } from '@midwayjs/core'; -import { CoolElasticSearch } from './elasticsearch'; - -@Configuration({ - namespace: 'cool:es', - importConfigs: [ - { - default: DefaultConfig, - }, - ], -}) -export class CoolEsConfiguration { - async onReady(container: IMidwayContainer) { - await container.getAsync(CoolElasticSearch); - // TODO something - } -} diff --git a/es/src/decorator/elasticsearch.ts b/es/src/decorator/elasticsearch.ts deleted file mode 100644 index 7c89d0f..0000000 --- a/es/src/decorator/elasticsearch.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { - Scope, - ScopeEnum, - saveClassMetadata, - saveModule, -} from '@midwayjs/decorator'; - -export const COOL_ES_KEY = 'decorator:cool:es'; - -export interface EsConfig { - shards?: number; - name: string; - replicas?: number; - analyzers?: any[]; -} - -/** - * 索引 - * @param config - * @returns - */ -export function CoolEsIndex( - config: EsConfig | string = { - name: '', - replicas: 1, - shards: 8, - analyzers: [], - } -): ClassDecorator { - if (typeof config == 'string') { - config = { name: config, replicas: 1, shards: 8, analyzers: [] }; - } - return (target: any) => { - // 将装饰的类,绑定到该装饰器,用于后续能获取到 class - saveModule(COOL_ES_KEY, target); - // 保存一些元数据信息,任意你希望存的东西 - saveClassMetadata(COOL_ES_KEY, config, target); - // 指定 IoC 容器创建实例的作用域,这里注册为请求作用域,这样能取到 ctx - Scope(ScopeEnum.Singleton)(target); - }; -} diff --git a/es/src/elasticsearch.ts b/es/src/elasticsearch.ts deleted file mode 100644 index 0b925d2..0000000 --- a/es/src/elasticsearch.ts +++ /dev/null @@ -1,154 +0,0 @@ -import { - Provide, - getClassMetadata, - App, - Logger, - Inject, - Init, - Scope, - ScopeEnum, - Config, -} from '@midwayjs/decorator'; -import { COOL_ES_KEY, EsConfig } from './decorator/elasticsearch'; -import { listModule } from '@midwayjs/decorator'; -import { IMidwayApplication } from '@midwayjs/core'; -import { CoolCoreException, CoolEventManager } from '@cool-midway/core'; -import { ILogger } from '@midwayjs/logger'; -import { Client } from '@elastic/elasticsearch'; -import * as _ from 'lodash'; -import { CoolEsConfig, ICoolEs } from '.'; - -/** - * 搜索引擎 - */ -@Provide() -@Scope(ScopeEnum.Singleton) -export class CoolElasticSearch { - @App() - app: IMidwayApplication; - - @Logger() - coreLogger: ILogger; - - @Config('cool.es') - esConfig: CoolEsConfig; - - client: Client; - - @Inject('cool:coolEventManager') - coolEventManager: CoolEventManager; - - @Init() - async init() { - if (!this.esConfig?.nodes) { - throw new CoolCoreException('es.nodes config is require'); - } - if (this.esConfig.nodes.length == 1) { - this.client = new Client({ node: this.esConfig.nodes[0], ...this.esConfig.options }); - } else { - this.client = new Client({ nodes: this.esConfig.nodes, ...this.esConfig.options }); - } - this.client.ping({}, { requestTimeout: 30000 }).then(res => { - if (res) { - this.coolEventManager.emit('esReady', this.client); - this.scan(); - } - }); - } - - async scan() { - const modules = listModule(COOL_ES_KEY); - for (let module of modules) { - const cls: ICoolEs = await this.app - .getApplicationContext() - .getAsync(module); - const data = getClassMetadata(COOL_ES_KEY, module); - this.createIndex(cls, data); - } - } - - /** - * 数据更新事件 - * @param method - * @param data - */ - async esDataChange(method, data) { - //this.coolEventManager.emit('esDataChange', { method, data }); - } - - /** - * 创建索引 - * @param cls - * @param config - */ - async createIndex(cls, config: EsConfig) { - cls.index = config.name; - cls.client = this.client; - const body = { - settings: { - number_of_shards: config.shards, - number_of_replicas: config.replicas, - analysis: { - analyzer: { - comma: { type: 'pattern', pattern: ',' }, - blank: { type: 'pattern', pattern: ' ' }, - }, - }, - mapping: { - nested_fields: { - limit: 100, - }, - }, - }, - mappings: { - properties: {}, - }, - }; - if (config.analyzers) { - for (const analyzer of config.analyzers) { - for (const key in analyzer) { - body.settings.analysis.analyzer[key] = analyzer[key]; - } - } - } - const param = { - index: config.name, - body, - }; - param.body = body; - param.body.mappings.properties = cls.indexInfo(); - - this.esDataChange('createIndex', { - properties: param.body.mappings.properties, - config, - }); - - this.client.indices.exists({ index: config.name }).then(async res => { - if (!res) { - await this.client.indices.create(param).then(res => { - if (res.acknowledged) { - this.coreLogger.info( - '\x1B[36m [cool:core] midwayjs cool elasticsearch ES索引创建成功: ' + - config.name + - ' \x1B[0m' - ); - } - }); - } else { - const updateParam = { - index: config.name, - body: param.body.mappings, - }; - await this.client.indices.putMapping(updateParam).then(res => { - if (res.acknowledged) { - this.coreLogger.info( - '\x1B[36m [cool:core] midwayjs cool elasticsearch ES索引更新成功: ' + - config.name + - ' \x1B[0m' - ); - } - }); - } - }); - } -} diff --git a/es/src/index.ts b/es/src/index.ts deleted file mode 100644 index 6b42a6f..0000000 --- a/es/src/index.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { ClientOptions } from '@elastic/elasticsearch'; - -export { CoolEsConfiguration as Configuration } from './configuration'; - -export * from './elasticsearch'; - -export * from './decorator/elasticsearch'; - -export * from './base'; - -export interface ICoolEs { - indexInfo(): Object; -} - -export interface CoolEsConfig { - nodes: string[]; - options?: ClientOptions -} \ No newline at end of file diff --git a/es/src/package.json b/es/src/package.json deleted file mode 100644 index 6be5353..0000000 --- a/es/src/package.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "name": "@cool-midway/es", - "version": "7.0.0", - "description": "cool-js.com elasticsearch", - "main": "index.js", - "typings": "index.d.ts", - "scripts": { - "build": "cross-env midway-bin build -c", - "cov": "cross-env midway-bin cov --ts", - "lint": "mwts check", - "lint:fix": "mwts fix" - }, - "keywords": [], - "author": "", - "files": [ - "**/*.js", - "**/*.d.ts" - ], - "repository": { - "type": "git", - "url": "https://cool-js.com" - }, - "license": "MIT", - "devDependencies": { - "@cool-midway/core": "^7.0.0", - "@midwayjs/cli": "^1.2.38", - "@midwayjs/core": "^3.0.0", - "@midwayjs/decorator": "^3.0.0", - "@midwayjs/mock": "^3.0.0", - "@types/jest": "^27.4.0", - "@types/node": "^16.11.22", - "cross-env": "^6.0.0", - "jest": "^27.5.1", - "mwts": "^1.0.5", - "ts-jest": "^27.1.3", - "typescript": "^4.0.0" - }, - "dependencies": { - "@elastic/elasticsearch": "^8.1.0" - } -} diff --git a/es/tsconfig.json b/es/tsconfig.json deleted file mode 100644 index f01e1d2..0000000 --- a/es/tsconfig.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "compileOnSave": true, - "compilerOptions": { - "target": "es2018", - "module": "commonjs", - "moduleResolution": "node", - "experimentalDecorators": true, - "emitDecoratorMetadata": true, - "inlineSourceMap":false, - "noImplicitThis": true, - "noUnusedLocals": true, - "stripInternal": true, - "skipLibCheck": true, - "noImplicitReturns": false, - "pretty": true, - "declaration": true, - "outDir": "dist" - }, - "exclude": [ - "dist", - "node_modules", - "test" - ] -} diff --git a/file/.editorconfig b/file/.editorconfig deleted file mode 100644 index 4c7f8a8..0000000 --- a/file/.editorconfig +++ /dev/null @@ -1,11 +0,0 @@ -# 🎨 editorconfig.org - -root = true - -[*] -charset = utf-8 -end_of_line = lf -indent_style = space -indent_size = 2 -trim_trailing_whitespace = true -insert_final_newline = true \ No newline at end of file diff --git a/file/.eslintrc.json b/file/.eslintrc.json deleted file mode 100644 index 93e32bd..0000000 --- a/file/.eslintrc.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "extends": "./node_modules/mwts/", - "ignorePatterns": ["node_modules", "dist", "test", "jest.config.js", "typings"], - "env": { - "jest": true - }, - "rules": { - "@typescript-eslint/explicit-module-boundary-types": "off", - "@typescript-eslint/no-unused-vars": "off", - "@typescript-eslint/ban-ts-comment": "off", - "node/no-extraneous-import": "off", - "no-empty": "off", - "node/no-extraneous-require": "off", - "eqeqeq": "off", - "node/no-unsupported-features/node-builtins": "off", - "@typescript-eslint/ban-types": "off", - "no-control-regex": "off", - "prefer-const": "off" - } -} diff --git a/file/.gitignore b/file/.gitignore deleted file mode 100644 index 13bc3a6..0000000 --- a/file/.gitignore +++ /dev/null @@ -1,15 +0,0 @@ -logs/ -npm-debug.log -yarn-error.log -node_modules/ -package-lock.json -yarn.lock -coverage/ -dist/ -.idea/ -run/ -.DS_Store -*.sw* -*.un~ -.tsbuildinfo -.tsbuildinfo.* diff --git a/file/.prettierrc.js b/file/.prettierrc.js deleted file mode 100644 index b964930..0000000 --- a/file/.prettierrc.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - ...require('mwts/.prettierrc.json') -} diff --git a/file/LICENSE b/file/LICENSE deleted file mode 100644 index 5a739ee..0000000 --- a/file/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2013 - Now midwayjs - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/file/index.d.ts b/file/index.d.ts deleted file mode 100644 index e0065de..0000000 --- a/file/index.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -export * from './dist/index'; - -declare module '@midwayjs/core/dist/interface' { - interface MidwayConfig { - book?: PowerPartial<{ - a: number; - b: string; - }>; - } -} diff --git a/file/jest.config.js b/file/jest.config.js deleted file mode 100644 index 82a8b85..0000000 --- a/file/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = { - preset: 'ts-jest', - testEnvironment: 'node', - testPathIgnorePatterns: ['/test/fixtures'], - coveragePathIgnorePatterns: ['/test/'], - setupFilesAfterEnv: ['./jest.setup.js'] -}; diff --git a/file/jest.setup.js b/file/jest.setup.js deleted file mode 100644 index 1399c91..0000000 --- a/file/jest.setup.js +++ /dev/null @@ -1 +0,0 @@ -jest.setTimeout(30000); diff --git a/file/package.json b/file/package.json deleted file mode 100644 index 0f08d5e..0000000 --- a/file/package.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "name": "@cool-midway/file", - "version": "7.0.5", - "description": "", - "main": "dist/index.js", - "typings": "index.d.ts", - "scripts": { - "build": "cross-env midway-bin build -c", - "cov": "cross-env midway-bin cov --ts", - "lint": "mwts check", - "lint:fix": "mwts fix" - }, - "keywords": [ - "cool", - "cool-admin", - "cooljs" - ], - "author": "COOL", - "files": [ - "dist/**/*.js", - "dist/**/*.d.ts", - "index.d.ts" - ], - "license": "MIT", - "repository": { - "type": "git", - "url": "https://cool-js.com" - }, - "devDependencies": { - "@cool-midway/core": "^7.0.0", - "@midwayjs/cli": "^2.0.9", - "@midwayjs/core": "^3.9.0", - "@midwayjs/decorator": "^3.9.0", - "@midwayjs/mock": "^3.9.0", - "@types/jest": "^29.2.5", - "@types/node": "^18.11.18", - "cross-env": "^7.0.3", - "jest": "^29.3.1", - "lodash": "^4.17.21", - "mwts": "^1.3.0", - "ts-jest": "^29.0.3", - "typescript": "^4.9.4" - }, - "dependencies": { - "@aws-sdk/client-s3": "^3.414.0", - "@aws-sdk/s3-presigned-post": "^3.414.0", - "@midwayjs/upload": "^3.9.9", - "ali-oss": "^6.17.1", - "cos-nodejs-sdk-v5": "^2.11.19", - "download": "^8.0.0", - "qcloud-cos-sts": "^3.1.0", - "qiniu": "^7.8.0" - } -} diff --git a/file/src/README.md b/file/src/README.md deleted file mode 100644 index 7edd966..0000000 --- a/file/src/README.md +++ /dev/null @@ -1,27 +0,0 @@ -### COOL-ADMIN - -cool-admin一个很酷的后台权限管理系统,开源免费,模块化、插件化、极速开发CRUD,方便快速构建迭代后台管理系统 - -大数据、微服务、AI编码快速开发!!! - - -### 技术栈 - -- 后端:node.js midway.js koa.js mysql typescript -- 前端:vue.js element-plus jsx pinia vue-router - -### 官网 - -[https://cool-js.com](https://cool-js.com) - - -### 演示地址 - -[https://show.cool-admin.com](https://show.cool-admin.com) - -- 账户:admin -- 密码:123456 - -### 项目地址 - -[https://github.com/cool-team-official/cool-admin-midway](https://github.com/cool-team-official/cool-admin-midway) \ No newline at end of file diff --git a/file/src/config/config.default.ts b/file/src/config/config.default.ts deleted file mode 100644 index 9b0cf96..0000000 --- a/file/src/config/config.default.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { CoolFileConfig } from './../interface'; -import { MODETYPE } from '../interface'; - -/** - * cool的配置 - */ -export default { - cool: { - file: { - // 上传模式 - mode: MODETYPE.LOCAL, - // 文件路径前缀 本地上传模式下 有效 - domain: 'http://127.0.0.1:8001', - } as CoolFileConfig, - }, -}; diff --git a/file/src/configuration.ts b/file/src/configuration.ts deleted file mode 100644 index e4ef4ba..0000000 --- a/file/src/configuration.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { Configuration } from '@midwayjs/decorator'; -import * as DefaultConfig from './config/config.default'; -import * as upload from '@midwayjs/upload'; -import { IMidwayContainer } from '@midwayjs/core'; -import { CoolFile } from './file'; - -@Configuration({ - namespace: 'cool:file', - importConfigs: [ - { - default: DefaultConfig, - }, - ], - imports: [upload], -}) -export class CoolFileConfiguration { - async onReady(container: IMidwayContainer) { - await container.getAsync(CoolFile); - // TODO something - } -} diff --git a/file/src/file.ts b/file/src/file.ts deleted file mode 100644 index 13f531e..0000000 --- a/file/src/file.ts +++ /dev/null @@ -1,568 +0,0 @@ -import { - App, - Config, - Init, - Logger, - Provide, - Scope, - ScopeEnum, -} from '@midwayjs/decorator'; -import { Mode, CoolFileConfig, MODETYPE, CLOUDTYPE } from './interface'; -import { CoolCommException } from '@cool-midway/core'; -import * as moment from 'moment'; -import { v1 as uuid } from 'uuid'; -import * as path from 'path'; -import * as fs from 'fs'; -import { ILogger, IMidwayApplication } from '@midwayjs/core'; -import * as _ from 'lodash'; -import * as OSS from 'ali-oss'; -import * as crypto from 'crypto'; -import * as STS from 'qcloud-cos-sts'; -import * as download from 'download'; -import * as COS from 'cos-nodejs-sdk-v5'; -import * as QINIU from 'qiniu'; -import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3'; -import { createPresignedPost } from '@aws-sdk/s3-presigned-post'; - -/** - * 文件上传 - */ -@Provide() -@Scope(ScopeEnum.Singleton) -export class CoolFile { - @Config('cool.file') - config: CoolFileConfig; - - @Logger() - coreLogger: ILogger; - - client: OSS & COS & QINIU.auth.digest.Mac & S3Client; - - @App() - app: IMidwayApplication; - - @Init() - async init(config: CoolFileConfig) { - const filePath = path.join(this.app.getBaseDir(), '..', 'public'); - const uploadsPath = path.join(filePath, 'uploads'); - const tempPath = path.join(filePath, 'temp'); - if (!fs.existsSync(uploadsPath)) { - fs.mkdirSync(uploadsPath); - } - if (!fs.existsSync(tempPath)) { - fs.mkdirSync(tempPath); - } - if (config) { - this.config = config; - } - const { mode, oss, cos, qiniu, aws } = this.config; - if (mode == MODETYPE.CLOUD) { - if (oss) { - const { accessKeyId, accessKeySecret, bucket, endpoint } = oss; - this.client = new OSS({ - region: endpoint.split('.')[0], - accessKeyId, - accessKeySecret, - bucket, - }); - } - if (cos) { - const { accessKeyId, accessKeySecret } = cos; - this.client = new COS({ - SecretId: accessKeyId, - SecretKey: accessKeySecret, - }); - } - if (qiniu) { - const { accessKeyId, accessKeySecret } = qiniu; - this.client = new QINIU.auth.digest.Mac(accessKeyId, accessKeySecret); - } - if (aws) { - const { - accessKeyId, - secretAccessKey, - region, - publicDomain, - forcePathStyle, - } = aws; - this.client = new S3Client({ - region, - credentials: { accessKeyId, secretAccessKey }, - // 支持自定义s3服务,如minio等 - endpoint: publicDomain - ? publicDomain - : `https://s3.${region}.amazonaws.com`, - // minio 使用域名时,forcePathStyle为true时,不增加二级域名,而是 xx.com/bucket的形式 - forcePathStyle: forcePathStyle ? forcePathStyle : false, - }); - } - } - } - - /** - * 上传模式 - * @returns 上传模式 - */ - async getMode(): Promise { - const { mode, oss, cos, qiniu, aws } = this.config; - if (mode == MODETYPE.LOCAL) { - return { - mode: MODETYPE.LOCAL, - type: MODETYPE.LOCAL, - }; - } - if (oss) { - return { - mode: MODETYPE.CLOUD, - type: CLOUDTYPE.OSS, - }; - } - if (cos) { - return { - mode: MODETYPE.CLOUD, - type: CLOUDTYPE.COS, - }; - } - if (qiniu) { - return { - mode: MODETYPE.CLOUD, - type: CLOUDTYPE.QINIU, - }; - } - if (aws) { - return { - mode: MODETYPE.CLOUD, - type: CLOUDTYPE.AWS, - }; - } - } - - /** - * 获得原始操作对象 - * @returns - */ - getMetaFileObj(): OSS & COS & QINIU.auth.digest.Mac & S3Client { - return this.client; - } - - /** - * 下载并上传 - * @param url - * @param fileName 文件名 - */ - async downAndUpload(url: string, fileName?: string) { - const { mode, oss, cos, qiniu, aws, domain } = this.config; - let extend = ''; - if (url.includes('.')) { - const urlArr = url.split('.'); - extend = '.' + urlArr[urlArr.length - 1].split('?')[0]; - } - - const data = url.includes('http') - ? await download(url) - : fs.readFileSync(url); - - const isCloud = mode == MODETYPE.CLOUD; - // 创建文件夹 - const dirPath = path.join( - this.app.getBaseDir(), - '..', - `public/${isCloud ? 'temp' : 'uploads'}/${moment().format('YYYYMMDD')}` - ); - if (!fs.existsSync(dirPath)) { - fs.mkdirSync(dirPath); - } - const uuidStr = uuid(); - const name = `uploads/${moment().format('YYYYMMDD')}/${ - fileName ? fileName : uuidStr + extend - }`; - if (isCloud) { - if (oss) { - const ossClient: OSS = this.getMetaFileObj(); - const { url } = await ossClient.put(name, data); - return oss.publicDomain ? `${oss.publicDomain}/${name}` : url; - } - if (cos) { - const cosClient: COS = this.getMetaFileObj(); - await cosClient.putObject({ - Bucket: cos.bucket, - Region: cos.region, - Key: name, - Body: data, - }); - return cos.publicDomain + '/' + name; - } - if (aws) { - const { bucket, fields, region, publicDomain } = aws; - const uploadParams = { - Bucket: bucket, - Key: name, - Body: data, - ACL: fields ? fields.acl : 'public-read', - }; - const command = new PutObjectCommand(uploadParams); - await this.client.send(command); - return publicDomain - ? `${publicDomain}/${name}` - : `https://${bucket}.s3.${region}.amazonaws.com/${name}`; - } - if (qiniu) { - let uploadToken = (await this.qiniu())['token']; - const formUploader = new QINIU.form_up.FormUploader(); - const putExtra = new QINIU.form_up.PutExtra(); - return new Promise((resolve, reject) => { - formUploader.put( - uploadToken, - name, - data, - putExtra, - (respErr, respBody, respInfo) => { - if (respErr) { - throw respErr; - } - if (respInfo.statusCode == 200) { - resolve(qiniu.publicDomain + '/' + name); - } - } - ); - }); - } - } else { - fs.writeFileSync( - `${dirPath}/${fileName ? fileName : uuidStr + extend}`, - data - ); - return `${domain}/public/${name}`; - } - } - - /** - * 指定Key(路径)上传 - * @param filePath 文件路径 - * @param key 路径一致会覆盖源文件 - */ - async uploadWithKey(filePath, key) { - const { mode, oss, cos, qiniu, aws } = this.config; - const data = fs.readFileSync(filePath); - if (mode == MODETYPE.LOCAL) { - fs.writeFileSync(path.join(this.app.getBaseDir(), '..', key), data); - return this.config.domain + key; - } - if (mode == MODETYPE.CLOUD) { - if (oss) { - const ossClient: OSS = this.getMetaFileObj(); - const { url } = await ossClient.put(key, data); - return oss.publicDomain ? `${oss.publicDomain}/${key}` : url; - } - if (cos) { - const cosClient: COS = this.getMetaFileObj(); - await cosClient.putObject({ - Bucket: cos.bucket, - Region: cos.region, - Key: key, - Body: data, - }); - return cos.publicDomain + '/' + key; - } - if (qiniu) { - let uploadToken = (await this.qiniu())['token']; - const formUploader = new QINIU.form_up.FormUploader(); - const putExtra = new QINIU.form_up.PutExtra(); - return new Promise((resolve, reject) => { - formUploader.put( - uploadToken, - key, - data, - putExtra, - (respErr, respBody, respInfo) => { - if (respErr) { - throw respErr; - } - if (respInfo.statusCode == 200) { - resolve(qiniu.publicDomain + '/' + key); - } - } - ); - }); - } - if (aws) { - const { bucket, fields, region, publicDomain } = aws; - const uploadParams = { - Bucket: bucket, - Key: key, - Body: data, - ACL: fields ? fields.acl : 'public-read', - }; - const command = new PutObjectCommand(uploadParams); - await this.client.send(command); - return publicDomain - ? `${publicDomain}/${key}` - : `https://${bucket}.s3.${region}.amazonaws.com/${key}`; - } - } - } - - /** - * 上传文件 - * @param ctx - * @param key 文件路径 - */ - async upload(ctx) { - const { mode, oss, cos, qiniu, aws } = this.config; - if (mode == MODETYPE.LOCAL) { - return await this.local(ctx); - } - if (mode == MODETYPE.CLOUD) { - if (oss) { - return await this.oss(ctx); - } - if (cos) { - return await this.cos(ctx); - } - if (qiniu) { - return await this.qiniu(ctx); - } - if (aws) { - return await this.aws(ctx); - } - } - } - - /** - * aws 文件上传 - * @param ctx - */ - private async aws(ctx) { - let { - bucket, - fields = {}, - conditions = [], - expires = 3600, - } = this.config.aws; - const { key } = ctx.request.body; - if (!conditions) { - conditions = [{ acl: 'public-read' }, { bucket }]; - } - if (_.isEmpty(fields)) { - fields = { - acl: 'public-read', - }; - } - const result = await createPresignedPost(this.client, { - Bucket: bucket, - Key: key, - Conditions: conditions, - Fields: fields, - Expires: expires, - }); - return result; - } - - /** - * 七牛上传 - * @param ctx - * @returns - */ - private async qiniu(ctx?) { - const { - bucket, - publicDomain, - region, - uploadUrl = `https://upload-${region}.qiniup.com/`, - fileKey = 'file', - } = this.config.qiniu; - let options = { - scope: bucket, - }; - const putPolicy = new QINIU.rs.PutPolicy(options); - const uploadToken = putPolicy.uploadToken(this.client); - return new Promise((resolve, reject) => { - resolve({ - uploadUrl, - publicDomain, - token: uploadToken, - fileKey, - }); - }); - } - - /** - * OSS 文件上传 - * @param ctx - */ - private async oss(ctx) { - const { - accessKeyId, - accessKeySecret, - bucket, - endpoint, - expAfter = 300000, - maxSize = 200 * 1024 * 1024, - host, - publicDomain, - } = this.config.oss; - const oss = { - bucket, - region: endpoint.split('.')[0], // 我的是 hangzhou - accessKeyId, - accessKeySecret, - expAfter, // 签名失效时间,毫秒 - maxSize, // 文件最大的 size - }; - const newHost = host ? host : `https://${bucket}.${endpoint}`; - const expireTime = new Date().getTime() + oss.expAfter; - const expiration = new Date(expireTime).toISOString(); - const policyString = JSON.stringify({ - expiration, - conditions: [ - ['content-length-range', 0, oss.maxSize], // 设置上传文件的大小限制,200mb - ], - }); - const policy = Buffer.from(policyString).toString('base64'); - - const signature = crypto - .createHmac('sha1', oss.accessKeySecret) - .update(policy) - .digest('base64'); - - return { - signature, - policy, - host: newHost, - publicDomain, - OSSAccessKeyId: accessKeyId, - success_action_status: 200, - }; - } - - /** - * COS 文件上传 - * @param ctx - */ - private async cos(ctx) { - const { - accessKeyId, - accessKeySecret, - bucket, - region, - publicDomain, - durationSeconds = 1800, - allowPrefix = '_ALLOW_DIR_/*', - allowActions = [ - // 所有 action 请看文档 https://cloud.tencent.com/document/product/436/31923 - // 简单上传 - 'name/cos:PutObject', - 'name/cos:PostObject', - // 分片上传 - 'name/cos:InitiateMultipartUpload', - 'name/cos:ListMultipartUploads', - 'name/cos:ListParts', - 'name/cos:UploadPart', - 'name/cos:CompleteMultipartUpload', - ], - } = this.config.cos; - // 配置参数 - let config = { - secretId: accessKeyId, - secretKey: accessKeySecret, - durationSeconds, - bucket: bucket, - region: region, - // 允许操作(上传)的对象前缀,可以根据自己网站的用户登录态判断允许上传的目录,例子: user1/* 或者 * 或者a.jpg - // 请注意当使用 * 时,可能存在安全风险,详情请参阅:https://cloud.tencent.com/document/product/436/40265 - allowPrefix, - // 密钥的权限列表 - allowActions, - }; - - // 获取临时密钥 - let LongBucketName = config.bucket; - let ShortBucketName = LongBucketName.substring( - 0, - LongBucketName.lastIndexOf('-') - ); - let AppId = LongBucketName.substring(LongBucketName.lastIndexOf('-') + 1); - - let policy = { - version: '2.0', - statement: [ - { - action: config.allowActions, - effect: 'allow', - resource: [ - 'qcs::cos:' + - config.region + - ':uid/' + - AppId + - ':prefix//' + - AppId + - '/' + - ShortBucketName + - '/' + - config.allowPrefix, - ], - }, - ], - }; - - return new Promise((resolve, reject) => { - STS.getCredential( - { - secretId: config.secretId, - secretKey: config.secretKey, - durationSeconds: config.durationSeconds, - policy: policy, - }, - (err, tempKeys) => { - if (err) { - reject(err); - } - if (tempKeys) { - tempKeys.startTime = Math.round(Date.now() / 1000); - } - resolve({ - ...tempKeys, - url: publicDomain, - }); - } - ); - }); - } - - /** - * 本地上传 - * @param ctx - * @returns - */ - private async local(ctx) { - try { - const { key } = ctx.fields; - if (_.isEmpty(ctx.files)) { - throw new CoolCommException('上传文件为空'); - } - const file = ctx.files[0]; - const extension = file.filename.split('.').pop(); - const name = - moment().format('YYYYMMDD') + '/' + (key || `${uuid()}.${extension}`); - const target = path.join( - this.app.getBaseDir(), - '..', - `public/uploads/${name}` - ); - const dirPath = path.join( - this.app.getBaseDir(), - '..', - `public/uploads/${moment().format('YYYYMMDD')}` - ); - if (!fs.existsSync(dirPath)) { - fs.mkdirSync(dirPath); - } - const data = fs.readFileSync(file.data); - fs.writeFileSync(target, data); - return this.config.domain + '/public/uploads/' + name; - } catch (err) { - this.coreLogger.error(err); - throw new CoolCommException('上传失败'); - } - } -} diff --git a/file/src/index.ts b/file/src/index.ts deleted file mode 100644 index 5a58056..0000000 --- a/file/src/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -export { CoolFileConfiguration as Configuration } from './configuration'; - -export * from './interface'; - -export * from './file'; diff --git a/file/src/interface.ts b/file/src/interface.ts deleted file mode 100644 index 6f8005f..0000000 --- a/file/src/interface.ts +++ /dev/null @@ -1,132 +0,0 @@ -// 模式 -export enum MODETYPE { - // 本地 - LOCAL = 'local', - // 云存储 - CLOUD = 'cloud', - // 其他 - OTHER = 'other', -} - -export enum CLOUDTYPE { - // 阿里云存储 - OSS = 'oss', - // 腾讯云存储 - COS = 'cos', - // 七牛云存储 - QINIU = 'qiniu', - /** AWS S3 */ - AWS = 'aws', -} - -/** - * 上传模式 - */ -export interface Mode { - // 模式 - mode: MODETYPE; - // 类型 - type: string; -} - -/** - * 模块配置 - */ -export interface CoolFileConfig { - // 上传模式 - mode: MODETYPE; - // 阿里云oss 配置 - oss: OSSConfig; - // 腾讯云 cos配置 - cos: COSConfig; - // 七牛云 配置 - qiniu: QINIUConfig; - /** AWS s3 配置 */ - aws: AWSConfig; - // 文件前缀 - domain: string; -} - -/** - * OSS 配置 - */ -export interface OSSConfig { - // 阿里云accessKeyId - accessKeyId: string; - // 阿里云accessKeySecret - accessKeySecret: string; - // 阿里云oss的bucket - bucket: string; - // 阿里云oss的endpoint - endpoint: string; - // 阿里云oss的timeout - timeout: string; - // 签名失效时间,毫秒 - expAfter?: number; - // 文件最大的 size - maxSize?: number; - // host - host?: string; - // 阿里云oss的公网访问地址 - publicDomain?: string; -} - -/** - * COS 配置 - */ -export interface COSConfig { - // 腾讯云accessKeyId - accessKeyId: string; - // 腾讯云accessKeySecret - accessKeySecret: string; - // 腾讯云cos的bucket - bucket: string; - // 腾讯云cos的区域 - region: string; - // 腾讯云cos的公网访问地址 - publicDomain: string; - // 上传持续时间 - durationSeconds?: number; - // 允许操作(上传)的对象前缀 - allowPrefix?: string; - // 密钥的权限列表 - allowActions?: string[]; -} - -export interface AWSConfig { - /** accessKeyId */ - accessKeyId: string; - /** secretAccessKey */ - secretAccessKey: string; - /** bucket */ - bucket: string; - /** region */ - region: string; - /** fields */ - fields?: any; - /** conditions */ - conditions?: any[]; - /** expires */ - expires?: number; - /** publicDomain */ - publicDomain?: string; - /** forcePathStyle */ - forcePathStyle?: boolean; -} - -export interface QINIUConfig { - // 七牛云accessKeyId - accessKeyId: string; - // 七牛云accessKeySecret - accessKeySecret: string; - // 七牛云cos的bucket - bucket: string; - // 七牛云cos的区域 - region: string; - // 七牛云cos的公网访问地址 - publicDomain: string; - // 上传地址 - uploadUrl?: string; - // 上传fileKey - fileKey?: string; -} diff --git a/file/src/package.json b/file/src/package.json deleted file mode 100644 index d206cf2..0000000 --- a/file/src/package.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "name": "@cool-midway/file", - "version": "7.0.5", - "description": "", - "main": "index.js", - "typings": "index.d.ts", - "scripts": { - "build": "cross-env midway-bin build -c", - "cov": "cross-env midway-bin cov --ts", - "lint": "mwts check", - "lint:fix": "mwts fix" - }, - "keywords": [ - "cool", - "cool-admin", - "cooljs" - ], - "author": "COOL", - "files": [ - "**/*.js", - "**/*.d.ts", - "index.d.ts" - ], - "license": "MIT", - "repository": { - "type": "git", - "url": "https://cool-js.com" - }, - "devDependencies": { - "@cool-midway/core": "^7.0.0", - "@midwayjs/cli": "^2.0.9", - "@midwayjs/core": "^3.9.0", - "@midwayjs/decorator": "^3.9.0", - "@midwayjs/mock": "^3.9.0", - "@types/jest": "^29.2.5", - "@types/node": "^18.11.18", - "cross-env": "^7.0.3", - "jest": "^29.3.1", - "lodash": "^4.17.21", - "mwts": "^1.3.0", - "ts-jest": "^29.0.3", - "typescript": "^4.9.4" - }, - "dependencies": { - "@midwayjs/upload": "^3.9.1", - "ali-oss": "^6.17.1", - "cos-nodejs-sdk-v5": "^2.11.19", - "download": "^8.0.0", - "qcloud-cos-sts": "^3.1.0", - "qiniu": "^7.8.0", - "@aws-sdk/client-s3": "^3.414.0", - "@aws-sdk/s3-presigned-post": "^3.414.0" - } -} diff --git a/file/tsconfig.json b/file/tsconfig.json deleted file mode 100644 index 9bb4ab7..0000000 --- a/file/tsconfig.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "compileOnSave": true, - "compilerOptions": { - "target": "es2018", - "module": "commonjs", - "moduleResolution": "node", - "experimentalDecorators": true, - "emitDecoratorMetadata": true, - "inlineSourceMap":false, - "noImplicitThis": true, - "noUnusedLocals": true, - "stripInternal": true, - "skipLibCheck": true, - "noImplicitReturns": false, - "pretty": true, - "declaration": true, - "forceConsistentCasingInFileNames": true, - "outDir": "dist" - }, - "exclude": [ - "dist", - "node_modules", - "test" - ] -} diff --git a/iot/.editorconfig b/iot/.editorconfig deleted file mode 100644 index 4c7f8a8..0000000 --- a/iot/.editorconfig +++ /dev/null @@ -1,11 +0,0 @@ -# 🎨 editorconfig.org - -root = true - -[*] -charset = utf-8 -end_of_line = lf -indent_style = space -indent_size = 2 -trim_trailing_whitespace = true -insert_final_newline = true \ No newline at end of file diff --git a/iot/.eslintrc.json b/iot/.eslintrc.json deleted file mode 100644 index aad9755..0000000 --- a/iot/.eslintrc.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "extends": "./node_modules/mwts/", - "ignorePatterns": [ - "node_modules", - "dist", - "test", - "jest.config.js", - "typings", - "public/**/**", - "view/**/**" - ], - "env": { - "jest": true - }, - "rules": { - "@typescript-eslint/explicit-module-boundary-types": "off", - "@typescript-eslint/no-unused-vars": "off", - "@typescript-eslint/ban-ts-comment": "off", - "node/no-extraneous-import": "off", - "no-empty": "off", - "node/no-extraneous-require": "off", - "eqeqeq": "off", - "node/no-unsupported-features/node-builtins": "off", - "@typescript-eslint/ban-types": "off", - "no-control-regex": "off", - "prefer-const": "off" - } -} \ No newline at end of file diff --git a/iot/.gitignore b/iot/.gitignore deleted file mode 100644 index 13bc3a6..0000000 --- a/iot/.gitignore +++ /dev/null @@ -1,15 +0,0 @@ -logs/ -npm-debug.log -yarn-error.log -node_modules/ -package-lock.json -yarn.lock -coverage/ -dist/ -.idea/ -run/ -.DS_Store -*.sw* -*.un~ -.tsbuildinfo -.tsbuildinfo.* diff --git a/iot/.prettierrc.js b/iot/.prettierrc.js deleted file mode 100644 index b964930..0000000 --- a/iot/.prettierrc.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - ...require('mwts/.prettierrc.json') -} diff --git a/iot/README.md b/iot/README.md deleted file mode 100644 index 610c3db..0000000 --- a/iot/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# cool-admin - -https://cool-js.com diff --git a/iot/index.d.ts b/iot/index.d.ts deleted file mode 100644 index e0065de..0000000 --- a/iot/index.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -export * from './dist/index'; - -declare module '@midwayjs/core/dist/interface' { - interface MidwayConfig { - book?: PowerPartial<{ - a: number; - b: string; - }>; - } -} diff --git a/iot/jest.config.js b/iot/jest.config.js deleted file mode 100644 index 82a8b85..0000000 --- a/iot/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = { - preset: 'ts-jest', - testEnvironment: 'node', - testPathIgnorePatterns: ['/test/fixtures'], - coveragePathIgnorePatterns: ['/test/'], - setupFilesAfterEnv: ['./jest.setup.js'] -}; diff --git a/iot/jest.setup.js b/iot/jest.setup.js deleted file mode 100644 index 1399c91..0000000 --- a/iot/jest.setup.js +++ /dev/null @@ -1 +0,0 @@ -jest.setTimeout(30000); diff --git a/iot/package.json b/iot/package.json deleted file mode 100644 index 818ad47..0000000 --- a/iot/package.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "name": "@cool-midway/iot", - "version": "7.0.0", - "description": "cool-js.com iot模块", - "main": "dist/index.js", - "typings": "index.d.ts", - "scripts": { - "build": "cross-env midway-bin build -c", - "cov": "cross-env midway-bin cov --ts", - "lint": "mwts check", - "lint:fix": "mwts fix" - }, - "keywords": [ - "cool", - "cool-admin", - "cooljs", - "cool-iot", - "iot" - ], - "author": "COOL", - "readme": "README.md", - "license": "MIT", - "repository": { - "type": "git", - "url": "https://cool-js.com" - }, - "files": [ - "dist/**/*.js", - "dist/**/*.d.ts", - "index.d.ts" - ], - "devDependencies": { - "@cool-midway/core": "^7.0.0", - "@midwayjs/cli": "^2.0.9", - "@midwayjs/core": "^3.9.0", - "@midwayjs/decorator": "^3.9.0", - "@midwayjs/mock": "^3.9.0", - "@types/jest": "^29.2.5", - "@types/node": "^18.11.18", - "cross-env": "^7.0.3", - "jest": "^29.3.1", - "mwts": "^1.3.0", - "ts-jest": "^29.0.3", - "typescript": "^4.9.4" - }, - "dependencies": { - "@cool-midway/mqemitter-redis": "^6.0.0", - "aedes": "^0.48.1", - "aedes-persistence-redis": "^9.0.2", - "aedes-server-factory": "^0.2.1" - } -} diff --git a/iot/src/README.md b/iot/src/README.md deleted file mode 100644 index 7edd966..0000000 --- a/iot/src/README.md +++ /dev/null @@ -1,27 +0,0 @@ -### COOL-ADMIN - -cool-admin一个很酷的后台权限管理系统,开源免费,模块化、插件化、极速开发CRUD,方便快速构建迭代后台管理系统 - -大数据、微服务、AI编码快速开发!!! - - -### 技术栈 - -- 后端:node.js midway.js koa.js mysql typescript -- 前端:vue.js element-plus jsx pinia vue-router - -### 官网 - -[https://cool-js.com](https://cool-js.com) - - -### 演示地址 - -[https://show.cool-admin.com](https://show.cool-admin.com) - -- 账户:admin -- 密码:123456 - -### 项目地址 - -[https://github.com/cool-team-official/cool-admin-midway](https://github.com/cool-team-official/cool-admin-midway) \ No newline at end of file diff --git a/iot/src/config/config.default.ts b/iot/src/config/config.default.ts deleted file mode 100644 index ee625da..0000000 --- a/iot/src/config/config.default.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { CoolIotConfig } from '../interface'; - -/** - * cool的配置 - */ -export default { - cool: { - iot: { - port: 1883, - wsPort: 8083, - } as CoolIotConfig, - }, -}; diff --git a/iot/src/configuration.ts b/iot/src/configuration.ts deleted file mode 100644 index ecb17aa..0000000 --- a/iot/src/configuration.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { CoolMqttServe } from './mqtt'; -import { Configuration } from '@midwayjs/decorator'; -import * as DefaultConfig from './config/config.default'; -import { IMidwayContainer } from '@midwayjs/core'; - -@Configuration({ - namespace: 'cool:iot', - importConfigs: [ - { - default: DefaultConfig, - }, - ], -}) -export class CoolIotConfiguration { - async onReady(container: IMidwayContainer) { - (await container.getAsync(CoolMqttServe)).init(); - } -} diff --git a/iot/src/decorator/mqtt.ts b/iot/src/decorator/mqtt.ts deleted file mode 100644 index 8feb4f6..0000000 --- a/iot/src/decorator/mqtt.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { - Scope, - ScopeEnum, - saveClassMetadata, - saveModule, - attachClassMetadata, -} from '@midwayjs/core'; - -export const COOL_MQTT_KEY = 'decorator:cool:cls:mqtt'; - -export function CoolMqtt(): ClassDecorator { - return (target: any) => { - // 将装饰的类,绑定到该装饰器,用于后续能获取到 class - saveModule(COOL_MQTT_KEY, target); - // 保存一些元数据信息,任意你希望存的东西 - saveClassMetadata(COOL_MQTT_KEY, {}, target); - // 指定 IoC 容器创建实例的作用域,这里注册为请求作用域,这样能取到 ctx - Scope(ScopeEnum.Singleton)(target); - }; -} - -export const COOL_MQTT_EVENT_KEY = 'decorator:cool:mqtt:event'; - -/** - * 事件 - * @param eventName - * @returns - */ -export function CoolMqttEvent(eventName?: string): MethodDecorator { - return (target: any, propertyKey: string, descriptor: PropertyDescriptor) => { - // 将装饰的类,绑定到该装饰器,用于后续能获取到 class - attachClassMetadata( - COOL_MQTT_EVENT_KEY, - { - eventName, - propertyKey, - descriptor, - }, - target - ); - }; -} diff --git a/iot/src/index.ts b/iot/src/index.ts deleted file mode 100644 index e827cde..0000000 --- a/iot/src/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -export { CoolIotConfiguration as Configuration } from './configuration'; - -export * from './decorator/mqtt'; - -export * from './mqtt'; - -export * from './interface'; diff --git a/iot/src/interface.ts b/iot/src/interface.ts deleted file mode 100644 index ca033f1..0000000 --- a/iot/src/interface.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { AedesOptions } from 'aedes'; -import { PublishPacket } from 'packet'; - -/** - * MQTT配置 - */ -export interface CoolIotConfig { - /** MQTT服务端口 */ - port: number; - /** MQTT Websocket服务端口 */ - wsPort: number; - /** redis 配置 mqtt cluster下必须要配置 */ - redis?: { - /** host */ - host: string; - /** port */ - port: number; - /** password */ - password: string; - /** db */ - db: number; - }; - /** 发布消息配置 */ - publish?: PublishPacket; - /** 认证 */ - auth?: { - /** 用户 */ - username: string; - /** 密码 */ - password: string; - }; - /** 服务配置 */ - serve?: AedesOptions; -} diff --git a/iot/src/mqtt.ts b/iot/src/mqtt.ts deleted file mode 100644 index 7fade44..0000000 --- a/iot/src/mqtt.ts +++ /dev/null @@ -1,163 +0,0 @@ -import { CoolIotConfig } from './interface'; -import { - App, - Config, - getClassMetadata, - ILogger, - IMidwayApplication, - listModule, - Logger, - Provide, - Scope, - ScopeEnum, -} from '@midwayjs/core'; -import { COOL_MQTT_EVENT_KEY, COOL_MQTT_KEY } from './decorator/mqtt'; -import Aedes, { AedesOptions } from 'aedes'; -import { randomUUID } from 'crypto'; - -/** - * MQTT服务 - */ -@Provide() -@Scope(ScopeEnum.Singleton) -export class CoolMqttServe { - @Config('cool.iot') - coolIotConfig: CoolIotConfig; - - @Logger() - coreLogger: ILogger; - - serve: Aedes; - - @App() - app: IMidwayApplication; - - async init() { - await this.initServe(); - await this.handlerCls(); - await this.startServe(); - } - - /** - * 开启服务 - */ - async startServe() { - const { port, wsPort } = this.coolIotConfig; - const { createServer } = require('aedes-server-factory'); - const server = createServer(this.serve); - - const serverWs = createServer(this.serve, { ws: true }); - - server.listen(port, () => { - this.coreLogger.info( - `\x1B[36m [cool:iot] MQTT serve started port: ${port} \x1B[0m` - ); - }); - - serverWs.listen(wsPort, () => { - this.coreLogger.info( - `\x1B[36m [cool:iot] MQTT websocket serve started port: ${wsPort} \x1B[0m` - ); - }); - } - - /** - * 初始化服务 - */ - async initServe() { - const { redis } = this.coolIotConfig; - let option = {} as AedesOptions; - // cluster模式下必须配置redis - if (redis) { - const mqredis = require('@cool-midway/mqemitter-redis'); - const mq = mqredis(redis); - option.id = randomUUID(); - // redis cluster模式 - if (redis instanceof Array) { - option.persistence = require('aedes-persistence-redis')({ - cluster: redis, - maxSessionDelivery: 1000, // maximum offline messages deliverable on client CONNECT, default is 1000 - }); - } else { - option.persistence = require('aedes-persistence-redis')({ - ...redis, - maxSessionDelivery: 1000, // maximum offline messages deliverable on client CONNECT, default is 1000 - }); - } - option = { - id: randomUUID(), - mq, - }; - } - this.serve = require('aedes')(option); - - // 认证 - if (this.coolIotConfig.auth) { - const auth = this.coolIotConfig.auth; - this.serve.authenticate = function ( - client, - username, - password, - callback - ) { - callback( - null, - username === auth.username && password.toString() === auth.password - ); - }; - } - } - - /** - * 处理类 - */ - async handlerCls() { - const eventModules = listModule(COOL_MQTT_KEY); - for (const module of eventModules) { - this.handlerEvent(module); - } - } - - /** - * 处理事件 - * @param module - */ - async handlerEvent(module) { - const events = getClassMetadata(COOL_MQTT_EVENT_KEY, module); - for (const event of events) { - const method = event.eventName ? event.eventName : event.propertyKey; - this.serve.on(method, async (...args) => { - const moduleInstance = await this.app - .getApplicationContext() - .getAsync(module); - moduleInstance[event.propertyKey](...args); - }); - } - } - - /** - * 发送消息 - * @param topic 话题 - * @param message 消息 - * @param other 其他配置 - */ - async publish(topic, message, other?) { - this.serve.publish( - { - cmd: 'publish', - qos: 2, - dup: false, - topic, - payload: Buffer.from(message), - retain: false, - ...this.coolIotConfig.publish, - ...other, - }, - error => { - if (error) { - this.coreLogger.error('publish fail', error); - } - } - ); - } -} diff --git a/iot/src/package.json b/iot/src/package.json deleted file mode 100644 index a4ce1d2..0000000 --- a/iot/src/package.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "name": "@cool-midway/iot", - "version": "7.0.0", - "description": "cool-js.com iot模块", - "main": "index.js", - "typings": "index.d.ts", - "scripts": { - "build": "cross-env midway-bin build -c", - "cov": "cross-env midway-bin cov --ts", - "lint": "mwts check", - "lint:fix": "mwts fix" - }, - "keywords": [ - "cool", - "cool-admin", - "cooljs", - "cool-iot", - "iot" - ], - "author": "COOL", - "readme": "README.md", - "license": "MIT", - "repository": { - "type": "git", - "url": "https://cool-js.com" - }, - "files": [ - "**/*.js", - "**/*.d.ts", - "index.d.ts" - ], - "devDependencies": { - "@cool-midway/core": "^7.0.0", - "@midwayjs/cli": "^2.0.9", - "@midwayjs/core": "^3.9.0", - "@midwayjs/decorator": "^3.9.0", - "@midwayjs/mock": "^3.9.0", - "@types/jest": "^29.2.5", - "@types/node": "^18.11.18", - "cross-env": "^7.0.3", - "jest": "^29.3.1", - "mwts": "^1.3.0", - "ts-jest": "^29.0.3", - "typescript": "^4.9.4" - }, - "dependencies": { - "aedes": "^0.48.1", - "aedes-persistence-redis": "^9.0.2", - "@cool-midway/mqemitter-redis": "^6.0.0", - "aedes-server-factory": "^0.2.1" - } -} diff --git a/iot/tsconfig.json b/iot/tsconfig.json deleted file mode 100644 index f01e1d2..0000000 --- a/iot/tsconfig.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "compileOnSave": true, - "compilerOptions": { - "target": "es2018", - "module": "commonjs", - "moduleResolution": "node", - "experimentalDecorators": true, - "emitDecoratorMetadata": true, - "inlineSourceMap":false, - "noImplicitThis": true, - "noUnusedLocals": true, - "stripInternal": true, - "skipLibCheck": true, - "noImplicitReturns": false, - "pretty": true, - "declaration": true, - "outDir": "dist" - }, - "exclude": [ - "dist", - "node_modules", - "test" - ] -} diff --git a/other/cache-manager-fs-hash/LICENSE b/other/cache-manager-fs-hash/LICENSE deleted file mode 100644 index 924498c..0000000 --- a/other/cache-manager-fs-hash/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 Roland Starke - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/other/cache-manager-fs-hash/README.md b/other/cache-manager-fs-hash/README.md deleted file mode 100644 index 7edd966..0000000 --- a/other/cache-manager-fs-hash/README.md +++ /dev/null @@ -1,27 +0,0 @@ -### COOL-ADMIN - -cool-admin一个很酷的后台权限管理系统,开源免费,模块化、插件化、极速开发CRUD,方便快速构建迭代后台管理系统 - -大数据、微服务、AI编码快速开发!!! - - -### 技术栈 - -- 后端:node.js midway.js koa.js mysql typescript -- 前端:vue.js element-plus jsx pinia vue-router - -### 官网 - -[https://cool-js.com](https://cool-js.com) - - -### 演示地址 - -[https://show.cool-admin.com](https://show.cool-admin.com) - -- 账户:admin -- 密码:123456 - -### 项目地址 - -[https://github.com/cool-team-official/cool-admin-midway](https://github.com/cool-team-official/cool-admin-midway) \ No newline at end of file diff --git a/other/cache-manager-fs-hash/index.js b/other/cache-manager-fs-hash/index.js deleted file mode 100644 index 211e452..0000000 --- a/other/cache-manager-fs-hash/index.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('./src'); \ No newline at end of file diff --git a/other/cache-manager-fs-hash/package.json b/other/cache-manager-fs-hash/package.json deleted file mode 100644 index 79e6a5b..0000000 --- a/other/cache-manager-fs-hash/package.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "name": "@cool-midway/cache-manager-fs-hash", - "version": "7.0.0", - "main": "index.js", - "engines": { - "node": ">=8.0.0" - }, - "description": "file system store for node cache manager", - "author": "Roland Starke", - "license": "MIT", - "files": [ - "index.js", - "src/*" - ], - "keywords": [ - "cache-manager", - "storage", - "filesystem" - ], - "repository": { - "type": "git", - "url": "git+https://github.com/rolandstarke/node-cache-manager-fs-hash.git" - }, - "bugs": { - "url": "https://github.com/rolandstarke/node-cache-manager-fs-hash/issues" - }, - "scripts": { - }, - "devDependencies": { - "cache-manager": "^3.2.1", - "mocha": "^7.1.1", - "rimraf": "^3.0.2" - }, - "dependencies": { - "lockfile": "^1.0.4" - } -} diff --git a/other/cache-manager-fs-hash/src/index.js b/other/cache-manager-fs-hash/src/index.js deleted file mode 100644 index 784f0e6..0000000 --- a/other/cache-manager-fs-hash/src/index.js +++ /dev/null @@ -1,260 +0,0 @@ -const fs = require("fs"); -const crypto = require("crypto"); -const path = require("path"); -const promisify = require("util").promisify; -const lockFile = require("lockfile"); -const jsonFileStore = require("./json-file-store"); -const wrapCallback = require("./wrap-callback"); - -/** - * construction of the disk storage - * @param {object} [args] options of disk store - * @param {string} [args.path] path for cached files - * @param {number} [args.ttl] time to life in seconds - * @param {boolean} [args.zip] zip content to save diskspace - * @todo {number} [args.maxsize] max size in bytes on disk - * @param {boolean} [args.subdirs] create subdirectories - * @returns {DiskStore} - */ -exports.create = function (args) { - return new DiskStore(args && args.options ? args.options : args); -}; - -function DiskStore(options) { - options = options || {}; - - this.options = { - path: options.path || "./cache" /* path for cached files */, - ttl: options.ttl /* time before expiring in seconds */, - maxsize: options.maxsize || Infinity /* max size in bytes on disk */, - subdirs: options.subdirs || false, - zip: options.zip || false, - lockFile: { - //check lock at 0ms 50ms 100ms ... 400ms 1400ms 1450ms... up to 10 seconds, after that just asume the lock is staled - wait: 400, - pollPeriod: 50, - stale: 10 * 1000, - retries: 10, - retryWait: 600, - }, - }; - - // check storage directory for existence (or create it) - if (!fs.existsSync(this.options.path)) { - fs.mkdirSync(this.options.path); - } -} - -/** - * save an entry in store - * @param {string} key - * @param {*} val - * @param {object} [options] - * @param {number} options.ttl time to life in seconds - * @param {function} [cb] - * @returns {Promise} - */ -DiskStore.prototype.set = wrapCallback(async function (key, val, options) { - key = key + ""; - const filePath = this._getFilePathByKey(key); - - const ttl = options && options.ttl >= 0 ? +options.ttl : this.options.ttl; - const data = { - key: key, - val: val, - }; - if (ttl > 0) { - data.expireTime = Date.now() + ttl * 1000; - } - - if (this.options.subdirs) { - //check if subdir exists or create it - const dir = path.dirname(filePath); - await promisify(fs.access)(dir, fs.constants.W_OK).catch(function () { - return promisify(fs.mkdir)(dir).catch((err) => { - if (err.code !== "EEXIST") throw err; - }); - }); - } - - try { - await this._lock(filePath); - await jsonFileStore.write(filePath, data, this.options); - } catch (err) { - throw err; - } finally { - await this._unlock(filePath); - } -}); - -DiskStore.prototype._readFile = async function (key) { - key = key + ""; - const filePath = this._getFilePathByKey(key); - - try { - const data = await jsonFileStore - .read(filePath, this.options) - .catch(async (err) => { - if (err.code === "ENOENT") { - throw err; - } - //maybe the file is currently written to, lets lock it and read again - try { - await this._lock(filePath); - return await jsonFileStore.read(filePath, this.options); - } catch (err2) { - throw err2; - } finally { - await this._unlock(filePath); - } - }); - if (data.expireTime <= Date.now()) { - //cache expired - this.del(key).catch(() => 0 /* ignore */); - return undefined; - } - if (data.key !== key) { - //hash collision - return undefined; - } - return data; - } catch (err) { - //file does not exist lets return a cache miss - if (err.code === "ENOENT") { - return undefined; - } else { - throw err; - } - } -}; - -/** - * get an entry from store - * @param {string} key - * @param {function} [cb] - * @returns {Promise} - */ -DiskStore.prototype.get = wrapCallback(async function (key) { - const data = await this._readFile(key); - if (data) { - return data.val; - } else { - return data; - } -}); - -/** - * get ttl in seconds for key in store - * @param {string} key - * @param {function} [cb] - * @returns {Promise} - */ -DiskStore.prototype.ttl = wrapCallback(async function (key) { - const data = await this._readFile(key); - if (data) { - return (data.expireTime - Date.now()) / 1000; - } else { - return 0; - } -}); - -/** - * delete entry from cache - */ -DiskStore.prototype.del = wrapCallback(async function (key) { - const filePath = this._getFilePathByKey(key); - try { - if (this.options.subdirs) { - //check if the folder exists to fail faster - const dir = path.dirname(filePath); - await promisify(fs.access)(dir, fs.constants.W_OK); - } - - await this._lock(filePath); - await jsonFileStore.delete(filePath, this.options); - } catch (err) { - //ignore deleting non existing keys - if (err.code !== "ENOENT") { - throw err; - } - } finally { - await this._unlock(filePath); - } -}); - -/** - * cleanup cache on disk -> delete all files from the cache - */ -DiskStore.prototype.reset = wrapCallback(async function () { - const readdir = promisify(fs.readdir); - const stat = promisify(fs.stat); - const unlink = promisify(fs.unlink); - - return await deletePath(this.options.path, 2); - - async function deletePath(fileOrDir, maxDeep) { - if (maxDeep < 0) { - return; - } - const stats = await stat(fileOrDir); - if (stats.isDirectory()) { - const files = await readdir(fileOrDir); - for (let i = 0; i < files.length; i++) { - await deletePath(path.join(fileOrDir, files[i]), maxDeep - 1); - } - } else if ( - stats.isFile() && - /[/\\]diskstore-[0-9a-fA-F/\\]+(\.json|-\d\.bin)/.test(fileOrDir) - ) { - //delete the file if it is a diskstore file - await unlink(fileOrDir); - } - } -}); - -/** - * locks a file so other forks that want to use the same file have to wait - * @param {string} filePath - * @returns {Promise} - * @private - */ -DiskStore.prototype._lock = function (filePath) { - return promisify(lockFile.lock)( - filePath + ".lock", - JSON.parse(JSON.stringify(this.options.lockFile)) //the options are modified -> create a copy to prevent that - ); -}; - -/** - * unlocks a file path - * @type {Function} - * @param {string} filePath - * @returns {Promise} - * @private - */ -DiskStore.prototype._unlock = function (filePath) { - return promisify(lockFile.unlock)(filePath + ".lock"); -}; - -/** - * returns the location where the value should be stored - * @param {string} key - * @returns {string} - * @private - */ -DiskStore.prototype._getFilePathByKey = function (key) { - const hash = crypto - .createHash("md5") - .update(key + "") - .digest("hex"); - if (this.options.subdirs) { - //create subdirs with the first 3 chars of the hash - return path.join( - this.options.path, - "diskstore-" + hash.substr(0, 3), - hash.substr(3) - ); - } else { - return path.join(this.options.path, "diskstore-" + hash); - } -}; diff --git a/other/cache-manager-fs-hash/src/json-file-store.js b/other/cache-manager-fs-hash/src/json-file-store.js deleted file mode 100644 index f655fd8..0000000 --- a/other/cache-manager-fs-hash/src/json-file-store.js +++ /dev/null @@ -1,118 +0,0 @@ -const promisify = require('util').promisify; -const fs = require('fs'); -const zlib = require('zlib'); - -exports.write = async function (path, data, options) { - const externalBuffers = []; - let dataString = JSON.stringify(data, function replacerFunction(k, value) { - //Buffers searilize to {data: [...], type: "Buffer"} - if (value && value.type === 'Buffer' && value.data && value.data.length >= 1024 /* only save bigger Buffers external, small ones can be inlined */) { - const buffer = Buffer.from(value.data); - externalBuffers.push({ - index: externalBuffers.length, - buffer: buffer, - }); - return { - type: 'ExternalBuffer', - index: externalBuffers.length - 1, - size: buffer.length, - }; - } else if (value === Infinity || value === -Infinity) { - return { type: 'Infinity', sign: Math.sign(value) }; - } else { - return value; - } - }); - - - let zipExtension = ''; - if (options.zip) { - zipExtension = '.gz'; - dataString = await promisify(zlib.deflate)(dataString); - } - //save main json file - await promisify(fs.writeFile)(path + '.json' + zipExtension, dataString, 'utf8'); - - //save external buffers - await Promise.all(externalBuffers.map(async function (externalBuffer) { - let buffer = externalBuffer.buffer; - if (options.zip) { - buffer = await promisify(zlib.deflate)(buffer); - } - await promisify(fs.writeFile)(path + '-' + externalBuffer.index + '.bin' + zipExtension, buffer, 'utf8'); - })); -}; - - -exports.read = async function (path, options) { - let zipExtension = ''; - if (options.zip) { - zipExtension = '.gz'; - } - - //read main json file - let dataString; - if (options.zip) { - const compressedData = await promisify(fs.readFile)(path + '.json' + zipExtension); - dataString = (await promisify(zlib.unzip)(compressedData)).toString(); - } else { - dataString = await promisify(fs.readFile)(path + '.json' + zipExtension, 'utf8'); - } - - - const externalBuffers = []; - const data = JSON.parse(dataString, function bufferReceiver(k, value) { - if (value && value.type === 'Buffer' && value.data) { - return Buffer.from(value.data); - } else if (value && value.type === 'ExternalBuffer' && typeof value.index === 'number' && typeof value.size === 'number') { - //JSON.parse is sync so we need to return a buffer sync, we will fill the buffer later - const buffer = Buffer.alloc(value.size); - externalBuffers.push({ - index: +value.index, - buffer: buffer, - }); - return buffer; - } else if (value && value.type === 'Infinity' && typeof value.sign === 'number') { - return Infinity * value.sign; - } else { - return value; - } - }); - - //read external buffers - await Promise.all(externalBuffers.map(async function (externalBuffer) { - - if (options.zip) { - const bufferCompressed = await promisify(fs.readFile)(path + '-' + +externalBuffer.index + '.bin' + zipExtension); - const buffer = await promisify(zlib.unzip)(bufferCompressed); - buffer.copy(externalBuffer.buffer); - } else { - const fd = await promisify(fs.open)(path + '-' + +externalBuffer.index + '.bin' + zipExtension, 'r'); - await promisify(fs.read)(fd, externalBuffer.buffer, 0, externalBuffer.buffer.length, 0); - await promisify(fs.close)(fd); - } - })); - return data; -}; - -exports.delete = async function (path, options) { - let zipExtension = ''; - if (options.zip) { - zipExtension = '.gz'; - } - - await promisify(fs.unlink)(path + '.json' + zipExtension); - - //delete binary files - try { - for (let i = 0; i < Infinity; i++) { - await promisify(fs.unlink)(path + '-' + i + '.bin' + zipExtension); - } - } catch (err) { - if (err.code === 'ENOENT') { - // every binary is deleted, we are done - } else { - throw err; - } - } -}; \ No newline at end of file diff --git a/other/cache-manager-fs-hash/src/wrap-callback.js b/other/cache-manager-fs-hash/src/wrap-callback.js deleted file mode 100644 index aafc3ba..0000000 --- a/other/cache-manager-fs-hash/src/wrap-callback.js +++ /dev/null @@ -1,21 +0,0 @@ -/** - * adds an callback param to the original function - * @param {function} fn - * @returns {function} - */ -module.exports = function wrapCallback(fn) { - return function (...args) { - let cb; - if (typeof args[args.length - 1] === 'function') { - cb = args.pop(); - } - - const promise = fn.apply(this, args); - - if (typeof cb === 'function') { - promise.then(value => setImmediate(cb, null, value), err => setImmediate(cb, err)); - } - - return promise; - }; -}; \ No newline at end of file diff --git a/other/mqemitter-redis/.github/dependabot.yml b/other/mqemitter-redis/.github/dependabot.yml deleted file mode 100644 index 4872c5a..0000000 --- a/other/mqemitter-redis/.github/dependabot.yml +++ /dev/null @@ -1,7 +0,0 @@ -version: 2 -updates: -- package-ecosystem: npm - directory: "/" - schedule: - interval: daily - open-pull-requests-limit: 10 diff --git a/other/mqemitter-redis/.github/workflows/ci.yml b/other/mqemitter-redis/.github/workflows/ci.yml deleted file mode 100644 index c9b1558..0000000 --- a/other/mqemitter-redis/.github/workflows/ci.yml +++ /dev/null @@ -1,35 +0,0 @@ -name: ci - -on: [push, pull_request] - -jobs: - test: - runs-on: ubuntu-latest - - strategy: - matrix: - node-version: [14.x, 16.x, 18.x] - redis-tag: [5, 6] - - services: - redis: - image: redis:${{ matrix.redis-tag }} - ports: - - 6379:6379 - options: --entrypoint redis-server - - steps: - - uses: actions/checkout@v1 - - - name: Use Node.js - uses: actions/setup-node@v2 - with: - node-version: ${{ matrix.node-version }} - - - name: Install - run: | - npm install - - - name: Run tests - run: | - npm run test diff --git a/other/mqemitter-redis/.gitignore b/other/mqemitter-redis/.gitignore deleted file mode 100644 index 6c655ef..0000000 --- a/other/mqemitter-redis/.gitignore +++ /dev/null @@ -1,33 +0,0 @@ -# Logs -logs -*.log - -# Runtime data -pids -*.pid -*.seed - -# Directory for instrumented libs generated by jscoverage/JSCover -lib-cov - -# Coverage directory used by tools like istanbul -coverage - -# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) -.grunt - -# Compiled binary addons (http://nodejs.org/api/addons.html) -build/Release - -# Dependency directory -# Commenting this out is preferred by some people, see -# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git- -node_modules - -# Users Environment Variables -.lock-wscript - -# ignore redis dump -dump.rdb - -package-lock.json diff --git a/other/mqemitter-redis/.travis.yml b/other/mqemitter-redis/.travis.yml deleted file mode 100644 index 73469a0..0000000 --- a/other/mqemitter-redis/.travis.yml +++ /dev/null @@ -1,9 +0,0 @@ -language: node_js -node_js: - - "10" - - "12" - - "13" - - "14" - - "15" -services: - - redis diff --git a/other/mqemitter-redis/LICENSE b/other/mqemitter-redis/LICENSE deleted file mode 100644 index feb2ed0..0000000 --- a/other/mqemitter-redis/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2014-2020 Matteo Collina - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/other/mqemitter-redis/README.md b/other/mqemitter-redis/README.md deleted file mode 100644 index 7edd966..0000000 --- a/other/mqemitter-redis/README.md +++ /dev/null @@ -1,27 +0,0 @@ -### COOL-ADMIN - -cool-admin一个很酷的后台权限管理系统,开源免费,模块化、插件化、极速开发CRUD,方便快速构建迭代后台管理系统 - -大数据、微服务、AI编码快速开发!!! - - -### 技术栈 - -- 后端:node.js midway.js koa.js mysql typescript -- 前端:vue.js element-plus jsx pinia vue-router - -### 官网 - -[https://cool-js.com](https://cool-js.com) - - -### 演示地址 - -[https://show.cool-admin.com](https://show.cool-admin.com) - -- 账户:admin -- 密码:123456 - -### 项目地址 - -[https://github.com/cool-team-official/cool-admin-midway](https://github.com/cool-team-official/cool-admin-midway) \ No newline at end of file diff --git a/other/mqemitter-redis/mqemitter-redis.js b/other/mqemitter-redis/mqemitter-redis.js deleted file mode 100644 index 62f2222..0000000 --- a/other/mqemitter-redis/mqemitter-redis.js +++ /dev/null @@ -1,250 +0,0 @@ -"use strict"; - -const Redis = require("ioredis"); -const MQEmitter = require("mqemitter"); -const hyperid = require("hyperid")(); -const inherits = require("inherits"); -const LRU = require("lru-cache"); -const msgpack = require("msgpack-lite"); -const EE = require("events").EventEmitter; -const Pipeline = require("ioredis-auto-pipeline"); - -function MQEmitterRedis(opts) { - if (!(this instanceof MQEmitterRedis)) { - return new MQEmitterRedis(opts); - } - - opts = opts || {}; - - this._opts = opts; - - if (opts instanceof Array) { - this.subConn = new Redis.Cluster(opts); - this.pubConn = new Redis.Cluster(opts); - } else { - this.subConn = new Redis(opts.connectionString || opts); - this.pubConn = new Redis(opts.connectionString || opts); - } - - this._pipeline = Pipeline(this.pubConn); - - this._topics = {}; - - this._cache = new LRU({ - max: 10000, - ttl: 60 * 1000, // one minute - }); - - this.state = new EE(); - - const that = this; - - function onError(err) { - if (err && !that.closing) { - that.state.emit("error", err); - } - } - - this._onError = onError; - - function handler(sub, topic, payload) { - const packet = msgpack.decode(payload); - if (!that._cache.get(packet.id)) { - that._emit(packet.msg); - } - that._cache.set(packet.id, true); - } - - this.subConn.on("messageBuffer", function (topic, message) { - handler(topic, topic, message); - }); - - this.subConn.on("pmessageBuffer", function (sub, topic, message) { - handler(sub, topic, message); - }); - - this.subConn.on("connect", function () { - that.state.emit("subConnect"); - }); - - this.subConn.on("error", function (err) { - that._onError(err); - }); - - this.pubConn.on("connect", function () { - that.state.emit("pubConnect"); - }); - - this.pubConn.on("error", function (err) { - that._onError(err); - }); - - MQEmitter.call(this, opts); - - this._opts.regexWildcardOne = new RegExp( - this._opts.wildcardOne.replace(/([/,!\\^${}[\]().*+?|<>\-&])/g, "\\$&"), - "g" - ); - this._opts.regexWildcardSome = new RegExp( - (this._opts.matchEmptyLevels - ? this._opts.separator.replace(/([/,!\\^${}[\]().*+?|<>\-&])/g, "\\$&") + - "?" - : "") + - this._opts.wildcardSome.replace(/([/,!\\^${}[\]().*+?|<>\-&])/g, "\\$&"), - "g" - ); -} - -inherits(MQEmitterRedis, MQEmitter); -["emit", "on", "removeListener", "close"].forEach(function (name) { - MQEmitterRedis.prototype["_" + name] = MQEmitterRedis.prototype[name]; -}); - -MQEmitterRedis.prototype.close = function (cb) { - cb = cb || noop; - - if (this.closed || this.closing) { - return cb(); - } - - this.closing = true; - - let count = 2; - const that = this; - - function onEnd() { - if (--count === 0) { - that._close(cb); - } - } - - this.subConn.on("end", onEnd); - this.subConn.quit(); - - this.pubConn.on("end", onEnd); - this.pubConn.quit(); - - return this; -}; - -MQEmitterRedis.prototype._subTopic = function (topic) { - return topic - .replace(this._opts.regexWildcardOne, "*") - .replace(this._opts.regexWildcardSome, "*"); -}; - -MQEmitterRedis.prototype.on = function on(topic, cb, done) { - const subTopic = this._subTopic(topic); - const onFinish = function () { - if (done) { - setImmediate(done); - } - }; - - this._on(topic, cb); - - if (this._topics[subTopic]) { - this._topics[subTopic]++; - onFinish.call(this); - return this; - } - - this._topics[subTopic] = 1; - - if (this._containsWildcard(topic)) { - this.subConn.psubscribe(subTopic, onFinish.bind(this)); - } else { - this.subConn.subscribe(subTopic, onFinish.bind(this)); - } - - return this; -}; - -MQEmitterRedis.prototype.emit = function (msg, done) { - done = done || this._onError; - - if (this.closed) { - const err = new Error("mqemitter-redis is closed"); - return done(err); - } - - const packet = { - id: hyperid(), - msg, - }; - - this._pipeline - .publish(msg.topic, msgpack.encode(packet)) - .then(() => done()) - .catch(done); -}; - -MQEmitterRedis.prototype.removeListener = function (topic, cb, done) { - const subTopic = this._subTopic(topic); - const onFinish = function () { - if (done) { - setImmediate(done); - } - }; - - this._removeListener(topic, cb); - - if (--this._topics[subTopic] > 0) { - onFinish(); - return this; - } - - delete this._topics[subTopic]; - - if (this._containsWildcard(topic)) { - this.subConn.punsubscribe(subTopic, onFinish); - } else if (this._matcher.match(topic)) { - this.subConn.unsubscribe(subTopic, onFinish); - } - - return this; -}; - -MQEmitterRedis.prototype._containsWildcard = function (topic) { - return ( - topic.indexOf(this._opts.wildcardOne) >= 0 || - topic.indexOf(this._opts.wildcardSome) >= 0 - ); -}; - -function noop() {} - -module.exports = MQEmitterRedis; - -function MQEmitterRedisPrefix(pubSubPrefix, options) { - MQEmitterRedis.call(this, options); - this._pubSubPrefix = pubSubPrefix; - this._sym_proxiedCallback = Symbol("proxiedCallback"); -} -inherits(MQEmitterRedisPrefix, MQEmitterRedis); -MQEmitterRedisPrefix.prototype.on = function (topic, cb, done) { - const t = this._pubSubPrefix + topic; - cb[this._sym_proxiedCallback] = function (packet, cbcb) { - const t = packet.topic.slice(this._pubSubPrefix.length); - const p = { ...packet, topic: t }; - return cb.call(this, p, cbcb); - }.bind(this); - return MQEmitterRedis.prototype.on.call( - this, - t, - cb[this._sym_proxiedCallback], - done - ); -}; -MQEmitterRedisPrefix.prototype.removeListener = function (topic, func, done) { - const t = this._pubSubPrefix + topic; - const f = func[this._sym_proxiedCallback]; - return MQEmitterRedis.prototype.removeListener.call(this, t, f, done); -}; -MQEmitterRedisPrefix.prototype.emit = function (packet, done) { - const t = this._pubSubPrefix + packet.topic; - const p = { ...packet, topic: t }; - return MQEmitterRedis.prototype.emit.call(this, p, done); -}; - -module.exports.MQEmitterRedisPrefix = MQEmitterRedisPrefix; diff --git a/other/mqemitter-redis/package.json b/other/mqemitter-redis/package.json deleted file mode 100644 index 709e740..0000000 --- a/other/mqemitter-redis/package.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - "name": "@cool-midway/mqemitter-redis", - "version": "7.0.0", - "description": "Redis-based MQEmitter", - "main": "mqemitter-redis.js", - "types": "types/index.d.ts", - "dependencies": { - "hyperid": "^3.0.1", - "inherits": "^2.0.1", - "ioredis": "^5.0.4", - "ioredis-auto-pipeline": "^1.0.1", - "lru-cache": "^7.9.0", - "mqemitter": "^4.1.3", - "msgpack-lite": "^0.1.14" - }, - "devDependencies": { - "@types/ioredis": "^4.19.4", - "faucet": "^0.0.1", - "pre-commit": "^1.0.7", - "safe-buffer": "^5.1.2", - "standard": "^17.0.0", - "tape": "^5.0.1", - "tsd": "^0.20.0" - }, - "scripts": { - }, - "pre-commit": "test", - "repository": { - "type": "git", - "url": "https://github.com/mcollina/mqemitter-redis.git" - }, - "keywords": [ - "redis", - "mqemitter", - "emitter", - "pubsub", - "publish", - "subscribe", - "cool" - ], - "author": "COOL", - "license": "MIT", - "homepage": "https://cool-js.com" -} diff --git a/other/mqemitter-redis/types/index.d.ts b/other/mqemitter-redis/types/index.d.ts deleted file mode 100644 index a6a5a6c..0000000 --- a/other/mqemitter-redis/types/index.d.ts +++ /dev/null @@ -1,37 +0,0 @@ -import type { RedisOptions } from 'ioredis'; -import type { MQEmitter } from 'mqemitter'; - -export interface MQEmitterOptions { - concurrency?: number; - matchEmptyLevels?: boolean; - separator?: string; - wildcardOne?: string; - wildcardSome?: string; - connectionString?: string; -} - -export type Message = Record & { topic: string }; - -export interface MQEmitterRedis extends MQEmitter { - new (options?: MQEmitterOptions & RedisOptions): MQEmitterRedis; - current: number; - concurrent: number; - on( - topic: string, - listener: (message: Message, done: () => void) => void, - callback?: () => void - ): this; - emit(message: Message, callback?: (error?: Error) => void): void; - removeListener( - topic: string, - listener: (message: Message, done: () => void) => void, - callback?: () => void - ): void; - close(callback: () => void): void; -} - -declare function MQEmitterRedis( - options?: MQEmitterOptions & RedisOptions -): MQEmitterRedis; - -export default MQEmitterRedis; diff --git a/pay/.editorconfig b/pay/.editorconfig deleted file mode 100644 index 4c7f8a8..0000000 --- a/pay/.editorconfig +++ /dev/null @@ -1,11 +0,0 @@ -# 🎨 editorconfig.org - -root = true - -[*] -charset = utf-8 -end_of_line = lf -indent_style = space -indent_size = 2 -trim_trailing_whitespace = true -insert_final_newline = true \ No newline at end of file diff --git a/pay/.eslintrc.json b/pay/.eslintrc.json deleted file mode 100644 index aad9755..0000000 --- a/pay/.eslintrc.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "extends": "./node_modules/mwts/", - "ignorePatterns": [ - "node_modules", - "dist", - "test", - "jest.config.js", - "typings", - "public/**/**", - "view/**/**" - ], - "env": { - "jest": true - }, - "rules": { - "@typescript-eslint/explicit-module-boundary-types": "off", - "@typescript-eslint/no-unused-vars": "off", - "@typescript-eslint/ban-ts-comment": "off", - "node/no-extraneous-import": "off", - "no-empty": "off", - "node/no-extraneous-require": "off", - "eqeqeq": "off", - "node/no-unsupported-features/node-builtins": "off", - "@typescript-eslint/ban-types": "off", - "no-control-regex": "off", - "prefer-const": "off" - } -} \ No newline at end of file diff --git a/pay/.gitignore b/pay/.gitignore deleted file mode 100644 index 13bc3a6..0000000 --- a/pay/.gitignore +++ /dev/null @@ -1,15 +0,0 @@ -logs/ -npm-debug.log -yarn-error.log -node_modules/ -package-lock.json -yarn.lock -coverage/ -dist/ -.idea/ -run/ -.DS_Store -*.sw* -*.un~ -.tsbuildinfo -.tsbuildinfo.* diff --git a/pay/.prettierrc.js b/pay/.prettierrc.js deleted file mode 100644 index b964930..0000000 --- a/pay/.prettierrc.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - ...require('mwts/.prettierrc.json') -} diff --git a/pay/index.d.ts b/pay/index.d.ts deleted file mode 100644 index e0065de..0000000 --- a/pay/index.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -export * from './dist/index'; - -declare module '@midwayjs/core/dist/interface' { - interface MidwayConfig { - book?: PowerPartial<{ - a: number; - b: string; - }>; - } -} diff --git a/pay/jest.config.js b/pay/jest.config.js deleted file mode 100644 index 82a8b85..0000000 --- a/pay/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = { - preset: 'ts-jest', - testEnvironment: 'node', - testPathIgnorePatterns: ['/test/fixtures'], - coveragePathIgnorePatterns: ['/test/'], - setupFilesAfterEnv: ['./jest.setup.js'] -}; diff --git a/pay/jest.setup.js b/pay/jest.setup.js deleted file mode 100644 index 1399c91..0000000 --- a/pay/jest.setup.js +++ /dev/null @@ -1 +0,0 @@ -jest.setTimeout(30000); diff --git a/pay/package.json b/pay/package.json deleted file mode 100644 index f759c76..0000000 --- a/pay/package.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "name": "@cool-midway/pay", - "version": "7.0.0", - "description": "cool-js.com 支付 微信 支付宝", - "main": "dist/index.js", - "typings": "index.d.ts", - "scripts": { - "build": "cross-env midway-bin build -c", - "cov": "cross-env midway-bin cov --ts", - "lint": "mwts check", - "lint:fix": "mwts fix" - }, - "keywords": [ - "cool", - "cool-admin", - "cooljs" - ], - "author": "COOL", - "readme": "README.md", - "files": [ - "dist/**/*.js", - "dist/**/*.d.ts", - "index.d.ts" - ], - "license": "MIT", - "repository": { - "type": "git", - "url": "https://cool-js.com" - }, - "devDependencies": { - "@cool-midway/core": "^7.0.0", - "@midwayjs/cli": "^2.0.9", - "@midwayjs/core": "^3.9.0", - "@midwayjs/decorator": "^3.9.0", - "@midwayjs/mock": "^3.9.0", - "@types/jest": "^29.2.5", - "@types/node": "^18.11.18", - "cross-env": "^7.0.3", - "jest": "^29.3.1", - "mwts": "^1.3.0", - "ts-jest": "^29.0.3", - "typescript": "^4.9.4" - }, - "dependencies": { - "@4a/cid": "^0.1.0", - "alipay-sdk": "^3.2.0", - "wechatpay-node-v3": "^2.1.0" - } -} diff --git a/pay/src/README.md b/pay/src/README.md deleted file mode 100644 index 7edd966..0000000 --- a/pay/src/README.md +++ /dev/null @@ -1,27 +0,0 @@ -### COOL-ADMIN - -cool-admin一个很酷的后台权限管理系统,开源免费,模块化、插件化、极速开发CRUD,方便快速构建迭代后台管理系统 - -大数据、微服务、AI编码快速开发!!! - - -### 技术栈 - -- 后端:node.js midway.js koa.js mysql typescript -- 前端:vue.js element-plus jsx pinia vue-router - -### 官网 - -[https://cool-js.com](https://cool-js.com) - - -### 演示地址 - -[https://show.cool-admin.com](https://show.cool-admin.com) - -- 账户:admin -- 密码:123456 - -### 项目地址 - -[https://github.com/cool-team-official/cool-admin-midway](https://github.com/cool-team-official/cool-admin-midway) \ No newline at end of file diff --git a/pay/src/ali.ts b/pay/src/ali.ts deleted file mode 100644 index b46e992..0000000 --- a/pay/src/ali.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { Config, Init, Provide, Scope, ScopeEnum } from '@midwayjs/decorator'; -import * as cid from '@4a/cid'; -import { CoolAliPayConfig } from './interface'; -import AlipaySdk from 'alipay-sdk'; - -/** - * 支付宝支付 - */ -@Provide() -@Scope(ScopeEnum.Singleton) -export class CoolAliPay { - pay: AlipaySdk; - - @Config('cool.pay.ali') - coolAlipay: CoolAliPayConfig; - - @Init() - async init() { - if (this.coolAlipay) this.pay = new AlipaySdk(this.coolAlipay); - } - - /** - * 获得支付宝支付SDK实例 - * @returns - */ - getInstance(): AlipaySdk { - return this.pay; - } - - /** - * 通知验签 - * @param postData {JSON} 服务端的消息内容 - * @param raw {Boolean} 是否使用 raw 内容而非 decode 内容验签 - */ - signVerify(postData: any, raw?: boolean) { - return this.pay.checkNotifySign(postData, raw); - } - - /** - * 创建订单 - * @param length 订单长度 - * @returns - */ - createOrderNum(length = 26) { - return cid(length); - } - - /** - * 动态配置支付参数 - * @param config 微信配置 - * @returns - */ - initPay(config: CoolAliPayConfig) { - return new AlipaySdk(config); - } -} diff --git a/pay/src/config/config.default.ts b/pay/src/config/config.default.ts deleted file mode 100644 index d8324ca..0000000 --- a/pay/src/config/config.default.ts +++ /dev/null @@ -1,4 +0,0 @@ -export const customKey = { - a: 1, - b: 'hello', -}; diff --git a/pay/src/configuration.ts b/pay/src/configuration.ts deleted file mode 100644 index a77d2e5..0000000 --- a/pay/src/configuration.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { Configuration } from '@midwayjs/decorator'; -import * as DefaultConfig from './config/config.default'; -import { IMidwayContainer } from '@midwayjs/core'; -import { CoolWxPay } from './wx'; -import { CoolAliPay } from './ali'; - -@Configuration({ - namespace: 'cool:pay', - importConfigs: [ - { - default: DefaultConfig, - }, - ], -}) -export class CoolPayConfiguration { - async onReady(container: IMidwayContainer) { - await container.getAsync(CoolWxPay); - await container.getAsync(CoolAliPay); - // TODO something - } -} diff --git a/pay/src/index.ts b/pay/src/index.ts deleted file mode 100644 index c040890..0000000 --- a/pay/src/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -export { CoolPayConfiguration as Configuration } from './configuration'; - -export * from './interface'; - -export * from './wx'; - -export * from './ali'; diff --git a/pay/src/interface.ts b/pay/src/interface.ts deleted file mode 100644 index 43eba55..0000000 --- a/pay/src/interface.ts +++ /dev/null @@ -1,77 +0,0 @@ -/** - * 微信支付配置 - */ -export interface CoolWxPayConfig { - // 直连商户申请的公众号或移动应用appid。 - appid: string; - // 商户号 - mchid: string; - // 可选参数 证书序列号 - serial_no?: string; - // 回调链接 - notify_url: string; - // 公钥 - publicKey: Buffer; - // 私钥 - privateKey: Buffer; - // 可选参数 认证类型,目前为WECHATPAY2-SHA256-RSA2048 - authType?: string; - // 可选参数 User-Agent - userAgent?: string; - // 可选参数 APIv3密钥 - key?: string; -} - -/** - * 支付宝支付配置 - */ -export interface CoolAliPayConfig { - // 支付回调地址 - notifyUrl: string; - /** 应用ID */ - appId: string; - /** - * 应用私钥字符串 - * RSA签名验签工具:https://docs.open.alipay.com/291/106097) - * 密钥格式一栏请选择 “PKCS1(非JAVA适用)” - */ - privateKey: string; - signType?: 'RSA2' | 'RSA'; - /** 支付宝公钥(需要对返回值做验签时候必填) */ - alipayPublicKey?: string; - /** 网关 */ - gateway?: string; - /** 网关超时时间(单位毫秒,默认 5s) */ - timeout?: number; - /** 是否把网关返回的下划线 key 转换为驼峰写法 */ - camelcase?: boolean; - /** 编码(只支持 utf-8) */ - charset?: 'utf-8'; - /** api版本 */ - version?: '1.0'; - urllib?: any; - /** 指定private key类型, 默认: PKCS1, PKCS8: PRIVATE KEY, PKCS1: RSA PRIVATE KEY */ - keyType?: 'PKCS1' | 'PKCS8'; - /** 应用公钥证书文件路径 */ - appCertPath?: string; - /** 应用公钥证书文件内容 */ - appCertContent?: string | Buffer; - /** 应用公钥证书sn */ - appCertSn?: string; - /** 支付宝根证书文件路径 */ - alipayRootCertPath?: string; - /** 支付宝根证书文件内容 */ - alipayRootCertContent?: string | Buffer; - /** 支付宝根证书sn */ - alipayRootCertSn?: string; - /** 支付宝公钥证书文件路径 */ - alipayPublicCertPath?: string; - /** 支付宝公钥证书文件内容 */ - alipayPublicCertContent?: string | Buffer; - /** 支付宝公钥证书sn */ - alipayCertSn?: string; - /** AES密钥,调用AES加解密相关接口时需要 */ - encryptKey?: string; - /** 服务器地址 */ - wsServiceUrl?: string; -} diff --git a/pay/src/package.json b/pay/src/package.json deleted file mode 100644 index 2e6674e..0000000 --- a/pay/src/package.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "name": "@cool-midway/pay", - "version": "7.0.0", - "description": "cool-js.com 支付 微信 支付宝", - "main": "index.js", - "typings": "index.d.ts", - "scripts": { - "build": "cross-env midway-bin build -c", - "cov": "cross-env midway-bin cov --ts", - "lint": "mwts check", - "lint:fix": "mwts fix" - }, - "keywords": [ - "cool", - "cool-admin", - "cooljs" - ], - "author": "COOL", - "readme": "README.md", - "files": [ - "**/*.js", - "**/*.d.ts", - "index.d.ts" - ], - "license": "MIT", - "repository": { - "type": "git", - "url": "https://cool-js.com" - }, - "devDependencies": { - "@cool-midway/core": "^7.0.0", - "@midwayjs/cli": "^2.0.9", - "@midwayjs/core": "^3.9.0", - "@midwayjs/decorator": "^3.9.0", - "@midwayjs/mock": "^3.9.0", - "@types/jest": "^29.2.5", - "@types/node": "^18.11.18", - "cross-env": "^7.0.3", - "jest": "^29.3.1", - "mwts": "^1.3.0", - "ts-jest": "^29.0.3", - "typescript": "^4.9.4" - }, - "dependencies": { - "@4a/cid": "^0.1.0", - "alipay-sdk": "^3.2.0", - "wechatpay-node-v3": "^2.1.0" - } -} diff --git a/pay/src/wx.ts b/pay/src/wx.ts deleted file mode 100644 index 09c67fc..0000000 --- a/pay/src/wx.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { CoolCommException } from '@cool-midway/core'; -import { Config, Init, Provide, Scope, ScopeEnum } from '@midwayjs/decorator'; -import * as cid from '@4a/cid'; -import { CoolWxPayConfig } from './interface'; -import WxPay = require('wechatpay-node-v3'); - -/** - * 微信支付 - */ -@Provide() -@Scope(ScopeEnum.Singleton) -export class CoolWxPay { - pay: WxPay; - - @Config('cool.pay.wx') - coolWxPay: CoolWxPayConfig; - - @Init() - async init() { - if (this.coolWxPay) this.pay = new WxPay(this.coolWxPay); - } - - /** - * 获得微信支付SDK实例 - * @returns - */ - getInstance(): WxPay { - return this.pay; - } - - /** - * 签名 - * @param params - * @returns - */ - async signVerify(ctx) { - if (!this.coolWxPay.key) { - throw new CoolCommException('未配置key(v3 API密钥)'); - } - const params = { - apiSecret: this.coolWxPay.key, // 如果在构造中传入了 key, 这里可以不传该值,否则需要传入该值 - body: ctx.request.body, // 请求体 body - signature: ctx.headers['wechatpay-signature'], - serial: ctx.headers['wechatpay-serial'], - nonce: ctx.headers['wechatpay-nonce'], - timestamp: ctx.headers['wechatpay-timestamp'], - }; - return await this.pay.verifySign(params); - } - - /** - * 创建订单 - * @param length 订单长度 - * @returns - */ - createOrderNum(length = 26) { - return cid(length); - } - - /** - * 动态配置支付参数 - * @param config 微信配置 - * @returns - */ - initPay(config: CoolWxPayConfig) { - return new WxPay(config); - } -} diff --git a/pay/tsconfig.json b/pay/tsconfig.json deleted file mode 100644 index f01e1d2..0000000 --- a/pay/tsconfig.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "compileOnSave": true, - "compilerOptions": { - "target": "es2018", - "module": "commonjs", - "moduleResolution": "node", - "experimentalDecorators": true, - "emitDecoratorMetadata": true, - "inlineSourceMap":false, - "noImplicitThis": true, - "noUnusedLocals": true, - "stripInternal": true, - "skipLibCheck": true, - "noImplicitReturns": false, - "pretty": true, - "declaration": true, - "outDir": "dist" - }, - "exclude": [ - "dist", - "node_modules", - "test" - ] -} diff --git a/plugin-cli/.gitignore b/plugin-cli/.gitignore deleted file mode 100644 index 04c01ba..0000000 --- a/plugin-cli/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -node_modules/ -dist/ \ No newline at end of file diff --git a/plugin-cli/.npmignore b/plugin-cli/.npmignore deleted file mode 100644 index eb6bd5d..0000000 --- a/plugin-cli/.npmignore +++ /dev/null @@ -1,3 +0,0 @@ -node_modules/ -src/ -tsconfig.json \ No newline at end of file diff --git a/plugin-cli/README.md b/plugin-cli/README.md deleted file mode 100644 index 7edd966..0000000 --- a/plugin-cli/README.md +++ /dev/null @@ -1,27 +0,0 @@ -### COOL-ADMIN - -cool-admin一个很酷的后台权限管理系统,开源免费,模块化、插件化、极速开发CRUD,方便快速构建迭代后台管理系统 - -大数据、微服务、AI编码快速开发!!! - - -### 技术栈 - -- 后端:node.js midway.js koa.js mysql typescript -- 前端:vue.js element-plus jsx pinia vue-router - -### 官网 - -[https://cool-js.com](https://cool-js.com) - - -### 演示地址 - -[https://show.cool-admin.com](https://show.cool-admin.com) - -- 账户:admin -- 密码:123456 - -### 项目地址 - -[https://github.com/cool-team-official/cool-admin-midway](https://github.com/cool-team-official/cool-admin-midway) \ No newline at end of file diff --git a/plugin-cli/package.json b/plugin-cli/package.json deleted file mode 100644 index 3b18454..0000000 --- a/plugin-cli/package.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "name": "@cool-midway/plugin-cli", - "version": "7.1.9", - "description": "cool-admin midway plugin", - "main": "dist/index.js", - "scripts": { - "build": "tsc" - }, - "keywords": [ - "cool", - "cool-admin", - "cooljs" - ], - "repository": { - "type": "git", - "url": "https://cool-js.com" - }, - "bin": { - "cool-plugin-cli": "scripts/index.js" - }, - "author": "COOL", - "readme": "README.md", - "license": "MIT", - "dependencies": { - "@cool-midway/cache-manager-fs-hash": "^7.0.0", - "@midwayjs/cache-manager": "^3.15.2", - "@midwayjs/core": "^3.15.0", - "archiver": "^6.0.1", - "esbuild": "^0.19.11", - "esbuild-plugin-copy": "^2.1.1" - }, - "devDependencies": { - "@types/node": "^20.12.7", - "typescript": "^5.3.3" - } -} diff --git a/plugin-cli/scripts/build.js b/plugin-cli/scripts/build.js deleted file mode 100644 index 655859f..0000000 --- a/plugin-cli/scripts/build.js +++ /dev/null @@ -1,47 +0,0 @@ -console.log("cool-plugin-cli run build"); - -const esbuild = require('esbuild'); -const copyPlugin = require('esbuild-plugin-copy').default; -const packageJson = require('../package.json'); -const path = require('path'); -const fs = require('fs'); - -const projectRoot = process.cwd(); - -// 输出目录 -const outdir = path.join(projectRoot, 'dist'); - -// 删除 dist 目录 -if (fs.existsSync(outdir)) { - fs.rmdirSync(outdir, { recursive: true }); -} - -// 构建 -module.exports.result = esbuild.build({ - entryPoints: [path.join(projectRoot, 'src', 'index.ts'), path.join(projectRoot, 'test', 'index.ts')], - external: Object.keys(packageJson.devDependencies), - bundle: true, - platform: 'node', - outdir, - plugins: [ - copyPlugin({ - assets: [{ - from: ['./README.md'], - to: ['./README.md'] - },{ - from: ['./package.json'], - to: ['./package.json'] - },{ - from: ['./plugin.json'], - to: ['./plugin.json'] - },{ - from: ['./assets/*'], - to: ['./assets'] - },{ - from: ['./src/*'], - to: ['./source'] - }] - }) - ] -}).catch(() => process.exit(1)); - diff --git a/plugin-cli/scripts/index.js b/plugin-cli/scripts/index.js deleted file mode 100644 index 4740398..0000000 --- a/plugin-cli/scripts/index.js +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env node -const args = process.argv.slice(2); // 去掉数组的前两个元素 - -// 发布 -if(args.includes('--release')){ - require('./release.js'); -} - -// 打包 -if(args.includes('--build')){ - require('./build.js'); -} \ No newline at end of file diff --git a/plugin-cli/scripts/release.js b/plugin-cli/scripts/release.js deleted file mode 100644 index 39898e9..0000000 --- a/plugin-cli/scripts/release.js +++ /dev/null @@ -1,48 +0,0 @@ -console.log("cool-plugin-cli run release"); - -const projectRoot = process.cwd(); - -const fs = require('fs'); -const path = require('path'); -const archiver = require('archiver'); -const pluginJson = require(path.join(projectRoot, 'plugin.json')); - -const packFolder = (folderPath, outputPath) => { - fs.mkdirSync(path.dirname(outputPath), { recursive: true }); - // 创建文件写入流 - const output = fs.createWriteStream(outputPath); - const archive = archiver('zip', { - zlib: { level: 9 } // 设置压缩级别 - }); - - // 监听关闭事件 - output.on('close', function() { - console.log(`cool plugin package successfully. Total size: ${archive.pointer()} bytes`); - }); - - // 监听错误事件 - archive.on('error', function(err) { - throw err; - }); - - // 将压缩内容流连接到文件写入流 - archive.pipe(output); - - // 添加文件夹 - archive.directory(folderPath, false); - - // 完成归档 - archive.finalize(); -} - -// 打包 -const folderPath = path.join(projectRoot, 'dist'); // 替换为你的文件夹路径 -const outputPath = path.join(projectRoot, 'release', `${pluginJson.name}_v${pluginJson.version}.cool`); // 替换为你希望创建的 .cool 文件路径 - -const { result } = require('./build.js'); - -result.then(()=>{ - packFolder(folderPath, outputPath); -}) - - diff --git a/plugin-cli/src/cache/store.ts b/plugin-cli/src/cache/store.ts deleted file mode 100644 index 44a74c1..0000000 --- a/plugin-cli/src/cache/store.ts +++ /dev/null @@ -1,64 +0,0 @@ -import * as FsStore from "@cool-midway/cache-manager-fs-hash"; - -/** - * cool 基于磁盘的缓存 - */ -export class FsCacheStore { - options: any; - - store: FsStore; - - constructor(options = {}) { - options = { - ...options, - path: "cache", - ttl: -1, - }; - this.options = options; - this.store = FsStore.create(options); - } - - /** - * 获得 - * @param key - * @returns - */ - async get(key: string): Promise { - return await this.store.get(key); - } - - /** - * 设置 - * @param key - * @param value - * @param ttl - */ - async set(key: string, value: T, ttl?: number): Promise { - let t = ttl ? ttl : this.options.ttl; - if (t > 0) { - t = t / 1000; - } - await this.store.set(key, value, { - ttl: t, - }); - } - - /** - * 删除 - * @param key - */ - async del(key: string): Promise { - await this.store.del(key); - } - - /** - * 重置 - */ - async reset(): Promise { - await this.store.reset(); - } -} - -export const CoolCacheStore = function (options = {}) { - return new FsCacheStore(options); -}; diff --git a/plugin-cli/src/constant/global.ts b/plugin-cli/src/constant/global.ts deleted file mode 100644 index ad18ebe..0000000 --- a/plugin-cli/src/constant/global.ts +++ /dev/null @@ -1,84 +0,0 @@ -/** - * 返回码 - */ -export enum RESCODE { - // 成功 - SUCCESS = 1000, - // 失败 - COMMFAIL = 1001, - // 参数验证失败 - VALIDATEFAIL = 1002, - // 参数验证失败 - COREFAIL = 1003, -} - -/** - * 返回信息 - */ -export enum RESMESSAGE { - // 成功 - SUCCESS = "success", - // 失败 - COMMFAIL = "comm fail", - // 参数验证失败 - VALIDATEFAIL = "validate fail", - // 核心异常 - COREFAIL = "core fail", -} - -/** - * 错误提示 - */ -export enum ERRINFO { - NOENTITY = "未设置操作实体", - NOID = "查询参数[id]不存在", - SORTFIELD = "排序参数不正确", -} - -/** - * 事件 - */ -export enum EVENT { - // 软删除 - SOFT_DELETE = "onSoftDelete", - // 服务成功启动 - SERVER_READY = "onServerReady", - // 服务就绪 - READY = "onReady", - // ES 数据改变 - ES_DATA_CHANGE = "esDataChange", -} - - -export class GlobalConfig { - private static instance: GlobalConfig; - - RESCODE = { - SUCCESS: 1000, - COMMFAIL: 1001, - VALIDATEFAIL: 1002, - COREFAIL: 1003, - }; - - RESMESSAGE = { - SUCCESS: "success", - COMMFAIL: "comm fail", - VALIDATEFAIL: "validate fail", - COREFAIL: "core fail", - }; - - // ... 其他的配置 ... - - private constructor() {} - - static getInstance(): GlobalConfig { - if (!GlobalConfig.instance) { - GlobalConfig.instance = new GlobalConfig(); - } - return GlobalConfig.instance; - } -} - - - - diff --git a/plugin-cli/src/exception/base.ts b/plugin-cli/src/exception/base.ts deleted file mode 100644 index 177b46b..0000000 --- a/plugin-cli/src/exception/base.ts +++ /dev/null @@ -1,13 +0,0 @@ -/** - * 异常基类 - */ -export class BaseException extends Error { - status: number; - - constructor(name: string, code: number, message: string) { - super(message); - - this.name = name; - this.status = code; - } -} diff --git a/plugin-cli/src/exception/comm.ts b/plugin-cli/src/exception/comm.ts deleted file mode 100644 index d2c9525..0000000 --- a/plugin-cli/src/exception/comm.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { GlobalConfig } from '../constant/global'; -import { BaseException } from './base'; - -/** - * 通用异常 - */ -export class CoolCommException extends BaseException { - constructor(message: string) { - const { RESCODE, RESMESSAGE } = GlobalConfig.getInstance(); - super( - 'CoolCommException', - RESCODE.COMMFAIL, - message ? message : RESMESSAGE.COMMFAIL - ); - } -} diff --git a/plugin-cli/src/exception/core.ts b/plugin-cli/src/exception/core.ts deleted file mode 100644 index 9dc3a7e..0000000 --- a/plugin-cli/src/exception/core.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { GlobalConfig } from '../constant/global'; -import { BaseException } from './base'; - -/** - * 核心异常 - */ -export class CoolCoreException extends BaseException { - constructor(message: string) { - const { RESCODE, RESMESSAGE } = GlobalConfig.getInstance(); - super( - 'CoolCoreException', - RESCODE.COREFAIL, - message ? message : RESMESSAGE.COREFAIL - ); - } -} diff --git a/plugin-cli/src/exception/validate.ts b/plugin-cli/src/exception/validate.ts deleted file mode 100644 index 9a49abb..0000000 --- a/plugin-cli/src/exception/validate.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { GlobalConfig } from "../constant/global"; -import { BaseException } from "./base"; - -/** - * 校验异常 - */ -export class CoolValidateException extends BaseException { - constructor(message: string) { - const { RESCODE, RESMESSAGE } = GlobalConfig.getInstance(); - super( - "CoolValidateException", - RESCODE.VALIDATEFAIL, - message ? message : RESMESSAGE.VALIDATEFAIL - ); - } -} diff --git a/plugin-cli/src/hook/upload.ts b/plugin-cli/src/hook/upload.ts deleted file mode 100644 index c2b9334..0000000 --- a/plugin-cli/src/hook/upload.ts +++ /dev/null @@ -1,67 +0,0 @@ -// 模式 -export enum MODETYPE { - // 本地 - LOCAL = "local", - // 云存储 - CLOUD = "cloud", - // 其他 - OTHER = "other", -} - -export enum CLOUDTYPE { - // 阿里云存储 - OSS = "oss", - // 腾讯云存储 - COS = "cos", - // 七牛云存储 - QINIU = "qiniu", - /** AWS S3 */ - AWS = "aws", -} - -/** - * 上传模式 - */ -export interface Mode { - // 模式 - mode: MODETYPE; - // 类型 - type: string; -} - -/** - * 文件上传 - */ -export interface BaseUpload { - /** - * 获得上传模式 - */ - getMode(): Promise; - - /** - * 获得原始操作对象 - * @returns - */ - getMetaFileObj(); - - /** - * 下载并上传 - * @param url - * @param fileName 文件名 - */ - downAndUpload(url: string, fileName?: string): Promise; - - /** - * 指定Key(路径)上传,本地文件上传到存储服务 - * @param filePath 文件路径 - * @param key 路径一致会覆盖源文件 - */ - uploadWithKey(filePath, key): Promise; - - /** - * 上传文件 - * @param ctx - * @param key 文件路径 - */ - upload(ctx): Promise; -} diff --git a/plugin-cli/src/index.ts b/plugin-cli/src/index.ts deleted file mode 100644 index 7ce6682..0000000 --- a/plugin-cli/src/index.ts +++ /dev/null @@ -1,158 +0,0 @@ -import { MidwayCache } from "@midwayjs/cache-manager"; -import { IMidwayContext, IMidwayApplication } from "@midwayjs/core"; -import { CoolCacheStore, FsCacheStore } from "./cache/store"; - -// 文件上传 -export * from "./hook/upload"; - -// 异常处理 -export * from "./exception/base"; -export * from "./exception/comm"; -export * from "./exception/core"; -export * from "./exception/validate"; - -// 全局参数 -export * from "./constant/global"; - -/** - * 插件信息 - */ -export interface PluginInfo { - /** 名称 */ - name: string; - /** 唯一标识 */ - key: string; - /** 钩子 */ - hook: string; - /** 版本 */ - version: string; - /** 描述 */ - description: string; - /** 作者 */ - author: string; - /** logo */ - logo: string; - /** README 使用说明 */ - readme: string; - /** 配置 */ - config: any; -} - -/** - * 插件基类,不建议修改 - */ -export abstract class BasePlugin { - /** 插件信息 */ - pluginInfo: PluginInfo; - /** 请求上下文,用到此项无法本地调试,需安装到cool-admin中才能调试 */ - ctx: IMidwayContext; - /** 应用实例,用到此项无法本地调试,需安装到cool-admin中才能调试 */ - app: IMidwayApplication; - /** 缓存 */ - cache: FsCacheStore | MidwayCache; - /** 插件 */ - pluginService: PluginService; - /** 基础目录位置 */ - baseDir: string; - - setCtx(ctx: IMidwayContext) { - this.ctx = ctx; - } - - setApp(app: IMidwayApplication) { - this.app = app; - this.baseDir = app.getBaseDir(); - this.configDir(); - } - - constructor() {} - - /** - * 获得App级别的实例 - * @param name - * @returns - */ - async getAppInstance(name: string) { - return await this.app.getApplicationContext().getAsync(name); - } - - /** - * 获得请求级别的实例 - * @param name - * @returns - */ - async getCtxInstance(name: string) { - return await this.ctx.requestContext.getAsync(name); - } - - /** - * 初始化插件 - * @param pluginInfo - * @param ctx - * @param app - */ - async init( - pluginInfo: PluginInfo, - ctx?: IMidwayContext, - app?: IMidwayApplication, - other?: any - ) { - this.pluginInfo = pluginInfo; - this.ctx = ctx; - this.app = app; - this.baseDir = process.cwd(); - if (this.app) { - this.baseDir = this.app?.getBaseDir(); - } - this.configDir(); - this.cache = CoolCacheStore({}); - if (other) { - this.cache = other.cache; - this.pluginService = other.pluginService; - } - await this.ready(); - } - - /** - * 处理配置目录 - */ - private configDir() { - // 替换\为/ - this.baseDir = this.baseDir.replace(/\\/g, "/"); - let config = this.pluginInfo.config || {}; - config = JSON.stringify(config); - this.pluginInfo.config = JSON.parse( - config.replace(/@baseDir/g, this.baseDir) - ); - } - - /** - * 插件就绪 - */ - async ready() {} -} - -/** - * 插件服务 - */ -export declare class PluginService { - /** - * 调用插件 - * @param key 插件key - * @param method 方法 - * @param params 参数 - * @returns - */ - invoke(key: string, method: string, ...params: any[]): Promise; - /** - * 获得插件实例 - * @param key - * @returns - */ - getInstance(key: string): Promise; - /** - * 检查状态 - * @param key - */ - checkStatus(key: string): Promise; -} diff --git a/plugin-cli/tsconfig.json b/plugin-cli/tsconfig.json deleted file mode 100644 index 227342c..0000000 --- a/plugin-cli/tsconfig.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "compilerOptions": { - "declaration": true, - "target": "ES2018", - "module": "CommonJS", - "esModuleInterop": true, - "moduleResolution": "Node", - "noImplicitAny": false, - "skipLibCheck": true, - "resolveJsonModule":true, - "outDir": "./dist" - }, - "include": ["src/**/*", "scripts"], - "exclude": ["node_modules", "dist", "**/*.test.ts"] -} \ No newline at end of file diff --git a/rpc/.editorconfig b/rpc/.editorconfig deleted file mode 100644 index 4c7f8a8..0000000 --- a/rpc/.editorconfig +++ /dev/null @@ -1,11 +0,0 @@ -# 🎨 editorconfig.org - -root = true - -[*] -charset = utf-8 -end_of_line = lf -indent_style = space -indent_size = 2 -trim_trailing_whitespace = true -insert_final_newline = true \ No newline at end of file diff --git a/rpc/.eslintrc.json b/rpc/.eslintrc.json deleted file mode 100644 index 0abd65a..0000000 --- a/rpc/.eslintrc.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "extends": "./node_modules/mwts/", - "ignorePatterns": [ - "node_modules", - "dist", - "test", - "jest.config.js", - "typings", - "public/**/**", - "view/**/**" - ], - "env": { - "jest": true - }, - "rules": { - "@typescript-eslint/explicit-module-boundary-types": "off", - "@typescript-eslint/no-unused-vars": "off", - "@typescript-eslint/ban-ts-comment": "off", - "node/no-extraneous-import": "off", - "@typescript-eslint/no-this-alias": "off", - "no-empty": "off", - "node/no-extraneous-require": "off", - "eqeqeq": "off", - "node/no-unsupported-features/node-builtins": "off", - "@typescript-eslint/ban-types": "off", - "no-control-regex": "off", - "prefer-const": "off" - } -} \ No newline at end of file diff --git a/rpc/.gitignore b/rpc/.gitignore deleted file mode 100644 index 13bc3a6..0000000 --- a/rpc/.gitignore +++ /dev/null @@ -1,15 +0,0 @@ -logs/ -npm-debug.log -yarn-error.log -node_modules/ -package-lock.json -yarn.lock -coverage/ -dist/ -.idea/ -run/ -.DS_Store -*.sw* -*.un~ -.tsbuildinfo -.tsbuildinfo.* diff --git a/rpc/.prettierrc.js b/rpc/.prettierrc.js deleted file mode 100644 index b964930..0000000 --- a/rpc/.prettierrc.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - ...require('mwts/.prettierrc.json') -} diff --git a/rpc/index.d.ts b/rpc/index.d.ts deleted file mode 100644 index e0065de..0000000 --- a/rpc/index.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -export * from './dist/index'; - -declare module '@midwayjs/core/dist/interface' { - interface MidwayConfig { - book?: PowerPartial<{ - a: number; - b: string; - }>; - } -} diff --git a/rpc/jest.config.js b/rpc/jest.config.js deleted file mode 100644 index 82a8b85..0000000 --- a/rpc/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = { - preset: 'ts-jest', - testEnvironment: 'node', - testPathIgnorePatterns: ['/test/fixtures'], - coveragePathIgnorePatterns: ['/test/'], - setupFilesAfterEnv: ['./jest.setup.js'] -}; diff --git a/rpc/jest.setup.js b/rpc/jest.setup.js deleted file mode 100644 index 1399c91..0000000 --- a/rpc/jest.setup.js +++ /dev/null @@ -1 +0,0 @@ -jest.setTimeout(30000); diff --git a/rpc/package.json b/rpc/package.json deleted file mode 100644 index 9c0622f..0000000 --- a/rpc/package.json +++ /dev/null @@ -1,47 +0,0 @@ -{ - "name": "@cool-midway/rpc", - "version": "7.0.0", - "description": "cool-js.com rpc 微服务", - "main": "dist/index.js", - "typings": "index.d.ts", - "scripts": { - "build": "cross-env midway-bin build -c", - "cov": "cross-env midway-bin cov --ts", - "lint": "mwts check", - "lint:fix": "mwts fix" - }, - "keywords": [], - "author": "", - "files": [ - "dist/**/*.js", - "dist/**/*.d.ts", - "index.d.ts" - ], - "repository": { - "type": "git", - "url": "https://cool-js.com" - }, - "license": "MIT", - "devDependencies": { - "@cool-midway/core": "^7.0.0", - "@midwayjs/cli": "^2.0.9", - "@midwayjs/core": "^3.9.0", - "@midwayjs/decorator": "^3.9.0", - "@midwayjs/mock": "^3.9.0", - "@midwayjs/redis": "^3.9.0", - "@midwayjs/typeorm": "^3.9.5", - "@types/jest": "^29.2.5", - "@types/node": "^18.11.18", - "cross-env": "^7.0.3", - "jest": "^29.3.1", - "lodash": "^4.17.21", - "mwts": "^1.3.0", - "ts-jest": "^29.0.3", - "typeorm": "^0.3.11", - "typescript": "^4.9.4" - }, - "dependencies": { - "ioredis": "4.28.5", - "moleculer": "^0.14.28" - } -} diff --git a/rpc/src/README.md b/rpc/src/README.md deleted file mode 100644 index 7edd966..0000000 --- a/rpc/src/README.md +++ /dev/null @@ -1,27 +0,0 @@ -### COOL-ADMIN - -cool-admin一个很酷的后台权限管理系统,开源免费,模块化、插件化、极速开发CRUD,方便快速构建迭代后台管理系统 - -大数据、微服务、AI编码快速开发!!! - - -### 技术栈 - -- 后端:node.js midway.js koa.js mysql typescript -- 前端:vue.js element-plus jsx pinia vue-router - -### 官网 - -[https://cool-js.com](https://cool-js.com) - - -### 演示地址 - -[https://show.cool-admin.com](https://show.cool-admin.com) - -- 账户:admin -- 密码:123456 - -### 项目地址 - -[https://github.com/cool-team-official/cool-admin-midway](https://github.com/cool-team-official/cool-admin-midway) \ No newline at end of file diff --git a/rpc/src/config/config.default.ts b/rpc/src/config/config.default.ts deleted file mode 100644 index a30c406..0000000 --- a/rpc/src/config/config.default.ts +++ /dev/null @@ -1,6 +0,0 @@ -/** - * cool的配置 - */ -export default { - cool: {}, -}; diff --git a/rpc/src/configuration.ts b/rpc/src/configuration.ts deleted file mode 100644 index 16ae071..0000000 --- a/rpc/src/configuration.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { Configuration } from '@midwayjs/decorator'; -import * as DefaultConfig from './config/config.default'; -import { IMidwayContainer } from '@midwayjs/core'; -import { CoolRpc } from './rpc'; -import { CoolRpcDecorator } from './decorator'; - -@Configuration({ - namespace: 'cool:rpc', - importConfigs: [ - { - default: DefaultConfig, - }, - ], -}) -export class CoolRpcConfiguration { - async onReady(container: IMidwayContainer) { - global['moleculer.transactions'] = {}; - (await container.getAsync(CoolRpc)).init(); - // 装饰器 - await container.getAsync(CoolRpcDecorator); - } - - async onStop(container: IMidwayContainer): Promise { - (await container.getAsync(CoolRpc)).stop(); - } -} diff --git a/rpc/src/decorator/event/event.ts b/rpc/src/decorator/event/event.ts deleted file mode 100644 index 526e11e..0000000 --- a/rpc/src/decorator/event/event.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { - Scope, - ScopeEnum, - saveClassMetadata, - saveModule, -} from '@midwayjs/decorator'; - -export const COOL_RPC_EVENT_KEY = 'decorator:cool:rpc:event'; - -export function CoolRpcEvent(): ClassDecorator { - return (target: any) => { - // 将装饰的类,绑定到该装饰器,用于后续能获取到 class - saveModule(COOL_RPC_EVENT_KEY, target); - // 保存一些元数据信息,任意你希望存的东西 - saveClassMetadata(COOL_RPC_EVENT_KEY, {}, target); - // 指定 IoC 容器创建实例的作用域 - Scope(ScopeEnum.Singleton)(target); - }; -} diff --git a/rpc/src/decorator/event/handler.ts b/rpc/src/decorator/event/handler.ts deleted file mode 100644 index e5a8328..0000000 --- a/rpc/src/decorator/event/handler.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { attachClassMetadata } from '@midwayjs/decorator'; - -export const COOL_RPC_EVENT_HANDLER_KEY = 'decorator:cool:rpc:event:handler'; - -/** - * 事件 - * @param eventName 事件名称 - * @returns - */ -export function CoolRpcEventHandler(eventName?: string): MethodDecorator { - return (target: any, propertyKey: string, descriptor: PropertyDescriptor) => { - // 将装饰的类,绑定到该装饰器,用于后续能获取到 class - attachClassMetadata( - COOL_RPC_EVENT_HANDLER_KEY, - { - propertyKey, - descriptor, - eventName, - }, - target - ); - }; -} diff --git a/rpc/src/decorator/index.ts b/rpc/src/decorator/index.ts deleted file mode 100644 index 3299815..0000000 --- a/rpc/src/decorator/index.ts +++ /dev/null @@ -1,101 +0,0 @@ -import { CoolCommException } from '@cool-midway/core'; -import { - Provide, - Scope, - ScopeEnum, - JoinPoint, - Init, - MidwayDecoratorService, - Inject, -} from '@midwayjs/core'; -import { TypeORMDataSourceManager } from '@midwayjs/typeorm'; -import { COOL_RPC_TRANSACTION, TransactionOptions } from './transaction'; -import { v1 as uuid } from 'uuid'; - -/** - * 装饰器 - */ -@Provide() -@Scope(ScopeEnum.Singleton) -export class CoolRpcDecorator { - @Inject() - decoratorService: MidwayDecoratorService; - - @Inject() - typeORMDataSourceManager: TypeORMDataSourceManager; - - @Init() - async init() { - // 事务 - await this.transaction(); - } - - /** - * 事务 - */ - async transaction() { - this.decoratorService.registerMethodHandler( - COOL_RPC_TRANSACTION, - options => { - return { - around: async (joinPoint: JoinPoint) => { - const option: TransactionOptions = options.metadata; - let isCaller = false; - let rpcTransactionId; - if (joinPoint.args[0]) { - isCaller = false; - rpcTransactionId = joinPoint.args[0].rpcTransactionId; - } - // 如果没有事务ID,手动创建 - if (!rpcTransactionId) { - isCaller = true; - rpcTransactionId = uuid(); - } - - let data; - const dataSource = this.typeORMDataSourceManager.getDataSource( - option?.connectionName || 'default' - ); - const queryRunner = dataSource.createQueryRunner(); - // 使用我们的新queryRunner建立真正的数据库连 - await queryRunner.connect(); - if (option && option.isolation) { - await queryRunner.startTransaction(option.isolation); - } else { - await queryRunner.startTransaction(); - } - - try { - global['moleculer.transactions'][rpcTransactionId] = queryRunner; - // 半小时后清除 - setTimeout(() => { - global['moleculer.transactions'][rpcTransactionId].release(); - delete global['moleculer.transactions'][rpcTransactionId]; - }, 1800 * 1000); - joinPoint.args.push(rpcTransactionId); - joinPoint.args.push(queryRunner); - data = await joinPoint.proceed(...joinPoint.args); - if (isCaller) { - global['moleculer:broker'].broadcast('moleculer.transaction', { - rpcTransactionId, - commit: true, - }); - } - //await queryRunner.commitTransaction(); - } catch (error) { - //await queryRunner.rollbackTransaction(); - if (isCaller) { - global['moleculer:broker'].broadcast('moleculer.transaction', { - rpcTransactionId, - commit: false, - }); - } - throw new CoolCommException(error.message); - } - return data; - }, - }; - } - ); - } -} diff --git a/rpc/src/decorator/rpc.ts b/rpc/src/decorator/rpc.ts deleted file mode 100644 index 8e91b4b..0000000 --- a/rpc/src/decorator/rpc.ts +++ /dev/null @@ -1,84 +0,0 @@ -import { - Scope, - ScopeEnum, - saveClassMetadata, - saveModule, -} from '@midwayjs/decorator'; - -export const MOLECYLER_KEY = 'decorator:cool:rpc'; - -export type MethodTypes = - | 'add' - | 'delete' - | 'update' - | 'page' - | 'info' - | 'list'; - -// 字段匹配 -export interface FieldEq { - // 字段 - column: string; - // 请求参数 - requestParam: string; -} - -// 关联查询 -export interface LeftJoinOp { - // 实体 - entity: any; - // 别名 - alias: string; - // 关联条件 - condition: string; -} - -// Crud配置 -export interface CurdOption { - // 路由前缀,不配置默认是按Controller下的文件夹路径 - prefix?: string; - // curd api接口 - method: MethodTypes[]; - // 分页查询配置 - pageQueryOp?: QueryOp; - // 非分页查询配置 - listQueryOp?: QueryOp; - // 插入参数 - insertParam?: Function; - // info 忽略返回属性 - infoIgnoreProperty?: string[]; - // 实体 - entity: { entityKey?: any; connectionName?: string } | any; -} - -// 查询配置 -export interface QueryOp { - // 需要模糊查询的字段 - keyWordLikeFields?: string[]; - // 查询条件 - where?: Function; - // 查询字段 - select?: string[]; - // 字段相等 - fieldEq?: string[] | FieldEq[]; - // 添加排序条件 - addOrderBy?: {}; - // 关联配置 - leftJoin?: LeftJoinOp[]; -} - -/** - * moleculer 微服务配置 - * @param option - * @returns - */ -export function CoolRpcService(option?: CurdOption): ClassDecorator { - return (target: any) => { - // 将装饰的类,绑定到该装饰器,用于后续能获取到 class - saveModule(MOLECYLER_KEY, target); - // 保存一些元数据信息,任意你希望存的东西 - saveClassMetadata(MOLECYLER_KEY, option, target); - // 指定 IoC 容器创建实例的作用域,这里注册为请求作用域,这样能取到 ctx - Scope(ScopeEnum.Request)(target); - }; -} diff --git a/rpc/src/decorator/transaction.ts b/rpc/src/decorator/transaction.ts deleted file mode 100644 index 93cc5ca..0000000 --- a/rpc/src/decorator/transaction.ts +++ /dev/null @@ -1,22 +0,0 @@ -import * as _ from 'lodash'; -import { createCustomMethodDecorator } from '@midwayjs/core'; - -type IsolationLevel = - | 'READ UNCOMMITTED' - | 'READ COMMITTED' - | 'REPEATABLE READ' - | 'SERIALIZABLE'; - -export interface TransactionOptions { - connectionName?: string; - isolation?: IsolationLevel; -} - -// 装饰器内部的唯一 id -export const COOL_RPC_TRANSACTION = 'decorator:cool_rpc_transaction'; - -export function CoolRpcTransaction( - option?: TransactionOptions -): MethodDecorator { - return createCustomMethodDecorator(COOL_RPC_TRANSACTION, option); -} diff --git a/rpc/src/index.ts b/rpc/src/index.ts deleted file mode 100644 index 4d68d39..0000000 --- a/rpc/src/index.ts +++ /dev/null @@ -1,25 +0,0 @@ -export { CoolRpcConfiguration as Configuration } from './configuration'; - -export * from './test'; -export * from './rpc'; -export * from './decorator/rpc'; -export * from './decorator/event/event'; -export * from './decorator/event/handler'; -export * from './service/base'; -export * from './decorator/transaction'; -export * from './transaction/event'; -export * from './decorator/index'; - -export interface CoolRpcConfig { - // 服务名称 - name: string; - // redis - redis: RedisConfig & RedisConfig[] & unknown; -} - -export interface RedisConfig { - host: string; - password: string; - port: number; - db: number; -} diff --git a/rpc/src/package.json b/rpc/src/package.json deleted file mode 100644 index 1059822..0000000 --- a/rpc/src/package.json +++ /dev/null @@ -1,47 +0,0 @@ -{ - "name": "@cool-midway/rpc", - "version": "7.0.0", - "description": "cool-js.com rpc 微服务", - "main": "index.js", - "typings": "index.d.ts", - "scripts": { - "build": "cross-env midway-bin build -c", - "cov": "cross-env midway-bin cov --ts", - "lint": "mwts check", - "lint:fix": "mwts fix" - }, - "keywords": [], - "author": "", - "files": [ - "**/*.js", - "**/*.d.ts", - "index.d.ts" - ], - "repository": { - "type": "git", - "url": "https://cool-js.com" - }, - "license": "MIT", - "devDependencies": { - "@cool-midway/core": "^7.0.0", - "@midwayjs/cli": "^2.0.9", - "@midwayjs/core": "^3.9.0", - "@midwayjs/decorator": "^3.9.0", - "@midwayjs/mock": "^3.9.0", - "@midwayjs/redis": "^3.9.0", - "@midwayjs/typeorm": "^3.9.5", - "@types/jest": "^29.2.5", - "@types/node": "^18.11.18", - "cross-env": "^7.0.3", - "jest": "^29.3.1", - "lodash": "^4.17.21", - "mwts": "^1.3.0", - "ts-jest": "^29.0.3", - "typeorm": "^0.3.11", - "typescript": "^4.9.4" - }, - "dependencies": { - "ioredis": "4.28.5", - "moleculer": "^0.14.28" - } -} diff --git a/rpc/src/rpc.ts b/rpc/src/rpc.ts deleted file mode 100644 index 1d6c1de..0000000 --- a/rpc/src/rpc.ts +++ /dev/null @@ -1,275 +0,0 @@ -import { ILogger, IMidwayApplication, Inject } from '@midwayjs/core'; -import { - App, - Config, - getClassMetadata, - listModule, - Logger, - Provide, - Scope, - ScopeEnum, -} from '@midwayjs/decorator'; -import { ServiceBroker } from 'moleculer'; -import { CoolRpcConfig } from '.'; -import { CoolCoreException, CoolValidateException } from '@cool-midway/core'; -import { v1 as uuid } from 'uuid'; -import { BaseRpcService } from './service/base'; -import { CurdOption, MOLECYLER_KEY } from './decorator/rpc'; -import { COOL_RPC_EVENT_KEY } from './decorator/event/event'; -import { COOL_RPC_EVENT_HANDLER_KEY } from './decorator/event/handler'; -import * as _ from 'lodash'; -import { TypeORMDataSourceManager } from '@midwayjs/typeorm'; -import { camelCase } from '@midwayjs/core/dist/util/camelCase'; -// import { AgentService } from '@moleculer/lab'; - -/** - * 微服务 - */ -@Provide() -@Scope(ScopeEnum.Singleton) -export class CoolRpc { - broker: ServiceBroker; - - @Inject() - typeORMDataSourceManager: TypeORMDataSourceManager; - - @Logger() - coreLogger: ILogger; - - @Config('cool.rpc') - rpcConfig: CoolRpcConfig; - - @Config('cool') - coolConfig; - - @App() - app: IMidwayApplication; - - cruds; - - async init() { - if (!this.rpcConfig?.name) { - throw new CoolCoreException( - 'cool.rpc.name config is require and every service name must be unique' - ); - } - - let redisConfig; - - if (!this.rpcConfig?.redis && !this.coolConfig?.redis) { - throw new CoolCoreException('cool.rpc.redis or cool.redis is require'); - } - - redisConfig = this.rpcConfig?.redis - ? this.rpcConfig?.redis - : this.coolConfig?.redis; - - const transporter = { - type: 'Redis', - options: {}, - }; - if (redisConfig instanceof Array) { - transporter.options = { - cluster: { - nodes: redisConfig, - }, - }; - } else { - transporter.options = redisConfig; - } - - this.broker = new ServiceBroker({ - nodeID: `${this.rpcConfig.name}-${uuid()}`, - transporter, - // metrics: { - // enabled: true, - // reporter: 'Laboratory', - // }, - // tracing: { - // enabled: true, - // exporter: 'Laboratory', - // }, - ...this.rpcConfig, - }); - - // this.broker.createService({ - // name: this.rpcConfig.name, - // mixins: [], - // // settings: { - // // name: 'test', - // // port: 3210, - // // token: '123123', - // // apiKey: '92C18ZR-ERM45EG-HT8GQGQ-4MHCXAT', - // // }, - // }); - - global['moleculer:broker'] = this.broker; - - await this.initService(); - await this.createService(); - } - - /** - * 获得事件 - * @returns - */ - async getEvents() { - const allEvents = {}; - const modules = listModule(COOL_RPC_EVENT_KEY); - for (const module of modules) { - const moduleInstance = await this.app - .getApplicationContext() - .getAsync(module); - moduleInstance['broker'] = this.broker; - const events = getClassMetadata(COOL_RPC_EVENT_HANDLER_KEY, module); - for (const event of events) { - allEvents[event.eventName ? event.eventName : event.propertyKey] = { - handler(ctx) { - moduleInstance[event.propertyKey](ctx.params); - }, - }; - } - } - return allEvents; - } - - /** - * 创建服务 - */ - async createService() { - const _this = this; - this.broker.createService({ - name: this.rpcConfig.name, - events: await this.getEvents(), - actions: { - async call(ctx) { - const { service, method, params } = ctx.params; - const targetName = _.upperFirst(service); - const target = _.find(_this.cruds, { name: targetName }); - if (!target) { - throw new CoolValidateException('找不到服务'); - } - const curdOption: CurdOption = getClassMetadata( - MOLECYLER_KEY, - target - ); - - const cls = await _this.app - .getApplicationContext() - .getAsync(camelCase(service)); - const serviceInstance: BaseRpcService = new target(); - Object.assign(serviceInstance, cls); - serviceInstance.setModel(_this.getModel(curdOption)); - serviceInstance.setApp(_this.app); - serviceInstance.init(); - - // 如果是通用crud方法 注入参数 - if ( - ['add', 'delete', 'update', 'page', 'info', 'list'].includes(method) - ) { - if (!curdOption.method.includes(method)) { - throw new CoolValidateException('方法不存在'); - } - } - return serviceInstance[method](params); - }, - }, - }); - this.broker.start(); - } - - /** - * 初始化service,设置entity - */ - async initService() { - // 获得所有的service - this.cruds = listModule(MOLECYLER_KEY); - for (const crud of this.cruds) { - const curdOption: CurdOption = getClassMetadata(MOLECYLER_KEY, crud); - const serviceInstance: BaseRpcService = await this.app - .getApplicationContext() - .getAsync(crud); - serviceInstance.setModel(this.getModel(curdOption)); - serviceInstance.setCurdOption(curdOption); - } - } - - /** - * 获得Model - * @param curdOption - */ - getModel(curdOption) { - // 获得到model - let entityModel; - const { entity } = curdOption || {}; - if (entity) { - const dataSourceName = - this.typeORMDataSourceManager.getDataSourceNameByModel(entity); - entityModel = this.typeORMDataSourceManager - .getDataSource(dataSourceName) - .getRepository(entity); - } - return entityModel; - } - - /** - * 调用服务 - * @param name 服务名称 - * @param controller 接口服务 - * @param method 方法 - * @param params 参数 - * @returns - */ - async call(name: string, service: string, method: string, params?: {}) { - return this.broker.call(`${name}.call`, { service, method, params }); - } - - /** - * 发送事件 - * @param name 事件名称 - * @param params 事件参数 - * @param node 节点名称 - */ - async event(name: string, params: any, node?: string | string[]) { - this.broker.emit(name, params); - } - - /** - * 发送广播事件 - * @param name - * @param params - * @param node 节点名称 - */ - async broadcastEvent(name: string, params: any, node?: string | string[]) { - this.broker.broadcast(name, params); - } - - /** - * 发送本地广播事件 - * @param name - * @param params - * @param node 节点名称 - */ - async broadcastLocalEvent( - name: string, - params: any, - node?: string | string[] - ) { - this.broker.broadcastLocal(name, params); - } - - /** - * 获得原始的broker对象 - * @returns - */ - getBroker() { - return this.broker; - } - - /** - * 停止 - */ - stop() { - this.broker.stop(); - } -} diff --git a/rpc/src/service/base.ts b/rpc/src/service/base.ts deleted file mode 100644 index 8d0abf3..0000000 --- a/rpc/src/service/base.ts +++ /dev/null @@ -1,406 +0,0 @@ -import { Config, Init, Provide, App } from '@midwayjs/decorator'; -import { Brackets } from 'typeorm'; -import * as _ from 'lodash'; -import { CoolValidateException, ERRINFO } from '@cool-midway/core'; -import { QueryOp } from '../decorator/rpc'; -import { IMidwayApplication, Inject } from '@midwayjs/core'; -import * as SqlString from 'sqlstring'; -import { TypeORMDataSourceManager } from '@midwayjs/typeorm'; - -/** - * 服务基类 - */ -@Provide() -export abstract class BaseRpcService { - // 分页配置 - @Config('cool.page') - private conf; - - // 模型 - protected entity; - - protected sqlParams; - - protected curdOption; - - @Inject() - typeORMDataSourceManager: TypeORMDataSourceManager; - - // 设置模型 - setModel(entity: any) { - this.entity = entity; - } - - setCurdOption(curdOption) { - this.curdOption = curdOption; - } - - @App() - app: IMidwayApplication; - - setApp(app) { - this.app = app; - } - - // 初始化 - @Init() - init() { - this.sqlParams = []; - } - - /** - * 检查排序 - * @param sort 排序 - * @returns - */ - private checkSort(sort) { - if (!['desc', 'asc'].includes(sort.toLowerCase())) { - throw new CoolValidateException('sort 非法传参~'); - } - return sort; - } - - /** - * 获得单个ID - * @param params 参数 - */ - async info(params: any): Promise { - const { id } = params; - if (!this.entity) throw new CoolValidateException(ERRINFO.NOENTITY); - if (!id) { - throw new CoolValidateException(ERRINFO.NOID); - } - const info = await this.entity.findOne({ id }); - if (info && this.curdOption.infoIgnoreProperty) { - for (const property of this.curdOption.infoIgnoreProperty) { - delete info[property]; - } - } - return info; - } - - /** - * 执行SQL并获得分页数据 - * @param sql 执行的sql语句 - * @param query 分页查询条件 - * @param autoSort 是否自动排序 - * @param connectionName 连接名称 - */ - async sqlRenderPage(sql, query, autoSort = false, connectionName?) { - const { - size = this.conf.size, - page = 1, - order = 'createTime', - sort = 'desc', - isExport = false, - maxExportLimit, - } = query; - if (order && sort && !autoSort) { - if (!(await this.paramSafetyCheck(order + sort))) { - throw new CoolValidateException('非法传参~'); - } - sql += ` ORDER BY ${SqlString.escapeId(order)} ${this.checkSort(sort)}`; - } - if (isExport && maxExportLimit > 0) { - this.sqlParams.push(parseInt(maxExportLimit)); - sql += ' LIMIT ? '; - } - if (!isExport) { - this.sqlParams.push((page - 1) * size); - this.sqlParams.push(parseInt(size)); - sql += ' LIMIT ?,? '; - } - - let params = []; - params = params.concat(this.sqlParams); - const result = await this.nativeQuery(sql, params, connectionName); - const countResult = await this.nativeQuery( - this.getCountSql(sql), - params, - connectionName - ); - return { - list: result, - pagination: { - page: parseInt(page), - size: parseInt(size), - total: parseInt(countResult[0] ? countResult[0].count : 0), - }, - }; - } - - /** - * 设置sql - * @param condition 条件是否成立 - * @param sql sql语句 - * @param params 参数 - */ - setSql(condition, sql, params) { - let rSql = false; - if (condition || (condition === 0 && condition !== '')) { - rSql = true; - this.sqlParams = this.sqlParams.concat(params); - } - return rSql ? sql : ''; - } - - /** - * 获得查询个数的SQL - * @param sql - */ - getCountSql(sql) { - sql = sql.replace('LIMIT ', 'limit '); - return `select count(*) as count from (${ - sql.replace(new RegExp('\n', 'gm'), ' ').split('limit ')[0] - }) a`; - } - - /** - * 参数安全性检查 - * @param params - */ - async paramSafetyCheck(params) { - const lp = params.toLowerCase(); - return !( - lp.indexOf('update ') > -1 || - lp.indexOf('select ') > -1 || - lp.indexOf('delete ') > -1 || - lp.indexOf('insert ') > -1 - ); - } - - /** - * 原生查询 - * @param sql - * @param params - * @param connectionName - */ - async nativeQuery(sql, params?, connectionName?) { - if (_.isEmpty(params)) { - params = this.sqlParams; - } - let newParams = []; - newParams = newParams.concat(params); - this.sqlParams = []; - return await this.getOrmManager(connectionName).query(sql, newParams || []); - } - - /** - * 获得ORM管理 - * @param connectionName 连接名称 - */ - getOrmManager(connectionName = 'default') { - return this.typeORMDataSourceManager.getDataSource(connectionName); - } - - /** - * 非分页查询 - * @param params 查询条件 - */ - async list(params?): Promise { - if (!this.entity) throw new CoolValidateException(ERRINFO.NOENTITY); - const sql = await this.getOptionFind(params, this.curdOption.listQueryOp); - return this.nativeQuery(sql, []); - } - - /** - * 删除 - * @param params 参数 - */ - async delete(params: any | string) { - const { ids } = params; - if (!this.entity) throw new CoolValidateException(ERRINFO.NOENTITY); - if (ids instanceof Array) { - await this.entity.delete(ids); - } else { - await this.entity.delete(ids.split(',')); - } - await this.modifyAfter(ids); - } - - /** - * 新增|修改 - * @param params 数据 - */ - async addOrUpdate(params: any) { - if (!this.entity) throw new CoolValidateException(ERRINFO.NOENTITY); - await this.entity.save(params); - } - - /** - * 新增 - * @param param 数据 - */ - async add(params: any): Promise { - if (!this.entity) throw new CoolValidateException(ERRINFO.NOENTITY); - await this.addOrUpdate(params); - await this.modifyAfter(params); - return { - id: params.id, - }; - } - - /** - * 修改 - * @param param 数据 - */ - async update(params: any) { - if (!this.entity) throw new CoolValidateException(ERRINFO.NOENTITY); - if (!params.id) throw new CoolValidateException(ERRINFO.NOID); - await this.addOrUpdate(params); - await this.modifyAfter(params); - } - - /** - * 新增|修改|删除 之后的操作 - * @param data 对应数据 - */ - async modifyAfter(data: any): Promise {} - - /** - * 分页查询 - * @param params 查询条件 - */ - async page(params?) { - if (!this.entity) throw new CoolValidateException(ERRINFO.NOENTITY); - const sql = await this.getOptionFind(params, this.curdOption.pageQueryOp); - return this.sqlRenderPage(sql, params, true); - } - - /** - * query - * @param data - * @param query - */ - renderPage(data, query) { - const { size = this.conf.size, page = 1 } = query; - return { - list: data[0], - pagination: { - page: parseInt(page), - size: parseInt(size), - total: data[1], - }, - }; - } - - /** - * 构建查询配置 - * @param query 前端查询 - * @param option - */ - private async getOptionFind(query, option: QueryOp) { - let { order = 'createTime', sort = 'desc', keyWord = '' } = query || {}; - let sqlArr = ['SELECT']; - let selects = ['a.*']; - let find = this.entity.createQueryBuilder('a'); - if (option) { - // 判断是否有关联查询,有的话取个别名 - if (!_.isEmpty(option.leftJoin)) { - for (const item of option.leftJoin) { - selects.push(`${item.alias}.*`); - find.leftJoin(item.entity, item.alias, item.condition); - } - } - // 默认条件 - if (option.where) { - const wheres = await option.where(query, this.app); - if (!_.isEmpty(wheres)) { - for (const item of wheres) { - if ( - item.length == 2 || - (item.length == 3 && - (item[2] || (item[2] === 0 && item[2] != ''))) - ) { - for (const key in item[1]) { - this.sqlParams.push(item[1][key]); - } - find.andWhere(item[0], item[1]); - } - } - } - } - // 附加排序 - if (!_.isEmpty(option.addOrderBy)) { - for (const key in option.addOrderBy) { - find.addOrderBy( - SqlString.escapeId(key), - this.checkSort(option.addOrderBy[key].toUpperCase()) - ); - } - } - // 关键字模糊搜索 - if (keyWord) { - keyWord = `%${keyWord}%`; - find.andWhere( - new Brackets(qb => { - const keyWordLikeFields = option.keyWordLikeFields; - for (let i = 0; i < option.keyWordLikeFields?.length || 0; i++) { - qb.orWhere(`${keyWordLikeFields[i]} like :keyWord`, { - keyWord, - }); - this.sqlParams.push(keyWord); - } - }) - ); - } - // 筛选字段 - if (!_.isEmpty(option.select)) { - sqlArr.push(option.select.join(',')); - find.select(option.select); - } else { - sqlArr.push(selects.join(',')); - } - // 字段全匹配 - if (!_.isEmpty(option.fieldEq)) { - for (const key of option.fieldEq) { - const c = {}; - // 单表字段无别名的情况下操作 - if (typeof key === 'string') { - if (query[key] || query[key] == 0) { - c[key] = query[key]; - const eq = query[key] instanceof Array ? 'in' : '='; - if (eq === 'in') { - find.andWhere(`${key} ${eq} (:${key})`, c); - } else { - find.andWhere(`${key} ${eq} :${key}`, c); - } - this.sqlParams.push(query[key]); - } - } else { - if (query[key.column] || query[key.column] == 0) { - c[key.column] = query[key.column]; - const eq = query[key.column] instanceof Array ? 'in' : '='; - if (eq === 'in') { - find.andWhere(`${key.column} ${eq} (:${key.column})`, c); - } else { - find.andWhere(`${key.column} ${eq} :${key.column}`, c); - } - this.sqlParams.push(query[key.column]); - } - } - } - } - } else { - sqlArr.push(selects.join(',')); - } - // 接口请求的排序 - if (sort && order) { - const sorts = sort.toUpperCase().split(','); - const orders = order.split(','); - if (sorts.length != orders.length) { - throw new CoolValidateException(ERRINFO.SORTFIELD); - } - for (const i in sorts) { - find.addOrderBy( - SqlString.escapeId(orders[i]), - this.checkSort(sorts[i]) - ); - } - } - const sqls = find.getSql().split('FROM'); - sqlArr.push('FROM'); - sqlArr.push(sqls[1]); - return sqlArr.join(' '); - } -} diff --git a/rpc/src/test.ts b/rpc/src/test.ts deleted file mode 100644 index d15b931..0000000 --- a/rpc/src/test.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { Controller, Inject, Post, Provide } from '@midwayjs/decorator'; -import { BaseController } from '@cool-midway/core'; -import { CoolRpc } from './rpc'; - -/** - * 本地开发调试 - */ -@Provide() -@Controller('/rpc') -export class RpcTestController extends BaseController { - @Inject() - rpc: CoolRpc; - - @Inject() - ctx; - - /** - * 测试 - */ - @Post('/test') - async test() { - const { name, service, method, params } = this.ctx.request.body; - return this.rpc.call(name, service, method, params); - } -} diff --git a/rpc/src/transaction/event.ts b/rpc/src/transaction/event.ts deleted file mode 100644 index c81cf6c..0000000 --- a/rpc/src/transaction/event.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { Logger, Provide, Scope, ScopeEnum } from '@midwayjs/decorator'; -import { CoolRpcEvent, CoolRpcEventHandler } from '..'; -import { ILogger } from '@midwayjs/logger'; - -/** - * moleculer 事件处理 - */ -@Provide() -@Scope(ScopeEnum.Singleton) -@CoolRpcEvent() -export class MoleculerTransactionHandler { - @Logger() - coreLogger: ILogger; - - /** - * 注册事件 - * @param params - */ - @CoolRpcEventHandler('moleculer.transaction') // 唯一参数,eventName,事件名,可不填,默认为方法名 - async handler(params) { - const { rpcTransactionId, commit } = params; - this.coreLogger.info( - `\x1B[36m [cool:core] MoleculerTransaction event params: ${JSON.stringify( - params - )} \x1B[0m` - ); - if (global['moleculer.transactions'][rpcTransactionId]) { - this.coreLogger.info( - `\x1B[36m [cool:core] MoleculerTransaction event ${ - commit ? 'commitTransaction' : 'rollbackTransaction' - } ID: ${rpcTransactionId} \x1B[0m` - ); - await global['moleculer.transactions'][rpcTransactionId][ - commit ? 'commitTransaction' : 'rollbackTransaction' - ](); - await global['moleculer.transactions'][rpcTransactionId].release(); - delete global['moleculer.transactions'][rpcTransactionId]; - } - } -} diff --git a/rpc/tsconfig.json b/rpc/tsconfig.json deleted file mode 100644 index f01e1d2..0000000 --- a/rpc/tsconfig.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "compileOnSave": true, - "compilerOptions": { - "target": "es2018", - "module": "commonjs", - "moduleResolution": "node", - "experimentalDecorators": true, - "emitDecoratorMetadata": true, - "inlineSourceMap":false, - "noImplicitThis": true, - "noUnusedLocals": true, - "stripInternal": true, - "skipLibCheck": true, - "noImplicitReturns": false, - "pretty": true, - "declaration": true, - "outDir": "dist" - }, - "exclude": [ - "dist", - "node_modules", - "test" - ] -} diff --git a/sms/.editorconfig b/sms/.editorconfig deleted file mode 100644 index 4c7f8a8..0000000 --- a/sms/.editorconfig +++ /dev/null @@ -1,11 +0,0 @@ -# 🎨 editorconfig.org - -root = true - -[*] -charset = utf-8 -end_of_line = lf -indent_style = space -indent_size = 2 -trim_trailing_whitespace = true -insert_final_newline = true \ No newline at end of file diff --git a/sms/.eslintrc.json b/sms/.eslintrc.json deleted file mode 100644 index aad9755..0000000 --- a/sms/.eslintrc.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "extends": "./node_modules/mwts/", - "ignorePatterns": [ - "node_modules", - "dist", - "test", - "jest.config.js", - "typings", - "public/**/**", - "view/**/**" - ], - "env": { - "jest": true - }, - "rules": { - "@typescript-eslint/explicit-module-boundary-types": "off", - "@typescript-eslint/no-unused-vars": "off", - "@typescript-eslint/ban-ts-comment": "off", - "node/no-extraneous-import": "off", - "no-empty": "off", - "node/no-extraneous-require": "off", - "eqeqeq": "off", - "node/no-unsupported-features/node-builtins": "off", - "@typescript-eslint/ban-types": "off", - "no-control-regex": "off", - "prefer-const": "off" - } -} \ No newline at end of file diff --git a/sms/.gitignore b/sms/.gitignore deleted file mode 100644 index 13bc3a6..0000000 --- a/sms/.gitignore +++ /dev/null @@ -1,15 +0,0 @@ -logs/ -npm-debug.log -yarn-error.log -node_modules/ -package-lock.json -yarn.lock -coverage/ -dist/ -.idea/ -run/ -.DS_Store -*.sw* -*.un~ -.tsbuildinfo -.tsbuildinfo.* diff --git a/sms/.prettierrc.js b/sms/.prettierrc.js deleted file mode 100644 index b964930..0000000 --- a/sms/.prettierrc.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - ...require('mwts/.prettierrc.json') -} diff --git a/sms/index.d.ts b/sms/index.d.ts deleted file mode 100644 index e0065de..0000000 --- a/sms/index.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -export * from './dist/index'; - -declare module '@midwayjs/core/dist/interface' { - interface MidwayConfig { - book?: PowerPartial<{ - a: number; - b: string; - }>; - } -} diff --git a/sms/jest.config.js b/sms/jest.config.js deleted file mode 100644 index 82a8b85..0000000 --- a/sms/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = { - preset: 'ts-jest', - testEnvironment: 'node', - testPathIgnorePatterns: ['/test/fixtures'], - coveragePathIgnorePatterns: ['/test/'], - setupFilesAfterEnv: ['./jest.setup.js'] -}; diff --git a/sms/jest.setup.js b/sms/jest.setup.js deleted file mode 100644 index 1399c91..0000000 --- a/sms/jest.setup.js +++ /dev/null @@ -1 +0,0 @@ -jest.setTimeout(30000); diff --git a/sms/package.json b/sms/package.json deleted file mode 100644 index a4c9037..0000000 --- a/sms/package.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "name": "@cool-midway/sms", - "version": "7.0.1", - "description": "cool-js.com 短信", - "main": "dist/index.js", - "typings": "index.d.ts", - "scripts": { - "build": "cross-env midway-bin build -c", - "cov": "cross-env midway-bin cov --ts", - "lint": "mwts check", - "lint:fix": "mwts fix" - }, - "keywords": [ - "cool", - "cool-admin", - "cooljs" - ], - "author": "COOL", - "readme": "README.md", - "files": [ - "dist/**/*.js", - "dist/**/*.d.ts", - "index.d.ts" - ], - "license": "MIT", - "repository": { - "type": "git", - "url": "https://cool-js.com" - }, - "devDependencies": { - "@cool-midway/core": "^7.0.0", - "@midwayjs/cli": "^2.0.9", - "@midwayjs/core": "^3.9.0", - "@midwayjs/decorator": "^3.9.0", - "@midwayjs/mock": "^3.9.0", - "@types/jest": "^29.2.5", - "@types/node": "^18.11.18", - "axios": "^1.5.0", - "cross-env": "^7.0.3", - "jest": "^29.3.1", - "mwts": "^1.3.0", - "ts-jest": "^29.0.3", - "typescript": "^4.9.4" - }, - "dependencies": { - "@alicloud/pop-core": "^1.7.13", - "@aws-sdk/client-sns": "^3.465.0", - "tencentcloud-sdk-nodejs": "^4.0.607" - } -} diff --git a/sms/src/README.md b/sms/src/README.md deleted file mode 100644 index 7edd966..0000000 --- a/sms/src/README.md +++ /dev/null @@ -1,27 +0,0 @@ -### COOL-ADMIN - -cool-admin一个很酷的后台权限管理系统,开源免费,模块化、插件化、极速开发CRUD,方便快速构建迭代后台管理系统 - -大数据、微服务、AI编码快速开发!!! - - -### 技术栈 - -- 后端:node.js midway.js koa.js mysql typescript -- 前端:vue.js element-plus jsx pinia vue-router - -### 官网 - -[https://cool-js.com](https://cool-js.com) - - -### 演示地址 - -[https://show.cool-admin.com](https://show.cool-admin.com) - -- 账户:admin -- 密码:123456 - -### 项目地址 - -[https://github.com/cool-team-official/cool-admin-midway](https://github.com/cool-team-official/cool-admin-midway) \ No newline at end of file diff --git a/sms/src/ali.ts b/sms/src/ali.ts deleted file mode 100644 index fdc4864..0000000 --- a/sms/src/ali.ts +++ /dev/null @@ -1,68 +0,0 @@ -import * as Core from '@alicloud/pop-core'; -import { Config, Provide } from '@midwayjs/core'; -import { CoolSmsAliConfig } from './interface'; -import { CoolCommException } from '@cool-midway/core'; - -/** - * 阿里云短信 - */ -@Provide() -export class SmsAli { - @Config('cool.sms.ali') - config: CoolSmsAliConfig; - - /** - * 配置 - * @param config - */ - setConfig(config: CoolSmsAliConfig) { - this.config = config; - } - - /** - * 发送短信 - * @param phone 手机号 - * @param params 参数 - * @param config signName 签名 template 模板 - * @returns - */ - async send( - phone, - params: { - [key: string]: string; - }, - config?: { - signName: string; - template: string; - } - ) { - const { accessKeyId, accessKeySecret } = this.config; - if (!accessKeyId || !accessKeyId) { - throw new CoolCommException('请配置阿里云短信'); - } - if (!config) { - config = { - signName: this.config.signName, - template: this.config.template, - }; - } - const client = new Core({ - accessKeyId, - accessKeySecret, - endpoint: 'https://dysmsapi.aliyuncs.com', - // endpoint: 'https://cs.cn-hangzhou.aliyuncs.com', - apiVersion: '2017-05-25', - // apiVersion: '2018-04-18', - }); - const data = { - RegionId: 'cn-shanghai', - PhoneNumbers: phone, - signName: config.signName, - templateCode: config.template, - TemplateParam: JSON.stringify(params), - }; - return await client.request('SendSms', data, { - method: 'POST', - }); - } -} diff --git a/sms/src/aws.ts b/sms/src/aws.ts deleted file mode 100644 index 6770e62..0000000 --- a/sms/src/aws.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { Config, Provide } from '@midwayjs/core'; -import { CoolSmsAwsConfig } from './interface'; -import { CoolCommException } from '@cool-midway/core'; -import { SNSClient, PublishCommand } from '@aws-sdk/client-sns'; - -/** - * 亚马逊云短信 - */ -@Provide() -export class SmsAws { - @Config('cool.sms.aws') - config: CoolSmsAwsConfig; - - /** - * 配置 - * @param config - */ - setConfig(config: CoolSmsAwsConfig) { - this.config = config; - } - - /** - * 发送短信 - * @param phone 手机号 - * @param params 参数 - * @returns - */ - async send(phone: string, content: string) { - const { region, accessKeyId, secretAccessKey, extend = {} } = this.config; - if (!region || !accessKeyId || !secretAccessKey) { - throw new CoolCommException('请配置AWS短信'); - } - // 配置 AWS - const client = new SNSClient({ - region, // 例如 'us-east-1' - credentials: { - accessKeyId, - secretAccessKey, - }, - ...extend, - }); - - const data = { - Message: content, - PhoneNumber: phone, - }; - const result = await client.send(new PublishCommand(data)); - return result; - } -} diff --git a/sms/src/config/config.default.ts b/sms/src/config/config.default.ts deleted file mode 100644 index 2a8c538..0000000 --- a/sms/src/config/config.default.ts +++ /dev/null @@ -1,5 +0,0 @@ -export const customKey = { - a: 1, - b: 'hello', - }; - \ No newline at end of file diff --git a/sms/src/configuration.ts b/sms/src/configuration.ts deleted file mode 100644 index d968e7f..0000000 --- a/sms/src/configuration.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { Configuration } from '@midwayjs/decorator'; -import * as DefaultConfig from './config/config.default'; -import { IMidwayContainer } from '@midwayjs/core'; - -@Configuration({ - namespace: 'cool:sms', - importConfigs: [ - { - default: DefaultConfig, - }, - ], -}) -export class CoolPayConfiguration { - async onReady(container: IMidwayContainer) { - // TODO something - } -} diff --git a/sms/src/index.ts b/sms/src/index.ts deleted file mode 100644 index 9285388..0000000 --- a/sms/src/index.ts +++ /dev/null @@ -1,10 +0,0 @@ -export { CoolPayConfiguration as Configuration } from './configuration'; - -export * from './interface'; - -export * from './ali'; -export * from './yp'; -export * from './tx'; -export * from './aws'; - -export * from './sms'; diff --git a/sms/src/interface.ts b/sms/src/interface.ts deleted file mode 100644 index dfb9a43..0000000 --- a/sms/src/interface.ts +++ /dev/null @@ -1,103 +0,0 @@ -export interface CoolSmsConfig { - /** - * 阿里云短信配置 - */ - ali: CoolSmsAliConfig; - /** - * 腾讯云短信配置 - */ - tx: CoolSmsTxConfig; - /** - * 云片短信配置 - */ - yp: CoolSmsYpConfig; - /** - * aws短信配置 - */ - aws: CoolSmsAwsConfig; -} - -export interface CoolSmsAwsConfig { - /** - * 区域 - */ - region: string; - /** - * accessKeyId - */ - accessKeyId: string; - /** - * secretAccessKey - */ - secretAccessKey: string; - /** - * 扩展配置 - */ - extend?: any; -} - -/** - * 阿里云配置 - */ -export interface CoolSmsAliConfig { - /** - * 阿里云accessKeyId - */ - accessKeyId: string; - /** - * 阿里云accessKeySecret - */ - accessKeySecret: string; - /** - * 签名,非必填,调用时可以传入 - */ - signName?: string; - /** - * 模板,非必填,调用时可以传入 - */ - template?: string; -} - -/** - * 腾讯云配置 - */ -export interface CoolSmsTxConfig { - /** - * 应用ID - */ - appId: string; - /** - * 腾讯云secretId - */ - secretId: string; - /** - * 腾讯云secretKey - */ - secretKey: string; - /** - * 签名,非必填,调用时可以传入 - */ - signName?: string; - /** - * 模板,非必填,调用时可以传入 - */ - template?: string; -} - -/** - * 云片短信配置 - */ -export interface CoolSmsYpConfig { - /** - * 云片apikey - */ - apikey: string; - /** - * 签名,非必填,调用时可以传入 - */ - signName?: string; - /** - * 模板,非必填,调用时可以传入 - */ - template?: string; -} diff --git a/sms/src/package.json b/sms/src/package.json deleted file mode 100644 index a78e7de..0000000 --- a/sms/src/package.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "name": "@cool-midway/sms", - "version": "7.0.1", - "description": "cool-js.com 短信", - "main": "index.js", - "typings": "index.d.ts", - "scripts": { - "build": "cross-env midway-bin build -c", - "cov": "cross-env midway-bin cov --ts", - "lint": "mwts check", - "lint:fix": "mwts fix" - }, - "keywords": [ - "cool", - "cool-admin", - "cooljs" - ], - "author": "COOL", - "readme": "README.md", - "files": [ - "**/*.js", - "**/*.d.ts", - "index.d.ts" - ], - "license": "MIT", - "repository": { - "type": "git", - "url": "https://cool-js.com" - }, - "devDependencies": { - "@cool-midway/core": "^7.0.0", - "@midwayjs/cli": "^2.0.9", - "@midwayjs/core": "^3.9.0", - "@midwayjs/decorator": "^3.9.0", - "@midwayjs/mock": "^3.9.0", - "@types/jest": "^29.2.5", - "@types/node": "^18.11.18", - "cross-env": "^7.0.3", - "jest": "^29.3.1", - "mwts": "^1.3.0", - "ts-jest": "^29.0.3", - "typescript": "^4.9.4", - "axios": "^1.5.0" - }, - "dependencies": { - "@alicloud/pop-core": "^1.7.13", - "@aws-sdk/client-sns": "^3.465.0", - "tencentcloud-sdk-nodejs": "^4.0.607" - } -} diff --git a/sms/src/sms.ts b/sms/src/sms.ts deleted file mode 100644 index 976b6e6..0000000 --- a/sms/src/sms.ts +++ /dev/null @@ -1,97 +0,0 @@ -import { Config, Inject, Provide } from '@midwayjs/core'; -import { SmsYp } from './yp'; -import { SmsAli } from './ali'; -import { SmsTx } from './tx'; -import { CoolSmsConfig } from './interface'; -import { SmsAws } from './aws'; - -@Provide() -export class CoolSms { - @Inject() - smsYp: SmsYp; - - @Inject() - smsAli: SmsAli; - - @Inject() - smsTx: SmsTx; - - @Inject() - smsAws: SmsAws; - - @Config('cool.sms') - config: CoolSmsConfig; - - /** - * 配置 - * @param config - */ - setConfig(config: CoolSmsConfig) { - this.smsYp.setConfig(config.yp); - this.smsAli.setConfig(config.ali); - this.smsTx.setConfig(config.tx); - this.config = config; - } - - /** - * 发送验证码 模板字段名为:code - * @param phone - * @param config - */ - async sendCode( - phone, - config?: { - signName: string; - template: string; - } - ) { - const code = this.generateNumber(); - let params = { - code, - }; - await this.send(phone, this.config.tx ? [code] : params, config); - return code; - } - - /** - * 发送短信 - * @param phone - * @param params - * @param config - * @returns - */ - async send( - phone: string, - params: any, - config?: { - signName: string; - template: string; - } - ) { - if (this.config.ali) { - return await this.smsAli.send(phone, params, config); - } - if (this.config.tx) { - return await this.smsTx.send(phone, params, config); - } - if (this.config.yp) { - return await this.smsYp.send(phone, params, config); - } - if (this.config.aws) { - return await this.smsAws.send(phone, params); - } - return true; - } - - /** - * 生成验证码 - */ - generateNumber(digits = 4) { - if (digits <= 0) { - return 0; - } - const min = Math.pow(10, digits - 1); - const max = Math.pow(10, digits) - 1; - return Math.floor(Math.random() * (max - min + 1)) + min; - } -} diff --git a/sms/src/tx.ts b/sms/src/tx.ts deleted file mode 100644 index 4d9fe87..0000000 --- a/sms/src/tx.ts +++ /dev/null @@ -1,74 +0,0 @@ -import { Config, Provide } from '@midwayjs/core'; -import { CoolSmsTxConfig } from './interface'; -import * as tencentcloud from 'tencentcloud-sdk-nodejs'; -import { CoolCommException } from '@cool-midway/core'; - -/** - * 腾讯云短信 - */ -@Provide() -export class SmsTx { - @Config('cool.sms.tx') - config: CoolSmsTxConfig; - - /** - * 配置 - * @param config - */ - setConfig(config: CoolSmsTxConfig) { - this.config = config; - } - - /** - * 发送短信 - * @param phone 手机号 - * @param params 参数 - * @param config signName 签名 template 模板 - * @returns - */ - async send( - phone: string, - params: string[], - config?: { - signName: string; - template: string; - } - ) { - const { appId, secretId, secretKey } = this.config; - if (!config) { - config = { - signName: this.config.signName, - template: this.config.template, - }; - } - if (!appId || !secretId || !secretKey) { - throw new CoolCommException('请配置腾讯云短信'); - } - const smsClient = tencentcloud.sms.v20210111.Client; - - const client = new smsClient({ - credential: { - secretId, - secretKey, - }, - region: 'ap-guangzhou', - profile: { - signMethod: 'HmacSHA256', - httpProfile: { - reqMethod: 'POST', - reqTimeout: 30, - endpoint: 'sms.tencentcloudapi.com', - }, - }, - }); - - const data = { - SmsSdkAppId: appId, - SignName: config.signName, - TemplateId: config.template, - TemplateParamSet: params, - PhoneNumberSet: [`+86${phone}`], - }; - return client.SendSms(data); - } -} diff --git a/sms/src/yp.ts b/sms/src/yp.ts deleted file mode 100644 index c7440fb..0000000 --- a/sms/src/yp.ts +++ /dev/null @@ -1,90 +0,0 @@ -import { Config, Provide } from '@midwayjs/core'; -import { CoolSmsYpConfig } from './interface'; -import { CoolCommException } from '@cool-midway/core'; -import axios from 'axios'; - -/** - * 云片短信 - */ -@Provide() -export class SmsYp { - @Config('cool.sms.yp') - config: CoolSmsYpConfig; - - /** - * 配置 - * @param config - */ - setConfig(config: CoolSmsYpConfig) { - this.config = config; - } - - /** - * 发送短信 - * @param phones 手机号 数组,需要加国家码如 ["+8612345678901"] - * @param params 参数 - * @param config signName 签名 template 模板 - * @returns - */ - async send( - phones: string, - params: { - [key: string]: string; - }, - config?: { - signName: string; - template: string; - } - ) { - const { apikey } = this.config; - if (!config) { - config = { - signName: this.config.signName, - template: this.config.template, - }; - } - if (!apikey) { - throw new CoolCommException('请配置云片短信'); - } - - const headers = { - Accept: 'application/json;charset=utf-8', - 'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8', - }; - const data = { - apikey: apikey, - mobile: phones, - tpl_id: config.template, - tpl_value: this.smsTplValue(params), - }; - const result = await axios.post( - 'https://sms.yunpian.com/v2/sms/tpl_single_send.json', - data, - { headers } - ); - if (result.data.code === 0) { - return true; - } - return false; - } - - /** - * 获得短信模板值 - * @param obj - * @returns - */ - protected smsTplValue(obj) { - const urlParams = []; - - for (let key in obj) { - // eslint-disable-next-line no-prototype-builtins - if (obj.hasOwnProperty(key)) { - const encodedKey = encodeURIComponent(`#${key}#`); - const encodedValue = encodeURIComponent(obj[key]); - urlParams.push(`${encodedKey}=${encodedValue}`); - } - } - - return urlParams.join('&'); - } -} diff --git a/sms/tsconfig.json b/sms/tsconfig.json deleted file mode 100644 index f01e1d2..0000000 --- a/sms/tsconfig.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "compileOnSave": true, - "compilerOptions": { - "target": "es2018", - "module": "commonjs", - "moduleResolution": "node", - "experimentalDecorators": true, - "emitDecoratorMetadata": true, - "inlineSourceMap":false, - "noImplicitThis": true, - "noUnusedLocals": true, - "stripInternal": true, - "skipLibCheck": true, - "noImplicitReturns": false, - "pretty": true, - "declaration": true, - "outDir": "dist" - }, - "exclude": [ - "dist", - "node_modules", - "test" - ] -} diff --git a/task/.editorconfig b/task/.editorconfig deleted file mode 100644 index 4c7f8a8..0000000 --- a/task/.editorconfig +++ /dev/null @@ -1,11 +0,0 @@ -# 🎨 editorconfig.org - -root = true - -[*] -charset = utf-8 -end_of_line = lf -indent_style = space -indent_size = 2 -trim_trailing_whitespace = true -insert_final_newline = true \ No newline at end of file diff --git a/task/.eslintrc.json b/task/.eslintrc.json deleted file mode 100644 index fa5dee4..0000000 --- a/task/.eslintrc.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "extends": "./node_modules/mwts/", - "ignorePatterns": [ - "node_modules", - "dist", - "test", - "jest.config.js", - "typings", - "public/**/**", - "view/**/**" - ], - "env": { - "jest": true - }, - "rules": { - "@typescript-eslint/explicit-module-boundary-types": "off", - "@typescript-eslint/no-unused-vars": "off", - "@typescript-eslint/ban-ts-comment": "off", - "node/no-extraneous-import": "off", - "no-empty": "off", - "node/no-extraneous-require": "off", - "eqeqeq": "off", - "node/no-unsupported-features/node-builtins": "off", - "@typescript-eslint/ban-types": "off", - "no-control-regex": "off", - "prefer-const": "off" - } -} \ No newline at end of file diff --git a/task/.gitignore b/task/.gitignore deleted file mode 100644 index 13bc3a6..0000000 --- a/task/.gitignore +++ /dev/null @@ -1,15 +0,0 @@ -logs/ -npm-debug.log -yarn-error.log -node_modules/ -package-lock.json -yarn.lock -coverage/ -dist/ -.idea/ -run/ -.DS_Store -*.sw* -*.un~ -.tsbuildinfo -.tsbuildinfo.* diff --git a/task/.prettierrc.js b/task/.prettierrc.js deleted file mode 100644 index b964930..0000000 --- a/task/.prettierrc.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - ...require('mwts/.prettierrc.json') -} diff --git a/task/README.md b/task/README.md deleted file mode 100644 index 610c3db..0000000 --- a/task/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# cool-admin - -https://cool-js.com diff --git a/task/index.d.ts b/task/index.d.ts deleted file mode 100644 index e0065de..0000000 --- a/task/index.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -export * from './dist/index'; - -declare module '@midwayjs/core/dist/interface' { - interface MidwayConfig { - book?: PowerPartial<{ - a: number; - b: string; - }>; - } -} diff --git a/task/jest.config.js b/task/jest.config.js deleted file mode 100644 index 82a8b85..0000000 --- a/task/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = { - preset: 'ts-jest', - testEnvironment: 'node', - testPathIgnorePatterns: ['/test/fixtures'], - coveragePathIgnorePatterns: ['/test/'], - setupFilesAfterEnv: ['./jest.setup.js'] -}; diff --git a/task/jest.setup.js b/task/jest.setup.js deleted file mode 100644 index 1399c91..0000000 --- a/task/jest.setup.js +++ /dev/null @@ -1 +0,0 @@ -jest.setTimeout(30000); diff --git a/task/package.json b/task/package.json deleted file mode 100644 index 999ec32..0000000 --- a/task/package.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "name": "@cool-midway/task", - "version": "7.0.0", - "description": "cool-js.com 任务与队列", - "main": "dist/index.js", - "typings": "index.d.ts", - "scripts": { - "build": "cross-env midway-bin build -c", - "cov": "cross-env midway-bin cov --ts", - "lint": "mwts check", - "lint:fix": "mwts fix" - }, - "keywords": [ - "cool", - "cool-admin", - "cooljs" - ], - "author": "COOL", - "readme": "README.md", - "files": [ - "dist/**/*.js", - "dist/**/*.d.ts", - "index.d.ts" - ], - "license": "MIT", - "repository": { - "type": "git", - "url": "https://cool-js.com" - }, - "devDependencies": { - "@cool-midway/core": "^7.0.0", - "@midwayjs/cli": "^2.0.9", - "@midwayjs/core": "^3.9.0", - "@midwayjs/decorator": "^3.9.0", - "@midwayjs/mock": "^3.9.0", - "@midwayjs/redis": "^3.9.0", - "@types/jest": "^29.2.5", - "@types/node": "^18.11.18", - "cross-env": "^7.0.3", - "jest": "^29.3.1", - "lodash": "^4.17.21", - "mwts": "^1.3.0", - "ts-jest": "^29.0.3", - "typescript": "^4.9.4" - }, - "dependencies": { - "bullmq": "^3.5.2", - "ioredis": "^5.2.4" - } -} diff --git a/task/src/README.md b/task/src/README.md deleted file mode 100644 index 7edd966..0000000 --- a/task/src/README.md +++ /dev/null @@ -1,27 +0,0 @@ -### COOL-ADMIN - -cool-admin一个很酷的后台权限管理系统,开源免费,模块化、插件化、极速开发CRUD,方便快速构建迭代后台管理系统 - -大数据、微服务、AI编码快速开发!!! - - -### 技术栈 - -- 后端:node.js midway.js koa.js mysql typescript -- 前端:vue.js element-plus jsx pinia vue-router - -### 官网 - -[https://cool-js.com](https://cool-js.com) - - -### 演示地址 - -[https://show.cool-admin.com](https://show.cool-admin.com) - -- 账户:admin -- 密码:123456 - -### 项目地址 - -[https://github.com/cool-team-official/cool-admin-midway](https://github.com/cool-team-official/cool-admin-midway) \ No newline at end of file diff --git a/task/src/base.ts b/task/src/base.ts deleted file mode 100644 index 8d1e5b6..0000000 --- a/task/src/base.ts +++ /dev/null @@ -1,118 +0,0 @@ -import { - Job, - JobsOptions, - Queue, - QueueGetters, - RepeatOptions, - Worker, -} from 'bullmq'; - -/** - * 队列基类 - */ -export abstract class BaseCoolQueue { - /** - * @deprecated 将在后续版本废弃 - */ - queue: BaseCoolQueue; - // 获得者 - getters: QueueGetters; - // 消费者 - worker: Worker; - // 队列名 - queueName: string; - // 原始队列 - metaQueue: Queue; - - constructor() { - this.queue = this; - } - - // 数据 - async data(job: Job, done: Function) {} - - /** - * 发送数据 - * @param data - * @param opts - */ - async add(data: any, opts?: JobsOptions): Promise> { - return this.metaQueue.add(this.queueName, data, opts); - } - - /** - * 批量新增 - * @param datas - * @param opts - */ - async addBulk( - datas: any[], - opts?: JobsOptions - ): Promise[]> { - return this.metaQueue.addBulk( - datas.map(data => { - return { - name: this.queueName, - data, - opts, - }; - }) - ); - } - - defaultJobOptions(): JobsOptions { - return this.metaQueue.defaultJobOptions; - } - - async repeat() { - return this.metaQueue.repeat; - } - - async pause() { - this.metaQueue.pause(); - } - - async resume() { - this.metaQueue.resume(); - } - - async isPaused() { - return this.metaQueue.isPaused(); - } - - async getRepeatableJobs(start?: number, end?: number, asc?: boolean) { - return this.metaQueue.getRepeatableJobs(start, end, asc); - } - - async removeRepeatable(repeatOpts: RepeatOptions, jobId?: string) { - this.metaQueue.removeRepeatable(this.queueName, repeatOpts, jobId); - } - - async removeRepeatableByKey(key: string) { - this.metaQueue.removeRepeatableByKey(key); - } - - async remove(jobId: string) { - return this.metaQueue.remove(jobId); - } - - async drain(delayed?: boolean) { - this.metaQueue.drain(delayed); - } - - async clean( - grace: number, - limit: number, - type?: 'completed' | 'wait' | 'active' | 'paused' | 'delayed' | 'failed' - ) { - return this.metaQueue.clean(grace, limit, type); - } - - async obliterate(opts?: { force?: boolean; count?: number }) { - this.metaQueue.obliterate(opts); - } - - async trimEvents(maxLength: number) { - return this.metaQueue.trimEvents(maxLength); - } -} diff --git a/task/src/config/config.default.ts b/task/src/config/config.default.ts deleted file mode 100644 index a30c406..0000000 --- a/task/src/config/config.default.ts +++ /dev/null @@ -1,6 +0,0 @@ -/** - * cool的配置 - */ -export default { - cool: {}, -}; diff --git a/task/src/configuration.ts b/task/src/configuration.ts deleted file mode 100644 index 4baebdf..0000000 --- a/task/src/configuration.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { Configuration } from '@midwayjs/decorator'; -import * as DefaultConfig from './config/config.default'; -import { IMidwayContainer } from '@midwayjs/core'; -import { CoolQueueHandle } from './queue'; - -@Configuration({ - namespace: 'cool:task', - importConfigs: [ - { - default: DefaultConfig, - }, - ], -}) -export class CoolTaskConfiguration { - async onReady(container: IMidwayContainer) { - await container.getAsync(CoolQueueHandle); - // TODO something - } -} diff --git a/task/src/decorator/queue.ts b/task/src/decorator/queue.ts deleted file mode 100644 index 6303fb4..0000000 --- a/task/src/decorator/queue.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { - Scope, - ScopeEnum, - saveClassMetadata, - saveModule, -} from '@midwayjs/decorator'; -import { JobsOptions } from 'bullmq'; - -export const COOL_TASK_KEY = 'decorator:cool:task'; - -export function CoolQueue( - config = { type: 'comm', queue: {}, worker: {} } as { - type?: 'comm' | 'getter' | 'noworker' | 'single'; - queue?: JobsOptions; - worker?: WorkerOptions; - } -): ClassDecorator { - return (target: any) => { - // 将装饰的类,绑定到该装饰器,用于后续能获取到 class - saveModule(COOL_TASK_KEY, target); - // 保存一些元数据信息,任意你希望存的东西 - saveClassMetadata(COOL_TASK_KEY, config, target); - // 指定 IoC 容器创建实例的作用域,这里注册为请求作用域,这样能取到 ctx - Scope(ScopeEnum.Singleton)(target); - }; -} diff --git a/task/src/index.ts b/task/src/index.ts deleted file mode 100644 index 37134d7..0000000 --- a/task/src/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -export { CoolTaskConfiguration as Configuration } from './configuration'; - -export * from './base'; - -export * from './queue'; - -export * from './decorator/queue'; diff --git a/task/src/package.json b/task/src/package.json deleted file mode 100644 index 6a820f9..0000000 --- a/task/src/package.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "name": "@cool-midway/task", - "version": "7.0.0", - "description": "cool-js.com 任务与队列", - "main": "index.js", - "typings": "index.d.ts", - "scripts": { - "build": "cross-env midway-bin build -c", - "cov": "cross-env midway-bin cov --ts", - "lint": "mwts check", - "lint:fix": "mwts fix" - }, - "keywords": [ - "cool", - "cool-admin", - "cooljs" - ], - "author": "COOL", - "readme": "README.md", - "files": [ - "**/*.js", - "**/*.d.ts", - "index.d.ts" - ], - "license": "MIT", - "repository": { - "type": "git", - "url": "https://cool-js.com" - }, - "devDependencies": { - "@cool-midway/core": "^7.0.0", - "@midwayjs/cli": "^2.0.9", - "@midwayjs/core": "^3.9.0", - "@midwayjs/decorator": "^3.9.0", - "@midwayjs/mock": "^3.9.0", - "@midwayjs/redis": "^3.9.0", - "@types/jest": "^29.2.5", - "@types/node": "^18.11.18", - "cross-env": "^7.0.3", - "jest": "^29.3.1", - "lodash": "^4.17.21", - "mwts": "^1.3.0", - "ts-jest": "^29.0.3", - "typescript": "^4.9.4" - }, - "dependencies": { - "bullmq": "^3.5.2", - "ioredis": "^5.2.4" - } -} diff --git a/task/src/queue.ts b/task/src/queue.ts deleted file mode 100644 index 533a824..0000000 --- a/task/src/queue.ts +++ /dev/null @@ -1,142 +0,0 @@ -import { ILogger, IMidwayApplication } from '@midwayjs/core'; -import { - App, - Config, - getClassMetadata, - Init, - listModule, - Logger, - Provide, - Scope, - ScopeEnum, -} from '@midwayjs/decorator'; -import { Job, QueueGetters, Queue, Worker } from 'bullmq'; -import { BaseCoolQueue } from './base'; -import { COOL_TASK_KEY } from './decorator/queue'; -import Redis from 'ioredis'; - -/** - * 任务队列 - */ -@Provide() -@Scope(ScopeEnum.Singleton) -export class CoolQueueHandle { - @Config('cool.redis') - redisConfig; - - @Logger() - coreLogger: ILogger; - - @App() - app: IMidwayApplication; - - redis; - - @Init() - async init() { - if (!this.redisConfig) { - this.coreLogger.error('@cool-midway/task组件 redis未配置'); - } - - await this.scan(); - } - - /** - * 扫描队列 - */ - async scan() { - const modules = listModule(COOL_TASK_KEY); - for (let mod of modules) { - const cls: BaseCoolQueue = await this.app - .getApplicationContext() - .getAsync(mod); - this.createQueue(cls, mod); - } - } - - /** - * 获得锁 - * @param key 键 - * @param expireTime 过期时间 - * @returns - */ - async getLock(key, expireTime) { - const lockSuccessful = await this.redis.setnx(key, 'locked'); - if (lockSuccessful) { - await this.redis.expire(key, expireTime); - return true; - } else { - return false; - } - } - - /** - * 队列名称 - * @param cls - * @param mod - */ - async createQueue(cls: BaseCoolQueue, mod: any) { - this.redis; - if (this.redisConfig instanceof Array) { - this.redis = new Redis.Cluster(this.redisConfig, { - enableReadyCheck: false, - }); - } else { - this.redis = new Redis({ - ...this.redisConfig, - enableReadyCheck: false, - maxRetriesPerRequest: null, - }); - } - const name = mod.name; - const config = getClassMetadata(COOL_TASK_KEY, mod); - const opts = { - connection: this.redis, - prefix: `{queue${name}}`, - defaultJobOptions: { - removeOnComplete: true, - removeOnFail: true, - attempts: 5, - backoff: { - type: 'fixed', - delay: 10000, - }, - ...(config.queue || {}), - }, - }; - const queue = new Queue(name, opts); - cls.metaQueue = queue; - cls.queueName = name; - let lock = false; - // 本地开发的情况下直接获得锁 - if (config.type == 'single') { - if (this.app.getEnv() == 'local') { - lock = true; - } else { - // cluster 需要配合redis 获得锁 - if (await this.getLock('COOL_QUEUE_SINGLE', 15)) { - lock = true; - } - } - } - - if (config.type == 'comm' || (config.type == 'single' && lock)) { - cls.worker = new Worker( - name, - async (job: Job) => { - await cls.data(job, async () => { - await job.isCompleted(); - }); - }, - { - connection: opts.connection, - prefix: opts.prefix, - ...(config.worker || {}), - } - ); - } else { - cls.getters = new QueueGetters(name, opts); - } - this.coreLogger.info(`\x1B[36m [cool:task] create ${name} queue \x1B[0m`); - } -} diff --git a/task/tsconfig.json b/task/tsconfig.json deleted file mode 100644 index f01e1d2..0000000 --- a/task/tsconfig.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "compileOnSave": true, - "compilerOptions": { - "target": "es2018", - "module": "commonjs", - "moduleResolution": "node", - "experimentalDecorators": true, - "emitDecoratorMetadata": true, - "inlineSourceMap":false, - "noImplicitThis": true, - "noUnusedLocals": true, - "stripInternal": true, - "skipLibCheck": true, - "noImplicitReturns": false, - "pretty": true, - "declaration": true, - "outDir": "dist" - }, - "exclude": [ - "dist", - "node_modules", - "test" - ] -} diff --git a/tsconfig.json b/tsconfig.json deleted file mode 100644 index 4ec9192..0000000 --- a/tsconfig.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "compileOnSave": true, - "compilerOptions": { - "target": "es2018", - "module": "commonjs", - "moduleResolution": "node", - "experimentalDecorators": true, - "emitDecoratorMetadata": true, - "inlineSourceMap":true, - "noImplicitThis": true, - "noUnusedLocals": true, - "stripInternal": true, - "skipLibCheck": true, - "pretty": true, - "declaration": true, - "noImplicitAny": false, - "typeRoots": [ "./typings", "./node_modules/@types"], - "outDir": "dist" - }, - "exclude": [ - "dist", - "node_modules", - "test" - ] -}