Compare commits

...

158 Commits

Author SHA1 Message Date
Liujian 17b4ede566 Merge branch 'main-github' into feature/permit
# Conflicts:
#	go.mod
2024-11-04 11:05:30 +08:00
Liujian bbc3fea848 update go.mod 2024-11-04 11:03:40 +08:00
Liujian 82e46b872b Merge remote-tracking branch 'origin/main' into main-github 2024-11-04 11:00:05 +08:00
Liujian 0f6a091c73 fix service info no prefix 2024-11-04 10:59:13 +08:00
Liujian 4e87adb4b3 Merge remote-tracking branch 'origin/main' into main-github 2024-11-04 10:49:05 +08:00
杨梦洁 320a2b6cf8 Merge branch 'feature/v1.2' into 'main'
fix: Modify service inside access

See merge request apipark/APIPark!81
2024-11-04 10:46:21 +08:00
maggieyyy b216556867 fix: Modify service inside access 2024-11-04 10:44:30 +08:00
Liujian 7fbb98a2a9 Merge remote-tracking branch 'github-pro/main' into main-github 2024-11-01 19:03:17 +08:00
Liujian 461a8edbea update .gitignore 2024-11-01 19:01:50 +08:00
刘健 cdef179bed Merge branch 'feature/permit' into 'main'
Feature/permit

See merge request apipark/APIPark!80
2024-11-01 18:53:22 +08:00
Liujian a067388d79 update ai permit 2024-11-01 18:52:50 +08:00
杨梦洁 2d5e541593 Merge branch 'feature/v1.2' into 'main'
fix: Modify link access

See merge request apipark/APIPark!79
2024-11-01 18:42:40 +08:00
Maggie be40186ad3 Merge pull request #129 from APIParkLab/feature/v1.2
fix: Modify link access
2024-11-01 18:42:26 +08:00
maggieyyy c9ae05b22e fix: Modify link access 2024-11-01 18:41:16 +08:00
Liujian 9da5e5d6c0 Merge remote-tracking branch 'github-pro/main' into feature/permit 2024-11-01 18:05:14 +08:00
Liujian a6bfce2a5f Merge remote-tracking branch 'origin/main' into feature/permit 2024-11-01 17:59:30 +08:00
Maggie 8cbeabe917 Merge pull request #128 from APIParkLab/feature/v1.2
Feature/v1.2
2024-11-01 16:45:24 +08:00
杨梦洁 1db354077f Merge branch 'feature/v1.2' into 'main'
fix: Modify consumer list reload and subscriber option

See merge request apipark/APIPark!78
2024-11-01 16:44:48 +08:00
maggieyyy e31d41a276 fix: Modify consumer list reload and subscriber option 2024-11-01 16:42:34 +08:00
Liujian 21d2abf716 Merge remote-tracking branch 'origin/main' into feature/permit 2024-11-01 16:19:35 +08:00
Liujian 3a86a88870 update subscribe permit 2024-11-01 16:19:25 +08:00
杨梦洁 6117a840e1 Merge branch 'feature/v1.2' into 'main'
fix: Add team selector to consumer

See merge request apipark/APIPark!77
2024-11-01 15:49:53 +08:00
maggieyyy 0e20987fb8 fix: Add team selector to consumer 2024-11-01 15:48:51 +08:00
Dot.L 65e7cab772 Update readme-zh-tw.md 2024-11-01 15:26:33 +08:00
Dot.L 935f2ac766 Update readme-zh-cn.md 2024-11-01 15:26:15 +08:00
Dot.L 3e12d7eb9c Update readme-jp.md 2024-11-01 15:25:55 +08:00
Dot.L d6095269b7 Update README.md 2024-11-01 15:25:15 +08:00
Liujian 0c415b4e32 Merge remote-tracking branch 'github-pro/main' into feature/permit 2024-11-01 14:59:54 +08:00
杨梦洁 bc1819b368 Merge branch 'feature/v1.2' into 'main'
Feature/v1.2

See merge request apipark/APIPark!76
2024-11-01 14:51:56 +08:00
Maggie a9be016c87 Merge pull request #127 from APIParkLab/feature/v1.2
Feature/v1.2
2024-11-01 14:49:21 +08:00
maggieyyy 11da5e9d26 fix: consumer menu access bug 2024-11-01 14:48:18 +08:00
maggieyyy 2c6c194821 fix: consumer menu access bug 2024-11-01 14:48:10 +08:00
杨梦洁 aedd8b4cc6 Merge branch 'feature/v1.2' into 'main'
fix: consumer menu access bug

See merge request apipark/APIPark!75
2024-11-01 14:46:49 +08:00
maggieyyy fa2607e9b8 fix: consumer menu access bug 2024-11-01 14:45:32 +08:00
Liujian 3783e5ee5d Merge remote-tracking branch 'github-pro/main' into feature/permit 2024-11-01 14:26:37 +08:00
Maggie fd56b8ffed Merge pull request #126 from APIParkLab/feature/v1.2
Feature/v1.2
2024-11-01 14:24:51 +08:00
杨梦洁 07e288be16 Merge branch 'feature/v1.2' into 'main'
Feature/v1.2

See merge request apipark/APIPark!74
2024-11-01 14:24:14 +08:00
maggieyyy 46143c3fe0 fix: Modify department children type 2024-11-01 14:23:05 +08:00
maggieyyy 83e3cc85f2 fix: Modify department children type 2024-11-01 14:21:04 +08:00
刘健 a4b50ae60a Merge branch 'feature/permit' into 'main'
Feature/permit

See merge request apipark/APIPark!73
2024-11-01 14:19:48 +08:00
Liujian a30d0c37eb update permit bug 2024-11-01 14:19:17 +08:00
maggieyyy 64fdf59905 fix: Add empty to member transfer 2024-11-01 13:54:33 +08:00
Liujian 68e8cb72d3 Merge remote-tracking branch 'origin/main' into feature/permit 2024-11-01 11:03:21 +08:00
Liujian a86d3cd65a update permit 2024-11-01 11:01:45 +08:00
杨梦洁 a4b4cbf60f Merge branch 'feature/v1.2' into 'main'
fix: Modify subscribe options

See merge request apipark/APIPark!72
2024-10-31 14:16:30 +08:00
maggieyyy 2dcb7ebd74 fix: Modify subscribe options 2024-10-31 14:14:44 +08:00
杨梦洁 8fa1985feb Merge branch 'feature/v1.2' into 'main'
fix: delete log

See merge request apipark/APIPark!71
2024-10-31 09:25:28 +08:00
Maggie 451efb8d3e Merge pull request #124 from APIParkLab/feature/v1.2
fix: delete log
2024-10-31 09:25:15 +08:00
maggieyyy d6bf3139ff fix: delete log 2024-10-31 09:14:24 +08:00
Maggie 309b9ea937 Merge pull request #123 from APIParkLab/feature/v1.2
fix: Modify access
2024-10-30 18:40:10 +08:00
杨梦洁 554bff38c6 Merge branch 'feature/v1.2' into 'main'
fix: Modify access

See merge request apipark/APIPark!70
2024-10-30 18:39:59 +08:00
maggieyyy d5e6062ec9 fix: Modify access 2024-10-30 18:38:39 +08:00
Maggie d588d43aa1 Merge pull request #122 from APIParkLab/feature/v1.2
fix: Modify local path
2024-10-30 10:59:54 +08:00
Liujian f455cecb54 update ap-account version 2024-10-30 10:45:58 +08:00
杨梦洁 b88c0a9305 Merge branch 'feature/v1.2' into 'main'
fix: Modify local path

See merge request apipark/APIPark!69
2024-10-30 09:08:35 +08:00
maggieyyy 9030cff8ba fix: Modify local path 2024-10-29 18:32:45 +08:00
杨梦洁 98f73f799a Merge branch 'feature/v1.2' into 'main'
Feature/v1.2

See merge request apipark/APIPark!68
2024-10-29 17:46:36 +08:00
JackLiu d2e428ada8 Merge pull request #121 from rolealiu/main
Update v1.2 translation
2024-10-29 17:29:21 +08:00
JackLiu 74156ec84c Merge branch 'APIParkLab:main' into main 2024-10-29 17:28:51 +08:00
HaoZhen Liu f9e6bc92d7 update v1.2 translation 2024-10-29 17:28:41 +08:00
Maggie 9884586cc9 Merge pull request #120 from APIParkLab/feature/v1.2
Feature/v1.2
2024-10-29 17:05:29 +08:00
杨梦洁 ac717a6efb Merge branch 'feature/v1.2' into 'main'
fix: Add psw to account

See merge request apipark/APIPark!67
2024-10-29 16:47:44 +08:00
maggieyyy 2b7c1ded15 fix: Add psw to account 2024-10-29 16:44:31 +08:00
杨梦洁 daac27712d Merge branch 'feature/v1.2' into 'main'
fix: Modify member transfer icon and department

See merge request apipark/APIPark!66
2024-10-29 15:13:44 +08:00
maggieyyy 1080f33282 fix: Modify member transfer icon and department 2024-10-29 15:12:43 +08:00
Dot.L cc5c0a0a89 Merge pull request #119 from APIParkLab/feature/permission
update i18n
2024-10-29 14:20:19 +08:00
Liujian 85971447e1 update i18n 2024-10-29 14:19:36 +08:00
杨梦洁 256e8ef275 Merge branch 'feature/v1.2' into 'main'
fix: update translation

See merge request apipark/APIPark!65
2024-10-29 13:54:49 +08:00
Maggie c07e54ec03 Merge pull request #118 from APIParkLab/feature/v1.2
fix: update translation
2024-10-29 13:54:42 +08:00
maggieyyy 70f834e1cf fix: update translation 2024-10-29 13:52:48 +08:00
Maggie c320c6f2a2 Merge pull request #117 from APIParkLab/feature/v1.2
Feature/v1.2
2024-10-29 13:39:34 +08:00
杨梦洁 256eb60df8 Merge branch 'feature/v1.2' into 'main'
Feature/v1.2

See merge request apipark/APIPark!64
2024-10-29 13:39:06 +08:00
maggieyyy 5f03973bf2 fix: Modify guide link 2024-10-29 13:37:38 +08:00
maggieyyy ab2a0d8ae2 fix: Modify member transfer 2024-10-29 11:58:09 +08:00
Maggie 7e48402591 Merge pull request #116 from APIParkLab/feature/v1.2
fix: account translation
2024-10-29 09:21:36 +08:00
杨梦洁 aa85f6fcd1 Merge branch 'feature/v1.2' into 'main'
fix: account translation

See merge request apipark/APIPark!62
2024-10-29 09:21:19 +08:00
maggieyyy cd441ccfe7 fix: account translation 2024-10-29 09:19:35 +08:00
Dot.L 47f6519006 Merge pull request #114 from APIParkLab/feature/permission
update remark
2024-10-28 18:41:17 +08:00
Maggie 9679376cb2 Merge pull request #113 from APIParkLab/feature/v1.2
fix: table fields
2024-10-28 18:40:48 +08:00
杨梦洁 efa97c3bbc Merge branch 'feature/v1.2' into 'main'
fix: table fields

See merge request apipark/APIPark!61
2024-10-28 18:40:09 +08:00
Liujian 087e598be0 update remark 2024-10-28 18:39:55 +08:00
Dot.L 31aa8243ee Merge pull request #112 from APIParkLab/feature/permission
Feature/permission
2024-10-28 18:34:19 +08:00
Liujian d3d05ef539 Merge remote-tracking branch 'github-pro/main' into feature/permission
# Conflicts:
#	resources/access/access.yaml
2024-10-28 18:33:42 +08:00
maggieyyy d6062ea4e7 fix: table fields 2024-10-28 18:32:20 +08:00
Liujian 7949748951 update permission 2024-10-28 18:27:37 +08:00
Liujian 94f7392060 update access 2024-10-28 16:48:18 +08:00
Maggie 0d737bad57 Merge pull request #111 from APIParkLab/feature/v1.2
Feature/v1.2
2024-10-28 16:22:58 +08:00
杨梦洁 1225db50c9 Merge branch 'feature/v1.2' into 'main'
fix: Modify access fields

See merge request apipark/APIPark!59
2024-10-28 16:17:09 +08:00
maggieyyy e5d85bb3df fix: Modify access fields 2024-10-28 16:15:38 +08:00
杨梦洁 0f09e5c236 Merge branch 'feature/v1.2' into 'main'
fix: cosumer list bug

See merge request apipark/APIPark!58
2024-10-28 16:01:48 +08:00
maggieyyy 0f0204b647 fix: cosumer list bug 2024-10-28 16:00:15 +08:00
杨梦洁 94421d2622 Merge branch 'feature/v1.2' into 'main'
fix: Consumer list bugs

See merge request apipark/APIPark!57
2024-10-28 15:45:11 +08:00
maggieyyy 44f0b70461 fix: Consumer list bugs 2024-10-28 15:44:10 +08:00
刘健 f58768237b Merge branch 'feature/translate' into 'main'
Feature/translate

See merge request apipark/APIPark!56
2024-10-28 15:15:00 +08:00
Dot.L 588cf839e3 Merge pull request #110 from APIParkLab/feature/translate
Feature/translate
2024-10-28 15:07:35 +08:00
Liujian 76872b3a97 Merge remote-tracking branch 'github-pro/main' into feature/translate
# Conflicts:
#	.github/ISSUE_TEMPLATE/bug_report.yml
#	.github/ISSUE_TEMPLATE/request_help.yml
2024-10-28 15:06:24 +08:00
Dot.L d253d68a12 Merge pull request #96 from sunanzhi/main
fix:issue template content
2024-10-28 15:03:56 +08:00
Liujian 4de0d29f30 update access 2024-10-28 15:03:04 +08:00
Maggie 0f0480db63 Merge pull request #108 from APIParkLab/feature/v1.2
Feature/v1.2
2024-10-28 15:02:37 +08:00
杨梦洁 aa40b62e0a Merge branch 'feature/v1.2' into 'main'
Feature/v1.2

See merge request apipark/APIPark!55
2024-10-28 15:02:10 +08:00
maggieyyy 68309ac582 fix: Modify access 2024-10-28 15:00:59 +08:00
maggieyyy 522183eb4d fix: update message 2024-10-28 13:39:47 +08:00
maggieyyy 4f6fee4d73 fix: Delete operation from team & Delete comments from publish 2024-10-28 11:52:51 +08:00
Liujian c5fecf73c8 update action 2024-10-28 10:53:28 +08:00
Liujian ee8e93d1e8 update action 2024-10-28 10:46:17 +08:00
Liujian 9d0fa5ea4a Merge remote-tracking branch 'origin/main' into feature/translate 2024-10-28 10:43:23 +08:00
Dot.L b0b9affbe7 Merge pull request #1 from Dot-Liu/feature/translate
Feature/translate
2024-10-28 10:01:46 +08:00
Liujian 1d1c7c78e8 update go.mod 2024-10-28 10:00:34 +08:00
杨梦洁 d7f5b87e70 Merge branch 'feature/v1.2' into 'main'
fix: Modify publish and title & add debug

See merge request apipark/APIPark!54
2024-10-28 09:59:00 +08:00
maggieyyy 1048666972 fix: Modify publish and title & add debug 2024-10-28 09:58:04 +08:00
Liujian 217f5d61c7 Merge remote-tracking branch 'origin/main' into feature/translate 2024-10-27 00:48:03 +08:00
Liujian 2f1677f581 role update 2024-10-27 00:47:48 +08:00
刘健 afd7ea6a1c Merge branch 'feature/translate' into 'main'
create ai service add provider

See merge request apipark/APIPark!53
2024-10-26 21:25:40 +08:00
Liujian 7155e14e64 create ai service add provider 2024-10-26 21:25:13 +08:00
刘健 68e5b49f46 Merge branch 'feature/translate' into 'main'
update translate

See merge request apipark/APIPark!52
2024-10-25 18:47:48 +08:00
Liujian c01e95c716 update translate 2024-10-25 18:45:38 +08:00
杨梦洁 ffa7e5130e Merge branch 'feature/v1.2' into 'main'
fix: update translation

See merge request apipark/APIPark!51
2024-10-25 16:35:30 +08:00
Maggie 7ce33bfd4c Merge pull request #101 from APIParkLab/feature/v1.2
fix: update translation
2024-10-25 16:35:27 +08:00
maggieyyy 0c64fa9986 fix: update translation 2024-10-25 16:34:06 +08:00
Maggie 07e8b347e1 Merge pull request #100 from APIParkLab/feature/v1.2
fix: update translation
2024-10-25 16:20:02 +08:00
杨梦洁 38a402adef Merge branch 'feature/v1.2' into 'main'
Feature/v1.2

See merge request apipark/APIPark!50
2024-10-25 16:18:59 +08:00
maggieyyy 7ab2e29101 fix: update translation 2024-10-25 16:16:15 +08:00
Maggie b96796793b Merge pull request #99 from APIParkLab/docs-update-frontend-README
docs: Update README.md
2024-10-25 15:48:21 +08:00
Scarqin baa073b05d Update README.md 2024-10-25 15:44:42 +08:00
Maggie c944f9de52 Merge pull request #95 from APIParkLab/feature/v1.2
fix: Remove guest's account setting & update translation
2024-10-25 15:24:37 +08:00
杨梦洁 5567a65e4b Merge branch 'feature/v1.2' into 'main'
Feature/v1.2

See merge request apipark/APIPark!49
2024-10-25 15:23:51 +08:00
maggieyyy c6c775f436 fix: Remove guest's account setting & update translation 2024-10-25 15:22:06 +08:00
sunanzhi c0c43be6b9 fix:issue template content 2024-10-25 15:16:47 +08:00
刘健 9b6074318a Merge branch 'feature/issue-templete' into 'main'
update ao-account dependent version

See merge request apipark/APIPark!48
2024-10-25 14:32:33 +08:00
Liujian ada121015d update ao-account dependent version 2024-10-25 14:32:11 +08:00
JackLiu 9d7b6c4bc6 Merge pull request #86 from rolealiu/main
update translation
2024-10-25 14:31:56 +08:00
JackLiu c262fc4f4d Merge branch 'APIParkLab:main' into main 2024-10-25 14:31:26 +08:00
刘健 335317bd86 Merge branch 'feature/issue-templete' into 'main'
update ao-account dependent version

See merge request apipark/APIPark!47
2024-10-25 14:31:21 +08:00
Liujian 396464c573 update ao-account dependent version 2024-10-25 14:30:58 +08:00
HaoZhen Liu d93c76ca36 update translation 2024-10-25 14:30:57 +08:00
刘健 60ad6007e5 Merge branch 'feature/issue-templete' into 'main'
Feature/issue templete

See merge request apipark/APIPark!46
2024-10-25 14:22:21 +08:00
Liujian ceee520102 tmp commit 2024-10-25 14:21:50 +08:00
Maggie a053557000 Merge pull request #83 from APIParkLab/feature/v1.2
fix: AI Model config bug
2024-10-25 14:07:39 +08:00
杨梦洁 e7c14b0817 Merge branch 'feature/v1.2' into 'main'
fix: AI Model config bug

See merge request apipark/APIPark!45
2024-10-25 14:04:00 +08:00
maggieyyy 727fd0bd36 fix: AI Model config bug 2024-10-25 14:02:23 +08:00
Liujian 885cec57db update issue templete 2024-10-25 09:32:12 +08:00
Maggie 4ba2b0c9ab Merge pull request #70 from APIParkLab/feature/v1.2
fix: update translation
2024-10-25 09:28:32 +08:00
杨梦洁 b3672b8c66 Merge branch 'feature/v1.2' into 'main'
Feature/v1.2

See merge request apipark/APIPark!44
2024-10-25 09:28:13 +08:00
maggieyyy b33dda4a32 fix: update translation 2024-10-25 09:27:00 +08:00
刘健 450e565718 Merge branch 'feature/ai-service' into 'main'
Feature/ai service

See merge request apipark/APIPark!43
2024-10-24 23:43:36 +08:00
Liujian 00bd72c1e4 fix get llm error 2024-10-24 23:42:55 +08:00
Dot.L 81da1f45f1 Merge pull request #68 from APIParkLab/feature/ai-service
Feature/ai service
2024-10-24 23:31:32 +08:00
杨梦洁 24c24c1307 Merge branch 'feature/v1.2' into 'main'
Feature/v1.2

See merge request apipark/APIPark!42
2024-10-24 18:28:36 +08:00
JackLiu 2bcee5e362 Merge pull request #67 from rolealiu/main
update translation
2024-10-24 18:25:40 +08:00
HaoZhen Liu 74d402a330 update translation 2024-10-24 18:24:51 +08:00
李冬杰 08bd8a9942 Merge branch 'feature/zhinao' into 'main'
Feature/zhinao

See merge request apipark/APIPark!41
2024-10-24 15:50:09 +08:00
lidongjie 6944260767 add:ai provider 360-zhinao 2024-10-24 15:47:43 +08:00
杨梦洁 3ada2d1d9d Merge branch 'feature/v1.2' into 'main'
fix: Update translation

See merge request apipark/APIPark!40
2024-10-24 14:43:41 +08:00
Maggie 4a48255be1 Merge pull request #66 from APIParkLab/feature/v1.2
Feature/v1.2
2024-10-24 14:41:41 +08:00
maggieyyy 25f8712a9f fix: Update translation 2024-10-24 14:39:49 +08:00
杨梦洁 f83b8c74ca Merge branch 'feature/v1.2' into 'main'
Feature/v1.2

See merge request apipark/APIPark!39
2024-10-24 13:52:16 +08:00
maggieyyy 7a4f3dc4c5 fix: Modify translation 2024-10-24 13:51:22 +08:00
maggieyyy 26b52b1ab0 fix: Modify Ai setting 2024-10-24 11:40:14 +08:00
142 changed files with 1918 additions and 1654 deletions
+5 -6
View File
@@ -45,19 +45,18 @@ body:
label: Steps to Reproduce
description: Share the steps you took so that we can reproduce the issue. Reports without proper steps details will likely be closed.
placeholder: |
1. Run apinto via the Docker image.
2. Create a Route with the Admin API.
3. Try configuring ...
4. ...
1. Run APIPark via the Docker image.
2. Try configuring ...
3. ...
validations:
required: true
required: false
- type: textarea
id: environment
attributes:
label: Environment
description: Share your environment details. Reports without proper environment details will likely be closed.
value: |
- APINTO Dashboard version (run `apinto dashboard version`):
- APINTO Dashboard version:
- Operating system (run `uname -a`):
validations:
required: true
+1 -1
View File
@@ -25,7 +25,7 @@ body:
label: Environment
description: Share your environment details. Reports without proper environment details will likely be closed.
value: |
- APIPark version (run `apinto dashboard version`):
- APIPark version:
- Operating system (run `uname -a`):
validations:
required: true
+3 -3
View File
@@ -25,7 +25,7 @@ jobs:
echo "Build frontend..."
cd ./frontend && pnpm run build
- name: upload frontend release
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: frontend-package
path: frontend/dist
@@ -41,7 +41,7 @@ jobs:
- name: Checkout #Checkout代码
uses: actions/checkout@v3
- name: download frontend release
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: frontend-package
path: frontend/dist
@@ -71,7 +71,7 @@ jobs:
- uses: actions/checkout@v3
- name: download frontend release
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: frontend-package
path: frontend/dist
+1 -1
View File
@@ -3,4 +3,4 @@
/config.yml
/build/
/apipark
/aoplatform
.gitlab-ci.yml
-98
View File
@@ -1,98 +0,0 @@
variables:
PATH: /opt/go-1.21/go/bin/:/opt/node/node/bin/:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
GOROOT: /opt/go-1.21/go
GOPROXY: https://goproxy.cn
VERSION: $CI_COMMIT_SHORT_SHA
APP: apipark
APP_PRE: ${APP}_${VERSION}
BUILD_DIR: ${APP}-build
DEPLOY_DESC: "DEV 环境"
VIEW_ADDR: http://172.18.166.219:8288
SAVE_DIR: /opt/${APP}
NODE_OPTIONS: --max_old_space_size=8192
stages:
- notice
- prefix
- build
- deploy
- webhook
feishu-informer: # 飞书回调
stage: notice
variables:
DIFF_URL: "$CI_MERGE_REQUEST_PROJECT_URL/-/merge_requests/$CI_MERGE_REQUEST_IID/diffs"
rules:
- if: $CI_PIPELINE_SOURCE=="merge_request_event" && $CI_COMMIT_BRANCH =~ "main"
script:
- echo "merge request"
- |
curl -X POST -H "Content-Type: application/json" \
-d "{\"msg_type\":\"text\",\"content\":{\"text\":\"项目:${CI_PROJECT_NAME}\\n提交人:${GITLAB_USER_NAME}\\n提交信息:${CI_MERGE_REQUEST_TITLE}\\n合并分支信息:${CI_MERGE_REQUEST_SOURCE_BRANCH_NAME} -> ${CI_MERGE_REQUEST_TARGET_BRANCH_NAME}\\n差异性地址:${DIFF_URL}\\n请及时review代码\"}}" \
https://open.feishu.cn/open-apis/bot/v2/hook/1c334752-2874-41a1-8f1b-3060f2d46b6c
prebuild:
stage: prefix
rules:
- if: $CI_COMMIT_BRANCH == "main"
script:
- echo "prebuild"
- chmod +x ./scripts/prefix.sh
- ./scripts/prefix.sh
builder:
stage: build
rules:
- if: $CI_COMMIT_BRANCH == "main"
script:
- set -e
- |
if [ ! -d "../artifacts" ]; then
mkdir -p ../artifacts
fi
if [ -d "../artifacts/dist" ]; then
cp -r ../artifacts/dist frontend/dist
fi
- |
if [ -n "$(git diff --name-status HEAD~1 HEAD -- frontend)" ]; then
./scripts/build.sh $BUILD_DIR ${VERSION} all ""
else
./scripts/build.sh $BUILD_DIR ${VERSION}
fi
if [ -d "frontend/dist" ]; then
echo "copy frontend/dist to artifacts/dist"
rm -fr ../artifacts/dist
cp -r frontend/dist ../artifacts/dist
fi
cp $BUILD_DIR/${APP_PRE}_linux_amd64.tar.gz ${SAVE_DIR}
deployer:
stage: deploy
rules:
- if: $CI_COMMIT_BRANCH == "main"
variables:
APIPARK_GUEST_MODE: allow
APIPARK_GUEST_ID: dklejrfbhjqwdh
script:
- cd ${SAVE_DIR};mkdir -p ${APP_PRE};tar -zxvf ${APP_PRE}_linux_amd64.tar.gz -C ${APP_PRE};cd ${APP_PRE};./install.sh ${SAVE_DIR};./run.sh restart;cd ${SAVE_DIR} && ./clean.sh ${APP_PRE}
when: on_success
success:
stage: webhook
rules:
- if: $CI_COMMIT_BRANCH == "main"
script:
- |
curl -X POST -H "Content-Type: application/json" \
-d "{\"msg_type\":\"text\",\"content\":{\"text\":\"最近一次提交:${CI_COMMIT_TITLE}\\n提交人:${GITLAB_USER_NAME}\\n项目:${CI_PROJECT_NAME}\\n环境:${DEPLOY_DESC}\\n更新部署完成.\\n访问地址:${VIEW_ADDR}\\n工作流地址:${CI_PIPELINE_URL}\"}}" \
https://open.feishu.cn/open-apis/bot/v2/hook/c3672932-4dfa-4989-8023-0128bae59338
when: on_success
failure:
stage: webhook
rules:
- if: $CI_COMMIT_BRANCH == "main"
script:
- |
curl -X POST -H "Content-Type: application/json" \
-d "{\"msg_type\":\"text\",\"content\":{\"text\":\"最近一次提交:${CI_COMMIT_TITLE}\\n提交人:${GITLAB_USER_NAME}\\n项目:${CI_PROJECT_NAME}\\n环境:${DEPLOY_DESC}\\n更新部署失败,请及时到gitlab上查看\\n工作流地址:${CI_PIPELINE_URL}\"}}" \
https://open.feishu.cn/open-apis/bot/v2/hook/c3672932-4dfa-4989-8023-0128bae59338
when: on_failure
+1 -1
View File
@@ -197,7 +197,7 @@ To achieve this goal, we plan to add new features to APIPark, including:
<br>
# 📕 Documentation
Visit [APIPark Documentation](https://docs.apipark.com/docs/install) for detailed installation guides, API references, and usage instructions.
Visit [APIPark Documentation](https://docs.apipark.com/docs/deploy) for detailed installation guides, API references, and usage instructions.
<br>
@@ -69,15 +69,6 @@ provider_credential_schema:
placeholder:
zh_Hans: 在此输入您的 API Key
en_US: Enter your API Key
- variable: openai_organization
label:
zh_Hans: 组织 ID
en_US: Organization
type: text-input
required: false
placeholder:
zh_Hans: 在此输入您的组织 ID
en_US: Enter your Organization ID
- variable: openai_api_base
label:
zh_Hans: API Base
@@ -30,4 +30,4 @@ provider_credential_schema:
placeholder:
zh_Hans: 在此输入您的 API Key
en_US: Enter your API Key
address: https://api.openai.com
address: https://api.360.cn
+2 -2
View File
@@ -4,7 +4,7 @@ import (
"bytes"
"fmt"
"github.com/urfave/cli/v2"
"github.com/urfave/cli"
)
// These should be set via go build -ldflags -X 'xxxx'.
@@ -20,7 +20,7 @@ var profileInfo []byte
func init() {
buffer := &bytes.Buffer{}
fmt.Fprintf(buffer, "Apinto version: %s\n", Version)
fmt.Fprintf(buffer, "APIPark version: %s\n", Version)
fmt.Fprintf(buffer, "Golang version: %s\n", goVersion)
fmt.Fprintf(buffer, "Git commit hash: %s\n", gitCommit)
fmt.Fprintf(buffer, "Built on: %s\n", BuildTime)
+16 -6
View File
@@ -5,6 +5,9 @@ import (
"fmt"
"net/http"
"strings"
"time"
"github.com/eolinker/eosc/log"
application_authorization "github.com/APIParkLab/APIPark/module/application-authorization"
application_authorization_dto "github.com/APIParkLab/APIPark/module/application-authorization/dto"
@@ -151,8 +154,9 @@ func (i *imlServiceController) createAIService(ctx *gin.Context, teamID string,
Prompt: "You need to translate {{source_lang}} into {{target_lang}}, and the following is the content that needs to be translated.\n---\n{{text}}",
}
aiModel := &ai_api_dto.AiModel{
Id: m.ID(),
Config: m.DefaultConfig(),
Id: m.ID(),
Config: m.DefaultConfig(),
Provider: *input.Provider,
}
name := "Demo Translation API"
description := "A demo that shows you how to use a prompt to create a Translation API."
@@ -211,10 +215,7 @@ func (i *imlServiceController) createAIService(ctx *gin.Context, teamID string,
if err != nil {
return err
}
//_, err = i.upstreamModule.Save(ctx, info.Id, newAIUpstream(info.Id, *input.Provider, p.URI()))
//if err != nil {
// return err
//}
return i.docModule.SaveServiceDoc(ctx, info.Id, &service_dto.SaveServiceDoc{
Doc: "The Translation API allows developers to translate text from one language to another. It supports multiple languages and enables easy integration of high-quality translation features into applications. With simple API requests, you can quickly translate content into different target languages.",
})
@@ -236,7 +237,12 @@ func (i *imlServiceController) SearchMyServices(ctx *gin.Context, teamId string,
//}
func (i *imlServiceController) Get(ctx *gin.Context, id string) (*service_dto.Service, error) {
now := time.Now()
defer func() {
log.Infof("get service %s cost %d ms", id, time.Since(now).Milliseconds())
}()
return i.module.Get(ctx, id)
}
func (i *imlServiceController) Search(ctx *gin.Context, teamID string, keyword string) ([]*service_dto.ServiceItem, error) {
@@ -278,6 +284,10 @@ type imlAppController struct {
authModule application_authorization.IAuthorizationModule `autowired:""`
}
func (i *imlAppController) SearchCanSubscribe(ctx *gin.Context, serviceId string) ([]*service_dto.SimpleAppItem, error) {
return i.module.SearchCanSubscribe(ctx, serviceId)
}
func (i *imlAppController) Search(ctx *gin.Context, teamId string, keyword string) ([]*service_dto.AppItem, error) {
return i.module.Search(ctx, teamId, keyword)
}
+1
View File
@@ -42,6 +42,7 @@ type IAppController interface {
// SimpleApps 获取简易项目列表
SimpleApps(ctx *gin.Context, keyword string) ([]*service_dto.SimpleAppItem, error)
MySimpleApps(ctx *gin.Context, keyword string) ([]*service_dto.SimpleAppItem, error)
SearchCanSubscribe(ctx *gin.Context, keyword string) ([]*service_dto.SimpleAppItem, error)
GetApp(ctx *gin.Context, appId string) (*service_dto.App, error)
DeleteApp(ctx *gin.Context, appId string) error
}
+3 -2
View File
@@ -381,8 +381,9 @@ func (i *imlInitController) createAIService(ctx context.Context, teamID string,
Prompt: "You need to translate {{source_lang}} into {{target_lang}}, and the following is the content that needs to be translated.\n---\n{{text}}",
}
aiModel := &ai_api_dto.AiModel{
Id: m.ID(),
Config: m.DefaultConfig(),
Id: m.ID(),
Config: m.DefaultConfig(),
Provider: providerId,
}
name := "Demo Translation API"
description := "A demo that shows you how to use a prompt to create a Translation API."
+1
View File
@@ -27,4 +27,5 @@ packages/core/public/tinymce/
*.sln
*.sw?
/pnpm-lock.yaml
+12 -5
View File
@@ -1,10 +1,17 @@
# 部署
## 安装依赖
建议使用pnpm
`npm install -g pnpm`
使用pnpm安装依赖
`pnpm install`
建议使用 pnpm
```
npm install -g pnpm
```
使用pnpm安装依赖
```
pnpm install
```
## 编译
`pnpm run build`
```
pnpm run build
```
+1 -8
View File
@@ -1,10 +1,3 @@
/*
* @Date: 2024-05-10 14:19:56
* @LastEditors: maggieyyy
* @LastEditTime: 2024-05-10 15:55:29
* @FilePath: \frontend\jest.config.js
*/
module.exports = {
roots: ['<rootDir>/packages'],
testMatch: ['**/__tests__/**/*.+(ts|tsx|js)', '**/?(*.)+(spec|test).+(ts|tsx|js)'],
@@ -15,4 +8,4 @@ module.exports = {
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json'],
testPathIgnorePatterns: ['/node_modules/', '/dist/'],
setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
};
};
+1 -7
View File
@@ -1,7 +1 @@
/*
* @Date: 2024-05-10 14:22:41
* @LastEditors: maggieyyy
* @LastEditTime: 2024-05-10 15:49:31
* @FilePath: \frontend\jest.setup.js
*/
// import '@testing-library/jest-dom/extend-expect';
// import '@testing-library/jest-dom/extend-expect';
+1
View File
@@ -3,4 +3,5 @@
"packages/*"
],
"version": "independent"
}
@@ -6,7 +6,6 @@ yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
dist
dist-ssr
+1 -1
View File
@@ -4,7 +4,7 @@
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/frontend/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>APIPark - 企业API数据开放平台</title>
<title>2APIPark</title>
</head>
<body>
<div id="root"></div>
+1 -1
View File
@@ -4,7 +4,7 @@
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": " vite --port 5000 --strictPort",
"dev": " vite --port 5000 --strictPort",
"build": "vite build ",
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
"preview": "vite preview --port 5000 --strictPort",
@@ -1,9 +1,3 @@
/*
* @Date: 2023-11-27 17:31:54
* @LastEditors: maggieyyy
* @LastEditTime: 2024-06-05 10:42:18
* @FilePath: \frontend\packages\core\postcss.config.js
*/
export default {
plugins: {
'postcss-import': {},
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,9 +1,4 @@
/*
* @Date: 2024-06-05 09:35:25
* @LastEditors: maggieyyy
* @LastEditTime: 2024-06-05 10:50:12
* @FilePath: \frontend\packages\core\start-vite.js
*/
// start-vite.js// start-vite.js
import { exec } from 'child_process';
+1 -6
View File
@@ -1,9 +1,4 @@
/*
* @Date: 2023-11-27 17:31:54
* @LastEditors: maggieyyy
* @LastEditTime: 2023-11-29 15:49:05
* @FilePath: \applatform\frontend\packages\core\postcss.config.js
*/
export default {
plugins: {
'postcss-import': {},
@@ -1,19 +1,15 @@
import {
ConfigProvider,
Dropdown,
MenuProps,
App,
Button} from 'antd';
Button,
ConfigProvider,
Dropdown} from 'antd';
import { Outlet, useLocation, useNavigate} from "react-router-dom";
import Logo from '@common/assets/layout-logo.png';
import AvatarPic from '@common/assets/default-avatar.png'
import {Outlet, useLocation, useNavigate} from "react-router-dom";
import { useEffect, useMemo, useState} from "react";
import { useEffect, useMemo, useState} from "react";
import { useGlobalContext } from '@common/contexts/GlobalStateContext.tsx';
import { PERMISSION_DEFINITION } from '@common/const/permissions.ts';
import {
ProConfigProvider,
ProLayout,
} from '@ant-design/pro-components';
import { BasicResponse, RESPONSE_TIPS, routerKeyMap, STATUS_CODE } from '@common/const/const.tsx';
import { UserInfoType } from '@common/const/type.ts';
import { useFetch } from '@common/hooks/http.ts';
@@ -21,6 +17,7 @@ import { ProjectFilled } from '@ant-design/icons';
import { getNavItem } from '@common/utils/navigation';
import { Icon } from '@iconify/react';
import { $t } from '@common/locales';
import { ProConfigProvider, ProLayout } from '@ant-design/pro-components';
import LanguageSetting from './LanguageSetting';
const APP_MODE = import.meta.env.VITE_APP_MODE;
@@ -41,9 +38,8 @@ const themeToken = {
const navigator = useNavigate()
const location = useLocation()
const currentUrl = location.pathname
const { state,accessData,checkPermission,accessInit} = useGlobalContext()
const [pathname, setPathname] = useState(currentUrl);
const mainPage = project === 'core' ?'/service/list':'/serviceHub/list'
const { state,accessData,checkPermission,accessInit,dispatch,resetAccess,getGlobalAccessData} = useGlobalContext()
const [pathname, setPathname] = useState(currentUrl); const mainPage = project === 'core' ?'/service/list':'/serviceHub/list'
const TOTAL_MENU_ITEMS:MenuProps['items'] = useMemo(() => [
getNavItem($t('工作空间'), 'workspace','/guide/page',<Icon icon="ic:baseline-space-dashboard" width="18" height="18"/>, [
@@ -52,27 +48,27 @@ const themeToken = {
getNavItem(<a>{$t('消费者')}</a>, 'consumer','/consumer',<Icon icon="ic:baseline-apps" width="18" height="18"/>,undefined,undefined,'all'),
getNavItem(<a>{$t('团队')}</a>, 'team','/team',<Icon icon="ic:baseline-people-alt" width="18" height="18"/>,undefined,undefined,'all'),
]),
getNavItem($t('API 市场'), 'serviceHub','/serviceHub',<Icon icon="ic:baseline-hub" width="18" height="18"/>,undefined,undefined,'system.workspace.api_market.view'),
getNavItem($t('API 市场'), 'serviceHub','/serviceHub',<Icon icon="ic:baseline-hub" width="18" height="18"/>,undefined,undefined,'system.api_portal.api_portal.view'),
getNavItem($t('仪表盘'), 'mainPage', APP_MODE === 'pro' ? '/analytics' : '/analytics/total',<Icon icon="ic:baseline-bar-chart" width="18" height="18"/>,[
getNavItem(<a >{$t('运行视图')}</a>, 'analytics',APP_MODE === 'pro' ? '/analytics' : '/analytics/total' ,<ProjectFilled />,undefined,undefined,'system.dashboard.run_view.view'),
getNavItem(<a >{$t('运行视图')}</a>, 'analytics',APP_MODE === 'pro' ? '/analytics' : '/analytics/total' ,<ProjectFilled />,undefined,undefined,'system.analysis.run_view.view'),
APP_MODE === 'pro' ? getNavItem(<a >{$t('系统拓扑图')}</a>, 'systemrunning','/systemrunning',<ProjectFilled />,undefined,undefined,'system.dashboard.systemrunning.view') : null,
],undefined,'system.dashboard.run_view.view'),
],undefined,'system.analysis.run_view.view'),
getNavItem($t('系统设置'), 'operationCenter','/commonsetting',<Icon icon="ic:baseline-settings" width="18" height="18"/>, [
getNavItem($t('系统'), 'serviceHubSetting','/commonsetting',null,[
getNavItem(<a>{$t('常规')}</a>, 'commonsetting','/commonsetting',<Icon icon="ic:baseline-hub" width="18" height="18"/>,undefined,undefined,'system.api_market.service_classification.view'),
getNavItem(<a>{$t('API 网关')}</a>, 'cluster','/cluster',<Icon icon="ic:baseline-device-hub" width="18" height="18"/>,undefined,undefined,'system.devops.cluster.view'),
getNavItem(<a>{$t('AI 模型')}</a>, 'aisetting','/aisetting',<Icon icon="hugeicons:ai-network" width="18" height="18"/>,undefined,undefined,'system.devops.cluster.view'),
getNavItem(<a>{$t('API 网关')}</a>, 'cluster','/cluster',<Icon icon="ic:baseline-device-hub" width="18" height="18"/>,undefined,undefined,'system.settings.api_gateway.view'),
getNavItem(<a>{$t('AI 模型')}</a>, 'aisetting','/aisetting',<Icon icon="hugeicons:ai-network" width="18" height="18"/>,undefined,undefined,'system.settings.api_gateway.view'),
],undefined,'system.api_market.service_classification.view'),
getNavItem($t('用户'), 'organization','/member',null,[
getNavItem(<a>{$t('账号')}</a>, 'member','/member',<Icon icon="ic:baseline-people-alt" width="18" height="18"/>,undefined,undefined,'system.organization.member.view'),
getNavItem(<a>{$t('账号')}</a>, 'member','/member',<Icon icon="ic:baseline-people-alt" width="18" height="18"/>,undefined,undefined,'system.settings.account.view'),
getNavItem(<a>{$t('角色')}</a>, 'role','/role',<Icon icon="ic:baseline-verified-user" width="18" height="18"/>,undefined,undefined,'system.organization.role.view'),
],undefined,''),
getNavItem($t('集成'), 'maintenanceCenter','/datasourcing', null, [
getNavItem(<a>{$t('数据源')}</a>, 'datasourcing','/datasourcing',<Icon icon="ic:baseline-monitor-heart" width="18" height="18"/>,undefined,undefined,'system.devops.data_source.view'),
getNavItem(<a>{$t('证书')}</a>, 'cert','/cert',<Icon icon="ic:baseline-security" width="18" height="18"/>,undefined,undefined,'system.devops.ssl_certificate.view'),
getNavItem(<a>{$t('日志')}</a>, 'logsettings','/logsettings',<Icon icon="ic:baseline-sticky-note-2" width="18" height="18"/>,undefined,undefined,'system.devops.log_configuration.view'),
getNavItem(<a>{$t('数据源')}</a>, 'datasourcing','/datasourcing',<Icon icon="ic:baseline-monitor-heart" width="18" height="18"/>,undefined,undefined,'system.settings.data_source.view'),
getNavItem(<a>{$t('证书')}</a>, 'cert','/cert',<Icon icon="ic:baseline-security" width="18" height="18"/>,undefined,undefined,'system.settings.ssl_certificate.view'),
getNavItem(<a>{$t('日志')}</a>, 'logsettings','/logsettings',<Icon icon="ic:baseline-sticky-note-2" width="18" height="18"/>,undefined,undefined,'system.settings.log_configuration.view'),
APP_MODE === 'pro' ? getNavItem(<a>{$t('资源')}</a>, 'resourcesettings','/resourcesettings',null,undefined,undefined,'system.partition.self.view'):null,
APP_MODE === 'pro' ? getNavItem(<a>{$t('Open API')}</a>, 'openapi','/openapi',null,undefined,undefined,'system.openapi.self.view'):null,
]),
@@ -126,7 +122,6 @@ const themeToken = {
const { message } = App.useApp()
const { dispatch,resetAccess,getGlobalAccessData} = useGlobalContext()
const [userInfo,setUserInfo] = useState<UserInfoType>()
const {fetchData} = useFetch()
const navigate = useNavigate();
@@ -163,8 +158,8 @@ const themeToken = {
})
}
const items: MenuProps['items'] = [
{
const items: MenuProps['items'] = useMemo(() => [
userInfo?.type !== 'guest' && {
key: '2',
label: (
<Button key="changePsw" type="text" className="flex items-center p-0 bg-transparent border-none " onClick={()=>navigator('/userProfile/changepsw')}>
@@ -178,7 +173,7 @@ const themeToken = {
{$t('退出登录')}
</Button>)
},
];
].filter(Boolean), [userInfo]);
@@ -248,7 +243,7 @@ const themeToken = {
</div>
)}
logo={Logo}
pageTitleRender={()=>$t('APIPark - 企业API数据开放平台')}
pageTitleRender={()=>$t('APIPark')}
menuFooterRender={(props) => {
if (props?.collapsed) return undefined;
}}
@@ -1,27 +1,23 @@
import { GetProp, TransferProps, TreeDataNode, theme, Transfer, Tree, Spin } from "antd";
import { DataNode, TreeProps } from "antd/es/tree";
import { TransferProps, TreeDataNode, Tree, Spin, Input, Empty } from "antd";
import { DataNode } from "antd/es/tree";
import { Ref, forwardRef, useEffect, useImperativeHandle, useMemo, useRef, useState } from "react";
import { ApartmentOutlined, LoadingOutlined, UserOutlined } from "@ant-design/icons";
import { cloneDeep, debounce } from "lodash-es";
import { ColumnsType } from "antd/es/table";
import { $t } from "@common/locales";
import { useGlobalContext } from "@common/contexts/GlobalStateContext";
type TransferItem = GetProp<TransferProps, 'dataSource'>[number];
export type TransferTableProps<T> = {
request?:(k?:string)=>Promise<{data:T[],success:boolean}>
columns: ColumnsType<T>
primaryKey:string
onSelect:(selectedData:T[])=>void
onSelect:(selectedData:string[])=>void
tableType?:'member'|'api'
disabledData:string[]
searchPlaceholder?:string
}
export type TransferTableHandle<T> = {
selectedData: () => T[];
selectedRowKeys: () => React.Key[];
}
@@ -31,10 +27,6 @@ interface TreeTransferProps {
onChange: TransferProps['onChange'];
}
// Customize Table Transfer
const isChecked = (selectedKeys: React.Key[], eventKey: React.Key) =>
selectedKeys.includes(eventKey);
const generateTree = (
treeNodes: TreeDataNode[] = [],
checkedKeys: TreeTransferProps['targetKeys'] = [],
@@ -73,200 +65,104 @@ const generateTree = (
)
};
const TransferTree = (props)=>{
const { direction, token, tableHeight, dataSource, targetKeys, onItemSelect, onItemSelectAll,checkedKey,selectedKeys, filteredItems ,disabledData} = props;
const [expandedKeys, setExpandedKeys] = useState<string[]>([]);
const getExpandedKeys = (newData:TreeDataNode[], expandedSet:Set<string> = new Set())=>{
newData.forEach((item)=>{
if(item.children && item.children.length > 0){
expandedSet.add(item.key)
getExpandedKeys(item.children,expandedSet)
}
})
return expandedSet
}
const treeData:TreeDataNode[] = useMemo(()=>{
const filteredSet = filteredItems && filteredItems.length > 0 ? new Set(filteredItems.map((x)=>x.id)) : new Set()
const res = dataSource && dataSource.length > 0 ? generateTree(dataSource, targetKeys,direction === 'right',disabledData,filteredSet) : []
setExpandedKeys(Array.from(getExpandedKeys(res)))
return res
},[
dataSource, targetKeys,direction ,disabledData,filteredItems
])
const onExpand: TreeProps['onExpand'] = (expandedKeysValue) => {
setExpandedKeys(expandedKeysValue as string[]);
};
return (
<div style={{ padding: token.paddingXS }}>
<Tree
className="icon-tree"
blockNode
checkable
showIcon
checkedKeys={direction === 'left' ? Array.from(new Set([...checkedKey,...disabledData])) : selectedKeys }
defaultExpandAll
expandedKeys={expandedKeys}
onExpand={onExpand}
height={tableHeight}
icon={(props)=> { return (props.type === 'member' ? <UserOutlined /> :<ApartmentOutlined /> )} }
treeData={treeData}
onCheck={(_checkedKeys, e:{checked: boolean, checkedNodes, node, event, halfCheckedKeys}) => {
if(e.checked){
onItemSelectAll( _checkedKeys, e.checked);
}else{
const checkedKeyArrFromTree = e.checkedNodes.map(node => node.key)
onItemSelectAll((checkedKey as string[]).filter(key => checkedKeyArrFromTree.indexOf(key) === -1),e.checked)
}
}}
onSelect={(_, { node: { key } }) => {
onItemSelect(key as string, !isChecked(checkedKey, key));
}}
/>
</div>
)
}
const MemberTransfer= forwardRef<TransferTableHandle<{[k:string]:unknown}>, TransferTableProps<{[k:string]:unknown}>>(
<T extends {[k:string]:unknown}>(props: TransferTableProps<T>, ref:Ref<TransferTableHandle<T>>) => {
const {request,columns,primaryKey,onSelect,tableType,disabledData = [],searchPlaceholder} = props
const [tableHeight, setTableHeight] = useState(window.innerHeight * 80 / 100 - 64 - 72 - 56 - 16 -3);
const [targetKeys, setTargetKeys] = useState<TreeTransferProps['targetKeys']>([]);
const [dataSource, setDataSource] = useState<DataNode[] >([])
const parentRef = useRef<HTMLDivElement>(null);
const [loading, setLoading] = useState<boolean>(false)
const {state} = useGlobalContext()
const [expandedKeys, setExpandedKeys] = useState<string[]>([]);
const [searchWord, setSearchWord] = useState<string>('')
useEffect(()=>{
setTargetKeys(disabledData)
},[disabledData])
useImperativeHandle(ref, () =>({
selectedData: () => dataSource,
selectedRowKeys: () => targetKeys,}))
const onChange: TreeTransferProps['onChange'] = (keys) => {
onSelect?.(new Set(keys))
setTargetKeys(Array.from(new Set(keys)));
};
const translatedDataSource = useMemo(()=>{
const loop = (data: DataNode[]): DataNode[] =>
data?.map((item) => {
const strTitle:string = item.name === '所有成员' ? $t(item.name) as string : item.name as string;
const index = strTitle.indexOf(searchWord);
const beforeStr = strTitle.substring(0, index);
const afterStr = strTitle.slice(index + searchWord.length);
const title =
index > -1 ? (
<span className='w-[calc(100%-16px)] truncate' title={strTitle}>
{beforeStr}
<span className="text-theme">{searchWord}</span>
{afterStr}
</span>
) : (
<span className='w-[calc(100%-16px)] truncate' title={`${strTitle}`}>{strTitle}</span>
)
if (item.children) {
return {
...item,
title,
disableCheckbox:disabledData.indexOf(item.key as string) !== -1,
icon:<ApartmentOutlined />,
children: loop(item.children as T[]) };
}
const { token } = theme.useToken();
const transferDataSource: TransferItem[] = useMemo(()=>{
function flatten(list: TreeDataNode[] = [], res:TransferItem[]) {
list.forEach((item) => {
res.push({...item, title:item.title === '所有成员' ? $t((item as unknown as {title:string}).title):item.title }as TransferItem);
flatten(item.children,res);
});
}
const res:TransferItem[] =[]
flatten(dataSource,res);
return res
},[
dataSource, state.language
])
const translatedDataSource = useMemo(()=>dataSource.map((item)=>({
...item,
name:item.name === '所有成员' ? $t((item as unknown as {name:string}).name):item.name,
})),[dataSource, state.language])
let memo: Record<string, boolean> = {};
const handlerFilterOption = (inputValue: string, item: any, parentResult: boolean = false, childrenSet: Set<string> = new Set()): boolean => {
const cacheKey = `${inputValue}_${item.key}`;
if (memo[cacheKey]) {
return memo[cacheKey];
}
childrenSet.add(item.key);
let result = item.title.includes(inputValue) || parentResult
if (item.children) {
for (const child of item.children) {
if (handlerFilterOption(inputValue, child, result,childrenSet)) {
result = true;
}
}
}
if (result) {
memo[cacheKey] = result;
childrenSet.forEach((key) => {
memo[`${inputValue}_${key}`] = result;
return {
...item,
title,
icon:<UserOutlined />,
isLeaf:true,
disableCheckbox:disabledData.indexOf(item.key as string) !== -1
};
});
}
return result;
};
return loop(dataSource);
},[dataSource, state.language, searchWord])
const getInitExpandKeys = (data:T[], expandKeys:string[] = [])=>{
data.forEach((item)=>{
if(item.children?.length){
expandKeys.push(item.key as string)
getInitExpandKeys(item.children,expandKeys)
}
})
return expandKeys
}
const getDataSource = ()=>{
setLoading(true)
request && request().then((res)=>{
const {data,success} = res
setDataSource(success? data : [])
setExpandedKeys(getInitExpandKeys(success? data:[]))
}).finally(()=>{setLoading(false)})
}
}
useEffect(() => {
getDataSource()
const handleResize = () => {
setTableHeight(window.innerHeight * 80 / 100 - 64 - 72 - 56 - 16 -3)
};
const debouncedHandleResize = debounce(handleResize, 200);
// 监听窗口大小变化
window.addEventListener('resize', debouncedHandleResize);
handleResize();
return () => {
window.removeEventListener('resize', debouncedHandleResize);
};
}, []);
useEffect(() => {
getDataSource()
}, []);
return (
<div ref={parentRef}>
<Spin indicator={<LoadingOutlined style={{ fontSize: 24 }} spin />} spinning={loading} className=''>
<Transfer
showSearch
onSearch={(dir)=>{
memo = {};
}}
listStyle={{width:'408px'}}
disabledData={disabledData}
filterOption={(inputValue: string, item: any) => handlerFilterOption(inputValue, item)}
targetKeys={targetKeys}
dataSource={transferDataSource}
className="tree-transfer"
render={(item) => item.title!}
showSelectAll={false}
onChange={onChange}
titles={['','']}
>
{({ direction, onItemSelect, selectedKeys,onItemSelectAll ,filteredItems}) => {
const treeProps = {
dataSource:translatedDataSource, direction, onItemSelect, selectedKeys,onItemSelectAll ,filteredItems,token,tableHeight,targetKeys,disabledData
}
if (direction === 'left') {
const checkedKey = [...selectedKeys, ...targetKeys as string[]];
return (
<TransferTree {...treeProps} checkedKey={checkedKey} />
);
}
if(direction === 'right'){
const checkedKey = [...selectedKeys,...targetKeys as string[]];
return (
<TransferTree {...treeProps} checkedKey={checkedKey} />
);
}
}}
</Transfer>
<Input className="mb-[10px]" placeholder={searchPlaceholder} onChange={(e)=>setSearchWord(e.target.value)} value={searchWord} />
<>{ translatedDataSource && translatedDataSource.length > 0 ? <Tree
checkable
expandedKeys={expandedKeys}
checkedKeys={targetKeys}
selectable={false}
onCheck={(e)=>{setTargetKeys(e);
onSelect(((e as string[])?.filter(x=>disabledData.indexOf(x as string) === -1))||[])}}
onExpand={setExpandedKeys}
treeData={translatedDataSource}
blockNode
showIcon
/>
: <Empty image={Empty.PRESENTED_IMAGE_SIMPLE}/> }</>
</Spin>
</div>
);
@@ -219,12 +219,12 @@ export const PublishApprovalModalContent = forwardRef<PublishApprovalModalHandle
/></Row>
</>
}
<Form.Item
{/* <Form.Item
label={$t("备注")}
name="remark"
>
<Input.TextArea className="w-INPUT_NORMAL" disabled={type !== 'add' && type !== 'publish'} placeholder={$t(PLACEHOLDER.input)} />
</Form.Item>
</Form.Item> */}
{/*
{type !== 'add' && type !== 'publish' && <Form.Item
label={$t("审核意见"
@@ -132,6 +132,33 @@ export const TranslateWord = ()=>{
{$t('每小时')}
{$t('每天')}
{$t('每周')}
{$t('上线结果')}
{$t('订阅服务数量')}
{$t('鉴权数量')}
{$t('列表')}
{$t('块')}
{$t('HTTP 请求头')}
{$t('全等匹配')}
{$t('前缀匹配')}
{$t('后缀匹配')}
{$t('子串匹配')}
{$t('非等匹配')}
{$t('空值匹配')}
{$t('存在匹配')}
{$t('不存在匹配')}
{$t('区分大小写的正则匹配')}
{$t('不区分大小写的正则匹配')}
{$t('任意匹配')}
{$t('驳回')}
{$t('已订阅')}
{$t('取消申请')}
{$t('透传客户端请求 Host')}
{$t('使用上游服务 Host')}
{$t('重写 Host')}
{$t('动态服务发现')}
{$t('地址')}
{$t('新增')}
{$t('申请方消费者')}
</>
)
@@ -39,7 +39,7 @@ const WithPermission = ({access, tooltip, children,disabled, showDisabled = true
{ cloneElement(children, {disabled:true})}
</Tooltip>}
{!editAccess && (children?.type !== Button && children?.type !== Upload && showDisabled) && <Tooltip title={tooltip ?? $t("暂无操作权限,请联系管理员分配。")}>
{ cloneElement(children, {disabled:true,okButtonProps:{disabled:true}})}
{ cloneElement(children, {disabled:true, onClick:(e)=>e.preventDefault(),okButtonProps:{disabled:true}})}
</Tooltip>}
</>
@@ -343,11 +343,6 @@ export const PUBLISH_APPROVAL_RECORD_INNER_TABLE_COLUMN : PageProColumns<Publish
dataIndex: 'status',
ellipsis:true,
},
{
title:('备注'),
dataIndex: 'comments',
ellipsis:true
},
{
title:('申请人'),
dataIndex: ['applicant','name'],
+119 -99
View File
@@ -4,84 +4,84 @@
export const PERMISSION_DEFINITION = [
{
"system.organization.member.view": {
"system.settings.account.view": {
"granted": {
"anyOf": [{ "backend": ["system.organization.member.view"] }]
"anyOf": [{ "backend": ["system.settings.account.view"] }]
}
},
"system.organization.member.add": {
"granted": {
"anyOf": [{ "backend": ["system.organization.member.manager"] }]
"anyOf": [{ "backend": ["system.settings.account.manager"] }]
}
},
"system.organization.member.edit": {
"granted": {
"anyOf": [{ "backend": ["system.organization.member.manager"] }]
"anyOf": [{ "backend": ["system.settings.account.manager"] }]
}
},
"system.organization.member.remove": {
"granted": {
"anyOf": [{ "backend": ["system.organization.member.manager"] }]
"anyOf": [{ "backend": ["system.settings.account.manager"] }]
}
},
"system.organization.member.delete": {
"granted": {
"anyOf": [{ "backend": ["system.organization.member.manager"] }]
"anyOf": [{ "backend": ["system.settings.account.manager"] }]
}
},
"system.organization.member.block": {
"granted": {
"anyOf": [{ "backend": ["system.organization.member.manager"] }]
"anyOf": [{ "backend": ["system.settings.account.manager"] }]
}
},
"system.organization.member.department.add": {
"granted": {
"anyOf": [{ "backend": ["system.organization.member.manager"] }]
"anyOf": [{ "backend": ["system.settings.account.manager"] }]
}
},
"system.organization.member.department.edit": {
"granted": {
"anyOf": [{ "backend": ["system.organization.member.manager"] }]
"anyOf": [{ "backend": ["system.settings.account.manager"] }]
}
},
"system.organization.member.department.delete": {
"granted": {
"anyOf": [{ "backend": ["system.organization.member.manager"] }]
"anyOf": [{ "backend": ["system.settings.account.manager"] }]
}
},
"system.organization.team.view": {
"system.workspace.team.view_all": {
"granted": {
"anyOf": [{ "backend": ["system.organization.team.view"] }]
"anyOf": [{ "backend": ["system.workspace.team.view_all"] }]
}
},
"system.organization.team.add": {
"granted": {
"anyOf": [{ "backend": ["system.organization.team.manager"] }]
"anyOf": [{ "backend": ["system.workspace.team.create"] }]
}
},
"system.organization.team.edit": {
"granted": {
"anyOf": [{ "backend": ["system.organization.team.manager"] }]
"anyOf": [{ "backend": ["system.workspace.team.manager"] }]
}
},
"system.organization.team.delete": {
"granted": {
"anyOf": [{ "backend": ["system.organization.team.manager"] }]
"anyOf": [{ "backend": ["system.workspace.team.manager"] }]
}
},
"system.organization.team.running": {
"granted": {
"anyOf": [{ "backend": ["system.organization.team.manager"] }]
"anyOf": [{ "backend": ["system.workspace.team.manager"] }]
}
},
"system.organization.role.view": {
"granted": {
"anyOf": [{ "backend": ["system.organization.role.view_system_role","system.organization.role.view_team_role"] }]
"anyOf": [{ "backend": ["system.settings.role.view"] }]
}
},
"system.organization.role.system.view": {
"granted": {
"anyOf": [{ "backend": ["system.organization.role.view_system_role"] }]
"anyOf": [{ "backend": ["system.settings.role.view"] }]
}
},
"system.organization.role.system.add": {
@@ -101,7 +101,7 @@ export const PERMISSION_DEFINITION = [
},
"system.organization.role.team.view": {
"granted": {
"anyOf": [{ "backend": ["system.organization.role.view_team_role"] }]
"anyOf": [{ "backend": ["system.settings.role.view"] }]
}
},
"system.organization.role.team.add": {
@@ -121,22 +121,22 @@ export const PERMISSION_DEFINITION = [
},
"system.api_market.service_classification.view": {
"granted": {
"anyOf": [{ "backend": ["system.settings.service_classification.view"] }]
"anyOf": [{ "backend": ["system.settings.general.view"] }]
}
},
"system.api_market.service_classification.add": {
"granted": {
"anyOf": [{ "backend": ["system.settings.service_classification.manager"] }]
"anyOf": [{ "backend": ["system.settings.general.manager"] }]
}
},
"system.api_market.service_classification.edit": {
"granted": {
"anyOf": [{ "backend": ["system.settings.service_classification.manager"] }]
"anyOf": [{ "backend": ["system.settings.general.manager"] }]
}
},
"system.api_market.service_classification.delete": {
"granted": {
"anyOf": [{ "backend": ["system.settings.service_classification.manager"] }]
"anyOf": [{ "backend": ["system.settings.general.manager"] }]
}
},
"system.devops.system_setting.view": {
@@ -149,94 +149,94 @@ export const PERMISSION_DEFINITION = [
"anyOf": [{ "backend": ["system.settings.general.manager"] }]
}
},
"system.dashboard.run_view.view":{
"system.analysis.run_view.view":{
"granted": {
"anyOf": [{ "backend": ['system.dashboard.run_view.view'] }]
"anyOf": [{ "backend": ['system.analysis.run_view.view'] }]
}
},
"system.devops.data_source.view":{
"system.settings.data_source.view":{
"granted":{
"anyOf":[{"backend":['system.devops.data_source.view']}]
"anyOf":[{"backend":['system.settings.data_source.view']}]
}
},
"system.devops.data_source.edit":{
"granted":{
"anyOf":[{"backend":['system.devops.data_source.manager']}]
"anyOf":[{"backend":['system.settings.data_source.manager']}]
}
},
"system.devops.cluster.view": {
"system.settings.api_gateway.view": {
"granted": {
"anyOf": [{ "backend": ["system.devops.cluster.view"] }]
"anyOf": [{ "backend": ["system.settings.api_gateway.view"] }]
}
},
"system.devops.cluster.add": {
"granted": {
"anyOf": [{ "backend": ["system.devops.cluster.manager"] }]
"anyOf": [{ "backend": ["system.settings.api_gateway.manager"] }]
}
},
"system.devops.cluster.edit": {
"granted": {
"anyOf": [{ "backend": ["system.devops.cluster.manager"] }]
"anyOf": [{ "backend": ["system.settings.api_gateway.manager"] }]
}
},
"system.devops.cluster.delete": {
"granted": {
"anyOf": [{ "backend": ["system.devops.cluster.manager"] }]
"anyOf": [{ "backend": ["system.settings.api_gateway.manager"] }]
}
},
"system.devops.ai_provider.view": {
"system.settings.ai_provider.view": {
"granted": {
"anyOf": [{ "backend": ["system.devops.ai_provider.view"] }]
"anyOf": [{ "backend": ["system.settings.ai_provider.view"] }]
}
},
"system.devops.ai_provider.edit": {
"granted": {
"anyOf": [{ "backend": ["system.devops.ai_provider.manager"] }]
"anyOf": [{ "backend": ["system.settings.ai_provider.manager"] }]
}
},
"system.devops.ssl_certificate.view": {
"system.settings.ssl_certificate.view": {
"granted": {
"anyOf": [{ "backend": ["system.devops.ssl_certificate.view"] }]
"anyOf": [{ "backend": ["system.settings.ssl_certificate.view"] }]
}
},
"system.devops.ssl_certificate.add": {
"granted": {
"anyOf": [{ "backend": ["system.devops.ssl_certificate.manager"] }]
"anyOf": [{ "backend": ["system.settings.ssl_certificate.manager"] }]
}
},
"system.devops.ssl_certificate.edit": {
"granted": {
"anyOf": [{ "backend": ["system.devops.ssl_certificate.manager"] }]
"anyOf": [{ "backend": ["system.settings.ssl_certificate.manager"] }]
}
},
"system.devops.ssl_certificate.delete": {
"granted": {
"anyOf": [{ "backend": ["system.devops.ssl_certificate.manager"] }]
"anyOf": [{ "backend": ["system.settings.ssl_certificate.manager"] }]
}
},
"system.devops.log_configuration.view": {
"system.settings.log_configuration.view": {
"granted": {
"anyOf": [{ "backend": ["system.devops.log_configuration.view"] }]
"anyOf": [{ "backend": ["system.settings.log_configuration.view"] }]
}
},
"system.devops.log_configuration.add": {
"granted": {
"anyOf": [{ "backend": ["system.devops.log_configuration.manager"] }]
"anyOf": [{ "backend": ["system.settings.log_configuration.manager"] }]
}
},
"system.devops.log_configuration.edit": {
"granted": {
"anyOf": [{ "backend": ["system.devops.log_configuration.manager"] }]
"anyOf": [{ "backend": ["system.settings.log_configuration.manager"] }]
}
},
"system.devops.log_configuration.publish": {
"granted": {
"anyOf": [{ "backend": ["system.devops.log_configuration.manager"] }]
"anyOf": [{ "backend": ["system.settings.log_configuration.manager"] }]
}
},
"system.devops.log_configuration.delete": {
"granted": {
"anyOf": [{ "backend": ["system.devops.log_configuration.manager"] }]
"anyOf": [{ "backend": ["system.settings.log_configuration.manager"] }]
}
},
"system.workspace.application.view_all": {
@@ -244,19 +244,24 @@ export const PERMISSION_DEFINITION = [
"anyOf": [{ "backend": ["system.workspace.application.view_all"] }]
}
},
"system.workspace.application.edit": {
"granted": {
"anyOf": [{ "backend": ["system.workspace.application.manager_all"] }]
}
},
"system.workspace.service.view_all": {
"granted": {
"anyOf": [{ "backend": ["system.workspace.service.view_all"] }]
}
},
"system.workspace.team.view_all": {
"system.workspace.service.edit": {
"granted": {
"anyOf": [{ "backend": ["system.workspace.team.view_all"] }]
"anyOf": [{ "backend": ["system.workspace.service.manager_all"] }]
}
},
"system.workspace.api_market.view": {
"system.api_portal.api_portal.view": {
"granted": {
"anyOf": [{ "backend": ["system.workspace.api_market.view"] }]
"anyOf": [{ "backend": ["system.api_portal.api_portal.view"] }]
}
},
"system.dashboard.dashboard.view": {
@@ -271,237 +276,252 @@ export const PERMISSION_DEFINITION = [
},
"team.service.api_doc.view": {
"granted": {
"anyOf": [{ "backend": ["team.service.api_doc.view"] }]
"anyOf": [{ "backend": ["system.workspace.service.view_all","team.service.api_doc.view"] }]
}
},
"team.service.api_doc.add": {
"granted": {
"anyOf": [{ "backend": ["team.service.api_doc.manager"] }]
"anyOf": [{ "backend": ["system.workspace.service.manager_all","team.service.api_doc.manager"] }]
}
},
"team.service.api_doc.edit": {
"granted": {
"anyOf": [{ "backend": ["team.service.api_doc.manager"] }]
"anyOf": [{ "backend": ["system.workspace.service.manager_all","team.service.api_doc.manager"] }]
}
},
"team.service.service_intro.view": {
"granted": {
"anyOf": [{ "backend": ["system.workspace.service.view_all","team.service.service_intro.view"] }]
}
},
"team.service.service_intro.add": {
"granted": {
"anyOf": [{ "backend": ["system.workspace.service.manager_all","team.service.service_intro.manager"] }]
}
},
"team.service.service_intro.edit": {
"granted": {
"anyOf": [{ "backend": ["system.workspace.service.manager_all","team.service.service_intro.manager"] }]
}
},
"team.service.api_doc.import": {
"granted": {
"anyOf": [{ "backend": ["team.service.api_doc.manager"] }]
"anyOf": [{ "backend": ["system.workspace.service.manager_all","team.service.api_doc.manager"] }]
}
},
"team.service.router.view": {
"granted": {
"anyOf": [{ "backend": ["team.service.router.view"] }]
"anyOf": [{ "backend": ["system.workspace.service.view_all","team.service.api.view"] }]
}
},
"team.service.router.add": {
"granted": {
"anyOf": [{ "backend": ["team.service.router.manager"] }]
"anyOf": [{ "backend": ["system.workspace.service.manager_all","team.service.api.manager"] }]
}
},
"team.service.router.edit": {
"granted": {
"anyOf": [{ "backend": ["team.service.router.manager"] }]
"anyOf": [{ "backend": ["system.workspace.service.manager_all","team.service.api.manager"] }]
}
},
"team.service.router.delete": {
"granted": {
"anyOf": [{ "backend": ["team.service.router.manager"] }]
"anyOf": [{ "backend": ["system.workspace.service.manager_all","team.service.api.manager"] }]
}
},
"team.service.upstream.view": {
"granted": {
"anyOf": [{ "backend": ["team.service.upstream.view"] }]
"anyOf": [{ "backend": ["system.workspace.service.view_all","team.service.upstream.view"] }]
}
},
"team.service.upstream.add": {
"granted": {
"anyOf": [{ "backend": ["team.service.upstream.manager"] }]
"anyOf": [{ "backend": ["system.workspace.service.manager_all","team.service.upstream.manager"] }]
}
},
"team.service.upstream.edit": {
"granted": {
"anyOf": [{ "backend": ["team.service.upstream.manager"] }]
"anyOf": [{ "backend": ["system.workspace.service.manager_all","team.service.upstream.manager"] }]
}
},
"team.service.upstream.delete": {
"granted": {
"anyOf": [{ "backend": ["team.service.upstream.manager"] }]
"anyOf": [{ "backend": ["system.workspace.service.manager_all","team.service.upstream.manager"] }]
}
},
"team.service.release.view": {
"granted": {
"anyOf": [{ "backend": ["team.service.release.view"] }]
"anyOf": [{ "backend": ["system.workspace.service.view_all","team.service.release.view"] }]
}
},
"team.service.release.add": {
"granted": {
"anyOf": [{ "backend": ["team.service.release.manager"] }]
"anyOf": [{ "backend": ["system.workspace.service.manager_all","team.service.release.manager"] }]
}
},
"team.service.release.online": {
"granted": {
"anyOf": [{ "backend": ["team.service.release.manager"] }]
"anyOf": [{ "backend": ["system.workspace.service.manager_all","team.service.release.manager"] }]
}
},
"team.service.release.stop": {
"granted": {
"anyOf": [{ "backend": ["team.service.release.manager"] }]
"anyOf": [{ "backend": ["system.workspace.service.manager_all","team.service.release.manager"] }]
}
},
"team.service.release.cancel": {
"granted": {
"anyOf": [{ "backend": ["team.service.release.manager"] }]
"anyOf": [{ "backend": ["system.workspace.service.manager_all","team.service.release.manager"] }]
}
},
"team.service.release.rollback": {
"granted": {
"anyOf": [{ "backend": ["team.service.release.manager"] }]
"anyOf": [{ "backend": ["system.workspace.service.manager_all","team.service.release.manager"] }]
}
},
"team.service.release.delete": {
"granted": {
"anyOf": [{ "backend": ["team.service.release.manager"] }]
"anyOf": [{ "backend": ["system.workspace.service.manager_all","team.service.release.manager"] }]
}
},
"team.service.release.approval": {
"granted": {
"anyOf": [{ "backend": ["team.service.release.manager"] }]
"anyOf": [{ "backend": ["system.workspace.service.manager_all","team.service.release.manager"] }]
}
},
"team.service.subscription.view": {
"granted": {
"anyOf": [{ "backend": ["team.service.subscription.view"] }]
"anyOf": [{ "backend": ["system.workspace.service.view_all","team.service.subscription.view"] }]
}
},
"team.service.subscription.approval": {
"granted": {
"anyOf": [{ "backend": ["team.service.subscription.manager"] }]
"anyOf": [{ "backend": ["system.workspace.service.manager_all","team.service.subscription.manager"] }]
}
},
"team.service.subscription.add": {
"granted": {
"anyOf": [{ "backend": ["team.service.subscription.manager"] }]
"anyOf": [{ "backend": ["system.workspace.service.manager_all","team.service.subscription.manager"] }]
}
},
"team.service.subscription.delete": {
"granted": {
"anyOf": [{ "backend": ["team.service.subscription.manager"] }]
"anyOf": [{ "backend": ["system.workspace.service.manager_all","team.service.subscription.manager"] }]
}
},
"team.service.service.view": {
"granted": {
"anyOf": [{ "backend": [""] }]
"anyOf": [{ "backend": ["system.workspace.service.manager_all","system.workspace.service.view_all","team.team.service.view"] }]
}
},
"team.service.service.add": {
"granted": {
"anyOf": [{ "backend": ["team.service.service.manager"] }]
"anyOf": [{ "backend": ["system.workspace.service.manager_all","team.team.service.manager","team.service.service.manager"] }]
}
},
"team.service.service.edit": {
"granted": {
"anyOf": [{ "backend": ["team.service.service.manager"] }]
"anyOf": [{ "backend": ["system.workspace.service.manager_all","team.team.service.manager","team.service.service.manager"] }]
}
},
"team.service.service.delete": {
"granted": {
"anyOf": [{ "backend": ["team.service.service.manager"] }]
"anyOf": [{ "backend": ["system.workspace.service.manager_all","team.team.service.manager","team.service.service.manager"] }]
}
},
"team.application.subscription.view": {
"granted": {
"anyOf": [{ "backend": ["team.application.subscription.view"] }]
"anyOf": [{ "backend": ["system.workspace.application.view_all","team.consumer.subscription.view_subscribed_service"] }]
}
},
"team.application.subscription.add": {
"granted": {
"anyOf": [{ "backend": ["team.application.subscription.manager"] }]
"anyOf": [{ "backend": ["system.workspace.application.manager_al","team.consumer.subscription.subscribe"] }]
}
},
"team.application.subscription.edit": {
"granted": {
"anyOf": [{ "backend": ["team.application.subscription.manager"] }]
"anyOf": [{ "backend": ["system.workspace.application.manager_al","team.consumer.subscription.manager_subscribed_services"] }]
}
},
"team.application.subscription.delete": {
"granted": {
"anyOf": [{ "backend": ["team.application.subscription.manager"] }]
"anyOf": [{ "backend": ["system.workspace.application.manager_al","team.team.consumer.subscription.manager_subscribed_services"] }]
}
},
"team.application.application.view": {
"granted": {
"anyOf": [{ "backend": ["team.application.application.view"] }]
"anyOf": [{ "backend": ["system.workspace.application.view_all","team.team.consumer.view"] }]
}
},
"team.application.application.add": {
"granted": {
"anyOf": [{ "backend": ["team.application.application.manager"] }]
"anyOf": [{ "backend": ["system.workspace.application.manager_al",'team.team.consumer.manager',"team.consumer.application.manager"] }]
}
},
"team.application.application.edit": {
"granted": {
"anyOf": [{ "backend": ["team.application.application.manager"] }]
"anyOf": [{ "backend": ["system.workspace.application.manager_al",'team.team.consumer.manager',"team.consumer.application.manager"] }]
}
},
"team.application.application.delete": {
"granted": {
"anyOf": [{ "backend": ["team.application.application.manager"] }]
"anyOf": [{ "backend": ["system.workspace.application.manager_al",'team.team.consumer.manager',"team.consumer.application.manager"] }]
}
},
"team.application.authorization.view": {
"team.consumer.authorization.view": {
"granted": {
"anyOf": [{ "backend": ["team.application.authorization.view"] }]
"anyOf": [{ "backend": ["system.workspace.application.manager_al","system.workspace.application.view_all","team.consumer.authorization.view"] }]
}
},
"team.application.authorization.add": {
"granted": {
"anyOf": [{ "backend": ["team.application.authorization.manager"] }]
"anyOf": [{ "backend": ["system.workspace.application.manager_al","team.consumer.authorization.manager"] }]
}
},
"team.application.authorization.edit": {
"granted": {
"anyOf": [{ "backend": ["team.application.authorization.manager"] }]
"anyOf": [{ "backend": ["system.workspace.application.manager_al","team.consumer.authorization.manager"] }]
}
},
"team.application.authorization.delete": {
"granted": {
"anyOf": [{ "backend": ["team.application.authorization.manager"] }]
"anyOf": [{ "backend": ["system.workspace.application.manager_al","team.consumer.authorization.manager"] }]
}
},
"team.application.authorization.cancelSubApply": {
"granted": {
"anyOf": [{ "backend": ["team.application.authorization.manager"] }]
"anyOf": [{ "backend": ["system.workspace.application.manager_al","team.consumer.authorization.manager"] }]
}
},
"team.application.authorization.cancelSub": {
"granted": {
"anyOf": [{ "backend": ["team.application.authorization.manager"] }]
"anyOf": [{ "backend": ["system.workspace.application.manager_al","team.consumer.authorization.manager"] }]
}
},
"team.team.team.view": {
"granted": {
"anyOf": [{ "backend": ["team.team.team.view"] }]
"anyOf": [{ "backend": ["system.workspace.team.view_all","team.team.team.view"] }]
}
},
"team.team.team.edit": {
"granted": {
"anyOf": [{ "backend": ["team.team.team.manager"] }]
"anyOf": [{ "backend": ["system.workspace.team.manager","team.team.team.manager"] }]
}
},
"team.team.member.view": {
"granted": {
"anyOf": [{ "backend": ["team.team.member.view"] }]
"anyOf": [{ "backend": ["system.workspace.team.view_all","team.team.member.view"] }]
}
},
"team.team.member.add": {
"granted": {
"anyOf": [{ "backend": ["team.team.member.manager"] }]
"anyOf": [{ "backend": ["system.workspace.team.manager","team.team.member.manager"] }]
}
},
"team.team.member.edit": {
"granted": {
"anyOf": [{ "backend": ["team.team.member.manager"] }]
"anyOf": [{ "backend": ["system.workspace.team.manager","team.team.member.manager"] }]
}
},
"project.mySystem.topology.view": {
@@ -7,7 +7,7 @@ system:
cname: '成员'
value: 'member'
access:
- system.organization.member.view
- system.settings.account.view
- system.organization.member.add
- system.organization.member.edit
- system.organization.member.delete
@@ -18,7 +18,7 @@ system:
- name: team_manager
cname: '团队管理'
desc: '团队管理'
- system.organization.team.view
- system.workspace.team.view_all
- system.organization.team.add
- system.organization.team.edit
- system.organization.team.delete
@@ -55,7 +55,7 @@ system:
cname: 集群
value: 'cluster'
children:
- system.devops.cluster.view
- system.settings.api_gateway.view
- system.devops.cluster.add
- system.devops.cluster.edit
- system.devops.cluster.delete
@@ -63,7 +63,7 @@ system:
cname: 证书
value: 'ssl_certificate'
children:
- system.devops.ssl_certificate.view
- system.settings.ssl_certificate.view
- system.devops.ssl_certificate.add
- system.devops.ssl_certificate.edit
- system.devops.ssl_certificate.delete
@@ -71,7 +71,7 @@ system:
cname: 日志
value: 'log_configuration'
children:
- system.devops.log_configuration.view
- system.settings.log_configuration.view
- system.devops.log_configuration.add
- system.devops.log_configuration.edit
- system.devops.log_configuration.publish
@@ -99,7 +99,7 @@ system:
cname: API市场
value: 'api_market'
children:
- system.workspace.api_market.view
- system.api_portal.api_portal.view
team:
- name: service
cname: 服务
@@ -172,8 +172,8 @@ team:
cname: 访问授权
value: 'authorization'
children:
- team.application.authorization.view
- team.application.authorization.manager
- team.consumer.authorization.view
- team.consumer.authorization.manager
- team.application.authorization.add
- team.application.authorization.edit
- team.application.authorization.delete
@@ -7,6 +7,8 @@ export type UserInfoType = {
email: string
phone: string
avatar: string
type:string
}
export type UserProfileProps = {
@@ -1,26 +0,0 @@
/*
* @Date: 2024-01-31 15:00:11
* @LastEditors: maggieyyy
* @LastEditTime: 2024-05-10 17:03:03
* @FilePath: \frontend\packages\core\src\hooks\crypto.ts
*/
// import CryptoJS from 'crypto-js';
// export const useCrypto = () => {
// const key = '1e42=7838a1vfc6n';
// const encryptByEnAES = (secretKey: string, data: string, initializationVector?: string): string => {
// const iv = CryptoJS.enc.Latin1.parse(initializationVector || key);
// const keyForEncryption = CryptoJS.enc.Latin1.parse(CryptoJS.MD5(secretKey).toString());
// const cipher = CryptoJS.AES.encrypt(data, keyForEncryption, {
// iv,
// mode: CryptoJS.mode.CBC,
// padding: CryptoJS.pad.Pkcs7,
// });
// return CryptoJS.enc.Base64.stringify(cipher.ciphertext);
// };
// return { encryptByEnAES };
// };
+1 -6
View File
@@ -1,9 +1,4 @@
/*
* @Date: 2024-06-04 14:58:33
* @LastEditors: maggieyyy
* @LastEditTime: 2024-06-04 15:39:24
* @FilePath: \frontend\packages\common\src\index.css
*/
@tailwind base;
@tailwind components;
@tailwind utilities;
@@ -1,8 +1,8 @@
{
"工作空间": "Kc0e5ef9f",
"首页": "K4de11e23",
"消费者": "Kfe93ef35",
"服务": "Kb58e0c3f",
"消费者": "K7acfcfad",
"团队": "Kc9e489f5",
"API 市场": "K61c89f5f",
"仪表盘": "K16d71239",
@@ -95,8 +95,8 @@
"只读成员": "Ke41d7451",
"服务管理员": "Kf99e8b66",
"服务开发者": "Kda8db57a",
"消费者开发者": "K216a1ac7",
"消费者管理员": "K27924db",
"消费者开发者": "Kc8054dba",
"消费者管理员": "Keb1673a6",
"驱动名称": "K8dc5c723",
"请求失败数": "Kda249fe8",
"转发失败数": "Kcf2df651",
@@ -131,8 +131,8 @@
"上传 OpenAPI 文档 (.json/.yaml)": "K6206e4ad",
"替换 OpenAPI 文档 (.json/.yaml)": "Kfba46e6d",
"打开 OpenAPI YAML 编辑器": "Kdac8ce7e",
"无需审核:允许任何消费者调用该服务": "Kffd7e274",
"人工审核:仅允许通过人工审核的消费者调用该服务": "K8a8b13e4",
"无需审核:允许任何消费者调用该服务": "K1fc2cc28",
"人工审核:仅允许通过人工审核的消费者调用该服务": "K8dabb98e",
"永久": "Kbfe02d7f",
"否": "K1e9c479e",
"是": "Kaddfcb6b",
@@ -150,7 +150,7 @@
"版本状态": "Kcbf39b82",
"创建人": "K339d15b5",
"审核时间": "K7194cea2",
"申请方-消费者": "K831aa6c0",
"申请方-消费者": "K7c1fb123",
"审核状态": "K7ad449bc",
"审核人": "K3b3a98ce",
"来源": "K61b62ace",
@@ -207,6 +207,33 @@
"每小时": "Kf00f01ca",
"每天": "Kfcda87fc",
"每周": "K29ec75dc",
"上线结果": "K93c2696e",
"订阅服务数量": "K6e32a344",
"鉴权数量": "Ka701316",
"列表": "K9eaa2eb6",
"块": "Kfaec39e9",
"HTTP 请求头": "K76036e25",
"全等匹配": "K44607e3f",
"前缀匹配": "Kc287500a",
"后缀匹配": "Kfc0b1147",
"子串匹配": "Ka4a92043",
"非等匹配": "K30b2e44f",
"空值匹配": "Kb1587991",
"存在匹配": "K1e97dbd8",
"不存在匹配": "Kc8ee3e62",
"区分大小写的正则匹配": "K87c5a801",
"不区分大小写的正则匹配": "K95f062f1",
"任意匹配": "Kfbd230a5",
"驳回": "Kd85208a3",
"已订阅": "Kad6aa439",
"取消申请": "K9a68443b",
"透传客户端请求 Host": "Kaeba0229",
"使用上游服务 Host": "K6d7e2fd0",
"重写 Host": "K31332633",
"动态服务发现": "K2c2bc64f",
"地址": "K78b1ca25",
"新增": "K1644b775",
"申请方消费者": "Kec91f0db",
"暂无操作权限,请联系管理员分配。": "K23fda291",
"微信小程序": "K4618cb0a",
"获取文件,需填路径": "Ka854f511",
@@ -369,7 +396,7 @@
"创建 AI 服务和 API": "Kc057704a",
"创建 AI 类型的服务,并且你可以将 Prompt 提示词设置为一个 API,简化使用 AI 的流程。": "K76bb4a09",
"创建调用 Token": "K71b2c70f",
"为了安全地调用 API,你需要创建一个消费者以及Token。": "K9bdd8403",
"为了安全地调用 API,你需要创建一个消费者以及Token。": "Kdea9a418",
"调用": "Kc5738b6c",
"现在你可以通过 Token 来调用这些 API。": "Kd6d7ca1f",
"快速接入 REST API": "K86cf95f",
@@ -379,13 +406,13 @@
"核心功能": "K2cdbb773",
"账号与角色": "K3378c50d",
"邀请你的团队成员加入 APIPark,共同管理和调用 API。": "Kda5bb930",
"团队中包含了人员、消费者和服务,不同团队之间的消费者和服务数据是隔离的,可用于管理企业内部不同的部门/项目组/团队。": "Kc8239422",
"团队中包含了人员、消费者和服务,不同团队之间的消费者和服务数据是隔离的,可用于管理企业内部不同的部门/项目组/团队。": "Keee27105",
"服务内包含一组 API,并且可以发布到 API 市场被其他团队使用。": "Kd5be0cd7",
"权限管理": "K62e89ee7",
"订阅服务": "K8f7808e6",
"如果需要调用某个服务的 API,需要先订阅该服务,并且等待提供服务的团队审核后才可发起 API 请求。": "Kf2410413",
"审核订阅申请": "K6c2e44b8",
"提供服务的团队可以审核来自其他团队的订阅申请,审核通过后的消费者才可发起 API 请求。": "Ka0a8840a",
"提供服务的团队可以审核来自其他团队的订阅申请,审核通过后的消费者才可发起 API 请求。": "Kaa717866",
"APIPark 提供详尽的 API 调用日志,帮助企业监控、分析和审计 API 的运行状况。": "K3453272",
"Hello!欢迎使用 APIPark": "Kd518ba3e",
"你能通过 APIPark 快速在企业内部构建 API 开放门户/市场,享受极致的转发性能、API 可观测、服务治理、多租户管理、订阅审核流程等诸多好处。": "K7e04ea16",
@@ -396,10 +423,10 @@
"了解 APIPark 如何更好地管理 API 和 AI": "K1afaf20e",
"了解更多功能": "K48f7e21f",
"隐藏该教程": "K698296e2",
"登录": "Kd2c1a316",
"请输入账号": "Kf076f63c",
"请输入密码": "K25c895d5",
"密码": "K551b0348",
"登录": "Kd2c1a316",
"访客模式": "K192b3e38",
"您可通过访客模式查看所有页面和功能,但是无法编辑数据。访客模式仅用于了解产品功能,您可以在正式产品中关闭该功能。": "K91aa4801",
"Version (0)-(1)": "K480045ce",
@@ -480,6 +507,8 @@
"只允许上传PNG、JPG或SVG格式的图片": "Ka9c08390",
"服务名称": "K413b9869",
"服务类型": "K9919285b",
"AI 服务": "Kd2c34e2c",
"REST 服务": "K62840d62",
"默认 AI 供应商": "Kcef64f4d",
"创建 API 时会默认选择该供应商,修改默认供应商不会影响现有 API": "K300c89d4",
"未配置任何 AI 模型供应商,": "Kcab588a9",
@@ -517,8 +546,8 @@
"移除成员": "K395acc14",
"添加成员": "Kec46a57f",
"输入姓名查找": "K48724410",
"搜索用户名、邮箱": "Kb9052305",
"设置团队和成员,然后你可以在团队内创建服务和消费者、订阅API,成员只能看到所属团队内的服务和消费者。": "K5ece3bac",
"输入名称查找用户": "Kf5fd27ed",
"设置团队和成员,然后你可以在团队内创建服务和消费者、订阅API,成员只能看到所属团队内的服务和消费者。": "K4c72fb6f",
"添加团队": "K510cdd27",
"输入名称、ID、负责人查找团队": "K9244ae14",
"配置团队": "Kc7b24b4b",
@@ -538,8 +567,8 @@
"导出": "Ka2c794a2",
"退出全屏": "Kaf70c3b",
"(0)调用详情": "Kd22841a4",
"消费者调用统计": "K1512e983",
"请选择消费者": "Kb4d2007f",
"消费者调用统计": "K61cca533",
"请选择消费者": "Kdfff59d4",
"调用趋势": "K8c7f2d2e",
"(0)-(1)调用趋势": "K657c3452",
"调用量统计": "Kc04efb87",
@@ -562,7 +591,7 @@
"请选择服务": "Kffcfe375",
"调用详情": "Ka65f739c",
"API 请求量 Top10": "K89b7ac79",
"消费者调用量 Top10": "Kc0915603",
"消费者调用量 Top10": "K386857bd",
"服务被调用量 Top10": "Kf90b54",
"暂无请求统计数据": "Kfb26388",
"请求统计": "Kc8cbd8f8",
@@ -585,9 +614,9 @@
"万": "Ke6a935d",
"搜索分类或标签": "Kd59290a2",
"暂无API数据": "K6b75bdbc",
"搜索或选择消费者": "Kd8a7a689",
"搜索或选择消费者": "Kb684c806",
"申请理由": "K4b15d6f5",
"消费者管理": "Kb7e869a4",
"消费者管理": "Ke0fbd1c8",
"鉴权类型": "Kb71b5a13",
"Iss": "K4d1465ee",
"签名算法": "K5dcd7ed8",
@@ -600,9 +629,9 @@
"SK": "K31418470",
"Apikey": "Kbfeb5297",
"隐藏鉴权信息": "Ke64e43a",
"消费者名称": "K5168eb63",
"消费者 ID": "K546e46f",
"删除消费者": "K95764d1d",
"消费者名称": "K67b530f",
"消费者 ID": "K11f34de",
"删除消费者": "Kc01002",
"鉴权详情": "K217cb125",
"添加鉴权": "K2bb63eca",
"编辑鉴权": "Kd74d69b7",
@@ -619,9 +648,11 @@
"请确认是否取消订阅申请?": "K1856c229",
"搜索服务": "K66ea2f0",
"审核中": "K8adf7f8b",
"添加消费者": "K667bbbe7",
"暂无服务描述": "Ka4b45550",
"添加消费者": "K84c4dc71",
"暂无消费者描述": "Kc3b7bfa8",
"创建并管理自己的消费者实体,每个消费者可以订阅多个API服务,确保在调用之前已获得相应权限。你可以为消费者生成 API 密钥等鉴权方式,用于安全地调用 API 服务": "K5c4e2865",
"订阅的服务数量:已通过 (0) 个,申请中 (1) 个": "K3c7b175f",
"输入名称、ID 查找消费者": "K3a6f905d",
"退出测试": "Kbe3e9335",
"服务市场": "K370a3eb2",
"服务详情": "Kf7ec36d",
@@ -630,14 +661,15 @@
"Base URL": "Kc29dabf2",
"申请": "K4aa9ed2c",
"服务信息": "K6c060779",
"接入消费者": "K8723422e",
"接入消费者": "Kba74f26d",
"供应方": "Kb97544cb",
"分类": "Kb32f0afe",
"版本": "K81634069",
"更新时间": "Keefda53d",
"无标签": "K96a2f1c8",
"暂无服务描述": "Ka4b45550",
"API 数量": "K72b0c0b3",
"接入消费者数量": "K93d5a66e",
"接入消费者数量": "K70b79760",
"关联标签": "K96059c69",
"更新者": "K8b7c2592",
"添加 Open Api": "K32263abd",
@@ -1,7 +1,6 @@
{
"Kc0e5ef9f": "Workspace",
"K4de11e23": "Home",
"Kfe93ef35": "Application",
"Kb58e0c3f": "Service",
"Kc9e489f5": "Team",
"K61c89f5f": "API Portal",
@@ -91,8 +90,6 @@
"K6206e4ad": "Upload OpenAPI File (.json/.yaml)",
"Kfba46e6d": "Replace OpenAPI File (.json/.yaml)",
"Kdac8ce7e": "Open OpenAPI YAML Editor",
"Kffd7e274": "No Review: All applications are allowed to subscribe to this service",
"K8a8b13e4": "Manual Review: Only reviewed and approved applications can subscribe to this service",
"Kbfe02d7f": "Permanent",
"K1e9c479e": "No",
"Kaddfcb6b": "Yes",
@@ -259,7 +256,6 @@
"Kc057704a": "Create AI Services and APIs",
"K76bb4a09": "Create AI-based services, and you can set the prompt as an API to simplify the process of using AI.",
"K71b2c70f": "Create Call Token",
"K9bdd8403": "To securely call APIs, you need to create an application and a token.",
"Kc5738b6c": "Call",
"Kd6d7ca1f": "You can now call these APIs with the token.",
"K86cf95f": "Quickly Integrate REST API",
@@ -269,13 +265,11 @@
"K2cdbb773": "Core Features",
"K3378c50d": "Account and Role",
"Kda5bb930": "Invite your team members to APIPark to collaboratively manage and call APIs.",
"Kc8239422": "Teams include personnel, applications, and services. Data between different teams is isolated, and can be used to manage different departments/project teams/teams within the enterprise.",
"Kd5be0cd7": "Services include a set of APIs and can be published to the API Marketplace for use by other teams.",
"K62e89ee7": "Permission Management",
"K8f7808e6": "Subscribe to Services",
"Kf2410413": "To call an API from a service, you need to subscribe to that service and wait for approval from the providing team before initiating the API request.",
"K6c2e44b8": "Review Subscription",
"Ka0a8840a": "Review subscription requests from other applications. Only approved requests can initiate API calls.",
"K3453272": "APIPark provides detailed API call logs, helping enterprises monitor, analyze, and audit API operations.",
"Kd518ba3e": "Hello! Welcome to APIPark",
"K7e04ea16": "🦄 APIPark is an open-source, all-in-one AI gateway and API developer portal, enabling enterprises and developers to quickly integrate over 100 AI models, combine AI models and prompts into new APIs, and standardize all AI request data formats, ensuring that switching AI models or adjusting prompts does not affect your APP or microservice. Additionally, APIParks developer portal allows you to share APIs within your team, manage applications that call your APIs, and ensure API security, while monitoring your AI API usage with clear charts.",
@@ -325,7 +319,7 @@
"Ka46b9b24": "Data Source Type",
"Kbb0cdcd0": "Data Source Address",
"Kd9dfb884": "Organization",
"K3e770a75": "Authentication Token",
"K3e770a75": "Credentials Token",
"K8ef69ee2": "Key",
"Kba3507d6": "Upload Key",
"K93ac0f23": "Key file suffix is usually .key",
@@ -371,7 +365,7 @@
"Kcef64f4d": "Default AI Provider",
"Kcab588a9": "No AI model provider set,",
"Kb9b56111": "Set Now",
"Kcf756b7a": "API Call Prefix",
"Kcf756b7a": "API Request Prefix",
"K13edc043": "As a prefix for all APIs in the service, e.g., host/{service_name}/{api_path}, cannot be modified once saved.",
"Kf52a584d": "Service Category",
"K72b21be5": "Set the category in which the service will be displayed in the service marketplace",
@@ -397,15 +391,14 @@
"K813e1c0a": "Team Name",
"K692f5aa6": "Team ID",
"K5de0bc2": "Team ID can be used to retrieve the team, cannot be modified once saved.",
"Ka63dd985": "Team Leader",
"Ka6bcd272": "The leader has management authority over the team, services, and members within the team",
"Ka63dd985": "Team Administrator",
"Ka6bcd272": "The Administrator has management authority over the team, services, and members within the team",
"Ka2012bdd": "Delete Team",
"Kbde1f3d": "Service data must be cleared before deletion",
"K395acc14": "Remove",
"Kec46a57f": "Add Member",
"K48724410": "Enter Name to Search",
"Kb9052305": "Search Username, Email",
"K5ece3bac": "Set up teams and members. You can then create services and applications, subscribe to APIs within the team. Members can only see services and applications within their team.",
"K510cdd27": "Add Team",
"K9244ae14": "Enter Name, ID, Person in Charge to Search Teams",
"Kc7b24b4b": "Configure Team",
@@ -425,8 +418,6 @@
"Ka2c794a2": "Export",
"Kaf70c3b": "Exit Fullscreen",
"Kd22841a4": "(0) Call Details",
"K1512e983": "Application Call Statistics",
"Kb4d2007f": "Please Select Application",
"K8c7f2d2e": "Call Trend",
"K657c3452": "(0)-(1) Call Trend",
"Kc04efb87": "Call Volume Statistics",
@@ -449,7 +440,6 @@
"Kffcfe375": "Please Select Service",
"Ka65f739c": "Call Details",
"K89b7ac79": "API Top 10",
"Kc0915603": "Application Top 10",
"Kf90b54": "Service Top 10",
"Kfb26388": "No Request Data",
"Kc8cbd8f8": "Request Statistics",
@@ -472,10 +462,8 @@
"Ke6a935d": "Ten Thousand",
"Kd59290a2": "Search Category or Tag",
"K6b75bdbc": "No API Data",
"Kd8a7a689": "Search or Select Application",
"K4b15d6f5": "Application Reason",
"Kb7e869a4": "Application Settings",
"Kb71b5a13": "Authentication Type",
"Kb71b5a13": "Credentials Type",
"K4d1465ee": "ISS",
"K5dcd7ed8": "Signature Algorithm",
"K5b0eedd3": "Secret",
@@ -487,13 +475,10 @@
"K31418470": "SK",
"Kbfeb5297": "API Key",
"K1a78e6f0": "Expiration Time",
"Ke64e43a": "Hide Authentication Info",
"K5168eb63": "Application Name",
"K546e46f": "Application ID",
"K95764d1d": "Delete Application",
"K217cb125": "Authentication Details",
"K2bb63eca": "Add Authentication",
"Kd74d69b7": "Edit Authentication",
"Ke64e43a": "Hide Credentials Info",
"K217cb125": "Credentials Details",
"K2bb63eca": "Add Credentials",
"Kd74d69b7": "Edit Credentials",
"K9cbe1e0": "Modify",
"Kb6e9328f": "Authorization",
"Kd23d1716": "Add Authorization",
@@ -507,7 +492,6 @@
"K1856c229": "Are you sure you want to cancel the subscription request?",
"K66ea2f0": "Search Services",
"K8adf7f8b": "Under Review",
"K667bbbe7": "Add Application",
"Ka4b45550": "No Service Description",
"K3c7b175f": "Number of Subscribed Services: (0) Approved, (1) Pending",
"Kbe3e9335": "Exit Test",
@@ -517,7 +501,6 @@
"K59cdbec3": "Intro",
"K4aa9ed2c": "Subscribe",
"K6c060779": "Service Information",
"K8723422e": "Access Application",
"Kb97544cb": "Provider",
"Kb32f0afe": "Category",
"K81634069": "Version",
@@ -525,7 +508,6 @@
"Keefda53d": "Update Time",
"K96a2f1c8": "No Tags",
"K72b0c0b3": "Number of APIs",
"K93d5a66e": "Number of Access Applications",
"K96059c69": "Associated Tags",
"K32263abd": "Add Open API",
"K7829bb78": "Configure Open API",
@@ -546,8 +528,6 @@
"Ke41d7451": "Read-Only Member",
"Kf99e8b66": "Service Administrator",
"Kda8db57a": "Service Developer",
"K216a1ac7": "Application Developer",
"K27924db": "Application Administrator",
"K8dc5c723": "Driver Name",
"Kda249fe8": "Failure",
"Kcf2df651": "Failure",
@@ -575,7 +555,6 @@
"K593e0c7e": "No Review Required",
"Ke2d747d9": "Review Required",
"Kc29dabf2": "Base URL",
"Kd55c6887": "Review",
"K300c89d4": "When creating an API, this provider is selected by default. Changing the default provider will not affect existing APIs.",
"Kefaf9956": "Create Time",
"Kad1c674c": "Protocol",
@@ -589,7 +568,6 @@
"Kcbf39b82": "Status",
"K339d15b5": "Creator",
"K7194cea2": "Review Time",
"K831aa6c0": "Applicant - Application",
"K7ad449bc": "Status",
"K3b3a98ce": "Reviewer",
"K61b62ace": "Source",
@@ -602,8 +580,8 @@
"Kd7d84192": "Name",
"Kc88e03b6": "Team Roles",
"Ke08ff808": "Addition Date",
"K19a3ebe0": "Successful Requests",
"Kcaa8259": "Successful Forwards",
"K19a3ebe0": "Success",
"Kcaa8259": "Success",
"K17f93984": "API",
"K888f038f": "Failed Status Code Count",
"Ke792d01c": "Service Association",
@@ -629,7 +607,7 @@
"Ke108c369": "Success",
"K9168d3e": "Redirecting to Login Page",
"K2f8a7ab7": "Review Comments Not Provided",
"Kb858d78a": "Copy Successful",
"Kb858d78a": "Copied",
"K26e85d15": "Copy Failed, Please Copy Manually",
"Kd60d204": "Service Team",
"K823bfe63": "Online",
@@ -646,5 +624,60 @@
"K29ec75dc": "Per Week",
"Kac172626": "Please provide a reason when rejecting the request.",
"Ke1b1865": "Private",
"K4786c57c": "Public"
"K4786c57c": "Public",
"K7acfcfad": "Consumer",
"Kc8054dba": "Consumer Developer",
"Keb1673a6": "Consumer Administrator",
"K1fc2cc28": "No Review: All consumers are allowed to subscribe to this service",
"K8dabb98e": "Manual Review: Only reviewed and approved consumers can subscribe to this service",
"K7c1fb123": "Applicant - Application",
"Kdea9a418": "To securely call APIs, you need to create an consumer and a token.",
"Keee27105": "Teams include personnel, consumers, and services. Data between different teams is isolated, and can be used to manage different departments/project teams/teams within the enterprise.",
"Kaa717866": "Review subscription requests from other consumers. Only approved requests can initiate API calls.",
"Kd2c34e2c": "AI Service",
"K62840d62": "REST Service",
"K4c72fb6f": "Set up teams and members. You can then create services and consumers, subscribe to APIs within the team. Members can only see services and applications within their team.",
"K61cca533": "Consumer Call Statistics",
"Kdfff59d4": "Please Select Consumer",
"K386857bd": "Consumer Top 10",
"Kb684c806": "Search or Select Consumer",
"Ke0fbd1c8": "Consumer Settings",
"K67b530f": "Consumer Name",
"K11f34de": "Consumer ID",
"Kc01002": "Delete Consumer",
"K84c4dc71": "Add Consumer",
"K5c4e2865": "Create and manage your own consumer entities, with each consumer able to subscribe to multiple API services, ensuring the necessary permissions are obtained before making any calls. You can generate API keys or other credentials for consumers to securely call API services.",
"K40a89bd8": "Enter Name, ID to Search Member",
"Kba74f26d": "Access Consumer",
"K70b79760": "Number of Access Consumers",
"K93c2696e": "Online Result",
"K6e32a344": "Number of Services",
"Ka701316": "Number of Auths",
"K9eaa2eb6": "List",
"Kfaec39e9": "Block",
"Kc3b7bfa8": "No Consumer Description",
"K3a6f905d": "Enter Name, ID to Search Consumer",
"K76036e25": "HTTP Request Header",
"K44607e3f": "Exact Match",
"Kc287500a": "Prefix Match",
"Kfc0b1147": "Suffix Match",
"Ka4a92043": "Substring Match",
"K30b2e44f": "Non-Exact Match",
"Kb1587991": "Null Match",
"K87c5a801": "Case-Sensitive Regex Match",
"K95f062f1": "Case-Insensitive Regex Match",
"Kfbd230a5": "Any Match",
"Kd85208a3": "Reject",
"Kad6aa439": "Subscribed",
"K9a68443b": "Cancel Request",
"Kaeba0229": "Pass-through Client Request Host",
"K6d7e2fd0": "Use Upstream Service Host",
"K31332633": "Rewrite Host",
"K2c2bc64f": "Dynamic Service Discovery",
"K78b1ca25": "Address",
"K1644b775": "Add",
"Kc8ee3e62": "Non-Existence",
"K1e97dbd8": "Existence",
"Kec91f0db": "Applicant Consumer",
"Kf5fd27ed": "Enter Name to Search User"
}
@@ -646,5 +646,60 @@
"Kfcda87fc": "毎日",
"K29ec75dc": "毎週",
"Ke1b1865": "プライベート",
"K4786c57c": "パブリック"
"K4786c57c": "パブリック",
"K7acfcfad": "コンシューマー",
"Kc8054dba": "コンシューマー開発者",
"Keb1673a6": "コンシューマー管理者",
"K1fc2cc28": "審査不要:どのコンシューマーでもこのサービスを呼び出せます",
"K8dabb98e": "手動審査:手動審査に合格したコンシューマーのみ、このサービスを呼び出せます",
"K7c1fb123": "申請元-コンシューマー",
"K93c2696e": "オンライン結果",
"K6e32a344": "サブスクライブサービス数",
"Ka701316": "認証数",
"K9eaa2eb6": "リスト",
"Kfaec39e9": "ブロック",
"Kdea9a418": "API を安全に呼び出すためには、コンシューマーとトークンを作成する必要があります。",
"Keee27105": "チームにはメンバー、コンシューマー、サービスが含まれ、異なるチームのコンシューマーとサービスデータは分離されています。企業内の部門やプロジェクトチームの管理に役立ちます。",
"Kaa717866": "サービスを提供するチームは、他のチームからのサブスクリプション申請を審査できます。審査に合格したコンシューマーのみ API リクエストを行うことができます。",
"Kd2c34e2c": "AI サービス",
"K62840d62": "REST サービス",
"K4c72fb6f": "チームとメンバーを設定してから、チーム内でサービスとコンシューマーを作成し、API をサブスクライブできます。メンバーは所属チーム内のサービスとコンシューマーのみを表示できます。",
"K61cca533": "コンシューマー呼び出し統計",
"Kdfff59d4": "コンシューマーを選択してください",
"K386857bd": "コンシューマー呼び出し量トップ10",
"Kb684c806": "コンシューマーを検索または選択",
"Ke0fbd1c8": "コンシューマー管理",
"K67b530f": "コンシューマー名",
"K11f34de": "コンシューマー ID",
"Kc01002": "コンシューマーを削除",
"K40a89bd8": "名前または ID を入力してサービスを検索",
"Kba74f26d": "コンシューマーを接続",
"K70b79760": "接続コンシューマー数",
"K5c4e2865": "コンシューマーエンティティを作成および管理し、各コンシューマーは複数の API サービスにサブスクライブできます。呼び出し前に適切な権限が付与されていることを確認してください。コンシューマー用に API キーなどの認証方法を生成して、安全に API サービスを呼び出せます。",
"K84c4dc71": "コンシューマーを追加",
"Kc3b7bfa8": "コンシューマーの説明がありません",
"K3a6f905d": "名前、IDを入力してコンシューマーを検索",
"K76036e25": "HTTPリクエストヘッダー",
"K44607e3f": "完全一致",
"Kc287500a": "プレフィックス一致",
"Kfc0b1147": "サフィックス一致",
"Ka4a92043": "部分一致",
"K30b2e44f": "非完全一致",
"Kb1587991": "ヌル一致",
"K87c5a801": "大文字小文字を区別する正規表現一致",
"K95f062f1": "大文字小文字を区別しない正規表現一致",
"Kfbd230a5": "任意一致",
"Kd85208a3": "拒否",
"Kad6aa439": "申し込み済み",
"K9a68443b": "申し込み取消",
"Kaeba0229": "クライアントリクエストホストのパススルー",
"K6d7e2fd0": "上位サービスホストの使用",
"K31332633": "ホストの書き換え",
"K2c2bc64f": "動的サービス発見",
"K78b1ca25": "アドレス",
"K1644b775": "追加",
"Kc8ee3e62": "存在しない",
"K1e97dbd8": "存在する",
"Kec91f0db": "申請側コンシューマー",
"Kf5fd27ed": "名前を入力してユーザーを検索"
}
@@ -0,0 +1,3 @@
{
"Kf5fd27ed": "输入名称查找用户"
}
@@ -0,0 +1,3 @@
{
"Kf5fd27ed": "输入名称查找用户"
}
@@ -0,0 +1,27 @@
{
"K76036e25": "HTTP 请求头",
"K44607e3f": "全等匹配",
"Kc287500a": "前缀匹配",
"Kfc0b1147": "后缀匹配",
"Ka4a92043": "子串匹配",
"K30b2e44f": "非等匹配",
"Kb1587991": "空值匹配",
"K1e97dbd8": "存在匹配",
"Kc8ee3e62": "不存在匹配",
"K87c5a801": "区分大小写的正则匹配",
"K95f062f1": "不区分大小写的正则匹配",
"Kfbd230a5": "任意匹配",
"Kd85208a3": "驳回",
"Kad6aa439": "已订阅",
"K9a68443b": "取消申请",
"Kaeba0229": "透传客户端请求 Host",
"K6d7e2fd0": "使用上游服务 Host",
"K31332633": "重写 Host",
"K2c2bc64f": "动态服务发现",
"K78b1ca25": "地址",
"K1644b775": "新增",
"Kec91f0db": "申请方消费者",
"Kf5fd27ed": "输入名称查找用户",
"Kc3b7bfa8": "暂无消费者描述",
"K3a6f905d": "输入名称、ID 查找消费者"
}
@@ -0,0 +1,3 @@
{
"Kf5fd27ed": "输入名称查找用户"
}
@@ -0,0 +1,4 @@
{
"Kb9052305": "Search Username, Email",
"K40a89bd8": "Enter Name, ID to Search Member"
}
@@ -0,0 +1,26 @@
{
"Kfe93ef35": "Application",
"Kffd7e274": "無審査:すべてのアプリケーションがこのサービスにサブスクライブできます",
"K8a8b13e4": "手動審査:承認されたアプリケーションのみがこのサービスにサブスクライブできます",
"K9bdd8403": "API を安全に呼び出すためには、アプリケーションとトークンを作成する必要があります。",
"Kc8239422": "チームにはユーザー、アプリケーション、サービスが含まれ、異なるチームのアプリケーションとサービスのデータは分離されています。企業内の部門/プロジェクトグループ/チームの管理に使用できます。",
"Ka0a8840a": "他のアプリケーションのサブスクリプション申請をレビューし、承認後に API リクエストが発行できます。",
"Kb9052305": "ユーザー名またはメールを検索",
"K5ece3bac": "チームとメンバーを設定してから、チーム内でサービスとアプリケーションを作成し、API をサブスクライブできます。メンバーは所属チーム内のサービスとアプリケーションのみを表示できます。",
"K1512e983": "アプリケーション呼び出し統計",
"Kb4d2007f": "Application を選択",
"Kc0915603": "Application トップ10",
"Kd8a7a689": "アプリケーションを検索または選択",
"Kb7e869a4": "アプリケーション管理",
"K5168eb63": "Application 名",
"K546e46f": "Application ID",
"K95764d1d": "Application を削除",
"K667bbbe7": "Application を追加",
"K8723422e": "アプリケーションを接続",
"K93d5a66e": "接続アプリケーション数",
"K216a1ac7": "アプリケーション開発者",
"K27924db": "アプリケーション管理者",
"Kd55c6887": "レビュー",
"K831aa6c0": "申請元-アプリケーション",
"K40a89bd8": "名前または ID を入力してサービスを検索"
}
@@ -0,0 +1,26 @@
{
"Kfe93ef35": "消费者",
"Kffd7e274": "无审核:允许所有消费者订阅该服务",
"K8a8b13e4": "人工审核:仅允许审核通过的消费者订阅该服务",
"K9bdd8403": "为了安全地调用 API,你需要创建一个消费者以及Token。",
"Kc8239422": "团队中包含了人员、消费者和服务,不同团队之间的消费者和服务数据是隔离的,可用于管理企业内部不同的部门/项目组/团队。",
"Ka0a8840a": "审核其他消费者的订阅申请,审核通过后的才可发起 API 请求。",
"Kb9052305": "搜索用户名、邮箱",
"K5ece3bac": "设置团队和成员,然后你可以在团队内创建服务和消费者、订阅API,成员只能看到所属团队内的服务和消费者。",
"K1512e983": "消费者调用统计",
"Kb4d2007f": "请选择消费者",
"Kc0915603": "消费者 Top10",
"Kd8a7a689": "搜索或选择消费者",
"Kb7e869a4": "消费者管理",
"K5168eb63": "消费者名称",
"K546e46f": "消费者 ID",
"K95764d1d": "删除消费者",
"K667bbbe7": "添加消费者",
"K8723422e": "接入消费者",
"K93d5a66e": "接入消费者数量",
"K216a1ac7": "消费者开发者",
"K27924db": "消费者管理员",
"Kd55c6887": "审核",
"K831aa6c0": "申请方-消费者",
"K40a89bd8": "输入名称、ID 查找服务"
}
@@ -0,0 +1,26 @@
{
"Kfe93ef35": "應用程式",
"Kffd7e274": "無審核:允許所有應用程式訂閱該服務",
"K8a8b13e4": "人工審核:僅允許審核通過的應用程式訂閱該服務",
"K9bdd8403": "為了安全地調用 API,你需要創建一個應用以及Token。",
"Kc8239422": "團隊中包含了人員、應用程式和服務,不同團隊之間的應用程式和服務數據是隔離的,可用於管理企業內部不同的部門/項目組/團隊。",
"Ka0a8840a": "審核其他應用程式的訂閱申請,審核通過後的才可發起 API 請求。",
"Kb9052305": "搜索用戶名、電郵",
"K5ece3bac": "設置團隊和成員,然後你可以在團隊內創建服務和應用程式、訂閱API,成員只能看到所屬團隊內的服務和應用程式。",
"K1512e983": "應用程式調用統計",
"Kb4d2007f": "請選擇應用程式",
"Kc0915603": "應用程式 Top10",
"Kd8a7a689": "搜索或選擇應用程式",
"Kb7e869a4": "應用程式管理",
"K5168eb63": "應用程式名稱",
"K546e46f": "應用程式 ID",
"K95764d1d": "刪除應用程式",
"K667bbbe7": "添加應用程式",
"K8723422e": "接入應用程式",
"K93d5a66e": "接入應用程式數量",
"K216a1ac7": "應用程式開發者",
"K27924db": "應用程式管理員",
"Kd55c6887": "審核",
"K831aa6c0": "申請方-應用程式",
"K40a89bd8": "輸入名稱、ID 查找服務"
}
@@ -646,5 +646,37 @@
"Kfcda87fc": "每天",
"K29ec75dc": "每周",
"Ke1b1865": "私有",
"K4786c57c": "公共"
"K4786c57c": "公共",
"K7acfcfad": "消费者",
"Kc8054dba": "消费者开发者",
"Keb1673a6": "消费者管理员",
"K1fc2cc28": "无需审核:允许任何消费者调用该服务",
"K8dabb98e": "人工审核:仅允许通过人工审核的消费者调用该服务",
"K7c1fb123": "申请方-消费者",
"Kdea9a418": "为了安全地调用 API,你需要创建一个消费者以及Token。",
"Keee27105": "团队中包含了人员、消费者和服务,不同团队之间的消费者和服务数据是隔离的,可用于管理企业内部不同的部门/项目组/团队。",
"Kaa717866": "提供服务的团队可以审核来自其他团队的订阅申请,审核通过后的消费者才可发起 API 请求。",
"Kd2c34e2c": "AI 服务",
"K62840d62": "REST 服务",
"K4c72fb6f": "设置团队和成员,然后你可以在团队内创建服务和消费者、订阅API,成员只能看到所属团队内的服务和消费者。",
"K61cca533": "消费者调用统计",
"Kdfff59d4": "请选择消费者",
"K386857bd": "消费者调用量 Top10",
"Kb684c806": "搜索或选择消费者",
"Ke0fbd1c8": "消费者管理",
"K67b530f": "消费者名称",
"K11f34de": "消费者 ID",
"Kc01002": "删除消费者",
"K84c4dc71": "添加消费者",
"K5c4e2865": "创建并管理自己的消费者实体,每个消费者可以订阅多个API服务,确保在调用之前已获得相应权限。你可以为消费者生成 API 密钥等鉴权方式,用于安全地调用 API 服务",
"K40a89bd8": "输入名称、ID 查找服务",
"Kba74f26d": "接入消费者",
"K70b79760": "接入消费者数量",
"K93c2696e": "上线结果",
"K6e32a344": "订阅服务数量",
"Ka701316": "鉴权数量",
"K9eaa2eb6": "列表",
"Kfaec39e9": "块",
"Kc3b7bfa8": "暂无消费者描述",
"K3a6f905d": "输入名称、ID 查找消费者"
}
@@ -646,5 +646,60 @@
"Kfcda87fc": "每天",
"K29ec75dc": "每週",
"Ke1b1865": "私有",
"K4786c57c": "公共"
"K4786c57c": "公共",
"K7acfcfad": "消費者",
"Kc8054dba": "消費者開發者",
"Keb1673a6": "消費者管理員",
"K1fc2cc28": "無需審核:允許任何消費者調用該服務",
"K8dabb98e": "人工審核:僅允許通過人工審核的消費者調用該服務",
"K7c1fb123": "申請方-消費者",
"K93c2696e": "上線結果",
"K6e32a344": "訂閱服務數量",
"Ka701316": "鑒權數量",
"K9eaa2eb6": "列表",
"Kfaec39e9": "塊",
"Kdea9a418": "為了安全地調用 API,你需要創建一個消費者以及Token。",
"Keee27105": "團隊中包含了人員、消費者和服務,不同團隊之間的消費者和服務數據是隔離的,可用於管理企業內部不同的部門/項目組/團隊。",
"Kaa717866": "提供服務的團隊可以審核來自其他團隊的訂閱申請,審核通過後的消費者才可發起 API 請求。",
"Kd2c34e2c": "AI 服務",
"K62840d62": "REST 服務",
"K4c72fb6f": "設置團隊和成員,然後你可以在團隊內創建服務和消費者、訂閱API,成員只能看到所屬團隊內的服務和消費者。",
"K61cca533": "消費者調用統計",
"Kdfff59d4": "請選擇消費者",
"K386857bd": "消費者調用量 Top10",
"Kb684c806": "搜索或選擇消費者",
"Ke0fbd1c8": "消費者管理",
"K67b530f": "消費者名稱",
"K11f34de": "消費者 ID",
"Kc01002": "刪除消費者",
"K84c4dc71": "添加消費者",
"K5c4e2865": "創建並管理自己的消費者實體,每個消費者可以訂閱多個API服務,確保在調用之前已獲得相應權限。你可以為消費者生成 API 密鑰等鑒權方式,用於安全地調用 API 服務",
"K40a89bd8": "輸入名稱、ID 查找服務",
"Kba74f26d": "接入消費者",
"K70b79760": "接入消費者數量",
"Kc3b7bfa8": "暫無消費者描述",
"K3a6f905d": "輸入名稱、ID 查找消費者",
"K76036e25": "HTTP請求頭",
"K44607e3f": "全等匹配",
"Kc287500a": "前綴匹配",
"Kfc0b1147": "後綴匹配",
"Ka4a92043": "子串匹配",
"K30b2e44f": "非等匹配",
"Kb1587991": "空值匹配",
"K87c5a801": "區分大小寫的正則匹配",
"K95f062f1": "不區分大小寫的正則匹配",
"Kfbd230a5": "任意匹配",
"Kd85208a3": "駁回",
"Kad6aa439": "已訂閱",
"K9a68443b": "取消申請",
"Kaeba0229": "透傳客戶端請求Host",
"K6d7e2fd0": "使用上游服務Host",
"K31332633": "重寫Host",
"K2c2bc64f": "動態服務發現",
"K78b1ca25": "位址",
"K1644b775": "新增",
"Kc8ee3e62": "不存在匹配",
"K1e97dbd8": "存在匹配",
"Kec91f0db": "申請方消費者",
"Kf5fd27ed": "輸入名稱查找使用者"
}
@@ -13,10 +13,15 @@ export const checkAccess:(access:AccessDataType, accessData:Map<string,string[]>
return false
}
const neededBackendAccessArr = PERMISSION_DEFINITION[0]?.[access]?.granted?.anyOf[0].backend || []
return accessData?.has(accLevel)&& accessData.get(accLevel)!.length > 0 ? hasIntersection(neededBackendAccessArr, accessData.get(accLevel)!) : false
let accessSet = new Set(accessData.get('system'))
if(accLevel === 'team'){
accessSet = new Set(Array.from(accessSet).concat(accessData?.get('team') || []))
}
return accessSet!.size > 0 ? hasIntersection(neededBackendAccessArr, accessSet) : false
}
const hasIntersection = (arr1:string[], arr2:string[])=> {
const hasIntersection = (arr1:string[], set1:Set<string>)=> {
const arr2 = Array.from(set1)
const set = new Set(arr1.length > arr2.length ? arr2:arr1)
const arr = arr1.length > arr2.length ? arr1:arr2
for (const item of arr) {
+1 -6
View File
@@ -1,9 +1,4 @@
/*
* @Date: 2024-06-04 15:05:05
* @LastEditors: maggieyyy
* @LastEditTime: 2024-08-01 17:59:56
* @FilePath: \frontend\packages\common\tailwind.config.js
*/
/** @type {import('tailwindcss').Config} */
module.exports = {
important:true,
+26 -6
View File
@@ -1,16 +1,36 @@
<!doctype html>
<html lang="en">
<head>
<head id="head">
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/frontend/favicon.ico" />
<link id="favicon" rel="icon" type="image/svg+xml" href="/frontend/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>APIPark - 企业API数据开放平台</title>
</head>
<body>
<body id="eo-body">
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
<script async src="/frontend/iconpark_eolink.js"></script>
<script async src="/frontend/iconpark_apinto.js"></script>
<script>
document.addEventListener('DOMContentLoaded', () => {
const eoBody = document.getElementById('eo-body');
const favicon = document.getElementById('favicon');
const createScript = (id, src) => {
const script = document.createElement('script');
script.id = id;
script.async = true;
script.src = src;
return script;
};
const iconparkApintoSrc = window.location.hostname === 'localhost' ? '/iconpark_apinto.js' : '/frontend/iconpark_apinto.js';
const iconparkEolinkSrc = window.location.hostname === 'localhost' ? '/iconpark_eolink.js' : '/frontend/iconpark_eolink.js';
const faviconSrc = window.location.hostname === 'localhost' ? '/favicon.ico' : '/frontend/favicon.ico';
favicon.href = faviconSrc;
eoBody.appendChild(createScript('iconpark_apinto', iconparkApintoSrc));
eoBody.appendChild(createScript('iconpark_eolink', iconparkEolinkSrc));
});
</script>
</body>
</html>
+1 -6
View File
@@ -1,9 +1,4 @@
/*
* @Date: 2023-11-27 17:31:54
* @LastEditors: maggieyyy
* @LastEditTime: 2024-06-05 10:42:18
* @FilePath: \frontend\packages\core\postcss.config.js
*/
export default {
plugins: {
'postcss-import': {},
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+10
View File
@@ -290,3 +290,13 @@ a{
transition: background-color 0s 600000s, color 0s 600000s !important;
}
}
.ant-select-selection-overflow-item:first-child {
max-width: calc(100% - 60px);
margin-right: 4px;
}
a[disabled]:hover {
color: #BBB;
cursor: not-allowed;
}
@@ -35,6 +35,7 @@ export type MemberDropdownModalFieldType = {
parent?:string
email?:string
departmentIds?:string[]
password:string
};
export type MemberDropdownModalProps = {
@@ -137,7 +137,7 @@ const ServiceInsideDocument = ()=>{
<div className=" pl-[8px] py-btnbase ">
<div className="flex justify-between items-center">
<p className="text-[14px] leading-[20px] text-[#999999]"><span className="mr-[20px]">{$t('最近一次更新者')}{updater || '-'}</span><span>{$t('最近一次更新时间')}{updateTime || '-'}</span></p>
<WithPermission access="team.service.service.edit"><Button type="primary" className="mr-btnbase" onClick={save}>{$t('保存')}</Button></WithPermission>
<WithPermission access="team.service.service_intro.edit"><Button type="primary" className="mr-btnbase" onClick={save}>{$t('保存')}</Button></WithPermission>
</div>
</div>
</div>)
@@ -42,6 +42,7 @@ const AiServiceInsidePage:FC = ()=> {
const getApiDefine = ()=>{
console.log('@@@@@@@')
setApiPrefix('')
setPrefixForce(false)
fetchData<BasicResponse<{ prefix:string, force:boolean }>>('service/router/define',{method:'GET',eoParams:{service:serviceId,team:teamId}}).then(response=>{
@@ -62,7 +63,7 @@ const AiServiceInsidePage:FC = ()=> {
[
getItem(<Link to="./route">{$t('API 路由')}</Link>, 'route',undefined,undefined,undefined,'team.service.router.view'),
getItem(<Link to="./api">{$t('API 文档')}</Link>, 'api',undefined,undefined,undefined,'team.service.api_doc.view'),
getItem(<Link to="./document">{$t('使用说明')}</Link>, 'document',undefined,undefined,undefined,''),
getItem(<Link to="./document">{$t('使用说明')}</Link>, 'document',undefined,undefined,undefined,'team.service.service_intro.view'),
getItem(<Link to="./publish">{$t('发布')}</Link>, 'publish',undefined,undefined,undefined,'team.service.release.view'),
],
'group'),
@@ -84,19 +85,22 @@ const AiServiceInsidePage:FC = ()=> {
const filterMenu = (menu:MenuItemGroupType<MenuItemType>[])=>{
const newMenu = cloneDeep(menu)
return newMenu!.filter((m:MenuItemGroupType )=>{
if(m.children && m.children.length > 0){
if(m&&m.children && m.children.length > 0){
m.children = m.children.filter(
(c)=>(c&&(c as MenuItemType&{access:string} ).access ?
(c)=>{
if(!c) return false
return (((c as MenuItemType&{access:string} ).access ?
checkPermission((c as MenuItemType&{access:string} ).access as keyof typeof PERMISSION_DEFINITION[0]):
true))
true))})
}
return m.children && m.children.length > 0
})
}
const filteredMenu = filterMenu(SYSTEM_PAGE_MENU_ITEMS as MenuItemGroupType<MenuItemType>[])
setActiveMenu((pre)=>{
return pre ?? 'route'
})
const menu = activeMenu ?? filteredMenu[0]?.children ? filteredMenu[0]?.children?.[0]?.key : filteredMenu[0]?.key
if(menu && currentUrl.split('/')[-1] !== menu){
navigateTo(`/service/${teamId}/aiInside/${serviceId}/${menu}`)
}
return filteredMenu || []
},[accessData,accessInit, SYSTEM_PAGE_MENU_ITEMS])
@@ -116,7 +120,7 @@ const AiServiceInsidePage:FC = ()=> {
}, [currentUrl]);
useEffect(()=>{
if(accessData && accessData.get('team') && accessData.get('team')?.indexOf('team.service.router.view') !== -1){
if(accessData && checkPermission('team.service.router.view')){
getApiDefine()
}
},[accessData])
@@ -256,7 +256,7 @@ const AiServiceInsideRouterCreate = () => {
</Form.Item>
<Form.Item label={$t("请求路径")}>
<Form.Item className="flex-1" label={$t("请求路径")}>
<Space.Compact block>
<Form.Item
name="pathMatch"
@@ -276,7 +276,7 @@ const AiServiceInsideRouterCreate = () => {
}]}
noStyle
>
<Input prefix={(prefixForce ? `${apiPrefix}/` :"/")} className="w-INPUT_NORMAL"
<Input prefix={(prefixForce ? `${apiPrefix}/` :"/")}
placeholder={$t(PLACEHOLDER.input)} onChange={(e)=>{
if((e.target.value as string).endsWith('/*')){
form.setFieldValue('path',e.target.value.slice(0,-2))
@@ -18,6 +18,7 @@ export type AiServiceRouterModelConfigProps = {
}
type AiServiceRouterModelConfigField = {
provider:string
id:string
config:string
}
@@ -70,6 +71,10 @@ const AiServiceRouterModelConfig = forwardRef<AiServiceRouterModelConfigHandle,
getLlmList(provider)
}
useEffect(()=>{
getLlmList(entity.provider)
},[])
return (
<Form
layout='vertical'
@@ -4,12 +4,11 @@ import { BasicResponse, STATUS_CODE, RESPONSE_TIPS } from "@common/const/const";
import { useFetch } from "@common/hooks/http";
import { $t } from "@common/locales";
import { Icon } from "@iconify/react/dist/iconify.js";
import { App, Spin, Card, Tag, Select, Button, Empty, Divider } from "antd";
import { App, Spin, Card, Tag, Button, Empty, Divider } from "antd";
import { memo, useEffect, useRef, useState } from "react";
import AiSettingModalContent, { AiSettingModalContentHandle } from "./AiSettingModal";
import WithPermission from "@common/components/aoplatform/WithPermission";
import { useGlobalContext } from "@common/contexts/GlobalStateContext";
import { DefaultOptionType } from "antd/es/select";
import { checkAccess } from "@common/utils/permission";
export type AiSettingListItem = {
@@ -90,7 +89,7 @@ const AiSettingList = ()=>{
}
modal.confirm({
title:$t('模型配置'),
content:<AiSettingModalContent ref={modalRef} entity={data.provider} readOnly={!checkAccess('system.devops.ai_provider.edit', accessData)}/>,
content:<AiSettingModalContent ref={modalRef} entity={{...data.provider,defaultLlm:entity.defaultLlm}} readOnly={!checkAccess('system.devops.ai_provider.edit', accessData)}/>,
onOk:()=>{
return modalRef.current?.save().then((res)=>{if(res === true)
setAiConfigFlushed(true)
@@ -125,48 +124,12 @@ const AiSettingList = ()=>{
}, []);
const CardBox = memo(({provider}:{provider:AiSettingListItem})=>{
const [options, setOptions] = useState<DefaultOptionType[]>([])
const [loading, setLoading] = useState<boolean>(false)
const [defaultLlm, setDefaultLlm] = useState<string>(provider.defaultLlm)
const getLlmList = ()=>{
if(options.length > 0) return
setLoading(true)
fetchData<BasicResponse<{llms:AiProviderLlmsItems[]}>>(`ai/provider/llms`,{method:'GET',eoParams:{provider:provider.id}}).then(response=>{
const {code,data,msg} = response
if(code === STATUS_CODE.SUCCESS){
setOptions(data.llms?.map((x:AiProviderLlmsItems)=>({
label:<span className="w-full truncate">{x.id}</span>,
value:x.id})))
}else{
message.error(msg || $t(RESPONSE_TIPS.error))
}
}).finally(()=>{
setLoading(false)
})
}
const changeDefaultModel = (value: string, entity:AiSettingListItem) => {
setLoading(true)
return fetchData<BasicResponse<null>>(`ai/provider/default-llm`,{method:'PUT', eoBody:{llm:value}, eoParams:{provider:entity.id}}).then(response=>{
const {code,msg} = response
if(code === STATUS_CODE.SUCCESS){
setDefaultLlm(value)
message.success(msg || $t(RESPONSE_TIPS.success))
}else{
message.error(msg || $t(RESPONSE_TIPS.error))
}
}).finally(()=>setLoading(false))
};
return (
<Card title={
<div className="flex items-center justify-between">
<div className="flex items-center gap-[4px]">
<div className="flex w-full items-center justify-between gap-[4px]">
<div className="flex flex-1 overflow-hidden items-center gap-[4px]">
<span className=" flex items-center h-[22px] ai-setting-svg-container" dangerouslySetInnerHTML={{ __html: provider.logo }} ></span>
<span className="font-normal">{provider.name}</span>
<span className="font-normal truncate">{provider.name}</span>
</div>
<Tag bordered={false} color={provider.configured ? 'green' : undefined} className="h-[22px] px-[4px] text-center">
{provider.configured ? $t('已配置') : $t('未配置')}
@@ -178,23 +141,12 @@ const AiSettingList = ()=>{
<div className="flex flex-col justify-between h-full gap-btnbase ">
<div className="flex items-center w-full h-[32px] flex-1">{
provider.configured && <><label className="text-nowrap">{$t('默认')}</label>
<WithPermission access="system.devops.ai_provider.edit">
<Select
value={defaultLlm}
variant="borderless"
className="flex-1 overflow-hidden"
// style={{ width: '100%' }}
onChange={(value)=>changeDefaultModel(value, provider)}
options={options}
onFocus={()=> getLlmList()}
loading={loading }
/>
</WithPermission>
<span className="flex-1 overflow-hidden truncate">{provider.defaultLlm}</span>
</>
}
</div>
<WithPermission access="system.devops.ai_provider.view">
<WithPermission access="system.settings.ai_provider.view">
<Button block icon={<Icon icon="ic:outline-settings" width={18} height={18}/>} onClick={()=>openModal(provider)} classNames={{icon:'h-[18px]'}}>{$t('设置')}</Button>
</WithPermission>
</div>
@@ -248,8 +200,8 @@ const AiSettingList = ()=>{
aiSettingList.filter((item)=>!item.configured).length > 0 && <>
<Divider style={{margin:'20px 0 !important;'}} />
<p className="text-[14px] text-[#666] mb-[4px] mt-[20px] font-bold">{$t('未配置')}</p>
<ModelCardArea modelList={aiSettingList.filter((item)=>!item.configured) || [] }/>
</>
<ModelCardArea modelList={aiSettingList.filter((item)=>!item.configured) || [] }/>
</>
}
</div>:<Empty image={Empty.PRESENTED_IMAGE_SIMPLE}/>}
</Spin>
@@ -1,15 +1,14 @@
import WithPermission from "@common/components/aoplatform/WithPermission";
import { BasicResponse, STATUS_CODE, RESPONSE_TIPS } from "@common/const/const";
import { BasicResponse, STATUS_CODE, RESPONSE_TIPS, PLACEHOLDER } from "@common/const/const";
import { useFetch } from "@common/hooks/http";
import { $t } from "@common/locales";
import { App } from "antd";
import { App, Form, Select, Tag } from "antd";
import { forwardRef, useEffect, useImperativeHandle, useState } from "react";
import { AiProviderConfig } from "./AiSettingList";
import { AiProviderConfig, AiProviderLlmsItems } from "./AiSettingList";
import { Codebox } from "@common/components/postcat/api/Codebox";
export type AiSettingModalContentProps = {
entity:AiProviderConfig
entity:AiProviderConfig & {defaultLlm:string}
readOnly:boolean
}
@@ -17,31 +16,65 @@ export type AiSettingModalContentHandle = {
save:()=>Promise<boolean|string>
}
type AiSettingModalContentField = {
config:string
defaultLlm:string
}
const AiSettingModalContent = forwardRef<AiSettingModalContentHandle,AiSettingModalContentProps>((props,ref)=>{
const [form] = Form.useForm();
const { message } = App.useApp()
const {entity,readOnly} = props
const {fetchData} = useFetch()
const [code, setCode] = useState<string>()
const [llmList, setLlmList] = useState<AiProviderLlmsItems[]>()
const [loading, setLoading] = useState<boolean>(false)
const getLlmList = ()=>{
setLoading(true)
fetchData<BasicResponse<{llms:AiProviderLlmsItems[]}>>(`ai/provider/llms`,{method:'GET',eoParams:{provider:entity.id}}).then(response=>{
const {code,data,msg} = response
if(code === STATUS_CODE.SUCCESS){
setLlmList(data.llms)
}else{
message.error(msg || $t(RESPONSE_TIPS.error))
}
}).finally(()=>{
setLoading(false)
})
}
useEffect(() => {
getLlmList()
try{
entity!.config && setCode(JSON.stringify(JSON.parse(entity!.config),null,2))
form.setFieldsValue({
defaultLlm:entity.defaultLlm,
config:entity!.config ? JSON.stringify(JSON.parse(entity!.config),null,2) : ''
})
}catch(e){
setCode('')
form.setFieldsValue({
defaultLlm:entity.defaultLlm,
config: ''
})
}
}, []);
const save: ()=>Promise<boolean | string> = ()=>{
return fetchData<BasicResponse<null>>('ai/provider/config',{method:'PUT',eoParams:{provider:entity?.id}, eoBody:({config:code})}).then(response=>{
const {code,msg} = response
if(code === STATUS_CODE.SUCCESS){
message.success(msg || $t(RESPONSE_TIPS.success))
return Promise.resolve(true)
}else{
message.error(msg || $t(RESPONSE_TIPS.error))
return Promise.reject(msg || $t(RESPONSE_TIPS.error))
}
}).catch((errorInfo)=> Promise.reject(errorInfo))
return new Promise((resolve, reject)=>{
form.validateFields().then((value)=>{
fetchData<BasicResponse<null>>('ai/provider/config',{method:'PUT',eoParams:{provider:entity?.id}, eoBody:value, eoTransformKeys:['defaultLlm']}).then(response=>{
const {code,msg} = response
if(code === STATUS_CODE.SUCCESS){
message.success(msg || $t(RESPONSE_TIPS.success))
resolve(true)
}else{
message.error(msg || $t(RESPONSE_TIPS.error))
reject(msg || $t(RESPONSE_TIPS.error))
}
}).catch((errorInfo)=> reject(errorInfo))
}).catch((errorInfo)=> reject(errorInfo))
})
}
useImperativeHandle(ref, ()=>({
@@ -50,8 +83,41 @@ const AiSettingModalContent = forwardRef<AiSettingModalContentHandle,AiSettingMo
)
return (
<Codebox editorTheme="vs-dark" readOnly={readOnly}
value={code} onChange={setCode} width="100%" height="300px" language='json' enableToolbar={false} />
<Form
layout='vertical'
labelAlign='left'
scrollToFirstError
form={form}
className="mx-auto flex flex-col h-full"
name="aiServiceInsideRouterModalConfig"
autoComplete="off"
>
<Form.Item<AiSettingModalContentField>
label={$t("模型")}
name="defaultLlm"
rules={[{ required: true }]}
>
<Select className="w-INPUT_NORMAL"
placeholder={$t(PLACEHOLDER.select)}
loading={loading}
options={llmList?.map(x=>({
value:x.id,
label:<div className="flex items-center gap-[10px]">
<span>{x.id}</span>
{x?.scopes?.map(s=><Tag >{s?.toLocaleUpperCase()}</Tag>)}
</div>}))}>
</Select>
</Form.Item>
<Form.Item<AiSettingModalContentField>
label={$t("参数")}
name="config"
>
<Codebox editorTheme="vs-dark" readOnly={readOnly}
width="100%" height="300px" language='json' enableToolbar={false} />
</Form.Item>
</Form>
)
})
@@ -21,22 +21,22 @@ export default function Guide(){
{
title: $t("配置你的 AI 模型"),
description: $t('通过 APIPark 快速接入各种 AI 模型,使用统一的格式来调用API,并且可以随意切换模型。'),
link: 'https://docs.apipark.com/docs/quick/pre-work/team'
link: 'https://docs.apipark.com/docs/system_setting/ai_model_providers'
},
{
title: $t("创建 AI 服务和 API"),
description: $t('创建 AI 类型的服务,并且你可以将 Prompt 提示词设置为一个 API,简化使用 AI 的流程。'),
link: 'https://docs.apipark.com/docs/quick/provider/service'
link: 'https://docs.apipark.com/docs/services/ai_services'
},
{
title: $t("创建调用 Token"),
description: $t('为了安全地调用 API,你需要创建一个消费者以及Token。'),
link: 'https://docs.apipark.com/docs/quick/suberscriber/application'
link: 'https://docs.apipark.com/docs/consumers'
},
{
title: $t("调用"),
description: $t('现在你可以通过 Token 来调用这些 API。'),
link: 'https://docs.apipark.com/docs/quick/suberscriber/application'
link: 'https://docs.apipark.com/docs/call_api'
}
]
},
@@ -46,17 +46,17 @@ export default function Guide(){
{
title: $t("创建 REST 服务和 API"),
description: $t('创建 AI 类型的服务,并且你可以将 Prompt 提示词设置为一个 API,简化使用 AI 的流程。'),
link: 'https://docs.apipark.com/docs/tutorials/api-market/service'
link: 'https://docs.apipark.com/docs/services/rest_services'
},
{
title: $t("创建调用 Token"),
description: $t('为了安全地调用 API,你需要创建一个消费者以及Token。'),
link: 'https://docs.apipark.com/docs/quick/suberscriber/subscribe'
link: 'https://docs.apipark.com/docs/consumers'
},
{
title: $t("调用"),
description: $t('现在你可以通过 Token 来调用这些 API。'),
link: 'https://docs.apipark.com/docs/quick/provider/approve'
link: 'https://docs.apipark.com/docs/call_api'
}
]
},
@@ -66,7 +66,7 @@ export default function Guide(){
{
title: $t("统计 API 调用情况"),
description: $t('仪表盘中提供了多种统计图表,帮助我们了解 API 的运行情况。'),
link: 'https://docs.apipark.com/docs/quick/pre-work/monitor'
link: 'https://docs.apipark.com/docs/analysis'
}
]
}
@@ -78,17 +78,17 @@ export default function Guide(){
{
title: $t("账号与角色"),
description: $t('邀请你的团队成员加入 APIPark,共同管理和调用 API。'),
link: 'https://docs.apipark.com/docs/quick/pre-work/team'
link: 'https://docs.apipark.com/docs/system_setting/account_role'
},
{
title: $t("团队"),
description: $t('团队中包含了人员、消费者和服务,不同团队之间的消费者和服务数据是隔离的,可用于管理企业内部不同的部门/项目组/团队。'),
link: 'https://docs.apipark.com/docs/quick/provider/service'
link: 'https://docs.apipark.com/docs/teams'
},
{
title: $t("服务"),
description: $t('服务内包含一组 API,并且可以发布到 API 市场被其他团队使用。'),
link: 'https://docs.apipark.com/docs/quick/suberscriber/application'
link: 'https://docs.apipark.com/docs/category/-%E6%9C%8D%E5%8A%A1'
}
]
},
@@ -98,12 +98,12 @@ export default function Guide(){
{
title: $t("订阅服务"),
description: $t('如果需要调用某个服务的 API,需要先订阅该服务,并且等待提供服务的团队审核后才可发起 API 请求。'),
link: 'https://docs.apipark.com/docs/tutorials/api-market/service'
link: 'https://docs.apipark.com/docs/developer_portal'
},
{
title: $t("审核订阅申请"),
description: $t('提供服务的团队可以审核来自其他团队的订阅申请,审核通过后的消费者才可发起 API 请求。'),
link: 'https://docs.apipark.com/docs/quick/suberscriber/subscribe'
link: 'https://docs.apipark.com/docs/services/review_consumers'
}
]
},
@@ -113,7 +113,7 @@ export default function Guide(){
{
title: $t("日志"),
description: $t('APIPark 提供详尽的 API 调用日志,帮助企业监控、分析和审计 API 的运行状况。'),
link: 'https://docs.apipark.com/docs/quick/pre-work/monitor'
link: 'https://docs.apipark.com/docs/system_setting/log/'
}
]
}
@@ -45,7 +45,7 @@ const LogSettings = ()=>{
undefined,
undefined,
undefined,
'system.devops.log_configuration.view')
'system.settings.log_configuration.view')
})
return newMenu
},[state.language,menuItems])
@@ -1,4 +1,5 @@
import WithPermission from "@common/components/aoplatform/WithPermission";
import { useBreadcrumb } from "@common/contexts/BreadcrumbContext";
import { $t } from "@common/locales";
import { useEffect } from "react";
@@ -24,7 +25,7 @@ export default function LogSettingsInstruction() {
<div className="h-[208px] w-[384px] flex flex-col items-center py-[32px] px-[24px] gap-[16px] rounded-DEFAULT bg-MENU_BG mr-[24px]">
<p className="text-[20px] font-medium leading-[32px] text-MAIN_TEXT"></p>
<p className="text-[12px] font-normal leading-[20px] text-DESC_TEXT"></p>
<p><Link to="/cluster"></Link></p>
<p><WithPermission access="system.settings.api_gateway.view" ><Link to="/cluster"></Link></WithPermission></p>
</div>
</div>
</div></div>
@@ -1,10 +1,11 @@
import {App, Form, Input, TreeSelect} from "antd";
import {forwardRef, useEffect, useImperativeHandle, useState} from "react";
import {forwardRef, useEffect, useImperativeHandle, useMemo, useState} from "react";
import {BasicResponse, PLACEHOLDER, RESPONSE_TIPS, STATUS_CODE, VALIDATE_MESSAGE} from "@common/const/const.tsx";
import {useFetch} from "@common/hooks/http.ts";
import { MemberDropdownModalHandle, MemberDropdownModalProps, DepartmentListItem, MemberDropdownModalFieldType, MemberTableListItem } from "../../const/member/type.ts";
import WithPermission from "@common/components/aoplatform/WithPermission.tsx";
import { $t } from "@common/locales/index.ts";
import { useGlobalContext } from "@common/contexts/GlobalStateContext.tsx";
export const MemberDropdownModal = forwardRef<MemberDropdownModalHandle,MemberDropdownModalProps>((props,ref)=>{
const { message} = App.useApp()
@@ -12,6 +13,7 @@ export const MemberDropdownModal = forwardRef<MemberDropdownModalHandle,MemberDr
const {type,entity,selectedMemberGroupId} = props
const {fetchData} = useFetch()
const [departmentList, setDepartmentList] = useState<DepartmentListItem[]>([])
const { state } = useGlobalContext()
const save:()=>Promise<boolean | string> = ()=>{
let url:string
@@ -78,6 +80,15 @@ export const MemberDropdownModal = forwardRef<MemberDropdownModalHandle,MemberDr
})
}
const generateRandomString = () =>{
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
let result = '';
for (let i = 0; i < 8; i++) {
result += chars.charAt(Math.floor(Math.random() * chars.length));
}
return result;
}
useEffect(() => {
switch(type){
case 'addChild':
@@ -87,7 +98,7 @@ export const MemberDropdownModal = forwardRef<MemberDropdownModalHandle,MemberDr
form.setFieldsValue({id:entity!.id,name:entity!.name})
break
case 'addMember':
form.setFieldsValue('-1' === selectedMemberGroupId ? {} : {departmentIds:selectedMemberGroupId})
form.setFieldsValue({...('-1' === selectedMemberGroupId ? {} : {departmentIds:selectedMemberGroupId}), password:generateRandomString()})
break
case 'editMember':
form.setFieldsValue({...entity,departmentIds:(entity as MemberTableListItem )?.department?.map(x=>x.id)})
@@ -97,6 +108,23 @@ export const MemberDropdownModal = forwardRef<MemberDropdownModalHandle,MemberDr
}, []);
const treeData = useMemo(() => {
const loop = (data: DepartmentListItem[]): unknown[] =>
data?.map((item) => {
const title = ['unknown','disable'].indexOf(item.id) === -1 ?item.name : $t(item.name) as string;
if (item.children) {
return {...item,name:title, children:loop(item.children)}
}
return {
...item,
name: title
};
});
return loop(departmentList);
}, [departmentList,state.language]);
return (<WithPermission access="">
<Form
@@ -163,6 +191,13 @@ export const MemberDropdownModal = forwardRef<MemberDropdownModalHandle,MemberDr
>
<Input className="w-INPUT_NORMAL" placeholder={$t(PLACEHOLDER.input)}/>
</Form.Item>
<Form.Item<MemberDropdownModalFieldType>
label={$t("密码")}
name="password"
rules={[{required: type === 'addMember',whitespace:true }]}
>
<Input className="w-INPUT_NORMAL" placeholder={$t(PLACEHOLDER.input)}/>
</Form.Item>
<Form.Item<MemberDropdownModalFieldType>
label={$t("部门")}
name="departmentIds"
@@ -175,7 +210,7 @@ export const MemberDropdownModal = forwardRef<MemberDropdownModalHandle,MemberDr
placeholder={$t(PLACEHOLDER.select)}
allowClear
treeDefaultExpandAll
treeData={departmentList}
treeData={treeData}
multiple
/>
</Form.Item>
@@ -346,7 +346,7 @@ const MemberList = ()=>{
<WithPermission access="system.organization.member.edit">
<Select
className="w-full"
mode="multiple"
mode="multiple"
value={entity.roles?.map((x:EntityItem)=>x.id)}
options={roleSelectableList?.map((x:{id:string,name:string})=>({label:(x.name), value:x.id}))}
onChange={(value)=>{
@@ -47,7 +47,7 @@ const LogSettings = ()=>{
undefined,
undefined,
undefined,
'system.devops.log_configuration.view')
'system.settings.log_configuration.view')
})
return newMenu
},[state.language,menuItems])
@@ -1,3 +1,4 @@
import WithPermission from "@common/components/aoplatform/WithPermission";
import { useBreadcrumb } from "@common/contexts/BreadcrumbContext";
import { useEffect } from "react";
import { Link } from "react-router-dom";
@@ -24,7 +25,7 @@ export default function ResourceSettingsInstruction() {
<div className="h-[208px] w-[384px] flex flex-col items-center py-[32px] px-[24px] gap-[16px] rounded-DEFAULT bg-MENU_BG mr-[24px]">
<p className="text-[20px] font-medium leading-[32px] text-MAIN_TEXT"></p>
<p className="text-[12px] font-normal leading-[20px] text-DESC_TEXT"></p>
<p><Link to="/cluster"></Link></p>
<p><WithPermission access="system.settings.data_source.view" ><Link to="/cluster"></Link></WithPermission></p>
</div>
</div>
</div></div>
@@ -176,13 +176,17 @@ const RoleConfig = ()=>{
},[permissionInfo, state.language])
useEffect(() => {
getPermissionTemplate()
form.setFieldsValue({name:'',permits:[]})
if(roleId){
getPermissionInfo()
}
}, []);
useEffect(()=>{
getPermissionTemplate()
},[state.language])
const onFinish =async() => {
const body = await form.validateFields()
@@ -292,7 +292,7 @@ const SystemConfig = forwardRef<SystemConfigHandle>((_,ref) => {
return (
<>
<WithPermission access={onEdit ? 'team.service.service.edit' :''}>
<WithPermission access={onEdit ? ['team.service.service.edit'] :''}>
<Form
layout='vertical'
labelAlign='left'
@@ -460,7 +460,7 @@ const SystemConfig = forwardRef<SystemConfigHandle>((_,ref) => {
<Row className="mb-[10px]"
// wrapperCol={{ offset: 5, span: 19 }}
>
<WithPermission access={onEdit ? 'team.service.service.edit' :''}>
<WithPermission access={onEdit ? ['team.service.service.edit'] :''}>
<Button type="primary" htmlType="submit">
{$t('保存')}
</Button>
@@ -468,11 +468,11 @@ const SystemConfig = forwardRef<SystemConfigHandle>((_,ref) => {
</Row></>}
</div>
{onEdit && <>
<WithPermission access="team.service.service.delete" showDisabled={false}>
<WithPermission access={["team.service.service.delete"]} showDisabled={false}>
<div className="bg-[rgb(255_120_117_/_5%)] rounded-[10px] mt-[50px] p-btnrbase pb-0">
<p className="text-left"><span className="font-bold">{$t('删除服务')}</span>{$t('删除操作不可恢复,请谨慎操作!')}</p>
<div className="text-left">
<WithPermission access="team.service.service.delete">
<WithPermission access={["team.service.service.delete"]}>
<Button className="m-auto mt-[16px] mb-[20px]" type="default" danger={true} onClick={deleteSystemModal}>{$t('删除服务')}</Button>
</WithPermission>
</div>
@@ -137,7 +137,7 @@ const ServiceInsideDocument = ()=>{
<div className=" pl-[8px] py-btnbase ">
<div className="flex justify-between items-center">
<p className="text-[14px] leading-[20px] text-[#999999]"><span className="mr-[20px]">{$t('最近一次更新者')}{updater || '-'}</span><span>{$t('最近一次更新时间')}{updateTime || '-'}</span></p>
<WithPermission access="team.service.service.edit"><Button type="primary" className="mr-btnbase" onClick={save}>{$t('保存')}</Button></WithPermission>
<WithPermission access="team.service.service_intro.edit"><Button type="primary" className="mr-btnbase" onClick={save}>{$t('保存')}</Button></WithPermission>
</div>
</div>
</div>)
@@ -62,7 +62,7 @@ const SystemInsidePage:FC = ()=> {
getItem(<Link to="./route">{$t('API 路由')}</Link>, 'route',undefined,undefined,undefined,'team.service.router.view'),
getItem(<Link to="./api">{$t('API 文档')}</Link>, 'api',undefined,undefined,undefined,'team.service.api_doc.view'),
getItem(<Link to="./upstream">{$t('上游')}</Link>, 'upstream',undefined,undefined,undefined,'team.service.upstream.view'),
getItem(<Link to="./document">{$t('使用说明')}</Link>, 'document',undefined,undefined,undefined,''),
getItem(<Link to="./document">{$t('使用说明')}</Link>, 'document',undefined,undefined,undefined,'team.service.service_intro.view'),
getItem(<Link to="./publish">{$t('发布')}</Link>, 'publish',undefined,undefined,undefined,'team.service.release.view'),
],
'group'),
@@ -84,19 +84,20 @@ const SystemInsidePage:FC = ()=> {
const filterMenu = (menu:MenuItemGroupType<MenuItemType>[])=>{
const newMenu = cloneDeep(menu)
return newMenu!.filter((m:MenuItemGroupType )=>{
if(m.children && m.children.length > 0){
if(m&&m.children && m.children.length > 0){
m.children = m.children.filter(
(c)=>(c&&(c as MenuItemType&{access:string} ).access ?
(c)=>{
if(!c) return false
return (((c as MenuItemType&{access:string} ).access ?
checkPermission((c as MenuItemType&{access:string} ).access as keyof typeof PERMISSION_DEFINITION[0]):
true))
true))})
}
return m.children && m.children.length > 0
})
}
const filteredMenu = filterMenu(SYSTEM_PAGE_MENU_ITEMS as MenuItemGroupType<MenuItemType>[])
setActiveMenu((pre)=>{
return pre ?? 'route'
})
const menu = activeMenu ?? filteredMenu[0]?.children ? filteredMenu[0]?.children?.[0]?.key : filteredMenu[0]?.key
if(menu && currentUrl.split('/')[-1] !== menu) navigateTo(`/service/${teamId}/inside/${serviceId}/${menu}`)
return filteredMenu || []
},[accessData,accessInit, SYSTEM_PAGE_MENU_ITEMS])
@@ -116,7 +117,7 @@ const SystemInsidePage:FC = ()=> {
}, [currentUrl]);
useEffect(()=>{
if(accessData && accessData.get('team') && accessData.get('team')?.indexOf('team.service.router.view') !== -1){
if(accessData && checkPermission('team.service.router.view')){
getApiDefine()
}
},[accessData])
@@ -153,7 +153,7 @@ const SystemList:FC = ()=>{
<InsidePage
pageTitle={$t('服务')}
description={'APIPark '+$t("服务提供了高性能 API 网关,并且可以无缝接入多种大型 AI 模型,并将这些 AI 能力打包成 API 进行调用,从而大幅简化了 AI 模型的使用门槛。同时,我们的平台提供了完善的 API 管理功能,支持 API 的创建、监控、访问控制等,保障开发者可以高效、安全地开发和管理 API 服务。")}
description={$t("服务提供了高性能 API 网关,并且可以无缝接入多种大型 AI 模型,并将这些 AI 能力打包成 API 进行调用,从而大幅简化了 AI 模型的使用门槛。同时,我们的平台提供了完善的 API 管理功能,支持 API 的创建、监控、访问控制等,保障开发者可以高效、安全地开发和管理 API 服务。")}
showBorder={false}
contentClassName=" pr-PAGE_INSIDE_X pb-PAGE_INSIDE_B"
>
@@ -3,7 +3,7 @@ import {App, Button, Form, Input, Row, Select} from "antd";
import {Link, useLocation, useNavigate, useParams} from "react-router-dom";
import {RouterParams} from "@core/components/aoplatform/RenderRoutes.tsx";
import { v4 as uuidv4 } from 'uuid'
import {BasicResponse, PLACEHOLDER, RESPONSE_TIPS, STATUS_CODE, VALIDATE_MESSAGE} from "@common/const/const.tsx";
import {BasicResponse, PLACEHOLDER, RESPONSE_TIPS, STATUS_CODE} from "@common/const/const.tsx";
import {MemberItem} from "@common/const/type.ts";
import {useFetch} from "@common/hooks/http.ts";
import {DefaultOptionType} from "antd/es/cascader";
@@ -34,10 +34,10 @@ const TeamConfig= forwardRef<TeamConfigHandle,TeamConfigProps>((props,ref) => {
const [managerOption, setManagerOption] = useState<DefaultOptionType[]>([])
const { setBreadcrumb} = useBreadcrumb()
const { setTeamInfo } =useTeamContext()
const {checkPermission,accessInit} = useGlobalContext()
const {checkPermission,accessInit,state} = useGlobalContext()
const pageType= useMemo(()=>{
if(!accessInit) return 'myteam'
return checkPermission('system.organization.team.view') ? 'manage' : 'myteam'
return checkPermission('system.workspace.team.view_all') ? 'manage' : 'myteam'
},[checkPermission,accessInit])
const [canDelete, setCanDelete] = useState<boolean>(false)
@@ -128,7 +128,10 @@ const TeamConfig= forwardRef<TeamConfigHandle,TeamConfigProps>((props,ref) => {
getTeamInfo();
} else {
setOnEdit(false);
form.setFieldsValue({id:uuidv4()}); // 清空 initialValues
form.setFieldsValue(
{id:uuidv4(),
master:state?.userData?.uid
}); // 清空 initialValues
}
return (form.setFieldsValue({}))
}, [teamId]);
@@ -197,7 +200,7 @@ const TeamConfig= forwardRef<TeamConfigHandle,TeamConfigProps>((props,ref) => {
<p className="text-left"><span className="font-bold">{$t('删除团队')}</span>{$t('删除操作不可恢复,请谨慎操作!')}</p>
<div className="text-left">
<WithPermission access="system.organization.team.delete" disabled={!canDelete} tooltip={canDelete ? '':$t('服务数据清除后,方可删除')}>
<Button className="m-auto mt-[16px] mb-[20px]" type="default" danger onClick={()=>deleteTeam(entity!)}>{$t('删除')}</Button>
<Button className="m-auto mt-[16px] mb-[20px]" type="default" danger onClick={()=>deleteTeam()}>{$t('删除')}</Button>
</WithPermission>
</div>
</div>
@@ -20,7 +20,7 @@ import WithPermission from "@common/components/aoplatform/WithPermission.tsx";
import { $t } from "@common/locales/index.ts";
export const getDepartmentWithMember = (department:(DepartmentListItem & {type?:'department'|'member'})[],departmentMap:Map<string, (MemberItem & {type:'department'|'member'})[]>) : (DepartmentWithMemberItem | undefined)[] =>{
return department.map((x:DepartmentListItem & {type?:'department'|'member'})=>{
return department?.map((x:DepartmentListItem & {type?:'department'|'member'})=>{
const res = ({
...x,
key:x.id,
@@ -28,7 +28,7 @@ export const getDepartmentWithMember = (department:(DepartmentListItem & {type?:
type: x.type || 'department',
children:((x.type === 'member' || (!x.children||x.children.length === 0 )&& (!departmentMap.get(x.id) || departmentMap.get(x.id)!.length === 0))? undefined : [...(x.children && x.children.length > 0 ? getDepartmentWithMember(x.children,departmentMap) : []),...departmentMap.get(x.id) || []])
});
return res}).filter(node=>node.type === 'member' ||( node.children && node.children.length > 0))
return res})?.filter(node=>node.type === 'member' ||( node.children && node.children.length > 0)) || []
}
export const addMemberToDepartment = (departmentMap: Map<string, (MemberItem & {type:'department'|'member'})[]>, departmentId: string, member: MemberItem) => {
@@ -84,6 +84,7 @@ const TeamInsideMember:FC = ()=>{
addMemberToDepartment(departmentMap, '_withoutDepartment', member);
}
});
const finalData = departmentResponse.data.department
? [
@@ -93,30 +94,33 @@ const TeamInsideMember:FC = ()=>{
name: departmentResponse.data.department.name,
title:departmentResponse.data.department.name,
children: [
...getDepartmentWithMember(departmentResponse.data.department.children, departmentMap),
...getDepartmentWithMember(departmentResponse.data.department?.children || [], departmentMap),
...departmentMap.get('_withoutDepartment') || []
]
}
]
: [...departmentMap.get('_withoutDepartment') || []];
let allMemberSelectedFlag:boolean = true
for(const [k,v] of departmentMap){
if(k !== '_withoutDepartment' && allMemberIds.length > 0 ){
// 筛选出部门内没被勾选的用户,如果不存在没勾选用户,需要将部门id放入ids中
if(v.filter(m => allMemberIds.indexOf(m.id) === -1).length === 0){
setAllMemberSelectedDepartIds((pre)=>[...pre, k])
}else if(['unknown','disable'].indexOf(k) === -1){
allMemberSelectedFlag = false
}
}
}
if(!finalData[0].children || finalData[0].children.filter(m => allMemberIds.indexOf(m.id) === -1).length === 0){
setAllMemberSelectedDepartIds((pre)=>[...pre, topDepartmentId])
if(departmentMap.get('_withoutDepartment')?.filter(x=>allMemberIds.indexOf(x)!==-1).length === 0 && allMemberSelectedFlag){
setAllMemberSelectedDepartIds((pre)=>[...pre, topDepartmentId])
}
return {data:finalData, success: true}
}).catch(()=>({data:[], success:false}))
}
const getMemberList = ()=>{
return fetchData<BasicResponse<{members:TeamMemberTableListItem}>>('team/members',{method:'GET',eoParams:{keyword:searchWord, team:teamId},eoTransformKeys:['attach_time','is_delete']}).then(response=>{
@@ -214,7 +218,6 @@ const TeamInsideMember:FC = ()=>{
const changeMemberInfo = (value:string[],entity:TeamMemberTableListItem )=>{
//console.log(value)
return new Promise((resolve, reject) => {
fetchData<BasicResponse<null>>(`team/member/role`, {method: 'PUT',eoBody:({roles:value, users:[entity.user.id]}), eoParams: {team:teamId}}).then(response => {
const {code, msg} = response
@@ -252,6 +255,7 @@ const TeamInsideMember:FC = ()=>{
<Select
className="w-full"
mode="multiple"
maxTagCount="responsive"
value={entity.roles?.map((x:EntityItem)=>x.id)}
options={roleList?.map((x:{id:string,name:string})=>({label:(x.name), value:x.id}))}
onChange={(value)=>{
@@ -272,7 +276,6 @@ const TeamInsideMember:FC = ()=>{
},[ state.language,roleList])
useEffect(() => {
getRoleList()
setBreadcrumb([
{title:<Link to="/team/list">{$t('团队')}</Link>},
{title:$t('成员')}
@@ -280,6 +283,11 @@ const TeamInsideMember:FC = ()=>{
manualReloadTable()
}, [teamId]);
useEffect(()=>{
getRoleList()
},[state.language])
const treeDisabledData = useMemo(()=>{ return [...allMemberIds,...allMemberSelectedDepartIds]},[allMemberIds,allMemberSelectedDepartIds])
return (
@@ -302,7 +310,7 @@ const TeamInsideMember:FC = ()=>{
title={$t("添加成员")}
open={modalVisible}
destroyOnClose={true}
width={900}
width={600}
onCancel={() => cleanModalData()}
maskClosable={false}
footer={[
@@ -329,7 +337,7 @@ const TeamInsideMember:FC = ()=>{
const memberKeyFromModal = Array.from(selectedData)?.filter(x => allMemberIds.indexOf(x) === -1 &&selectableMemberIds.has(x)) || [];
setAddMemberBtnDisabled((memberKeyFromModal.length === 0));
}}
searchPlaceholder={$t("搜索用户名、邮箱")}
searchPlaceholder={$t("输入名称查找用户")}
/>
</Modal>
</>
@@ -1,16 +1,15 @@
import PageList, { PageProColumns } from "@common/components/aoplatform/PageList.tsx"
import PageList from "@common/components/aoplatform/PageList.tsx"
import {ActionType} from "@ant-design/pro-components";
import {FC, useEffect, useMemo, useRef, useState} from "react";
import {useLocation, useNavigate} from "react-router-dom";
import {useBreadcrumb} from "@common/contexts/BreadcrumbContext.tsx";
import {App, Divider, Modal} from "antd";
import {BasicResponse, COLUMNS_TITLE, DELETE_TIPS, RESPONSE_TIPS, STATUS_CODE} from "@common/const/const.tsx";
import {App, Modal} from "antd";
import {BasicResponse, DELETE_TIPS, RESPONSE_TIPS, STATUS_CODE} from "@common/const/const.tsx";
import { SimpleMemberItem } from "@common/const/type.ts";
import {useFetch} from "@common/hooks/http.ts";
import { TEAM_TABLE_COLUMNS } from "../../const/team/const.tsx";
import { TeamConfigFieldType, TeamConfigHandle, TeamTableListItem } from "../../const/team/type.ts";
import TableBtnWithPermission from "@common/components/aoplatform/TableBtnWithPermission.tsx";
import { useGlobalContext } from "@common/contexts/GlobalStateContext.tsx";
import { checkAccess } from "@common/utils/permission.ts";
import TeamConfig from "./TeamConfig.tsx";
@@ -131,21 +130,6 @@ const TeamList:FC = ()=>{
})
}
const operation:PageProColumns<TeamTableListItem>[] =[
{
title: COLUMNS_TITLE.operate,
key: 'option',
fixed:'right',
btnNums:2,
valueType: 'option',
render: (_: React.ReactNode, entity: TeamTableListItem) => [
<TableBtnWithPermission access="" key="view" btnType="view" navigateTo={`../inside/${entity.id}/setting`} btnTitle="查看"/>,
<Divider type="vertical" className="mx-0" key="div2"/>,
<TableBtnWithPermission access="system.organization.team.delete" key="delete" btnType="delete" disabled={!entity.canDelete} tooltip="服务数据清除后,方可删除" onClick={()=>{openModal('delete',entity)}} btnTitle="删除"/>,
],
}
]
useEffect(() => {
setBreadcrumb([
{title: $t('团队')}
@@ -173,7 +157,7 @@ const TeamList:FC = ()=>{
id="global_team"
className="pl-btnbase"
ref={pageListRef}
columns = {[...columns,...operation]}
columns = {[...columns]}
request = {()=>getTeamList()}
showPagination={false}
addNewBtnTitle={$t('添加团队')}
@@ -207,7 +191,7 @@ const TeamList:FC = ()=>{
}
return res})}
>
<TeamConfig ref={teamConfigRef} inModal entity={modalType === 'add' ? undefined : curTeam} />
<TeamConfig ref={teamConfigRef} entity={modalType === 'add' ? undefined : curTeam} />
</Modal>
</InsidePage>
)
+1 -6
View File
@@ -1,9 +1,4 @@
/*
* @Date: 2024-06-05 09:35:25
* @LastEditors: maggieyyy
* @LastEditTime: 2024-06-05 10:50:12
* @FilePath: \frontend\packages\core\start-vite.js
*/
// start-vite.js// start-vite.js
import { exec } from 'child_process';
+1 -6
View File
@@ -1,9 +1,4 @@
/*
* @Date: 2023-11-27 17:31:44
* @LastEditors: maggieyyy
* @LastEditTime: 2024-06-05 10:36:46
* @FilePath: \frontend\packages\core\tailwind.config.js
*/
/** @type {import('tailwindcss').Config} */
export default {
@@ -1,9 +1,4 @@
/*
* @Date: 2023-11-27 17:31:54
* @LastEditors: maggieyyy
* @LastEditTime: 2023-11-29 15:49:05
* @FilePath: \applatform\frontend\packages\core\postcss.config.js
*/
export default {
plugins: {
'postcss-import': {},
@@ -231,9 +231,9 @@ const MonitorTotalPage = (props:MonitorTotalPageProps) => {
}
return (
<div className={`h-full overflow-hidden pb-btnybase flex flex-col bg-[#fff]`}>
<div className={`h-full overflow-hidden pb-btnybase flex flex-col bg-[#fff] `}>
<ScrollableSection>
<div className="flex items-center flex-wrap pb-[10px] px-btnbase content-before bg-MAIN_BG">
<div className="flex items-center flex-wrap pb-[10px] px-btnbase content-before bg-MAIN_BG pr-PAGE_INSIDE_X ">
<TimeRangeSelector
labelSize="small"
initialTimeButton={timeButton}
@@ -247,7 +247,7 @@ const MonitorTotalPage = (props:MonitorTotalPageProps) => {
</div>
<Spin wrapperClassName={`flex-1 ${totalEmpty ?'':'overflow-auto'}`} indicator={<LoadingOutlined style={{ fontSize: 24 }} spin/>} spinning={queryBtnLoading}>
{totalEmpty ?<Empty className="mt-[100px]" image={Empty.PRESENTED_IMAGE_SIMPLE} />:
<div className=" h-full scroll-area">
<div className=" h-full scroll-area pr-PAGE_INSIDE_X ">
{/* 图表区域 */}
<div className=" px-btnbase mt-[12px] mb-[16px] grid gap-[20px]" style={{ gridTemplateColumns: 'repeat(auto-fill, minmax(570px, 1fr))'}}>
{/* 请求统计饼图 */}
@@ -10,7 +10,6 @@ import { reject } from "lodash-es";
import { EntityItem } from "@common/const/type";
import { LoadingOutlined } from "@ant-design/icons";
import DashboardInstruction from "./DashboardInstruction";
import cluster from "cluster";
export default function Dashboard(){
const { setBreadcrumb } = useBreadcrumb()
@@ -47,7 +46,7 @@ export default function Dashboard(){
return (
<>
<Spin wrapperClassName="h-full w-full pr-PAGE_INSIDE_X pb-PAGE_INSIDE_B " indicator={<LoadingOutlined style={{ fontSize: 24 }} spin/>} spinning={loading}>
<Spin wrapperClassName="h-full w-full pb-PAGE_INSIDE_B " indicator={<LoadingOutlined style={{ fontSize: 24 }} spin/>} spinning={loading}>
{
!loading && <>
{
@@ -1,4 +1,5 @@
import WithPermission from "@common/components/aoplatform/WithPermission";
import { $t } from "@common/locales";
import { Link } from "react-router-dom";
@@ -15,13 +16,13 @@ export default function DashboardInstruction({showClusterIns, showMonitorIns}:{s
{showClusterIns && <div className="h-[208px] w-[50%] max-w-[384px] flex flex-col items-center py-[32px] px-[24px] gap-[16px] rounded-DEFAULT bg-MENU_BG mr-[24px] justify-around">
<p className="text-[20px] font-medium leading-[32px] text-MAIN_TEXT">{$t('集群配置')}</p>
<p className="text-[12px] font-normal leading-[20px] text-DESC_TEXT">{$t('配置集群地址,以确保监控系统能够正确识别和连接到集群')}</p>
<p><a href="/cluster" target="_blank">{$t('配置集群信息')}</a></p>
<p><WithPermission access="system.settings.api_gateway.view" ><a href="/cluster" target="_blank">{$t('配置集群信息')}</a></WithPermission></p>
</div>}
{showMonitorIns &&
<div className="h-[208px] w-[50%] max-w-[384px] flex flex-col items-center py-[32px] px-[24px] gap-[16px] rounded-DEFAULT bg-MENU_BG justify-around">
<p className="text-[20px] font-medium leading-[32px] text-MAIN_TEXT">{$t('监控设置')}</p>
<p className="text-[12px] font-normal leading-[20px] text-DESC_TEXT">{$t('设置监控报表的数据来源,设置完成之后即可获得详细的API调用统计图表。')}</p>
<p><a href="/datasourcing" target="_blank">{$t('配置监控信息')}</a></p>
<p><WithPermission access="system.settings.data_source.view" ><a href="/datasourcing" target="_blank">{$t('配置监控信息')}</a></WithPermission></p>
</div>
}
@@ -1,9 +1,4 @@
/*
* @Date: 2023-11-27 17:31:44
* @LastEditors: maggieyyy
* @LastEditTime: 2024-06-05 10:36:11
* @FilePath: \frontend\packages\market\tailwind.config.js
*/
/** @type {import('tailwindcss').Config} */
export default {
+1 -6
View File
@@ -1,9 +1,4 @@
/*
* @Date: 2023-11-27 17:31:54
* @LastEditors: maggieyyy
* @LastEditTime: 2024-06-05 10:42:18
* @FilePath: \frontend\packages\core\postcss.config.js
*/
export default {
plugins: {
'postcss-import': {},
@@ -25,7 +25,6 @@ export const SERVICE_HUB_TABLE_COLUMNS: PageProColumns<ServiceHubTableListItem>[
title:('团队'),
dataIndex: ['team','name'],
ellipsis:true,
renderText:(_,entity:ServiceHubTableListItem)=>entity.tags?.map(x=>x.name).join(',') || '-'
},
{
title:('订阅服务数量'),
@@ -89,10 +89,10 @@ const ServiceHubDetail = ()=>{
const getMySelectList = ()=>{
setMySystemOptionList([])
fetchData<BasicResponse<{ apps: SimpleSystemItem[] }>>('simple/apps/mine',{method:'GET'}).then(response=>{
fetchData<BasicResponse<{ app: EntityItem[] }>>('apps/can_subscribe',{method:'GET'}).then(response=>{
const {code,data,msg} = response
if(code === STATUS_CODE.SUCCESS){
setMySystemOptionList(data.apps?.map((x:SimpleSystemItem)=>{return {
setMySystemOptionList(data.app?.map((x:EntityItem)=>{return {
label:x.name, value:x.id
}}))
}else{
@@ -8,6 +8,9 @@ import { useFetch } from "@common/hooks/http";
import { useNavigate } from "react-router-dom";
import { useTenantManagementContext } from "@market/contexts/TenantManagementContext";
import { $t } from "@common/locales";
import Select, { DefaultOptionType } from "antd/es/select";
import { useGlobalContext } from "@common/contexts/GlobalStateContext";
import { SimpleTeamItem, MemberItem } from "@common/const/type";
export type ManagementConfigFieldType = {
name:string
@@ -21,6 +24,7 @@ type ManagementConfigProps = {
type:'add'|'edit'
teamId:string
appId?:string
dataShowType?:'block'|'list'
}
export type ManagementConfigHandle = {
@@ -30,16 +34,18 @@ export type ManagementConfigHandle = {
const ManagementConfig = forwardRef<ManagementConfigHandle,ManagementConfigProps>((props, ref) => {
const { message,modal } = App.useApp()
const {type,teamId,appId} = props
const {type,teamId,appId,dataShowType} = props
const [form] = Form.useForm();
const {fetchData} = useFetch()
const [delBtnLoading, setDelBtnLoading] = useState<boolean>(false)
const {setAppName} = type === 'edit' ? useTenantManagementContext():{setAppName:()=>{}}
const navigate = type === 'edit' ? useNavigate() : ()=>{}
const [teamOptionList, setTeamOptionList] = useState<DefaultOptionType[]>()
const {checkPermission,accessInit, getGlobalAccessData} = useGlobalContext()
const save:()=>Promise<boolean | string> = ()=>{
return new Promise((resolve, reject)=>{
form.validateFields().then((value)=>{
fetchData<BasicResponse<{apps:ManagementConfigFieldType}>>(type === 'add'? 'team/app' : 'app/info',{method:type === 'add'? 'POST' : 'PUT',eoBody:(value), eoParams:type === 'add' ? {team:teamId}:{app:appId,team:teamId}}).then(response=>{
fetchData<BasicResponse<{apps:ManagementConfigFieldType}>>(type === 'add'? 'team/app' : 'app/info',{method:type === 'add'? 'POST' : 'PUT',eoBody:(value), eoParams:type === 'add' ? {team:dataShowType === 'list' ? value.team : teamId}:{app:appId,team:teamId}}).then(response=>{
const {code,data,msg} = response
if(code === STATUS_CODE.SUCCESS){
message.success(msg || $t(RESPONSE_TIPS.success))
@@ -68,6 +74,24 @@ const ManagementConfig = forwardRef<ManagementConfigHandle,ManagementConfigProps
})
};
const getTeamOptionList = ()=>{
setTeamOptionList([])
fetchData<BasicResponse<{ teams: SimpleTeamItem[] }>>(!checkPermission('system.workspace.team.view_all') ?'simple/teams/mine' :'simple/teams',{method:'GET',eoTransformKeys:[]}).then(response=>{
const {code,data,msg} = response
if(code === STATUS_CODE.SUCCESS){
setTeamOptionList(data.teams?.map((x:MemberItem)=>{return {...x,
label:x.name, value:x.id
}}))
if(form.getFieldValue('team') === undefined&&data.teams?.length){
form.setFieldValue('team',data.teams[0].id);
}
}else{
message.error(msg || $t(RESPONSE_TIPS.error))
}
})
}
const deleteApplicationModal = async ()=>{
setDelBtnLoading(true)
modal.confirm({
@@ -112,7 +136,17 @@ const ManagementConfig = forwardRef<ManagementConfigHandle,ManagementConfigProps
if(type === 'edit'){
appId && getApplicationInfo()
}else{
form.setFieldValue('id',uuidv4())
form.setFieldsValue({
'id':uuidv4()})
}
if(type !== 'edit' && dataShowType === 'list'){
if(accessInit){
getTeamOptionList()
}else{
getGlobalAccessData()?.then?.(()=>{
getTeamOptionList()
})
}
}
}, [appId]);
@@ -146,6 +180,16 @@ const ManagementConfig = forwardRef<ManagementConfigHandle,ManagementConfigProps
<Input className="w-INPUT_NORMAL" placeholder={$t(PLACEHOLDER.input)} disabled={type === 'edit'}/>
</Form.Item>
{dataShowType === 'list' && <Form.Item<ManagementConfigFieldType>
label={$t("所属团队")}
name="team"
rules={[{ required: true }]}
>
<Select className="w-INPUT_NORMAL" disabled={type === 'edit'} placeholder={$t(PLACEHOLDER.input)} options={teamOptionList} >
</Select>
</Form.Item>}
<Form.Item
label={$t("描述")}
name="description"
@@ -14,7 +14,9 @@ import { ManagementConfigFieldType } from "./ManagementConfig";
import { useGlobalContext } from "@common/contexts/GlobalStateContext";
import { $t } from "@common/locales";
import { getItem } from "@common/utils/navigation";
import { MenuItemType } from "antd/es/menu/interface";
import { MenuItemGroupType, MenuItemType } from "antd/es/menu/interface";
import { PERMISSION_DEFINITION } from "@common/const/permissions";
import { cloneDeep } from "lodash-es";
export default function ManagementInsidePage(){
const { message } = App.useApp()
@@ -27,17 +29,29 @@ export default function ManagementInsidePage(){
const [openKeys, setOpenKeys] = useState<string[]>([])
const [loading, setLoading] = useState<boolean>(false)
const {appName,setAppName} = useTenantManagementContext()
const {getTeamAccessData,cleanTeamAccessData,state} = useGlobalContext()
const {getTeamAccessData,cleanTeamAccessData,state,accessData,checkPermission,accessInit} = useGlobalContext()
const TENANT_MANAGEMENT_APP_MENU: MenuProps['items'] = useMemo(()=>[
getItem($t('订阅的服务'), 'service'),
getItem($t('访问授权'), 'authorization'),
getItem($t('消费者管理'), 'setting'),
getItem($t('订阅的服务'), 'service',undefined, undefined, undefined, 'team.application.subscription.view'),
getItem($t('访问授权'), 'authorization',undefined, undefined, undefined, 'team.consumer.authorization.view'),
getItem($t('消费者管理'), 'setting',undefined, undefined, undefined, 'team.application.application.view'),
],[state.language])
const menuData = useMemo(()=>{
return TENANT_MANAGEMENT_APP_MENU
},[])
const filterMenu = (menu:(MenuItemType&{access:string})[])=>{
const newMenu = cloneDeep(menu)
return newMenu!.filter((c:MenuItemType&{access:string} )=>{
if(!c) return false
return (((c as MenuItemType&{access:string} ).access ?
checkPermission((c as MenuItemType&{access:string} ).access as keyof typeof PERMISSION_DEFINITION[0]):
true))
})}
const filteredMenu = filterMenu(TENANT_MANAGEMENT_APP_MENU as (MenuItemType&{access:string})[])
const menu = activeMenu ?? filteredMenu[0]?.children ? filteredMenu[0]?.children?.[0]?.key : filteredMenu[0]?.key
if(menu && currentUrl.split('/')[-1] !== menu) navigateTo(`/consumer/${teamId}/inside/${appId}/${menu}`)
return filteredMenu || []
},[accessData,accessInit, TENANT_MANAGEMENT_APP_MENU])
useEffect(()=>{
setActiveMenu(currentUrl.split('/').pop() || 'service')
@@ -1,5 +1,5 @@
import { MenuProps, Menu, App, Avatar, Card, Tooltip, Empty, Button, Radio } from "antd";
import { useState, forwardRef, useEffect, useRef, useMemo, memo } from "react";
import { useState, forwardRef, useEffect, useRef, useMemo, memo, Ref, useImperativeHandle } from "react";
import { VirtuosoGrid } from "react-virtuoso";
import { BasicResponse, DATA_SHOW_TYPE_OPTIONS, RESPONSE_TIPS, STATUS_CODE } from "@common/const/const";
import { ServiceHubAppListItem } from "../../../const/serviceHub/type";
@@ -17,6 +17,7 @@ import WithPermission from "@common/components/aoplatform/WithPermission";
import InsidePage from "@common/components/aoplatform/InsidePage";
import PageList from "@common/components/aoplatform/PageList";
import { SERVICE_HUB_TABLE_COLUMNS } from "@market/const/serviceHub/const";
import { ActionType } from "@ant-design/pro-components";
export default function ServiceHubManagement() {
const { message ,modal} = App.useApp()
@@ -36,23 +37,25 @@ export default function ServiceHubManagement() {
const [tableHttpReload, setTableHttpReload] = useState(true);
const [tableListDataSource, setTableListDataSource] = useState<ServiceHubAppListItem[]>([]);
const [tableSearchWord, setTableSearchWord] = useState<string>('')
const tableRef = useRef<TableAreaHandle>(null)
const getServiceList = ()=>{
if(!accessInit){
getGlobalAccessData()?.then?.(()=>{getServiceList()})
return Promise.resolve({data:[], success:false})
}
const getServiceList = (dataType?:'block'|'list')=>{
dataType = dataType ?? dataShowType
if(!accessInit){
getGlobalAccessData()?.then?.(()=>{getServiceList(dataType)})
return Promise.resolve({data:[], success:false})
}
if(dataType === 'list' && !tableHttpReload){
setTableHttpReload(true)
return Promise.resolve({
data: tableListDataSource,
success: true,
});
}
if(dataShowType === 'list' && !tableHttpReload){
setTableHttpReload(true)
return Promise.resolve({
data: tableListDataSource,
success: true,
});
}
setServiceLoading(true)
return fetchData<BasicResponse<{apps:ServiceHubAppListItem}>>(!checkPermission('system.workspace.application.view_all') ? 'my_apps':'apps',{method:'GET',eoParams:{ team:teamId,keyword:tableSearchWord},eoTransformKeys:['api_num','subscribe_num','subscribe_verify_num']}).then(response=>{
setServiceLoading(true)
return fetchData<BasicResponse<{apps:ServiceHubAppListItem}>>(!checkPermission('system.workspace.application.view_all') ? 'my_apps':'apps',{method:'GET',eoParams:{ team: dataType === 'list' ? undefined : teamId,keyword:tableSearchWord},eoTransformKeys:['api_num','subscribe_num','subscribe_verify_num','auth_num','create_time','can_delete']}).then(response=>{
const {code,data,msg} = response
if(code === STATUS_CODE.SUCCESS){
setServiceList([...data.apps,{type:'addNewItem'}])
@@ -75,36 +78,78 @@ const getServiceList = ()=>{
};
const getTeamsList = ()=>{
if(!accessInit){
getGlobalAccessData()?.then?.(()=>{getTeamsList()})
return
}
setPageLoading(true)
fetchData<BasicResponse<{ teams: SimpleTeamItem[] }>>(!checkPermission('system.workspace.team.view_all') ?'simple/teams/mine' :'simple/teams',{method:'GET',eoTransformKeys:['app_num','subscribe_num']}).then(response=>{
const {code,data,msg} = response
if(code === STATUS_CODE.SUCCESS){
setTeamList(data.teams.map((x:SimpleTeamItem)=>({label:<div className="flex items-center justify-between "><span className="w-[calc(100%-42px)] truncate" title={x.name}>{x.name}</span><span className="bg-[#fff] rounded-[5px] h-[20px] w-[30px] flex items-center justify-center">{x.appNum || 0}</span></div>, key:x.id})))
if(!teamId && data.teams?.[0]?.id){
navigateTo(data.teams[0].id)
const getTeamsList = () => {
setPageLoading(true);
const fetchTeams = () => {
fetchData<BasicResponse<{ teams: SimpleTeamItem[] }>>(
!checkPermission('system.workspace.team.view_all')
? 'simple/teams/mine'
: 'simple/teams',
{
method: 'GET',
eoTransformKeys: ['app_num', 'subscribe_num'],
}
}else{
message.error(msg || $t(RESPONSE_TIPS.error))
}
}).finally(()=>{
setPageLoading(false)
})
}
)
.then(response => {
const { code, data, msg } = response;
if (code === STATUS_CODE.SUCCESS) {
setTeamList(
data.teams.map((x: SimpleTeamItem) => ({
label: (
<div className="flex items-center justify-between">
<span className="w-[calc(100%-42px)] truncate" title={x.name}>
{x.name}
</span>
<span className="bg-[#fff] rounded-[5px] h-[20px] w-[30px] flex items-center justify-center">
{x.appNum || 0}
</span>
</div>
),
key: x.id,
}))
);
if (!teamId && data.teams?.[0]?.id) {
navigateTo(data.teams[0].id);
}
} else {
message.error(msg || $t(RESPONSE_TIPS.error));
}
})
.finally(() => {
setPageLoading(false);
});
};
if (!accessInit) {
const checkAccessData = () => {
const accessInitd = getGlobalAccessData();
if (!accessInitd) {
setTimeout(checkAccessData, 100);
return;
}
if (typeof accessInitd.then === 'function') {
accessInitd.then(fetchTeams);
} else {
fetchTeams();
}
};
checkAccessData();
} else {
fetchTeams();
}
};
const openModal = async (type:'add'|'edit'|'delete')=>{
let title:string = ''
let content:string|React.ReactNode = ''
switch (type){
case 'add':
title=$t('添加消费者')
content=<ManagementConfig ref={addManagementRef} type={type} teamId={teamId!} />
content=<ManagementConfig ref={addManagementRef} dataShowType={dataShowType} type={type} teamId={teamId!} />
break;
// case 'edit':{
// title='配置 Open Api'
@@ -130,7 +175,15 @@ const getServiceList = ()=>{
onOk:()=> {
switch (type){
case 'add':
return addManagementRef.current?.save().then((res)=>{if(res === true) getTeamsList();getServiceList()})
return addManagementRef.current?.save().then((res)=>{if(res === true) {
getTeamsList();
if(dataShowType === 'list'){
setTableHttpReload(true)
tableRef.current?.manualReloadTable()
}else{
getServiceList()
}
}})
// case 'edit':
// return editManagementRef.current?.save().then((res)=>{if(res === true) manualReloadTable()})
// case 'delete':
@@ -196,7 +249,7 @@ useEffect(() => {
item.type === 'addNewItem' ?<WithPermission access="team.application.application.add" showDisabled={false}><Card className="shadow-[0_5px_10px_0_rgba(0,0,0,0.05)] rounded-[10px] overflow-visible cursor-pointer h-[180px] transition duration-500 hover:shadow-[0_5px_20px_0_rgba(0,0,0,0.15)] hover:scale-[1.05]" classNames={{body:'h-[180px] flex items-center justify-center cursor-pointer'}} onClick={()=>{openModal('add')}}>
<div className="flex items-center"><Icon icon="ic:baseline-add" width="18" height="18"/><span>{$t('添加消费者')}</span></div>
</Card></WithPermission> : <Card title={CardTitle(item)} className="shadow-[0_5px_10px_0_rgba(0,0,0,0.05)] rounded-[10px] overflow-visible cursor-pointer h-[180px] transition duration-500 hover:shadow-[0_5px_20px_0_rgba(0,0,0,0.15)] hover:scale-[1.05]" classNames={{header:'border-b-[0px] p-[20px] ', body:"pt-0"}} onClick={()=>{setAppName(item.name);navigateTo(`/consumer/${teamId}/inside/${item.id}/service`)}}>
<span className="line-clamp-3 break-all">{item.description || $t('暂无服务描述')}</span>
<span className="line-clamp-3 break-all">{item.description || $t('暂无消费者描述')}</span>
</Card>}</div>
);
@@ -241,13 +294,13 @@ useEffect(() => {
customBtn={
<Radio.Group
options={dataShowTypeOptions}
onChange={(e)=>setDataShowType(e.target.value)}
onChange={(e)=>{setDataShowType(e.target.value); setTableHttpReload(true); if(e.target.value === 'block'){getServiceList(e.target.value)}}}
value={dataShowType}
optionType="button"
buttonStyle="solid"
/>}
>{
dataShowType === 'block' ? <BlockArea /> : <TableArea language={state.language} getServiceList={getServiceList} addNewApp={()=>openModal('add')} setTableHttpReload={setTableHttpReload} setTableSearchWord={setTableSearchWord} editApp={(row:ServiceHubAppListItem)=>{setAppName(row.name);navigateTo(`/consumer/${row.team.id}/inside/${row.id}/service`)}}/>
dataShowType === 'block' ? <BlockArea /> : <TableArea language={state.language} getServiceList={()=>getServiceList('list')} ref={tableRef} addNewApp={()=>openModal('add')} setTableHttpReload={setTableHttpReload} setTableSearchWord={setTableSearchWord} editApp={(row:ServiceHubAppListItem)=>{setAppName(row.name);navigateTo(`/consumer/${row.team.id}/inside/${row.id}/service`)}}/>
}
</InsidePage> :
<Empty className="mt-[100px]" image={Empty.PRESENTED_IMAGE_SIMPLE} />
@@ -281,20 +334,35 @@ type TableAreaProps = {
editApp:(item:ServiceHubAppListItem)=>void
}
const TableArea = memo(({language, getServiceList, addNewApp, setTableHttpReload, setTableSearchWord, editApp}:TableAreaProps)=>{
type TableAreaHandle = {
manualReloadTable:()=>void
}
const TableArea = memo(forwardRef((props:TableAreaProps, ref:Ref<TableAreaHandle>)=>{
const {language, getServiceList, addNewApp, setTableHttpReload, setTableSearchWord, editApp} = props
const pageListRef = useRef<ActionType>(null);
const columns = useMemo(()=>{
const res = SERVICE_HUB_TABLE_COLUMNS.map(x=>{
return {...x,title:typeof x.title === 'string' ? $t(x.title as string) : x.title}})
return res
},[language])
const manualReloadTable = ()=>{
pageListRef.current?.reload()
}
useImperativeHandle(ref, () =>({
manualReloadTable}))
return (
<PageList
id="service_hub_list"
ref={pageListRef}
columns={[...columns]}
request={()=>getServiceList()}
addNewBtnTitle={$t("添加服务")}
searchPlaceholder={$t("输入名称、ID 查找服务")}
addNewBtnTitle={$t("添加消费者")}
searchPlaceholder={$t("输入名称、ID 查找消费者")}
onAddNewBtnClick={addNewApp}
onChange={() => {
setTableHttpReload(false)
@@ -304,4 +372,4 @@ const TableArea = memo(({language, getServiceList, addNewApp, setTableHttpReload
}}
onRowClick={(row:ServiceHubAppListItem)=>editApp(row)}
/>
)})
)}))
+1 -6
View File
@@ -1,9 +1,4 @@
/*
* @Date: 2023-11-27 17:31:54
* @LastEditors: maggieyyy
* @LastEditTime: 2023-11-29 15:49:05
* @FilePath: \applatform\frontend\packages\core\postcss.config.js
*/
export default {
plugins: {
'postcss-import': {},
+1 -6
View File
@@ -1,9 +1,4 @@
/*
* @Date: 2023-11-27 17:31:44
* @LastEditors: maggieyyy
* @LastEditTime: 2024-06-05 10:36:11
* @FilePath: \frontend\packages\market\tailwind.config.js
*/
/** @type {import('tailwindcss').Config} */
export default {
@@ -1,9 +1,4 @@
/*
* @Date: 2023-11-27 17:31:54
* @LastEditors: maggieyyy
* @LastEditTime: 2023-11-29 15:49:05
* @FilePath: \applatform\frontend\packages\core\postcss.config.js
*/
export default {
plugins: {
'postcss-import': {},
@@ -1,9 +1,4 @@
/*
* @Date: 2023-11-27 17:31:44
* @LastEditors: maggieyyy
* @LastEditTime: 2024-06-05 10:36:11
* @FilePath: \frontend\packages\market\tailwind.config.js
*/
/** @type {import('tailwindcss').Config} */
export default {
+2 -1
View File
@@ -1,2 +1,3 @@
packages:
- "packages/*"
- "packages/*"
+1 -6
View File
@@ -1,9 +1,4 @@
/*
* @Date: 2023-11-27 17:31:44
* @LastEditors: maggieyyy
* @LastEditTime: 2024-06-04 15:03:36
* @FilePath: \frontend\tailwind.config.js
*/
/** @type {import('tailwindcss').Config} */
module.exports = {
+1
View File
@@ -11,4 +11,5 @@
},
"include": ["**/*.test.ts", "**/*.test.tsx", "jest.setup.js"],
"exclude": ["node_modules"]
}
+7 -6
View File
@@ -5,15 +5,15 @@ go 1.21
//toolchain go1.21.1
require (
github.com/eolinker/ap-account v1.0.13
github.com/eolinker/ap-account v1.0.15
github.com/eolinker/eosc v0.17.3
github.com/eolinker/go-common v1.1.0
github.com/eolinker/go-common v1.1.1
github.com/gabriel-vasile/mimetype v1.4.4
github.com/getkin/kin-openapi v0.127.0
github.com/gin-gonic/gin v1.10.0
github.com/google/uuid v1.6.0
github.com/influxdata/influxdb-client-go/v2 v2.14.0
github.com/urfave/cli/v2 v2.27.2
github.com/urfave/cli v1.22.16
golang.org/x/crypto v0.24.0
gopkg.in/yaml.v3 v3.0.1
gorm.io/gorm v1.25.5
@@ -26,7 +26,7 @@ require (
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/cloudwego/base64x v0.1.4 // indirect
github.com/cloudwego/iasm v0.2.0 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/dustin/go-humanize v1.0.0 // indirect
github.com/ghodss/yaml v1.0.0 // indirect
@@ -62,7 +62,6 @@ require (
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.2.12 // indirect
github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 // indirect
go.etcd.io/etcd/client/pkg/v3 v3.5.13 // indirect
go.uber.org/atomic v1.7.0 // indirect
go.uber.org/multierr v1.6.0 // indirect
@@ -76,4 +75,6 @@ require (
gorm.io/driver/mysql v1.5.2 // indirect
)
//replace github.com/eolinker/ap-account => ../../eolinker/ap-account
//replace github.com/eolinker/ap-account => ../aoaccount
//
//replace github.com/eolinker/go-common => ../go-common
+9 -10
View File
@@ -1,3 +1,4 @@
github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
github.com/RaveNoX/go-jsoncommentstrip v1.0.0/go.mod h1:78ihd09MekBnJnxpICcwzCMzGrKSKYe4AqU6PDYYpjk=
github.com/apapsch/go-jsonmerge/v2 v2.0.0 h1:axGnT1gRIfimI7gJifB699GoE/oq+F2MU7Dml6nw9rQ=
github.com/apapsch/go-jsonmerge/v2 v2.0.0/go.mod h1:lvDnEdqiQrp0O42VQGgmlKpxL1AP2+08jFMw88y4klk=
@@ -18,8 +19,8 @@ github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/
github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=
github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg=
github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4=
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/cpuguy83/go-md2man/v2 v2.0.5 h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB0alcyc=
github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -27,12 +28,12 @@ github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/r
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/eolinker/ap-account v1.0.13 h1:6iWdyxLAIkJfgw9JvkHEq0t2m8Levpg30kSx5pTK2wY=
github.com/eolinker/ap-account v1.0.13/go.mod h1:qLKg4xervGHTNBWaGckfPkQb+FZT0XfhwPEdNpzvsjE=
github.com/eolinker/ap-account v1.0.15 h1:n6DJeL6RHZ8eLlZUcY2U3H4d/GPaA5oelAx3R0E6yL8=
github.com/eolinker/ap-account v1.0.15/go.mod h1:zm/Ivs6waJ/M/nEszhpPmM6g50y/MKO+5eABFAdeD0g=
github.com/eolinker/eosc v0.17.3 h1:sr2yT+v/AsqEdciRaaZZj0zL9pTufR5RvDW6+65hraQ=
github.com/eolinker/eosc v0.17.3/go.mod h1:xgq816hpanlMXFtZw7Ztdctb1eEk9UPHchY4NfFO6Cw=
github.com/eolinker/go-common v1.1.0 h1:n/XXK7yVRen3jhNG/SfZGXJA+KNnaYf0XTDfMeviaBw=
github.com/eolinker/go-common v1.1.0/go.mod h1:Kb/jENMN1mApnodvRgV4YwO9FJby1Jkt2EUjrBjvSX4=
github.com/eolinker/go-common v1.1.1 h1:3WqqecGqcHDgpa8Ljp156c1uWeZKP1CKScdU+6sOfcc=
github.com/eolinker/go-common v1.1.1/go.mod h1:Kb/jENMN1mApnodvRgV4YwO9FJby1Jkt2EUjrBjvSX4=
github.com/gabriel-vasile/mimetype v1.4.4 h1:QjV6pZ7/XZ7ryI2KuyeEDE8wnh7fHP9YnQy+R0LnH8I=
github.com/gabriel-vasile/mimetype v1.4.4/go.mod h1:JwLei5XPtWdGiMFB5Pjle1oEeoSeEuJfJE+TtfvdB/s=
github.com/getkin/kin-openapi v0.127.0 h1:Mghqi3Dhryf3F8vR370nN67pAERW+3a95vomb3MAREY=
@@ -139,10 +140,8 @@ github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE=
github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
github.com/urfave/cli/v2 v2.27.2 h1:6e0H+AkS+zDckwPCUrZkKX38mRaau4nL2uipkJpbkcI=
github.com/urfave/cli/v2 v2.27.2/go.mod h1:g0+79LmHHATl7DAcHO99smiR/T7uGLw84w8Y42x+4eM=
github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 h1:+qGGcbkzsfDQNPPe9UDgpxAWQrhbbBXOYJFQDq/dtJw=
github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913/go.mod h1:4aEEwZQutDLsQv2Deui4iYQ6DWTxR14g6m8Wv88+Xqk=
github.com/urfave/cli v1.22.16 h1:MH0k6uJxdwdeWQTwhSO42Pwr4YLrNLwBtg1MRgTqPdQ=
github.com/urfave/cli v1.22.16/go.mod h1:EeJR6BKodywf4zciqrdw6hpCPk68JO9z5LazXZMn5Po=
go.etcd.io/etcd/client/pkg/v3 v3.5.13 h1:RVZSAnWWWiI5IrYAXjQorajncORbS0zI48LQlE2kQWg=
go.etcd.io/etcd/client/pkg/v3 v3.5.13/go.mod h1:XxHT4u1qU12E2+po+UVPrEeL94Um6zL58ppuJWXSAB8=
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=

Some files were not shown because too many files have changed in this diff Show More