From 10d8c56e23e9644b2ffdbdaf1bce1294100cde1f Mon Sep 17 00:00:00 2001 From: Archer <545436317@qq.com> Date: Sat, 11 Jan 2025 15:15:38 +0800 Subject: [PATCH] V4.8.18 feature (#3565) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: org CRUD (#3380) * feat: add org schema * feat: org manage UI * feat: OrgInfoModal * feat: org tree view * feat: org management * fix: init root org * feat: org permission for app * feat: org support for dataset * fix: disable org role control * styles: opt type signatures * fix: remove unused permission * feat: delete org collaborator * perf: Team org ui (#3499) * perf: org ui * perf: org ui * feat: org auth for app & dataset (#3498) * feat: auth org resource permission * feat: org auth support for app & dataset * perf: org permission check (#3500) * i18n (#3501) * name * i18n * feat: support dataset changeOwner (#3483) * feat: support dataset changeOwner * chore: update dataset change owner api * feat: permission manage UI for org (#3503) * perf: password check;perf: image upload check;perf: sso login check (#3509) * perf: password check * perf: image upload check * perf: sso login check * force show update notification modal & fix login page text (#3512) * fix login page English text * update notification modal * perf: notify account (#3515) * perf(plugin): improve searXNG empty result handling and documentation (#3507) * perf(plugin): improve searXNG empty result handling and documentation * 修改了文档和代码部分无搜索的结果的反馈 * refactor: org pathId (#3516) * optimize payment process (#3517) * feat: support wecom sso (#3518) * feat: support wecom sso * chore: remove unused wecom js-sdk dependency * fix qrcode script (#3520) * fix qrcode script * i18n * perf: full text collection and search code;perf: rename function (#3519) * perf: full text collection and search code * perf: rename function * perf: notify modal * remove invalid code * perf: sso login * perf: pay process * 4.8.18 test (#3524) * perf: remove local token * perf: index * perf: file encoding;perf: leave team code;@c121914yu perf: full text search code (#3528) * perf: text encoding * perf: leave team code * perf: full text search code * fix: http status * perf: embedding search and vector avatar * perf: async read file (#3531) * refactor: team permission manager (#3535) * perf: classify org, group and member * refactor: team per manager * fix: missing functions * 4.8.18 test (#3543) * perf: login check * doc * perf: llm model config * perf: team clb config * fix: MemberModal UI (#3553) * fix: adapt MemberModal title and icon * fix: adapt member modal * fix: search input placeholder * fix: add button text * perf: org permission (#3556) * docs:用户答疑的官方文档补充 (#3540) * docs:用户答疑的官方文档补充 * 问题回答的内容修补 * share link random avatar (#3541) * share link random avatar * fix * delete unused code * share page avatar (#3558) * feat: init 4818 * share page avatar * feat: tmp upgrade code (#3559) * feat: tmp upgrade code * fulltext search test * update action * full text tmp code (#3561) * full text tmp code * fix: init * fix: init * remove tmp code * remove tmp code * 4818-alpha * 4.8.18 test (#3562) * full text tmp code * fix: init * upgrade code * account log * account log * perf: dockerfile * upgrade code * chore: update docs app template submission (#3564) --------- Co-authored-by: a.e. <49438478+I-Info@users.noreply.github.com> Co-authored-by: Finley Ge <32237950+FinleyGe@users.noreply.github.com> Co-authored-by: heheer Co-authored-by: Jiangween <145003935+Jiangween@users.noreply.github.com> --- .github/workflows/preview-fastgpt-image.yml | 4 +- dev.md | 2 +- docSite/assets/imgs/dataset1.png | Bin 0 -> 82627 bytes docSite/assets/imgs/dataset2.png | Bin 0 -> 132459 bytes docSite/assets/imgs/template_submission2.png | Bin 47239 -> 69983 bytes docSite/content/zh-cn/docs/development/faq.md | 4 + .../zh-cn/docs/development/upgrading/4818.md | 37 + docSite/content/zh-cn/docs/faq/app.md | 10 +- docSite/content/zh-cn/docs/faq/dataset.md | 49 +- .../guide/plugins/searxng_plugin_guide.md | 12 + .../app-cases/submit_application_template.md | 6 +- packages/global/common/error/code/common.ts | 6 + packages/global/common/error/code/team.ts | 43 +- packages/global/common/error/code/user.ts | 15 +- packages/global/common/file/api.d.ts | 5 +- .../global/common/file/image/constants.ts | 56 -- packages/global/common/file/image/type.d.ts | 4 - packages/global/common/file/tools.ts | 17 + packages/global/common/system/constants.ts | 3 + .../global/common/system/types/index.d.ts | 5 + packages/global/core/ai/model.d.ts | 1 + packages/global/core/app/collaborator.d.ts | 5 +- .../global/core/dataset/collaborator.d.ts | 1 + packages/global/core/dataset/type.d.ts | 9 + .../support/permission/collaborator.d.ts | 16 +- packages/global/support/permission/type.d.ts | 4 +- packages/global/support/user/constant.ts | 1 + .../global/support/user/login/constants.ts | 3 + .../global/support/user/team/org/api.d.ts | 32 + .../global/support/user/team/org/constant.ts | 12 + .../global/support/user/team/org/type.d.ts | 25 + packages/global/support/user/team/type.d.ts | 3 +- packages/global/support/user/utils.ts | 16 + packages/plugins/register.ts | 32 +- packages/plugins/src/searchXNG/index.ts | 10 + .../service/common/file/gridfs/controller.ts | 6 +- .../service/common/file/image/controller.ts | 63 +- packages/service/common/file/image/schema.ts | 23 +- packages/service/common/file/read/utils.ts | 7 +- .../common/middle/reqFrequencyLimit.ts | 7 +- packages/service/common/response/index.ts | 2 +- .../embedding/text-embedding-ada-002.json | 11 + .../core/ai/config/llm/gpt-4o-mini.json | 33 + .../ai/config/rerank/bge-reranker-v2-m3.json | 6 + .../service/core/ai/config/stt/whisper-1.json | 6 + .../service/core/ai/config/tts/tts-1.json | 32 + packages/service/core/app/plugin/utils.ts | 12 +- packages/service/core/chat/chatItemSchema.ts | 13 +- packages/service/core/chat/chatSchema.ts | 12 +- .../core/dataset/collection/controller.ts | 14 +- packages/service/core/dataset/controller.ts | 13 +- .../core/dataset/data/dataTextSchema.ts | 45 ++ packages/service/core/dataset/data/schema.ts | 26 +- .../service/core/dataset/search/controller.ts | 369 ++++++---- packages/service/support/outLink/schema.ts | 1 + .../service/support/permission/auth/org.ts | 43 ++ .../service/support/permission/auth/team.ts | 4 +- .../service/support/permission/controller.ts | 143 ++-- .../support/permission/inheritPermission.ts | 13 +- .../permission/memberGroup/controllers.ts | 75 +-- .../support/permission/org/controllers.ts | 95 +++ .../support/permission/org/orgMemberSchema.ts | 65 ++ .../support/permission/org/orgSchema.ts | 77 +++ packages/service/support/permission/schema.ts | 29 + .../service/support/permission/teamLimit.ts | 4 +- packages/service/support/user/schema.ts | 21 +- .../service/support/user/team/controller.ts | 19 +- .../support/user/team/teamMemberSchema.ts | 10 +- .../service/support/user/team/teamSchema.ts | 5 +- .../service/support/wallet/usage/schema.ts | 6 +- packages/service/worker/htmlStr2Md/utils.ts | 27 +- .../worker/readFile/extension/rawText.ts | 6 +- .../service/worker/readFile/parseOffice.ts | 16 +- packages/templates/register.ts | 24 +- .../web/components/common/Icon/button.tsx | 1 - .../web/components/common/Icon/constants.ts | 7 +- .../Icon/icons/common/downArrowFill.svg | 5 + .../common/Icon/icons/common/wallet.svg | 4 + .../common/Icon/icons/common/wecom.svg | 7 + .../Icon/icons/{support/team => }/key.svg | 0 .../common/Icon/icons/keyPrimary.svg | 9 + .../icons/support/outlink/apikeyLight.svg | 8 - .../components/common/Tabs/FillRowTabs.tsx | 14 +- packages/web/i18n/en/account.json | 7 + packages/web/i18n/en/account_info.json | 6 +- packages/web/i18n/en/account_team.json | 14 +- packages/web/i18n/en/common.json | 27 +- packages/web/i18n/en/login.json | 9 +- packages/web/i18n/en/user.json | 12 +- packages/web/i18n/en/workflow.json | 2 +- packages/web/i18n/zh-CN/account.json | 7 + packages/web/i18n/zh-CN/account_info.json | 6 +- packages/web/i18n/zh-CN/account_team.json | 68 +- packages/web/i18n/zh-CN/common.json | 25 +- packages/web/i18n/zh-CN/login.json | 16 +- packages/web/i18n/zh-CN/user.json | 12 +- packages/web/i18n/zh-CN/workflow.json | 2 +- packages/web/i18n/zh-Hant/account.json | 7 + packages/web/i18n/zh-Hant/account_info.json | 6 +- packages/web/i18n/zh-Hant/account_team.json | 14 +- packages/web/i18n/zh-Hant/common.json | 25 +- packages/web/i18n/zh-Hant/login.json | 11 +- packages/web/i18n/zh-Hant/user.json | 10 +- packages/web/i18n/zh-Hant/workflow.json | 2 +- pnpm-lock.yaml | 56 +- projects/app/Dockerfile | 3 + projects/app/package.json | 2 +- .../public/imgs/avatar/defaultOrgAvatar.svg | 10 + projects/app/public/imgs/modal/key.svg | 1 - projects/app/public/js/iframe.js | 16 + projects/app/src/components/Layout/index.tsx | 17 +- .../common/Modal/EditResourceModal.tsx | 44 +- .../components/common/folder/SlideCard.tsx | 7 - .../core/chat/ChatContainer/ChatBox/index.tsx | 13 - .../src/components/support/apikey/Table.tsx | 4 +- .../permission/ConfigPerModal/index.tsx | 2 +- .../MemberManager/AddMemberModal.tsx | 308 --------- .../permission/MemberManager/ManageModal.tsx | 32 +- .../MemberManager/MemberListCard.tsx | 16 +- .../permission/MemberManager/MemberModal.tsx | 512 ++++++++++++++ .../MemberManager/PermissionSelect.tsx | 11 +- .../MemberManager/PermissionTags.tsx | 5 +- .../permission/MemberManager/context.tsx | 46 +- .../user/inform}/UpdateNotificationModal.tsx | 22 +- .../wallet/NotSufficientModal/index.tsx | 166 ++++- .../support/wallet/QRCodePayModal.tsx | 61 +- .../account/components/AccountContainer.tsx | 2 +- .../pages/account/components/TeamSelector.tsx | 2 +- .../info/components/UpdatePswModal.tsx | 55 +- projects/app/src/pages/account/info/index.tsx | 57 +- .../account/model/components/DefaultModal.tsx | 84 +++ .../app/src/pages/account/model/index.tsx | 67 +- .../account/team/components/EditInfoModal.tsx | 43 +- .../components/GroupManage/GroupInfoModal.tsx | 13 +- .../team/components/GroupManage/index.tsx | 319 +++++---- .../account/team/components/MemberTable.tsx | 280 +++++--- .../team/components/OrgManage/IconButton.tsx | 31 + .../components/OrgManage/OrgInfoModal.tsx | 162 +++++ .../OrgManage/OrgMemberManageModal.tsx | 197 ++++++ .../components/OrgManage/OrgMoveModal.tsx | 74 ++ .../team/components/OrgManage/OrgTree.tsx | 103 +++ .../team/components/OrgManage/index.tsx | 354 ++++++++++ .../components/PermissionManage/index.tsx | 633 +++++++++++------- .../pages/account/team/components/context.tsx | 10 +- projects/app/src/pages/account/team/index.tsx | 244 +------ projects/app/src/pages/api/admin/initv4818.ts | 123 ++++ .../app/src/pages/api/common/file/upload.ts | 1 - .../src/pages/api/common/file/uploadImage.ts | 30 +- .../src/pages/api/common/system/writefile.ts | 25 + projects/app/src/pages/api/core/app/create.ts | 4 +- projects/app/src/pages/api/core/app/del.ts | 5 +- .../pages/api/core/app/httpPlugin/update.ts | 9 +- projects/app/src/pages/api/core/app/list.ts | 22 +- projects/app/src/pages/api/core/app/update.ts | 3 + .../src/pages/api/core/chat/outLink/init.ts | 10 +- .../dataset/collection/create/localFile.ts | 1 - .../app/src/pages/api/core/dataset/create.ts | 40 +- .../app/src/pages/api/core/dataset/delete.ts | 5 + .../app/src/pages/api/core/dataset/list.ts | 20 +- .../app/src/pages/api/core/dataset/update.ts | 3 + .../support/user/account/loginByPassword.ts | 12 +- .../pages/api/support/user/account/update.ts | 31 +- .../pages/app/detail/components/InfoModal.tsx | 102 ++- .../components/WorkflowComponents/AppCard.tsx | 2 +- .../Flow/nodes/render/NodeCard.tsx | 2 +- .../pages/app/list/components/CreateModal.tsx | 46 +- .../list/components/HttpPluginEditModal.tsx | 42 +- .../src/pages/app/list/components/List.tsx | 5 +- projects/app/src/pages/app/list/index.tsx | 10 +- .../dataset/component/ApiDatasetForm.tsx | 2 +- .../pages/dataset/component/MemberManager.tsx | 2 +- .../dataset/detail/components/Info/index.tsx | 38 +- .../pages/dataset/detail/components/Test.tsx | 11 +- .../dataset/list/component/CreateModal.tsx | 45 +- .../src/pages/dataset/list/component/List.tsx | 16 +- projects/app/src/pages/dataset/list/index.tsx | 8 +- .../login/components/ForgetPasswordForm.tsx | 34 +- .../login/components/LoginForm/LoginForm.tsx | 40 +- .../LoginForm/components/FormLayout.tsx | 118 ++-- .../pages/login/components/RegisterForm.tsx | 34 +- projects/app/src/pages/login/fastlogin.tsx | 3 +- projects/app/src/pages/login/index.tsx | 7 +- projects/app/src/pages/login/provider.tsx | 26 +- .../src/pages/price/components/ExtraPlan.tsx | 23 +- .../src/pages/price/components/Standard.tsx | 34 +- projects/app/src/pages/price/index.tsx | 97 ++- .../app/src/service/common/system/index.ts | 32 +- .../app/src/service/core/ai/apiproxy.d.ts | 5 + projects/app/src/service/core/ai/apiproxy.ts | 66 ++ projects/app/src/service/core/app/plugin.ts | 4 +- .../service/core/dataset/data/controller.ts | 33 +- .../app/src/service/events/generateVector.ts | 4 +- projects/app/src/service/mongo.ts | 2 +- projects/app/src/web/common/api/fetch.ts | 2 +- projects/app/src/web/common/api/request.ts | 18 +- .../app/src/web/common/file/controller.ts | 23 +- .../web/common/file/hooks/useSelectFile.tsx | 43 +- .../src/web/common/system/useSystemStore.ts | 21 +- projects/app/src/web/core/dataset/api.ts | 4 + projects/app/src/web/support/user/auth.ts | 11 - .../web/support/user/hooks/useSendCode.tsx | 6 +- .../src/web/support/user/login/constants.ts | 3 + projects/app/src/web/support/user/team/api.ts | 21 +- .../app/src/web/support/user/team/org/api.ts | 30 + .../app/src/web/support/user/useUserStore.ts | 56 +- 205 files changed, 5305 insertions(+), 2428 deletions(-) create mode 100644 docSite/assets/imgs/dataset1.png create mode 100644 docSite/assets/imgs/dataset2.png create mode 100644 docSite/content/zh-cn/docs/development/upgrading/4818.md create mode 100644 packages/global/support/user/login/constants.ts create mode 100644 packages/global/support/user/team/org/api.d.ts create mode 100644 packages/global/support/user/team/org/constant.ts create mode 100644 packages/global/support/user/team/org/type.d.ts create mode 100644 packages/global/support/user/utils.ts create mode 100644 packages/service/core/ai/config/embedding/text-embedding-ada-002.json create mode 100644 packages/service/core/ai/config/llm/gpt-4o-mini.json create mode 100644 packages/service/core/ai/config/rerank/bge-reranker-v2-m3.json create mode 100644 packages/service/core/ai/config/stt/whisper-1.json create mode 100644 packages/service/core/ai/config/tts/tts-1.json create mode 100644 packages/service/core/dataset/data/dataTextSchema.ts create mode 100644 packages/service/support/permission/auth/org.ts create mode 100644 packages/service/support/permission/org/controllers.ts create mode 100644 packages/service/support/permission/org/orgMemberSchema.ts create mode 100644 packages/service/support/permission/org/orgSchema.ts create mode 100644 packages/web/components/common/Icon/icons/common/downArrowFill.svg create mode 100644 packages/web/components/common/Icon/icons/common/wallet.svg create mode 100644 packages/web/components/common/Icon/icons/common/wecom.svg rename packages/web/components/common/Icon/icons/{support/team => }/key.svg (100%) create mode 100644 packages/web/components/common/Icon/icons/keyPrimary.svg delete mode 100644 packages/web/components/common/Icon/icons/support/outlink/apikeyLight.svg create mode 100644 projects/app/public/imgs/avatar/defaultOrgAvatar.svg delete mode 100644 projects/app/public/imgs/modal/key.svg delete mode 100644 projects/app/src/components/support/permission/MemberManager/AddMemberModal.tsx create mode 100644 projects/app/src/components/support/permission/MemberManager/MemberModal.tsx rename projects/app/src/{pages/account/info/components => components/support/user/inform}/UpdateNotificationModal.tsx (79%) create mode 100644 projects/app/src/pages/account/model/components/DefaultModal.tsx create mode 100644 projects/app/src/pages/account/team/components/OrgManage/IconButton.tsx create mode 100644 projects/app/src/pages/account/team/components/OrgManage/OrgInfoModal.tsx create mode 100644 projects/app/src/pages/account/team/components/OrgManage/OrgMemberManageModal.tsx create mode 100644 projects/app/src/pages/account/team/components/OrgManage/OrgMoveModal.tsx create mode 100644 projects/app/src/pages/account/team/components/OrgManage/OrgTree.tsx create mode 100644 projects/app/src/pages/account/team/components/OrgManage/index.tsx create mode 100644 projects/app/src/pages/api/admin/initv4818.ts create mode 100644 projects/app/src/pages/api/common/system/writefile.ts create mode 100644 projects/app/src/service/core/ai/apiproxy.d.ts create mode 100644 projects/app/src/service/core/ai/apiproxy.ts create mode 100644 projects/app/src/web/support/user/team/org/api.ts diff --git a/.github/workflows/preview-fastgpt-image.yml b/.github/workflows/preview-fastgpt-image.yml index 4db6e43ad..9e5780112 100644 --- a/.github/workflows/preview-fastgpt-image.yml +++ b/.github/workflows/preview-fastgpt-image.yml @@ -36,7 +36,7 @@ jobs: password: ${{ secrets.GH_PAT }} - name: Set DOCKER_REPO_TAGGED based on branch or tag run: | - echo "DOCKER_REPO_TAGGED=ghcr.io/${{ github.repository_owner }}/fastgpt-pr:${{ github.event.pull_request.number }}" >> $GITHUB_ENV + echo "DOCKER_REPO_TAGGED=ghcr.io/${{ github.repository_owner }}/fastgpt-pr:${{ github.event.pull_request.head.sha }}" >> $GITHUB_ENV - name: Build image for PR env: DOCKER_REPO_TAGGED: ${{ env.DOCKER_REPO_TAGGED }} @@ -44,7 +44,7 @@ jobs: docker buildx build \ -f projects/app/Dockerfile \ --label "org.opencontainers.image.source=https://github.com/${{ github.repository_owner }}/FastGPT" \ - --label "org.opencontainers.image.description=fastgpt-pr imae" \ + --label "org.opencontainers.image.description=fastgpt-pr image" \ --label "org.opencontainers.image.licenses=Apache" \ --push \ --cache-from=type=local,src=/tmp/.buildx-cache \ diff --git a/dev.md b/dev.md index 373ac626b..2a58d8d30 100644 --- a/dev.md +++ b/dev.md @@ -1,6 +1,6 @@ ## Premise -Since FastGPT is managed in the same way as monorepo, it is recommended to install 'make' first during development. +Since FastGPT is managed in the same way as monorepo, it is recommended to install ‘make’ first during development. monorepo Project Name: diff --git a/docSite/assets/imgs/dataset1.png b/docSite/assets/imgs/dataset1.png new file mode 100644 index 0000000000000000000000000000000000000000..c521ba6812570011b433d896c5f404c92e54efc4 GIT binary patch literal 82627 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�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 D;WANm literal 0 HcmV?d00001 diff --git a/docSite/assets/imgs/template_submission2.png b/docSite/assets/imgs/template_submission2.png index 338d47b1a119fca33d1254719e63c2fb015d48fb..14ca7b91fe35e5a59f63dc50056b3923a95a7c43 100644 GIT binary patch literal 69983 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

Yq*6^XK3Ts`hq$PbIrd8LdAp`MH^%G)) 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ν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

i&m!K^1_t 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 A3jhEB diff --git a/docSite/content/zh-cn/docs/development/faq.md b/docSite/content/zh-cn/docs/development/faq.md index 8f15f7a97..52582e8b1 100644 --- a/docSite/content/zh-cn/docs/development/faq.md +++ b/docSite/content/zh-cn/docs/development/faq.md @@ -19,6 +19,10 @@ images: [] ## 二、通用问题 +### 本地部署的限制 + +具体内容参考https://fael3z0zfze.feishu.cn/wiki/OFpAw8XzAi36Guk8dfucrCKUnjg。 + ### 能否纯本地运行 可以。需要准备好向量模型和LLM模型。 diff --git a/docSite/content/zh-cn/docs/development/upgrading/4818.md b/docSite/content/zh-cn/docs/development/upgrading/4818.md new file mode 100644 index 000000000..0f102c2d6 --- /dev/null +++ b/docSite/content/zh-cn/docs/development/upgrading/4818.md @@ -0,0 +1,37 @@ +--- +title: 'V4.8.18(进行中)' +description: 'FastGPT V4.8.18 更新说明' +icon: 'upgrade' +draft: false +toc: true +weight: 806 +--- + +## 更新指南 + +### 2. 运行升级脚本 + +从任意终端,发起 1 个 HTTP 请求。其中 {{rootkey}} 替换成环境变量里的 `rootkey`;{{host}} 替换成**FastGPT 域名**。 + +```bash +curl --location --request POST 'https://{{host}}/api/admin/initv4818' \ +--header 'rootkey: {{rootkey}}' \ +--header 'Content-Type: application/json' +``` + +会迁移全文检索表,时间较长,迁移期间全文检索会失效,日志中会打印已经迁移的数据长度。 + + +## 完整更新内容 + +1. 新增 - 支持部门架构权限模式。 +2. 新增 - 支持配置自定跨域安全策略,默认全开。 +3. 优化 - 分享链接随机生成用户头像。 +4. 优化 - 图片上传安全校验。并增加头像图片唯一存储,确保不会累计存储。 +5. 优化 - Mongo 全文索引表分离。 +6. 优化 - 知识库检索查询语句合并,同时减少查库数量。 +7. 优化 - 文件编码检测,减少 CSV 文件乱码概率。 +8. 优化 - 异步读取文件内容,减少进程阻塞。 +9. 优化 - 文件阅读,HTML 直接下载,不允许在线阅读。 +10. 修复 - HTML 文件上传,base64 图片无法自动转图片链接。 +11. 修复 - 插件计费错误。 diff --git a/docSite/content/zh-cn/docs/faq/app.md b/docSite/content/zh-cn/docs/faq/app.md index 41e427276..7631fb783 100644 --- a/docSite/content/zh-cn/docs/faq/app.md +++ b/docSite/content/zh-cn/docs/faq/app.md @@ -13,4 +13,12 @@ weight: 908 但是,当连续问题之间的关联性较小,模型判断的准确度可能会受到限制。在这种情况下,我们可以引入全局变量的概念来记录分类结果。在后续的问题分类阶段,首先检查全局变量是否存有分类结果。如果有,那么直接沿用该结果;若没有,则让模型自行判断。 -建议:构建批量运行脚本进行测试,评估问题分类的准确性。 \ No newline at end of file +建议:构建批量运行脚本进行测试,评估问题分类的准确性。 + +## 系统编排配置中的定时执行,如果用户打开分享的连接,停留在那个页面,定时执行触发问题 + +发布后,后台生效。 + +## AI对话回答要求中的Markdown语法取消 + +在针对知识库的回答要求里有, 要给它配置提示词,不然他就是默认的,默认的里面就有该语法。 \ No newline at end of file diff --git a/docSite/content/zh-cn/docs/faq/dataset.md b/docSite/content/zh-cn/docs/faq/dataset.md index e66ebc01e..589b57160 100644 --- a/docSite/content/zh-cn/docs/faq/dataset.md +++ b/docSite/content/zh-cn/docs/faq/dataset.md @@ -14,4 +14,51 @@ weight: 910 ## 知识库配置里的文件处理模型是什么?与索引模型有什么区别? * **文件处理模型**:用于数据处理的【增强处理】和【问答拆分】。在【增强处理】中,生成相关问题和摘要,在【问答拆分】中执行问答对生成。 -* **索引模型**:用于向量化,即通过对文本数据进行处理和组织,构建出一个能够快速查询的数据结构。 \ No newline at end of file +* **索引模型**:用于向量化,即通过对文本数据进行处理和组织,构建出一个能够快速查询的数据结构。 + +## 基于知识库的查询,但是问题相关的答案过多。ai回答到一半就不继续回答。 + +FastGPT回复长度计算公式: + +最大回复=min(配置的最大回复(内置的限制),最大上下文(输入和输出的总和)-历史记录) + +18K模型->输入与输出的和 + +输出增多->输入减小 + +所以可以: + +1. 检查配置的最大回复(回复上限) +2. 减小输入来增大输出,即减小历史记录,在工作流其实也就是“聊天记录” + +配置的最大回复: + +![](/imgs/dataset1.png) + +![](/imgs/dataset2.png) + +1. 私有化部署的时候,后台配模型参数,可以在配置最大上文时候,预留一些空间,比如 128000 的模型,可以只配置 120000, 剩余的空间后续会被安排给输出 + + +## 受到模型上下文的限制,有时候达不到聊天记录的轮次,连续对话字数过多就会报上下文不够的错误。 + +FastGPT回复长度计算公式: + +最大回复=min(配置的最大回复(内置的限制),最大上下文(输入和输出的总和)-历史记录) + +18K模型->输入与输出的和 + +输出增多->输入减小 + +所以可以: + +1. 检查配置的最大回复(回复上限) +2. 减小输入来增大输出,即减小历史记录,在工作流其实也就是“聊天记录” + +配置的最大回复: + +![](/imgs/dataset1.png) + +![](/imgs/dataset2.png) + +1. 私有化部署的时候,后台配模型参数,可以在配置最大上文时候,预留一些空间,比如 128000 的模型,可以只配置 120000, 剩余的空间后续会被安排给输出 \ No newline at end of file diff --git a/docSite/content/zh-cn/docs/guide/plugins/searxng_plugin_guide.md b/docSite/content/zh-cn/docs/guide/plugins/searxng_plugin_guide.md index 36e1d2c60..6652d7ff1 100644 --- a/docSite/content/zh-cn/docs/guide/plugins/searxng_plugin_guide.md +++ b/docSite/content/zh-cn/docs/guide/plugins/searxng_plugin_guide.md @@ -160,6 +160,18 @@ default_doi_resolver: 'oadoi.org' } ``` +* 搜索结果为空时会返回友好提示: + +```Bash +{ + "result": "[]", + "error": { + "message": "No search results", + "code": 500 + } +} +``` + * 失败时通过 Promise.reject 可能返回错误信息: ```Bash diff --git a/docSite/content/zh-cn/docs/use-cases/app-cases/submit_application_template.md b/docSite/content/zh-cn/docs/use-cases/app-cases/submit_application_template.md index 1df015e97..2ef61eaf9 100644 --- a/docSite/content/zh-cn/docs/use-cases/app-cases/submit_application_template.md +++ b/docSite/content/zh-cn/docs/use-cases/app-cases/submit_application_template.md @@ -32,11 +32,11 @@ weight: 602 1. ### 创建应用模板 -应用模板配置以及相关资源,都会在 **projects/app/public/appMarketTemplates** 目录下。 +应用模板配置以及相关资源,都会在 **packages/templates/src** 目录下。 ![](/imgs/template_submission2.png) -1. 在 **projects/app/public/appMarketTemplates** 目录下,创建一个文件夹,名称为模板对应的 id。 +1. 在**packages/templates/src** 目录下,创建一个文件夹,名称为模板对应的 id。 2. 在刚刚创建的文件夹中,再创建一个 **template.json** 文件,复制粘贴并填写如下配置: ```JSON @@ -83,4 +83,4 @@ weight: 602 - 写清楚模板的介绍和功能 - 配上模板运行的效果图 -- 模板参数填写说明,需要在 PR 中写清楚。例如,有些模板需要去某个提供商申请 key,需要附上对应的地址和教程,后续我们会加入到文档中。 \ No newline at end of file +- 模板参数填写说明,需要在 PR 中写清楚。例如,有些模板需要去某个提供商申请 key,需要附上对应的地址和教程,后续我们会加入到文档中。 diff --git a/packages/global/common/error/code/common.ts b/packages/global/common/error/code/common.ts index 13f74643b..38d76dbec 100644 --- a/packages/global/common/error/code/common.ts +++ b/packages/global/common/error/code/common.ts @@ -1,14 +1,20 @@ +import { i18nT } from '../../../../web/i18n/utils'; import { ErrType } from '../errorCode'; /* dataset: 507000 */ const startCode = 507000; export enum CommonErrEnum { + invalidParams = 'invalidParams', fileNotFound = 'fileNotFound', unAuthFile = 'unAuthFile', missingParams = 'missingParams', inheritPermissionError = 'inheritPermissionError' } const datasetErr = [ + { + statusText: CommonErrEnum.fileNotFound, + message: i18nT('common:error.invalid_params') + }, { statusText: CommonErrEnum.fileNotFound, message: 'error.fileNotFound' diff --git a/packages/global/common/error/code/team.ts b/packages/global/common/error/code/team.ts index 8ad9abe02..7c2ab6790 100644 --- a/packages/global/common/error/code/team.ts +++ b/packages/global/common/error/code/team.ts @@ -1,9 +1,11 @@ -import { ErrType } from '../errorCode'; import { i18nT } from '../../../../web/i18n/utils'; +import type { ErrType } from '../errorCode'; /* team: 500000 */ export enum TeamErrEnum { + notUser = 'notUser', teamOverSize = 'teamOverSize', unAuthTeam = 'unAuthTeam', + teamMemberOverSize = 'teamMemberOverSize', aiPointsNotEnough = 'aiPointsNotEnough', datasetSizeNotEnough = 'datasetSizeNotEnough', datasetAmountNotEnough = 'datasetAmountNotEnough', @@ -14,11 +16,22 @@ export enum TeamErrEnum { groupNameEmpty = 'groupNameEmpty', groupNameDuplicate = 'groupNameDuplicate', groupNotExist = 'groupNotExist', + orgMemberNotExist = 'orgMemberNotExist', + orgMemberDuplicated = 'orgMemberDuplicated', + orgNotExist = 'orgNotExist', + orgParentNotExist = 'orgParentNotExist', + cannotMoveToSubPath = 'cannotMoveToSubPath', + cannotModifyRootOrg = 'cannotModifyRootOrg', + cannotDeleteNonEmptyOrg = 'cannotDeleteNonEmptyOrg', cannotDeleteDefaultGroup = 'cannotDeleteDefaultGroup', userNotActive = 'userNotActive' } const teamErr = [ + { + statusText: TeamErrEnum.notUser, + message: i18nT('common:code_error.team_error.not_user') + }, { statusText: TeamErrEnum.teamOverSize, message: i18nT('common:code_error.team_error.over_size') @@ -71,6 +84,34 @@ const teamErr = [ { statusText: TeamErrEnum.userNotActive, message: i18nT('common:code_error.team_error.user_not_active') + }, + { + statusText: TeamErrEnum.orgMemberNotExist, + message: i18nT('common:code_error.team_error.org_member_not_exist') + }, + { + statusText: TeamErrEnum.orgMemberDuplicated, + message: i18nT('common:code_error.team_error.org_member_duplicated') + }, + { + statusText: TeamErrEnum.orgNotExist, + message: i18nT('common:code_error.team_error.org_not_exist') + }, + { + statusText: TeamErrEnum.orgParentNotExist, + message: i18nT('common:code_error.team_error.org_parent_not_exist') + }, + { + statusText: TeamErrEnum.cannotMoveToSubPath, + message: i18nT('common:code_error.team_error.cannot_move_to_sub_path') + }, + { + statusText: TeamErrEnum.cannotModifyRootOrg, + message: i18nT('common:code_error.team_error.cannot_modify_root_org') + }, + { + statusText: TeamErrEnum.cannotDeleteNonEmptyOrg, + message: i18nT('common:code_error.team_error.cannot_delete_non_empty_org') } ]; diff --git a/packages/global/common/error/code/user.ts b/packages/global/common/error/code/user.ts index e58136041..98d8e9a0f 100644 --- a/packages/global/common/error/code/user.ts +++ b/packages/global/common/error/code/user.ts @@ -2,25 +2,16 @@ import { ErrType } from '../errorCode'; import { i18nT } from '../../../../web/i18n/utils'; /* team: 503000 */ export enum UserErrEnum { - unAuthUser = 'unAuthUser', unAuthRole = 'unAuthRole', - binVisitor = 'binVisitor', + account_psw_error = 'account_psw_error', balanceNotEnough = 'balanceNotEnough', unAuthSso = 'unAuthSso' } const errList = [ { - statusText: UserErrEnum.unAuthUser, - message: i18nT('common:code_error.user_error.un_auth_user') + statusText: UserErrEnum.account_psw_error, + message: i18nT('common:code_error.account_error') }, - { - statusText: UserErrEnum.binVisitor, - message: i18nT('common:code_error.user_error.bin_visitor') - }, // 身份校验未通过 - { - statusText: UserErrEnum.binVisitor, - message: i18nT('common:code_error.user_error.bin_visitor_guest') - }, // 游客身份 { statusText: UserErrEnum.balanceNotEnough, message: i18nT('common:code_error.user_error.balance_not_enough') diff --git a/packages/global/common/file/api.d.ts b/packages/global/common/file/api.d.ts index e26033ae7..5da698b58 100644 --- a/packages/global/common/file/api.d.ts +++ b/packages/global/common/file/api.d.ts @@ -1,10 +1,7 @@ -import { MongoImageTypeEnum } from './image/constants'; import { OutLinkChatAuthProps } from '../../support/permission/chat.d'; export type preUploadImgProps = OutLinkChatAuthProps & { - type: `${MongoImageTypeEnum}`; - - expiredTime?: Date; + // expiredTime?: Date; metadata?: Record; }; export type UploadImgProps = preUploadImgProps & { diff --git a/packages/global/common/file/image/constants.ts b/packages/global/common/file/image/constants.ts index 6a178e2af..5e511e4b2 100644 --- a/packages/global/common/file/image/constants.ts +++ b/packages/global/common/file/image/constants.ts @@ -1,61 +1,5 @@ export const imageBaseUrl = '/api/system/img/'; -export enum MongoImageTypeEnum { - systemAvatar = 'systemAvatar', - appAvatar = 'appAvatar', - pluginAvatar = 'pluginAvatar', - datasetAvatar = 'datasetAvatar', - userAvatar = 'userAvatar', - teamAvatar = 'teamAvatar', - groupAvatar = 'groupAvatar', - - chatImage = 'chatImage', - collectionImage = 'collectionImage' -} -export const mongoImageTypeMap = { - [MongoImageTypeEnum.systemAvatar]: { - label: 'appAvatar', - unique: true - }, - [MongoImageTypeEnum.appAvatar]: { - label: 'appAvatar', - unique: true - }, - [MongoImageTypeEnum.pluginAvatar]: { - label: 'pluginAvatar', - unique: true - }, - [MongoImageTypeEnum.datasetAvatar]: { - label: 'datasetAvatar', - unique: true - }, - [MongoImageTypeEnum.userAvatar]: { - label: 'userAvatar', - unique: true - }, - [MongoImageTypeEnum.teamAvatar]: { - label: 'teamAvatar', - unique: true - }, - [MongoImageTypeEnum.groupAvatar]: { - label: 'groupAvatar', - unique: true - }, - - [MongoImageTypeEnum.chatImage]: { - label: 'chatImage', - unique: false - }, - [MongoImageTypeEnum.collectionImage]: { - label: 'collectionImage', - unique: false - } -}; - -export const uniqueImageTypeList = Object.entries(mongoImageTypeMap) - .filter(([key, value]) => value.unique) - .map(([key]) => key as `${MongoImageTypeEnum}`); - export const FolderIcon = 'file/fill/folder'; export const FolderImgUrl = '/imgs/files/folder.svg'; export const HttpPluginImgUrl = '/imgs/app/httpPluginFill.svg'; diff --git a/packages/global/common/file/image/type.d.ts b/packages/global/common/file/image/type.d.ts index 6fe274794..320df97fd 100644 --- a/packages/global/common/file/image/type.d.ts +++ b/packages/global/common/file/image/type.d.ts @@ -1,12 +1,8 @@ -import { MongoImageTypeEnum } from './constants'; - export type MongoImageSchemaType = { _id: string; teamId: string; binary: Buffer; - createTime: Date; expiredTime?: Date; - type: `${MongoImageTypeEnum}`; metadata?: { mime?: string; // image mime type. diff --git a/packages/global/common/file/tools.ts b/packages/global/common/file/tools.ts index df0de53c0..4f75f4e5d 100644 --- a/packages/global/common/file/tools.ts +++ b/packages/global/common/file/tools.ts @@ -2,6 +2,7 @@ import { detect } from 'jschardet'; import { documentFileType, imageFileType } from './constants'; import { ChatFileTypeEnum } from '../../core/chat/constants'; import { UserChatItemValueItemType } from '../../core/chat/type'; +import * as fs from 'fs'; export const formatFileSize = (bytes: number): string => { if (bytes === 0) return '0 B'; @@ -16,6 +17,22 @@ export const formatFileSize = (bytes: number): string => { export const detectFileEncoding = (buffer: Buffer) => { return detect(buffer.slice(0, 200))?.encoding?.toLocaleLowerCase(); }; +export const detectFileEncodingByPath = async (path: string) => { + // Get 64KB file head + const MAX_BYTES = 64 * 1024; + const buffer = Buffer.alloc(MAX_BYTES); + + const fd = await fs.promises.open(path, 'r'); + try { + // Read file head + const { bytesRead } = await fd.read(buffer, 0, MAX_BYTES, 0); + const actualBuffer = buffer.slice(0, bytesRead); + + return detect(actualBuffer)?.encoding?.toLocaleLowerCase(); + } finally { + await fd.close(); + } +}; // Url => user upload file type export const parseUrlToFileType = (url: string): UserChatItemValueItemType['file'] | undefined => { diff --git a/packages/global/common/system/constants.ts b/packages/global/common/system/constants.ts index 1ca44a611..4dcc4d276 100644 --- a/packages/global/common/system/constants.ts +++ b/packages/global/common/system/constants.ts @@ -1,6 +1,9 @@ export const HUMAN_ICON = `/icon/human.svg`; export const LOGO_ICON = `/icon/logo.svg`; export const HUGGING_FACE_ICON = `/imgs/model/huggingface.svg`; + export const DEFAULT_TEAM_AVATAR = `/imgs/avatar/defaultTeamAvatar.svg`; +export const DEFAULT_ORG_AVATAR = '/imgs/avatar/defaultOrgAvatar.svg'; +export const DEFAULT_USER_AVATAR = '/imgs/avatar/BlueAvatar.svg'; export const isProduction = process.env.NODE_ENV === 'production'; diff --git a/packages/global/common/system/types/index.d.ts b/packages/global/common/system/types/index.d.ts index 7cc24da41..90bcb7dfd 100644 --- a/packages/global/common/system/types/index.d.ts +++ b/packages/global/common/system/types/index.d.ts @@ -73,6 +73,11 @@ export type FastGPTFeConfigsType = { google?: string; wechat?: string; dingtalk?: string; + wecom?: { + corpid?: string; + agentid?: string; + secret?: string; + }; microsoft?: { clientId?: string; tenantId?: string; diff --git a/packages/global/core/ai/model.d.ts b/packages/global/core/ai/model.d.ts index 83f13eb81..533ced31d 100644 --- a/packages/global/core/ai/model.d.ts +++ b/packages/global/core/ai/model.d.ts @@ -53,6 +53,7 @@ export type VectorModelItemType = PriceType & { }; export type ReRankModelItemType = PriceType & { + provider: ModelProviderIdType; model: string; name: string; requestUrl: string; diff --git a/packages/global/core/app/collaborator.d.ts b/packages/global/core/app/collaborator.d.ts index ca0fec721..66a456379 100644 --- a/packages/global/core/app/collaborator.d.ts +++ b/packages/global/core/app/collaborator.d.ts @@ -1,6 +1,6 @@ -import { RequireOnlyOne } from '../../common/type/utils'; +import type { RequireOnlyOne } from '../../common/type/utils'; import { - UpdateClbPermissionProps, + type UpdateClbPermissionProps, UpdatePermissionBody } from '../../support/permission/collaborator'; import { PermissionValueType } from '../../support/permission/type'; @@ -14,4 +14,5 @@ export type AppCollaboratorDeleteParams = { } & RequireOnlyOne<{ tmbId: string; groupId: string; + orgId: string; }>; diff --git a/packages/global/core/dataset/collaborator.d.ts b/packages/global/core/dataset/collaborator.d.ts index 7f33f4d51..672430c1d 100644 --- a/packages/global/core/dataset/collaborator.d.ts +++ b/packages/global/core/dataset/collaborator.d.ts @@ -11,4 +11,5 @@ export type DatasetCollaboratorDeleteParams = { } & RequireOnlyOne<{ tmbId: string; groupId: string; + orgId: string; }>; diff --git a/packages/global/core/dataset/type.d.ts b/packages/global/core/dataset/type.d.ts index 1b4dae45c..7a772f78d 100644 --- a/packages/global/core/dataset/type.d.ts +++ b/packages/global/core/dataset/type.d.ts @@ -112,6 +112,15 @@ export type DatasetDataSchemaType = { rebuilding?: boolean; }; +export type DatasetDataTextSchemaType = { + _id: string; + teamId: string; + datasetId: string; + collectionId: string; + dataId: string; + fullTextToken: string; +}; + export type DatasetTrainingSchemaType = { _id: string; userId: string; diff --git a/packages/global/support/permission/collaborator.d.ts b/packages/global/support/permission/collaborator.d.ts index 60a84a9d5..af7ee84e1 100644 --- a/packages/global/support/permission/collaborator.d.ts +++ b/packages/global/support/permission/collaborator.d.ts @@ -10,22 +10,18 @@ export type CollaboratorItemType = { } & RequireOnlyOne<{ tmbId: string; groupId: string; + orgId: string; }>; export type UpdateClbPermissionProps = { members?: string[]; groups?: string[]; + orgs?: string[]; permission: PermissionValueType; }; -export type DeleteClbPermissionProps = RequireOnlyOne<{ - tmbId: string; - groupId: string; -}>; - -export type UpdatePermissionBody = { - permission: PermissionValueType; -} & RequireOnlyOne<{ - memberId: string; - groupId: string; +export type DeletePermissionQuery = RequireOnlyOne<{ + tmbId?: string; + groupId?: string; + orgId?: string; }>; diff --git a/packages/global/support/permission/type.d.ts b/packages/global/support/permission/type.d.ts index 619f8503e..f473d2941 100644 --- a/packages/global/support/permission/type.d.ts +++ b/packages/global/support/permission/type.d.ts @@ -1,8 +1,9 @@ import { UserModelSchema } from '../user/type'; import { RequireOnlyOne } from '../../common/type/utils'; import { TeamMemberSchema } from '../user/team/type'; -import { AuthUserTypeEnum, PermissionKeyEnum, PerResourceTypeEnum } from './constant'; import { MemberGroupSchemaType } from './memberGroup/type'; +import type { TeamMemberWithUserSchema } from '../user/team/type'; +import { AuthUserTypeEnum, type PermissionKeyEnum, type PerResourceTypeEnum } from './constant'; // PermissionValueType, the type of permission's value is a number, which is a bit field actually. // It is spired by the permission system in Linux. @@ -29,6 +30,7 @@ export type ResourcePermissionType = { } & RequireOnlyOne<{ tmbId: string; groupId: string; + orgId: string; }>; export type ResourcePerWithTmbWithUser = Omit & { diff --git a/packages/global/support/user/constant.ts b/packages/global/support/user/constant.ts index bd696afc7..8d8d24e27 100644 --- a/packages/global/support/user/constant.ts +++ b/packages/global/support/user/constant.ts @@ -17,5 +17,6 @@ export enum OAuthEnum { wechat = 'wechat', microsoft = 'microsoft', dingtalk = 'dingtalk', + wecom = 'wecom', sso = 'sso' } diff --git a/packages/global/support/user/login/constants.ts b/packages/global/support/user/login/constants.ts new file mode 100644 index 000000000..0093f9367 --- /dev/null +++ b/packages/global/support/user/login/constants.ts @@ -0,0 +1,3 @@ +export function checkIsWecomTerminal() { + return /wxwork/i.test(navigator.userAgent); +} diff --git a/packages/global/support/user/team/org/api.d.ts b/packages/global/support/user/team/org/api.d.ts new file mode 100644 index 000000000..69ca09796 --- /dev/null +++ b/packages/global/support/user/team/org/api.d.ts @@ -0,0 +1,32 @@ +export type postCreateOrgData = { + name: string; + parentId: string; + description?: string; + avatar?: string; +}; + +export type putUpdateOrgMembersData = { + orgId: string; + members: { + tmbId: string; + // role: `${OrgMemberRole}`; + }[]; +}; + +export type putUpdateOrgData = { + orgId: string; + name?: string; + avatar?: string; + description?: string; +}; + +export type putMoveOrgType = { + orgId: string; + targetOrgId: string; +}; + +// type putChnageOrgOwnerData = { +// orgId: string; +// tmbId: string; +// toAdmin?: boolean; +// }; diff --git a/packages/global/support/user/team/org/constant.ts b/packages/global/support/user/team/org/constant.ts new file mode 100644 index 000000000..370cdad82 --- /dev/null +++ b/packages/global/support/user/team/org/constant.ts @@ -0,0 +1,12 @@ +import { OrgSchemaType } from './type'; + +export const OrgCollectionName = 'team_orgs'; +export const OrgMemberCollectionName = 'team_org_members'; + +export const getOrgChildrenPath = (org: OrgSchemaType) => `${org.path}/${org.pathId}`; + +// export enum OrgMemberRole { +// owner = 'owner', +// admin = 'admin', +// member = 'member' +// } diff --git a/packages/global/support/user/team/org/type.d.ts b/packages/global/support/user/team/org/type.d.ts new file mode 100644 index 000000000..ca4a73292 --- /dev/null +++ b/packages/global/support/user/team/org/type.d.ts @@ -0,0 +1,25 @@ +import type { TeamPermission } from 'support/permission/user/controller'; +import { ResourcePermissionType } from '../type'; + +type OrgSchemaType = { + _id: string; + teamId: string; + pathId: string; + path: string; + name: string; + avatar?: string; + description?: string; + updateTime: Date; +}; + +type OrgMemberSchemaType = { + teamId: string; + orgId: string; + tmbId: string; +}; + +type OrgType = Omit & { + avatar: string; + members: OrgMemberSchemaType[]; + permission: TeamPermission; +}; diff --git a/packages/global/support/user/team/type.d.ts b/packages/global/support/user/team/type.d.ts index 9914e631a..9c7dc12b4 100644 --- a/packages/global/support/user/team/type.d.ts +++ b/packages/global/support/user/team/type.d.ts @@ -55,10 +55,11 @@ export type TeamMemberWithTeamAndUserSchema = TeamMemberSchema & { export type TeamTmbItemType = { userId: string; teamId: string; + teamAvatar?: string; teamName: string; memberName: string; avatar: string; - balance: number; + balance?: number; tmbId: string; teamDomain: string; defaultTeam: boolean; diff --git a/packages/global/support/user/utils.ts b/packages/global/support/user/utils.ts new file mode 100644 index 000000000..b0db78a92 --- /dev/null +++ b/packages/global/support/user/utils.ts @@ -0,0 +1,16 @@ +export const getRandomUserAvatar = () => { + const defaultAvatars = [ + '/imgs/avatar/RoyalBlueAvatar.svg', + '/imgs/avatar/PurpleAvatar.svg', + '/imgs/avatar/AdoraAvatar.svg', + '/imgs/avatar/OrangeAvatar.svg', + '/imgs/avatar/RedAvatar.svg', + '/imgs/avatar/GrayModernAvatar.svg', + '/imgs/avatar/TealAvatar.svg', + '/imgs/avatar/GreenAvatar.svg', + '/imgs/avatar/BrightBlueAvatar.svg', + '/imgs/avatar/BlueAvatar.svg' + ]; + + return defaultAvatars[Math.floor(Math.random() * defaultAvatars.length)]; +}; diff --git a/packages/plugins/register.ts b/packages/plugins/register.ts index 2509422d2..9989fbc78 100644 --- a/packages/plugins/register.ts +++ b/packages/plugins/register.ts @@ -35,24 +35,26 @@ export const list = [...staticPluginList, ...packagePluginList]; /* Get plugins */ export const getCommunityPlugins = () => { - return list.map((name) => { - const config = require(`./src/${name}/template.json`); + return Promise.all( + list.map>(async (name) => { + const config = (await import(`./src/${name}/template.json`))?.default; - const isFolder = list.find((item) => item.startsWith(`${name}/`)); + const isFolder = list.find((item) => item.startsWith(`${name}/`)); - const parentIdList = name.split('/').slice(0, -1); - const parentId = - parentIdList.length > 0 ? `${PluginSourceEnum.community}-${parentIdList.join('/')}` : null; + const parentIdList = name.split('/').slice(0, -1); + const parentId = + parentIdList.length > 0 ? `${PluginSourceEnum.community}-${parentIdList.join('/')}` : null; - return { - ...config, - id: `${PluginSourceEnum.community}-${name}`, - isFolder, - parentId, - isActive: true, - isOfficial: true - }; - }); + return { + ...config, + id: `${PluginSourceEnum.community}-${name}`, + isFolder, + parentId, + isActive: true, + isOfficial: true + }; + }) + ); }; export const getSystemPluginTemplates = () => { diff --git a/packages/plugins/src/searchXNG/index.ts b/packages/plugins/src/searchXNG/index.ts index c325f64a1..eebe87adc 100644 --- a/packages/plugins/src/searchXNG/index.ts +++ b/packages/plugins/src/searchXNG/index.ts @@ -48,6 +48,16 @@ const main = async (props: Props, retry = 3): Response => { }); }); + if (results.length === 0) { + return { + result: JSON.stringify([]), + error: { + message: 'No search results', + code: 500 + } + }; + } + return { result: JSON.stringify(results.slice(0, 10)) }; diff --git a/packages/service/common/file/gridfs/controller.ts b/packages/service/common/file/gridfs/controller.ts index a5693e39b..af304714c 100644 --- a/packages/service/common/file/gridfs/controller.ts +++ b/packages/service/common/file/gridfs/controller.ts @@ -4,7 +4,7 @@ import fsp from 'fs/promises'; import fs from 'fs'; import { DatasetFileSchema } from '@fastgpt/global/core/dataset/type'; import { MongoChatFileSchema, MongoDatasetFileSchema } from './schema'; -import { detectFileEncoding } from '@fastgpt/global/common/file/tools'; +import { detectFileEncoding, detectFileEncodingByPath } from '@fastgpt/global/common/file/tools'; import { CommonErrEnum } from '@fastgpt/global/common/error/code/common'; import { MongoRawTextBuffer } from '../../buffer/rawText/schema'; import { readRawContentByFileBuffer } from '../read/utils'; @@ -36,7 +36,6 @@ export async function uploadFile({ path, filename, contentType, - encoding, metadata = {} }: { bucketName: `${BucketNameEnum}`; @@ -45,7 +44,6 @@ export async function uploadFile({ path: string; filename: string; contentType?: string; - encoding: string; metadata?: Record; }) { if (!path) return Promise.reject(`filePath is empty`); @@ -59,7 +57,7 @@ export async function uploadFile({ // Add default metadata metadata.teamId = teamId; metadata.uid = uid; - metadata.encoding = encoding; + metadata.encoding = await detectFileEncodingByPath(path); // create a gridfs bucket const bucket = getGridBucket(bucketName); diff --git a/packages/service/common/file/image/controller.ts b/packages/service/common/file/image/controller.ts index 3a8e6f299..27bc7ade5 100644 --- a/packages/service/common/file/image/controller.ts +++ b/packages/service/common/file/image/controller.ts @@ -1,43 +1,92 @@ import { UploadImgProps } from '@fastgpt/global/common/file/api'; import { imageBaseUrl } from '@fastgpt/global/common/file/image/constants'; import { MongoImage } from './schema'; -import { ClientSession } from '../../../common/mongo'; +import { ClientSession, Types } from '../../../common/mongo'; import { guessBase64ImageType } from '../utils'; import { readFromSecondary } from '../../mongo/utils'; +import { addHours } from 'date-fns'; export const maxImgSize = 1024 * 1024 * 12; const base64MimeRegex = /data:image\/([^\)]+);base64/; export async function uploadMongoImg({ - type, base64Img, teamId, - expiredTime, metadata, - shareId + shareId, + forever = false }: UploadImgProps & { teamId: string; + forever?: Boolean; }) { if (base64Img.length > maxImgSize) { return Promise.reject('Image too large'); } const [base64Mime, base64Data] = base64Img.split(','); + // Check if mime type is valid + if (!base64MimeRegex.test(base64Mime)) { + return Promise.reject('Invalid image mime type'); + } + const mime = `image/${base64Mime.match(base64MimeRegex)?.[1] ?? 'image/jpeg'}`; const binary = Buffer.from(base64Data, 'base64'); const extension = mime.split('/')[1]; const { _id } = await MongoImage.create({ - type, teamId, binary, - expiredTime, metadata: Object.assign({ mime }, metadata), - shareId + shareId, + expiredTime: forever ? undefined : addHours(new Date(), 1) }); return `${process.env.FE_DOMAIN || ''}${process.env.NEXT_PUBLIC_BASE_URL || ''}${imageBaseUrl}${String(_id)}.${extension}`; } +const getIdFromPath = (path?: string) => { + if (!path) return; + + const paths = path.split('/'); + const name = paths[paths.length - 1]; + + if (!name) return; + + const id = name.split('.')[0]; + if (!id || !Types.ObjectId.isValid(id)) return; + + return id; +}; +// 删除旧的头像,新的头像去除过期时间 +export const refreshSourceAvatar = async ( + path?: string, + oldPath?: string, + session?: ClientSession +) => { + const newId = getIdFromPath(path); + const oldId = getIdFromPath(oldPath); + + if (!newId) return; + + await MongoImage.updateOne({ _id: newId }, { $unset: { expiredTime: 1 } }, { session }); + + if (oldId) { + await MongoImage.deleteOne({ _id: oldId }, { session }); + } +}; +export const removeImageByPath = (path?: string, session?: ClientSession) => { + if (!path) return; + + const paths = path.split('/'); + const name = paths[paths.length - 1]; + + if (!name) return; + + const id = name.split('.')[0]; + if (!id || !Types.ObjectId.isValid(id)) return; + + return MongoImage.deleteOne({ _id: id }, { session }); +}; + export async function readMongoImg({ id }: { id: string }) { const formatId = id.replace(/\.[^/.]+$/, ''); diff --git a/packages/service/common/file/image/schema.ts b/packages/service/common/file/image/schema.ts index f5c62d5cd..1418fa479 100644 --- a/packages/service/common/file/image/schema.ts +++ b/packages/service/common/file/image/schema.ts @@ -1,8 +1,7 @@ import { TeamCollectionName } from '@fastgpt/global/support/user/team/constant'; -import { connectionMongo, getMongoModel, type Model } from '../../mongo'; +import { connectionMongo, getMongoModel } from '../../mongo'; import { MongoImageSchemaType } from '@fastgpt/global/common/file/image/type.d'; -import { mongoImageTypeMap } from '@fastgpt/global/common/file/image/constants'; -const { Schema, model, models } = connectionMongo; +const { Schema } = connectionMongo; const ImageSchema = new Schema({ teamId: { @@ -14,27 +13,15 @@ const ImageSchema = new Schema({ type: Date, default: () => new Date() }, - expiredTime: { - type: Date - }, - binary: { - type: Buffer - }, - type: { - type: String, - enum: Object.keys(mongoImageTypeMap), - required: true - }, - metadata: { - type: Object - } + expiredTime: Date, + binary: Buffer, + metadata: Object }); try { // tts expired(60 Minutes) ImageSchema.index({ expiredTime: 1 }, { expireAfterSeconds: 60 * 60 }); ImageSchema.index({ type: 1 }); - ImageSchema.index({ createTime: 1 }); // delete related img ImageSchema.index({ teamId: 1, 'metadata.relatedId': 1 }); } catch (error) { diff --git a/packages/service/common/file/read/utils.ts b/packages/service/common/file/read/utils.ts index 0c3cb1ba9..7f41f6c47 100644 --- a/packages/service/common/file/read/utils.ts +++ b/packages/service/common/file/read/utils.ts @@ -1,5 +1,4 @@ import { uploadMongoImg } from '../image/controller'; -import { MongoImageTypeEnum } from '@fastgpt/global/common/file/image/constants'; import FormData from 'form-data'; import { WorkerNameEnum, runWorker } from '../../../worker/utils'; @@ -8,7 +7,6 @@ import type { ReadFileResponse } from '../../../worker/readFile/type'; import axios from 'axios'; import { addLog } from '../../system/log'; import { batchRun } from '@fastgpt/global/common/fn/utils'; -import { addHours } from 'date-fns'; import { matchMdImgTextAndUpload } from '@fastgpt/global/common/string/markdown'; export type readRawTextByLocalFileParams = { @@ -22,7 +20,7 @@ export const readRawTextByLocalFile = async (params: readRawTextByLocalFileParam const extension = path?.split('.')?.pop()?.toLowerCase() || ''; - const buffer = fs.readFileSync(path); + const buffer = await fs.promises.readFile(path); const { rawText } = await readRawContentByFileBuffer({ extension, @@ -114,10 +112,9 @@ export const readRawContentByFileBuffer = async ({ if (imageList) { await batchRun(imageList, async (item) => { const src = await uploadMongoImg({ - type: MongoImageTypeEnum.collectionImage, base64Img: `data:${item.mime};base64,${item.base64}`, teamId, - expiredTime: addHours(new Date(), 1), + // expiredTime: addHours(new Date(), 1), metadata: { ...metadata, mime: item.mime diff --git a/packages/service/common/middle/reqFrequencyLimit.ts b/packages/service/common/middle/reqFrequencyLimit.ts index 8f950c75d..de7249483 100644 --- a/packages/service/common/middle/reqFrequencyLimit.ts +++ b/packages/service/common/middle/reqFrequencyLimit.ts @@ -9,10 +9,10 @@ import { jsonRes } from '../response'; // unit: times/s // how to use? // export default NextAPI(useQPSLimit(10), handler); // limit 10 times per second for a ip -export function useReqFrequencyLimit(seconds: number, limit: number) { +export function useReqFrequencyLimit(seconds: number, limit: number, force = false) { return async (req: ApiRequestProps, res: NextApiResponse) => { const ip = requestIp.getClientIp(req); - if (!ip || process.env.USE_IP_LIMIT !== 'true') { + if (!ip || (process.env.USE_IP_LIMIT !== 'true' && !force)) { return; } try { @@ -22,10 +22,9 @@ export function useReqFrequencyLimit(seconds: number, limit: number) { expiredTime: addSeconds(new Date(), seconds) }); } catch (_) { - res.status(429); jsonRes(res, { code: 429, - message: ERROR_ENUM.tooManyRequest + error: ERROR_ENUM.tooManyRequest }); } }; diff --git a/packages/service/common/response/index.ts b/packages/service/common/response/index.ts index a6586d077..a6de2e38a 100644 --- a/packages/service/common/response/index.ts +++ b/packages/service/common/response/index.ts @@ -33,7 +33,7 @@ export const jsonRes = ( addLog.error(`Api response error: ${url}`, ERROR_RESPONSE[errResponseKey]); - return res.json(ERROR_RESPONSE[errResponseKey]); + return res.status(code).json(ERROR_RESPONSE[errResponseKey]); } // another error diff --git a/packages/service/core/ai/config/embedding/text-embedding-ada-002.json b/packages/service/core/ai/config/embedding/text-embedding-ada-002.json new file mode 100644 index 000000000..4f6290f75 --- /dev/null +++ b/packages/service/core/ai/config/embedding/text-embedding-ada-002.json @@ -0,0 +1,11 @@ +{ + "provider": "OpenAI", + "model": "text-embedding-ada-002", + "name": "text-embedding-ada-002", + + "defaultToken": 512, // 默认分块 token + "maxToken": 3000, // 最大分块 token + "weight": 0, // 权重 + + "charsPointsPrice": 0 // 积分/1k token +} diff --git a/packages/service/core/ai/config/llm/gpt-4o-mini.json b/packages/service/core/ai/config/llm/gpt-4o-mini.json new file mode 100644 index 000000000..0bcf7f6de --- /dev/null +++ b/packages/service/core/ai/config/llm/gpt-4o-mini.json @@ -0,0 +1,33 @@ +{ + "provider": "OpenAI", + "model": "gpt-4o-mini", + "name": "GPT-4o-mini", // alias + + "maxContext": 125000, // 最大上下文 + "maxResponse": 16000, // 最大回复 + "quoteMaxToken": 60000, // 最大引用 + "maxTemperature": 1.2, // 最大温度 + "presencePenaltyRange": [-2, 2], // 惩罚系数范围 + "frequencyPenaltyRange": [-2, 2], // 频率惩罚系数范围 + "responseFormatList": ["text", "json_object", "json_schema"], // 响应格式 + "showStopSign": true, // 是否显示停止符号 + + "vision": true, // 是否支持图片识别 + "toolChoice": true, // 是否支持工具调用 + "functionCall": false, // 是否支持函数调用(一般都可以 false 了,基本不用了) + "defaultSystemChatPrompt": "", // 默认系统提示 + + "datasetProcess": true, // 用于知识库文本处理 + "usedInClassify": true, // 用于问题分类 + "customCQPrompt": "", // 自定义问题分类提示 + "usedInExtractFields": true, // 用于提取字段 + "customExtractPrompt": "", // 自定义提取提示 + "usedInToolCall": true, // 用于工具调用 + "usedInQueryExtension": true, // 用于问题优化 + + "defaultConfig": {}, // 额外的自定义 body + "fieldMap": {}, // body 字段映射 + + "censor": false, // 是否开启敏感词过滤 + "charsPointsPrice": 0 // n 积分/1k token +} diff --git a/packages/service/core/ai/config/rerank/bge-reranker-v2-m3.json b/packages/service/core/ai/config/rerank/bge-reranker-v2-m3.json new file mode 100644 index 000000000..3cc1a33b5 --- /dev/null +++ b/packages/service/core/ai/config/rerank/bge-reranker-v2-m3.json @@ -0,0 +1,6 @@ +{ + "provider": "BAAI", + "model": "bge-reranker-v2-m3", + "name": "bge-reranker-v2-m3", + "charsPointsPrice": 0 +} diff --git a/packages/service/core/ai/config/stt/whisper-1.json b/packages/service/core/ai/config/stt/whisper-1.json new file mode 100644 index 000000000..2d8639786 --- /dev/null +++ b/packages/service/core/ai/config/stt/whisper-1.json @@ -0,0 +1,6 @@ +{ + "provider": "OpenAI", + "model": "whisper-1", + "name": "whisper-1", + "charsPointsPrice": 0 +} diff --git a/packages/service/core/ai/config/tts/tts-1.json b/packages/service/core/ai/config/tts/tts-1.json new file mode 100644 index 000000000..80105c227 --- /dev/null +++ b/packages/service/core/ai/config/tts/tts-1.json @@ -0,0 +1,32 @@ +{ + "provider": "OpenAI", + "model": "tts-1", + "name": "TTS1", + "charsPointsPrice": 0, + "voices": [ + { + "label": "Alloy", + "value": "alloy" + }, + { + "label": "Echo", + "value": "echo" + }, + { + "label": "Fable", + "value": "fable" + }, + { + "label": "Onyx", + "value": "onyx" + }, + { + "label": "Nova", + "value": "nova" + }, + { + "label": "Shimmer", + "value": "shimmer" + } + ] +} diff --git a/packages/service/core/app/plugin/utils.ts b/packages/service/core/app/plugin/utils.ts index bd1b764da..43e0db8aa 100644 --- a/packages/service/core/app/plugin/utils.ts +++ b/packages/service/core/app/plugin/utils.ts @@ -5,11 +5,11 @@ import { PluginSourceEnum } from '@fastgpt/global/core/plugin/constants'; /* Plugin points calculation: - 1. 商业版插件: + 1. 系统插件/商业版插件: - 有错误:返回 0 - - 无错误:返回 配置的点数 + 子节点点数 - 2. 其他插件: - - 返回 子节点点数 + - 无错误:返回 单次积分 + 子流程积分(可配置) + 2. 个人插件 + - 返回 子流程积分 */ export const computedPluginUsage = async ({ plugin, @@ -26,9 +26,9 @@ export const computedPluginUsage = async ({ if (source !== PluginSourceEnum.personal) { if (error) return 0; - const pluginCurrentCose = plugin.currentCost ?? 0; + const pluginCurrentCost = plugin.currentCost ?? 0; - return plugin.hasTokenFee ? pluginCurrentCose + childrenUsages : pluginCurrentCose; + return plugin.hasTokenFee ? pluginCurrentCost + childrenUsages : pluginCurrentCost; } return childrenUsages; diff --git a/packages/service/core/chat/chatItemSchema.ts b/packages/service/core/chat/chatItemSchema.ts index be569b748..a18065330 100644 --- a/packages/service/core/chat/chatItemSchema.ts +++ b/packages/service/core/chat/chatItemSchema.ts @@ -86,24 +86,21 @@ const ChatItemSchema = new Schema({ }); try { - ChatItemSchema.index({ dataId: 1 }, { background: true }); + ChatItemSchema.index({ dataId: 1 }); /* delete by app; delete by chat id; get chat list; get chat logs; close custom feedback; */ - ChatItemSchema.index({ appId: 1, chatId: 1, dataId: 1 }, { background: true }); + ChatItemSchema.index({ appId: 1, chatId: 1, dataId: 1 }); // admin charts - ChatItemSchema.index({ time: -1, obj: 1 }, { background: true }); + ChatItemSchema.index({ time: -1, obj: 1 }); // timer, clear history - ChatItemSchema.index({ teamId: 1, time: -1 }, { background: true }); + ChatItemSchema.index({ teamId: 1, time: -1 }); // Admin charts - ChatItemSchema.index( - { obj: 1, time: -1 }, - { background: true, partialFilterExpression: { obj: 'Human' } } - ); + ChatItemSchema.index({ obj: 1, time: -1 }, { partialFilterExpression: { obj: 'Human' } }); } catch (error) { console.log(error); } diff --git a/packages/service/core/chat/chatSchema.ts b/packages/service/core/chat/chatSchema.ts index 5f5a2f403..53a6569ee 100644 --- a/packages/service/core/chat/chatSchema.ts +++ b/packages/service/core/chat/chatSchema.ts @@ -81,19 +81,19 @@ const ChatSchema = new Schema({ }); try { - ChatSchema.index({ chatId: 1 }, { background: true }); + ChatSchema.index({ chatId: 1 }); // get user history - ChatSchema.index({ tmbId: 1, appId: 1, top: -1, updateTime: -1 }, { background: true }); + ChatSchema.index({ tmbId: 1, appId: 1, top: -1, updateTime: -1 }); // delete by appid; clear history; init chat; update chat; auth chat; get chat; - ChatSchema.index({ appId: 1, chatId: 1 }, { background: true }); + ChatSchema.index({ appId: 1, chatId: 1 }); // get chat logs; - ChatSchema.index({ teamId: 1, appId: 1, updateTime: -1 }, { background: true }); + ChatSchema.index({ teamId: 1, appId: 1, updateTime: -1 }); // get share chat history - ChatSchema.index({ shareId: 1, outLinkUid: 1, updateTime: -1 }, { background: true }); + ChatSchema.index({ shareId: 1, outLinkUid: 1, updateTime: -1 }); // timer, clear history - ChatSchema.index({ teamId: 1, updateTime: -1 }, { background: true }); + ChatSchema.index({ teamId: 1, updateTime: -1 }); } catch (error) { console.log(error); } diff --git a/packages/service/core/dataset/collection/controller.ts b/packages/service/core/dataset/collection/controller.ts index 6875fb546..061543274 100644 --- a/packages/service/core/dataset/collection/controller.ts +++ b/packages/service/core/dataset/collection/controller.ts @@ -24,6 +24,7 @@ import { pushDataListToTrainingQueue } from '../training/controller'; import { MongoImage } from '../../../common/file/image/schema'; import { hashStr } from '@fastgpt/global/common/string/tools'; import { addDays } from 'date-fns'; +import { MongoDatasetDataText } from '../data/dataTextSchema'; export const createCollectionAndInsertData = async ({ dataset, @@ -240,12 +241,12 @@ export const delCollectionRelatedSource = async ({ .map((item) => item?.metadata?.relatedImgId || '') .filter(Boolean); - // delete files + // Delete files await delFileByFileIdList({ bucketName: BucketNameEnum.dataset, fileIdList }); - // delete images + // Delete images await delImgByRelatedId({ teamId, relateIds: relatedImageIds, @@ -273,7 +274,7 @@ export async function delCollection({ const datasetIds = Array.from(new Set(collections.map((item) => String(item.datasetId)))); const collectionIds = collections.map((item) => String(item._id)); - // delete training data + // Delete training data await MongoDatasetTraining.deleteMany({ teamId, datasetIds: { $in: datasetIds }, @@ -285,11 +286,16 @@ export async function delCollection({ await delCollectionRelatedSource({ collections, session }); } - // delete dataset.datas + // Delete dataset_datas await MongoDatasetData.deleteMany( { teamId, datasetIds: { $in: datasetIds }, collectionId: { $in: collectionIds } }, { session } ); + // Delete dataset_data_texts + await MongoDatasetDataText.deleteMany( + { teamId, datasetIds: { $in: datasetIds }, collectionId: { $in: collectionIds } }, + { session } + ); // delete collections await MongoDatasetCollection.deleteMany( diff --git a/packages/service/core/dataset/controller.ts b/packages/service/core/dataset/controller.ts index 8ed6a3539..96f6523e7 100644 --- a/packages/service/core/dataset/controller.ts +++ b/packages/service/core/dataset/controller.ts @@ -6,6 +6,7 @@ import { ClientSession } from '../../common/mongo'; import { MongoDatasetTraining } from './training/schema'; import { MongoDatasetData } from './data/schema'; import { deleteDatasetDataVector } from '../../common/vectorStore/controller'; +import { MongoDatasetDataText } from './data/dataTextSchema'; /* ============= dataset ========== */ /* find all datasetId by top datasetId */ @@ -92,7 +93,7 @@ export async function delDatasetRelevantData({ { session } ).lean(); - // image and file + // Delete Image and file await delCollectionRelatedSource({ collections, session }); // delete collections @@ -101,9 +102,15 @@ export async function delDatasetRelevantData({ datasetId: { $in: datasetIds } }).session(session); - // delete dataset.datas(Not need session) + // No session delete: + // Delete dataset_data_texts + await MongoDatasetDataText.deleteMany({ + teamId, + datasetId: { $in: datasetIds } + }); + // delete dataset_datas await MongoDatasetData.deleteMany({ teamId, datasetId: { $in: datasetIds } }); - // no session delete: delete files, vector data + // Delete vector data await deleteDatasetDataVector({ teamId, datasetIds }); } diff --git a/packages/service/core/dataset/data/dataTextSchema.ts b/packages/service/core/dataset/data/dataTextSchema.ts new file mode 100644 index 000000000..e0564ed2b --- /dev/null +++ b/packages/service/core/dataset/data/dataTextSchema.ts @@ -0,0 +1,45 @@ +import { connectionMongo, getMongoModel } from '../../../common/mongo'; +const { Schema } = connectionMongo; +import { DatasetDataSchemaType } from '@fastgpt/global/core/dataset/type.d'; +import { TeamCollectionName } from '@fastgpt/global/support/user/team/constant'; +import { DatasetCollectionName } from '../schema'; +import { DatasetColCollectionName } from '../collection/schema'; +import { DatasetDataCollectionName } from './schema'; + +export const DatasetDataTextCollectionName = 'dataset_data_texts'; + +const DatasetDataTextSchema = new Schema({ + teamId: { + type: Schema.Types.ObjectId, + ref: TeamCollectionName, + required: true + }, + datasetId: { + type: Schema.Types.ObjectId, + ref: DatasetCollectionName, + required: true + }, + collectionId: { + type: Schema.Types.ObjectId, + ref: DatasetColCollectionName, + required: true + }, + dataId: { + type: Schema.Types.ObjectId, + ref: DatasetDataCollectionName, + required: true + }, + fullTextToken: String +}); + +try { + DatasetDataTextSchema.index({ teamId: 1, datasetId: 1, fullTextToken: 'text' }); + DatasetDataTextSchema.index({ dataId: 1 }, { unique: true }); +} catch (error) { + console.log(error); +} + +export const MongoDatasetDataText = getMongoModel( + DatasetDataTextCollectionName, + DatasetDataTextSchema +); diff --git a/packages/service/core/dataset/data/schema.ts b/packages/service/core/dataset/data/schema.ts index 241f14285..85dd8a7d2 100644 --- a/packages/service/core/dataset/data/schema.ts +++ b/packages/service/core/dataset/data/schema.ts @@ -1,4 +1,4 @@ -import { connectionMongo, getMongoModel, type Model } from '../../../common/mongo'; +import { connectionMongo, getMongoModel } from '../../../common/mongo'; const { Schema, model, models } = connectionMongo; import { DatasetDataSchemaType } from '@fastgpt/global/core/dataset/type.d'; import { @@ -39,10 +39,6 @@ const DatasetDataSchema = new Schema({ type: String, default: '' }, - fullTextToken: { - type: String, - default: '' - }, indexes: { type: [ { @@ -71,17 +67,11 @@ const DatasetDataSchema = new Schema({ type: Number, default: 0 }, - inited: { - type: Boolean - }, - rebuilding: Boolean -}); + rebuilding: Boolean, -DatasetDataSchema.virtual('collection', { - ref: DatasetColCollectionName, - localField: 'collectionId', - foreignField: '_id', - justOne: true + // Abandon + fullTextToken: String, + initFullText: Boolean }); try { @@ -93,13 +83,15 @@ try { chunkIndex: 1, updateTime: -1 }); - // full text index - DatasetDataSchema.index({ teamId: 1, datasetId: 1, fullTextToken: 'text' }); + // FullText tmp full text index + // DatasetDataSchema.index({ teamId: 1, datasetId: 1, fullTextToken: 'text' }); // Recall vectors after data matching DatasetDataSchema.index({ teamId: 1, datasetId: 1, collectionId: 1, 'indexes.dataId': 1 }); DatasetDataSchema.index({ updateTime: 1 }); // rebuild data DatasetDataSchema.index({ rebuilding: 1, teamId: 1, datasetId: 1 }); + + DatasetDataSchema.index({ initFullText: 1 }); } catch (error) { console.log(error); } diff --git a/packages/service/core/dataset/search/controller.ts b/packages/service/core/dataset/search/controller.ts index 4b87d2ca7..0de4c2884 100644 --- a/packages/service/core/dataset/search/controller.ts +++ b/packages/service/core/dataset/search/controller.ts @@ -8,8 +8,8 @@ import { getVectorsByText } from '../../ai/embedding'; import { getVectorModel } from '../../ai/model'; import { MongoDatasetData } from '../data/schema'; import { - DatasetCollectionSchemaType, DatasetDataSchemaType, + DatasetDataTextSchemaType, SearchDataResponseItemType } from '@fastgpt/global/core/dataset/type'; import { MongoDatasetCollection } from '../collection/schema'; @@ -23,6 +23,7 @@ import { Types } from '../../../common/mongo'; import json5 from 'json5'; import { MongoDatasetCollectionTags } from '../tag/schema'; import { readFromSecondary } from '../../../common/mongo/utils'; +import { MongoDatasetDataText } from '../data/dataTextSchema'; type SearchDatasetDataProps = { teamId: string; @@ -266,57 +267,60 @@ export async function searchDatasetData(props: SearchDatasetDataProps) { filterCollectionIdList }); - // get q and a - const dataList = await MongoDatasetData.find( - { - teamId, - datasetId: { $in: datasetIds }, - collectionId: { $in: Array.from(new Set(results.map((item) => item.collectionId))) }, - 'indexes.dataId': { $in: results.map((item) => item.id?.trim()) } - }, - 'datasetId collectionId updateTime q a chunkIndex indexes' - ) - .populate<{ collection: DatasetCollectionSchemaType }>( - 'collection', - 'name fileId rawLink externalFileId externalFileUrl' - ) - .lean(); + // Get data and collections + const collectionIdList = Array.from(new Set(results.map((item) => item.collectionId))); + const [dataList, collections] = await Promise.all([ + MongoDatasetData.find( + { + teamId, + datasetId: { $in: datasetIds }, + collectionId: { $in: collectionIdList }, + 'indexes.dataId': { $in: results.map((item) => item.id?.trim()) } + }, + '_id datasetId collectionId updateTime q a chunkIndex indexes', + { ...readFromSecondary } + ).lean(), + MongoDatasetCollection.find( + { + _id: { $in: collectionIdList } + }, + '_id name fileId rawLink externalFileId externalFileUrl', + { ...readFromSecondary } + ).lean() + ]); - // add score to data(It's already sorted. The first one is the one with the most points) - const concatResults = dataList.map((data) => { - const dataIdList = data.indexes.map((item) => item.dataId); + const formatResult = results + .map((item, index) => { + const collection = collections.find((col) => String(col._id) === String(item.collectionId)); + if (!collection) { + console.log('Collection is not found', item); + return; + } + const data = dataList.find((data) => + data.indexes.some((index) => index.dataId === item.id) + ); + if (!data) { + console.log('Data is not found', item); + return; + } - const maxScoreResult = results.find((item) => { - return dataIdList.includes(item.id); - }); + const score = item?.score || 0; - return { - ...data, - score: maxScoreResult?.score || 0 - }; - }); + const result: SearchDataResponseItemType = { + id: String(data._id), + updateTime: data.updateTime, + q: data.q, + a: data.a, + chunkIndex: data.chunkIndex, + datasetId: String(data.datasetId), + collectionId: String(data.collectionId), + ...getCollectionSourceData(collection), + score: [{ type: SearchScoreTypeEnum.embedding, value: score, index }] + }; - concatResults.sort((a, b) => b.score - a.score); - - const formatResult = concatResults.map((data, index) => { - if (!data.collectionId) { - console.log('Collection is not found', data); - } - - const result: SearchDataResponseItemType = { - id: String(data._id), - updateTime: data.updateTime, - q: data.q, - a: data.a, - chunkIndex: data.chunkIndex, - datasetId: String(data.datasetId), - collectionId: String(data.collectionId), - ...getCollectionSourceData(data.collection), - score: [{ type: SearchScoreTypeEnum.embedding, value: data.score, index }] - }; - - return result; - }); + return result; + }) + .filter(Boolean) as SearchDataResponseItemType[]; return { embeddingRecallResults: formatResult, @@ -344,88 +348,224 @@ export async function searchDatasetData(props: SearchDatasetDataProps) { }; } - let searchResults = ( + const searchResults = ( await Promise.all( datasetIds.map(async (id) => { - return MongoDatasetData.aggregate([ - { - $match: { - teamId: new Types.ObjectId(teamId), - datasetId: new Types.ObjectId(id), - $text: { $search: jiebaSplit({ text: query }) }, - ...(filterCollectionIdList - ? { - collectionId: { - $in: filterCollectionIdList.map((id) => new Types.ObjectId(id)) + return MongoDatasetData.aggregate( + [ + { + $match: { + teamId: new Types.ObjectId(teamId), + datasetId: new Types.ObjectId(id), + $text: { $search: jiebaSplit({ text: query }) }, + ...(filterCollectionIdList + ? { + collectionId: { + $in: filterCollectionIdList.map((id) => new Types.ObjectId(id)) + } } - } - : {}), - ...(forbidCollectionIdList && forbidCollectionIdList.length > 0 - ? { - collectionId: { - $nin: forbidCollectionIdList.map((id) => new Types.ObjectId(id)) + : {}), + ...(forbidCollectionIdList && forbidCollectionIdList.length > 0 + ? { + collectionId: { + $nin: forbidCollectionIdList.map((id) => new Types.ObjectId(id)) + } } - } - : {}) + : {}) + } + }, + { + $sort: { + score: { $meta: 'textScore' } + } + }, + { + $limit: limit + }, + { + $project: { + _id: 1, + datasetId: 1, + collectionId: 1, + updateTime: 1, + q: 1, + a: 1, + chunkIndex: 1, + score: { $meta: 'textScore' } + } } - }, + ], { - $addFields: { - score: { $meta: 'textScore' } - } - }, - { - $sort: { - score: { $meta: 'textScore' } - } - }, - { - $limit: limit - }, - { - $project: { - _id: 1, - datasetId: 1, - collectionId: 1, - updateTime: 1, - q: 1, - a: 1, - chunkIndex: 1, - score: 1 - } + ...readFromSecondary } - ]); + ); }) ) ).flat() as (DatasetDataSchemaType & { score: number })[]; - // resort - searchResults.sort((a, b) => b.score - a.score); - searchResults.slice(0, limit); - + // Get data and collections const collections = await MongoDatasetCollection.find( { _id: { $in: searchResults.map((item) => item.collectionId) } }, - '_id name fileId rawLink' - ); + '_id name fileId rawLink externalFileId externalFileUrl', + { ...readFromSecondary } + ).lean(); return { - fullTextRecallResults: searchResults.map((item, index) => { - const collection = collections.find((col) => String(col._id) === String(item.collectionId)); - return { - id: String(item._id), - datasetId: String(item.datasetId), - collectionId: String(item.collectionId), - updateTime: item.updateTime, - ...getCollectionSourceData(collection), - q: item.q, - a: item.a, - chunkIndex: item.chunkIndex, - indexes: item.indexes, - score: [{ type: SearchScoreTypeEnum.fullText, value: item.score, index }] - }; - }), + fullTextRecallResults: searchResults + .map((data, index) => { + const collection = collections.find( + (col) => String(col._id) === String(data.collectionId) + ); + if (!collection) { + console.log('Collection is not found', data); + return; + } + + return { + id: String(data._id), + datasetId: String(data.datasetId), + collectionId: String(data.collectionId), + updateTime: data.updateTime, + q: data.q, + a: data.a, + chunkIndex: data.chunkIndex, + indexes: data.indexes, + ...getCollectionSourceData(collection), + score: [{ type: SearchScoreTypeEnum.fullText, value: data.score ?? 0, index }] + }; + }) + .filter(Boolean) as SearchDataResponseItemType[], + tokenLen: 0 + }; + }; + const fullTextRecall2 = async ({ + query, + limit, + filterCollectionIdList, + forbidCollectionIdList + }: { + query: string; + limit: number; + filterCollectionIdList?: string[]; + forbidCollectionIdList: string[]; + }): Promise<{ + fullTextRecallResults: SearchDataResponseItemType[]; + tokenLen: number; + }> => { + if (limit === 0) { + return { + fullTextRecallResults: [], + tokenLen: 0 + }; + } + + const searchResults = ( + await Promise.all( + datasetIds.map(async (id) => { + return MongoDatasetDataText.aggregate( + [ + { + $match: { + teamId: new Types.ObjectId(teamId), + datasetId: new Types.ObjectId(id), + $text: { $search: jiebaSplit({ text: query }) }, + ...(filterCollectionIdList + ? { + collectionId: { + $in: filterCollectionIdList.map((id) => new Types.ObjectId(id)) + } + } + : {}), + ...(forbidCollectionIdList && forbidCollectionIdList.length > 0 + ? { + collectionId: { + $nin: forbidCollectionIdList.map((id) => new Types.ObjectId(id)) + } + } + : {}) + } + }, + { + $sort: { + score: { $meta: 'textScore' } + } + }, + { + $limit: limit + }, + { + $project: { + _id: 1, + collectionId: 1, + dataId: 1, + score: { $meta: 'textScore' } + } + } + ], + { + ...readFromSecondary + } + ); + }) + ) + ).flat() as (DatasetDataTextSchemaType & { score: number })[]; + + // Get data and collections + const [dataList, collections] = await Promise.all([ + MongoDatasetData.find( + { + _id: { $in: searchResults.map((item) => item.dataId) } + }, + '_id datasetId collectionId updateTime q a chunkIndex indexes', + { ...readFromSecondary } + ).lean(), + MongoDatasetCollection.find( + { + _id: { $in: searchResults.map((item) => item.collectionId) } + }, + '_id name fileId rawLink externalFileId externalFileUrl', + { ...readFromSecondary } + ).lean() + ]); + + return { + fullTextRecallResults: searchResults + .map((item, index) => { + const collection = collections.find( + (col) => String(col._id) === String(item.collectionId) + ); + if (!collection) { + console.log('Collection is not found', item); + return; + } + const data = dataList.find((data) => String(data._id) === String(item.dataId)); + if (!data) { + console.log('Data is not found', item); + return; + } + + return { + id: String(data._id), + datasetId: String(data.datasetId), + collectionId: String(data.collectionId), + updateTime: data.updateTime, + q: data.q, + a: data.a, + chunkIndex: data.chunkIndex, + indexes: data.indexes, + ...getCollectionSourceData(collection), + score: [ + { + type: SearchScoreTypeEnum.fullText, + value: item.score || 0, + index + } + ] + }; + }) + .filter(Boolean) as SearchDataResponseItemType[], tokenLen: 0 }; }; @@ -496,7 +636,8 @@ export async function searchDatasetData(props: SearchDatasetDataProps) { forbidCollectionIdList, filterCollectionIdList }), - fullTextRecall({ + // FullText tmp + fullTextRecall2({ query, limit: fullTextLimit, filterCollectionIdList, diff --git a/packages/service/support/outLink/schema.ts b/packages/service/support/outLink/schema.ts index 7d1f1dbe3..0c6d5ea4c 100644 --- a/packages/service/support/outLink/schema.ts +++ b/packages/service/support/outLink/schema.ts @@ -92,6 +92,7 @@ OutLinkSchema.virtual('associatedApp', { try { OutLinkSchema.index({ shareId: -1 }); + OutLinkSchema.index({ teamId: 1, tmbId: 1, appId: 1 }); } catch (error) { console.log(error); } diff --git a/packages/service/support/permission/auth/org.ts b/packages/service/support/permission/auth/org.ts new file mode 100644 index 000000000..d864b1cb5 --- /dev/null +++ b/packages/service/support/permission/auth/org.ts @@ -0,0 +1,43 @@ +import { TeamPermission } from '@fastgpt/global/support/permission/user/controller'; +import { AuthModeType, AuthResponseType } from '../type'; +import { TeamErrEnum } from '@fastgpt/global/common/error/code/team'; +import { authUserPer } from '../user/auth'; +import { ManagePermissionVal } from '@fastgpt/global/support/permission/constant'; + +/* + Team manager can control org +*/ +export const authOrgMember = async ({ + orgIds, + ...props +}: { + orgIds: string | string[]; +} & AuthModeType): Promise => { + const result = await authUserPer({ + ...props, + per: ManagePermissionVal + }); + const { teamId, tmbId, isRoot, tmb } = result; + + if (isRoot) { + return { + teamId, + tmbId, + userId: result.userId, + appId: result.appId, + apikey: result.apikey, + isRoot, + authType: result.authType, + permission: new TeamPermission({ isOwner: true }) + }; + } + + if (tmb.permission.hasManagePer) { + return { + ...result, + permission: tmb.permission + }; + } + + return Promise.reject(TeamErrEnum.unAuthTeam); +}; diff --git a/packages/service/support/permission/auth/team.ts b/packages/service/support/permission/auth/team.ts index b659f2ffd..48d676ed4 100644 --- a/packages/service/support/permission/auth/team.ts +++ b/packages/service/support/permission/auth/team.ts @@ -1,8 +1,8 @@ import { MongoTeamMember } from '../../user/team/teamMemberSchema'; import { checkTeamAIPoints } from '../teamLimit'; -import { UserErrEnum } from '@fastgpt/global/common/error/code/user'; import { UserModelSchema } from '@fastgpt/global/support/user/type'; import { TeamSchema } from '@fastgpt/global/support/user/team/type'; +import { TeamErrEnum } from '@fastgpt/global/common/error/code/team'; export async function getUserChatInfoAndAuthTeamPoints(tmbId: string) { const tmb = await MongoTeamMember.findById(tmbId, 'userId teamId') @@ -18,7 +18,7 @@ export async function getUserChatInfoAndAuthTeamPoints(tmbId: string) { ]) .lean(); - if (!tmb) return Promise.reject(UserErrEnum.unAuthUser); + if (!tmb) return Promise.reject(TeamErrEnum.notUser); await checkTeamAIPoints(tmb.team._id); diff --git a/packages/service/support/permission/controller.ts b/packages/service/support/permission/controller.ts index 458c05d01..f233c66b1 100644 --- a/packages/service/support/permission/controller.ts +++ b/packages/service/support/permission/controller.ts @@ -8,10 +8,7 @@ import { authOpenApiKey } from '../openapi/auth'; import { FileTokenQuery } from '@fastgpt/global/common/file/type'; import { MongoResourcePermission } from './schema'; import { ClientSession } from 'mongoose'; -import { - PermissionValueType, - ResourcePermissionType -} from '@fastgpt/global/support/permission/type'; +import { PermissionValueType } from '@fastgpt/global/support/permission/type'; import { bucketNameMap } from '@fastgpt/global/common/file/constants'; import { addMinutes } from 'date-fns'; import { getGroupsByTmbId } from './memberGroup/controllers'; @@ -21,6 +18,8 @@ import { CommonErrEnum } from '@fastgpt/global/common/error/code/common'; import { MemberGroupSchemaType } from '@fastgpt/global/support/permission/memberGroup/type'; import { TeamMemberSchema } from '@fastgpt/global/support/user/team/type'; import { UserModelSchema } from '@fastgpt/global/support/user/type'; +import { OrgSchemaType } from '@fastgpt/global/support/user/team/org/type'; +import { getOrgIdSetWithParentByTmbId } from './org/controllers'; /** get resource permission for a team member * If there is no permission for the team member, it will return undefined @@ -67,67 +66,44 @@ export const getResourcePermission = async ({ } // If there is no personal permission, get the group permission - const groupIdList = (await getGroupsByTmbId({ tmbId, teamId })).map((item) => item._id); + const [groupPers, orgPers] = await Promise.all([ + getGroupsByTmbId({ tmbId, teamId }) + .then((res) => res.map((item) => item._id)) + .then((groupIdList) => + MongoResourcePermission.find( + { + teamId, + resourceType, + groupId: { + $in: groupIdList + }, + resourceId + }, + 'permission' + ).lean() + ) + .then((perList) => perList.map((item) => item.permission)), + getOrgIdSetWithParentByTmbId({ tmbId, teamId }) + .then((item) => Array.from(item)) + .then((orgIds) => + MongoResourcePermission.find( + { + teamId, + resourceType, + orgId: { + $in: Array.from(orgIds) + }, + resourceId + }, + 'permission' + ).lean() + ) + .then((perList) => perList.map((item) => item.permission)) + ]); - if (groupIdList.length === 0) { - return undefined; - } - - // get the maximum permission of the group - const pers = ( - await MongoResourcePermission.find( - { - teamId, - resourceType, - groupId: { - $in: groupIdList - }, - resourceId - }, - 'permission' - ).lean() - ).map((item) => item.permission); - - const groupPer = getGroupPer(pers); - - return groupPer; + return concatPer([...groupPers, ...orgPers]); }; -/* 仅取 members 不取 groups */ -export async function getResourceAllClbs({ - resourceId, - teamId, - resourceType, - session -}: { - teamId: string; - session?: ClientSession; -} & ( - | { - resourceType: 'team'; - resourceId?: undefined; - } - | { - resourceType: Omit; - resourceId?: string | null; - } -)): Promise { - return MongoResourcePermission.find( - { - resourceType: resourceType, - teamId: teamId, - resourceId, - groupId: { - $exists: false - } - }, - null, - { - session - } - ).lean(); -} - export async function getResourceClbsAndGroups({ resourceId, resourceType, @@ -155,10 +131,17 @@ export const getClbsAndGroupsWithInfo = async ({ resourceType, teamId }: { - resourceId: ParentIdType; - resourceType: Omit<`${PerResourceTypeEnum}`, 'team'>; teamId: string; -}) => +} & ( + | { + resourceId: ParentIdType; + resourceType: Omit<`${PerResourceTypeEnum}`, 'team'>; + } + | { + resourceType: 'team'; + resourceId?: undefined; + } +)) => Promise.all([ MongoResourcePermission.find({ teamId, @@ -170,7 +153,7 @@ export const getClbsAndGroupsWithInfo = async ({ }) .populate<{ tmb: TeamMemberSchema & { user: UserModelSchema } }>({ path: 'tmb', - select: 'name userId', + select: 'name userId role', populate: { path: 'user', select: 'avatar' @@ -186,6 +169,16 @@ export const getClbsAndGroupsWithInfo = async ({ } }) .populate<{ group: MemberGroupSchemaType }>('group', 'name avatar') + .lean(), + MongoResourcePermission.find({ + teamId, + resourceId, + resourceType, + orgId: { + $exists: true + } + }) + .populate<{ org: OrgSchemaType }>({ path: 'org', select: 'name avatar' }) .lean() ]); @@ -196,6 +189,7 @@ export const delResourcePermission = ({ session, tmbId, groupId, + orgId, ...props }: { resourceType: PerResourceTypeEnum; @@ -204,15 +198,18 @@ export const delResourcePermission = ({ session?: ClientSession; tmbId?: string; groupId?: string; + orgId?: string; }) => { - // tmbId or groupId only one and not both - if (!!tmbId === !!groupId) { + // either tmbId or groupId or orgId must be provided + if (!tmbId && !groupId && !orgId) { return Promise.reject(CommonErrEnum.missingParams); } + return MongoResourcePermission.deleteOne( { ...(tmbId ? { tmbId } : {}), ...(groupId ? { groupId } : {}), + ...(orgId ? { orgId } : {}), ...props }, { session } @@ -250,7 +247,7 @@ export function authJWT(token: string) { }>((resolve, reject) => { const key = process.env.TOKEN_KEY as string; - jwt.verify(token, key, function (err, decoded: any) { + jwt.verify(token, key, (err, decoded: any) => { if (err || !decoded?.userId) { reject(ERROR_ENUM.unAuthorization); return; @@ -436,7 +433,7 @@ export const authFileToken = (token?: string) => } const key = (process.env.FILE_TOKEN_KEY as string) ?? 'filetoken'; - jwt.verify(token, key, function (err, decoded: any) { + jwt.verify(token, key, (err, decoded: any) => { if (err || !decoded.bucketName || !decoded?.teamId || !decoded?.fileId) { reject(ERROR_ENUM.unAuthFile); return; @@ -450,10 +447,10 @@ export const authFileToken = (token?: string) => }); }); -export const getGroupPer = (groups: PermissionValueType[] = []) => { - if (groups.length === 0) { +export const concatPer = (perList: PermissionValueType[] = []) => { + if (perList.length === 0) { return undefined; } - return new Permission().addPer(...groups).value; + return new Permission().addPer(...perList).value; }; diff --git a/packages/service/support/permission/inheritPermission.ts b/packages/service/support/permission/inheritPermission.ts index c3ac42eb8..4f9993f5a 100644 --- a/packages/service/support/permission/inheritPermission.ts +++ b/packages/service/support/permission/inheritPermission.ts @@ -1,11 +1,11 @@ import { mongoSessionRun } from '../../common/mongo/sessionRun'; import { MongoResourcePermission } from './schema'; -import { ClientSession, Model } from 'mongoose'; -import { PerResourceTypeEnum } from '@fastgpt/global/support/permission/constant'; -import { PermissionValueType } from '@fastgpt/global/support/permission/type'; +import type { ClientSession, Model } from 'mongoose'; +import type { PerResourceTypeEnum } from '@fastgpt/global/support/permission/constant'; +import type { PermissionValueType } from '@fastgpt/global/support/permission/type'; import { getResourceClbsAndGroups } from './controller'; -import { RequireOnlyOne } from '@fastgpt/global/common/type/utils'; -import { ParentIdType } from '@fastgpt/global/common/parentFolder/type'; +import type { RequireOnlyOne } from '@fastgpt/global/common/type/utils'; +import type { ParentIdType } from '@fastgpt/global/common/parentFolder/type'; export type SyncChildrenPermissionResourceType = { _id: string; @@ -18,6 +18,7 @@ export type UpdateCollaboratorItem = { } & RequireOnlyOne<{ tmbId: string; groupId: string; + orgId: string; }>; // sync the permission to all children folders. @@ -161,7 +162,7 @@ export async function resumeInheritPermission({ } } -/* +/* Delete all the collaborators and then insert the new collaborators. */ export async function syncCollaborators({ diff --git a/packages/service/support/permission/memberGroup/controllers.ts b/packages/service/support/permission/memberGroup/controllers.ts index 78bae10c9..c34d2b4b3 100644 --- a/packages/service/support/permission/memberGroup/controllers.ts +++ b/packages/service/support/permission/memberGroup/controllers.ts @@ -1,9 +1,6 @@ import { MemberGroupSchemaType } from '@fastgpt/global/support/permission/memberGroup/type'; import { MongoGroupMemberModel } from './groupMemberSchema'; -import { TeamMemberSchema } from '@fastgpt/global/support/user/team/type'; -import { PerResourceTypeEnum } from '@fastgpt/global/support/permission/constant'; -import { MongoResourcePermission } from '../schema'; -import { getGroupPer, parseHeaderCert } from '../controller'; +import { parseHeaderCert } from '../controller'; import { MongoMemberGroupModel } from './memberGroupSchema'; import { DefaultGroupName } from '@fastgpt/global/support/user/team/group/constant'; import { ClientSession } from 'mongoose'; @@ -50,26 +47,32 @@ export const getTeamDefaultGroup = async ({ export const getGroupsByTmbId = async ({ tmbId, teamId, - role + role, + session }: { tmbId: string; teamId: string; role?: `${GroupMemberRole}`[]; + session?: ClientSession; }) => ( await Promise.all([ ( - await MongoGroupMemberModel.find({ - tmbId, - groupId: { - $exists: true + await MongoGroupMemberModel.find( + { + tmbId, + groupId: { + $exists: true + }, + ...(role ? { role: { $in: role } } : {}) }, - ...(role ? { role: { $in: role } } : {}) - }) + undefined, + { session } + ) .populate<{ group: MemberGroupSchemaType }>('group') .lean() ).map((item) => item.group), - role ? [] : getTeamDefaultGroup({ teamId }) + role ? [] : getTeamDefaultGroup({ teamId, session }) ]) ).flat(); @@ -79,46 +82,6 @@ export const getGroupMembersByGroupId = async (groupId: string) => { }).lean(); }; -/** - * Get tmb's group permission: the maximum permission of the group - * @param tmbId - * @param resourceId - * @param resourceType - * @returns the maximum permission of the group - */ -export const getGroupPermission = async ({ - tmbId, - resourceId, - teamId, - resourceType -}: { - tmbId: string; - teamId: string; -} & ( - | { - resourceId?: undefined; - resourceType: 'team'; - } - | { - resourceId: string; - resourceType: Omit; - } -)) => { - const groupIds = (await getGroupsByTmbId({ tmbId, teamId })).map((item) => item._id); - const groupPermissions = ( - await MongoResourcePermission.find({ - groupId: { - $in: groupIds - }, - resourceType, - resourceId, - teamId - }) - ).map((item) => item.permission); - - return getGroupPer(groupPermissions); -}; - // auth group member role export const authGroupMemberRole = async ({ groupId, @@ -140,8 +103,12 @@ export const authGroupMemberRole = async ({ tmbId }; } - const groupMember = await MongoGroupMemberModel.findOne({ groupId, tmbId }); - const tmb = await getTmbInfoByTmbId({ tmbId }); + const [groupMember, tmb] = await Promise.all([ + MongoGroupMemberModel.findOne({ groupId, tmbId }), + getTmbInfoByTmbId({ tmbId }) + ]); + + // Team admin or role check if (tmb.permission.hasManagePer || (groupMember && role.includes(groupMember.role))) { return { ...result, diff --git a/packages/service/support/permission/org/controllers.ts b/packages/service/support/permission/org/controllers.ts new file mode 100644 index 000000000..ce0746055 --- /dev/null +++ b/packages/service/support/permission/org/controllers.ts @@ -0,0 +1,95 @@ +import { TeamErrEnum } from '@fastgpt/global/common/error/code/team'; +import type { OrgSchemaType } from '@fastgpt/global/support/user/team/org/type'; +import type { ClientSession } from 'mongoose'; +import { MongoOrgModel } from './orgSchema'; +import { MongoOrgMemberModel } from './orgMemberSchema'; +import { getOrgChildrenPath } from '@fastgpt/global/support/user/team/org/constant'; + +export const getOrgsByTmbId = async ({ teamId, tmbId }: { teamId: string; tmbId: string }) => + MongoOrgMemberModel.find({ teamId, tmbId }, 'orgId').lean(); + +export const getOrgIdSetWithParentByTmbId = async ({ + teamId, + tmbId +}: { + teamId: string; + tmbId: string; +}) => { + const orgMembers = await MongoOrgMemberModel.find({ teamId, tmbId }, 'orgId').lean(); + + const orgIds = Array.from(new Set(orgMembers.map((item) => String(item.orgId)))); + const orgs = await MongoOrgModel.find({ _id: { $in: orgIds } }, 'path').lean(); + + const pathIdList = new Set( + orgs + .map((org) => { + const pathIdList = org.path.split('/').filter(Boolean); + return pathIdList; + }) + .flat() + ); + const parentOrgs = await MongoOrgModel.find( + { + teamId, + pathId: { $in: Array.from(pathIdList) } + }, + '_id' + ).lean(); + const parentOrgIds = parentOrgs.map((item) => String(item._id)); + + return new Set([...orgIds, ...parentOrgIds]); +}; + +export const getChildrenByOrg = async ({ + org, + teamId, + session +}: { + org: OrgSchemaType; + teamId: string; + session?: ClientSession; +}) => { + return MongoOrgModel.find( + { teamId, path: { $regex: `^${getOrgChildrenPath(org)}` } }, + undefined, + { + session + } + ).lean(); +}; + +export const getOrgAndChildren = async ({ + orgId, + teamId, + session +}: { + orgId: string; + teamId: string; + session?: ClientSession; +}) => { + const org = await MongoOrgModel.findOne({ _id: orgId, teamId }, undefined, { session }).lean(); + if (!org) { + return Promise.reject(TeamErrEnum.orgNotExist); + } + const children = await getChildrenByOrg({ org, teamId, session }); + return { org, children }; +}; + +export async function createRootOrg({ + teamId, + session +}: { + teamId: string; + session?: ClientSession; +}) { + return MongoOrgModel.create( + [ + { + teamId, + name: 'ROOT', + path: '' + } + ], + { session } + ); +} diff --git a/packages/service/support/permission/org/orgMemberSchema.ts b/packages/service/support/permission/org/orgMemberSchema.ts new file mode 100644 index 000000000..3abc5c233 --- /dev/null +++ b/packages/service/support/permission/org/orgMemberSchema.ts @@ -0,0 +1,65 @@ +import { OrgCollectionName } from '@fastgpt/global/support/user/team/org/constant'; +import { connectionMongo, getMongoModel } from '../../../common/mongo'; +import { + TeamCollectionName, + TeamMemberCollectionName +} from '@fastgpt/global/support/user/team/constant'; +import { OrgMemberSchemaType } from '@fastgpt/global/support/user/team/org/type'; +const { Schema } = connectionMongo; + +export const OrgMemberCollectionName = 'team_org_members'; + +export const OrgMemberSchema = new Schema({ + teamId: { + type: Schema.Types.ObjectId, + ref: TeamCollectionName, + required: true + }, + orgId: { + type: Schema.Types.ObjectId, + ref: OrgCollectionName, + required: true + }, + tmbId: { + type: Schema.Types.ObjectId, + ref: TeamMemberCollectionName, + required: true + } + // role: { + // type: String, + // enum: Object.values(OrgMemberRole), + // required: true, + // default: OrgMemberRole.member + // } +}); + +OrgMemberSchema.virtual('org', { + ref: OrgCollectionName, + localField: 'orgId', + foreignField: '_id', + justOne: true +}); + +try { + OrgMemberSchema.index( + { + teamId: 1, + orgId: 1, + tmbId: 1 + }, + { + unique: true + } + ); + OrgMemberSchema.index({ + teamId: 1, + tmbId: 1 + }); +} catch (error) { + console.log(error); +} + +export const MongoOrgMemberModel = getMongoModel( + OrgMemberCollectionName, + OrgMemberSchema +); diff --git a/packages/service/support/permission/org/orgSchema.ts b/packages/service/support/permission/org/orgSchema.ts new file mode 100644 index 000000000..45030c4a6 --- /dev/null +++ b/packages/service/support/permission/org/orgSchema.ts @@ -0,0 +1,77 @@ +import { TeamCollectionName } from '@fastgpt/global/support/user/team/constant'; +import { OrgCollectionName } from '@fastgpt/global/support/user/team/org/constant'; +import type { OrgSchemaType } from '@fastgpt/global/support/user/team/org/type'; +import { connectionMongo, getMongoModel } from '../../../common/mongo'; +import { OrgMemberCollectionName } from './orgMemberSchema'; +import { getNanoid } from '@fastgpt/global/common/string/tools'; +const { Schema } = connectionMongo; + +export const OrgSchema = new Schema( + { + teamId: { + type: Schema.Types.ObjectId, + ref: TeamCollectionName, + required: true + }, + pathId: { + // path id, only used for path + type: String, + required: true, + default: () => getNanoid() + }, + path: { + type: String, + required: function (this: OrgSchemaType) { + return typeof this.path !== 'string'; + } // allow empty string, but not null + }, + name: { + type: String, + required: true + }, + avatar: String, + description: String, + updateTime: { + type: Date, + default: () => new Date() + } + }, + { + // Auto update updateTime + timestamps: { + updatedAt: 'updateTime' + } + } +); + +OrgSchema.virtual('members', { + ref: OrgMemberCollectionName, + localField: '_id', + foreignField: 'orgId' +}); +// OrgSchema.virtual('permission', { +// ref: ResourcePermissionCollectionName, +// localField: '_id', +// foreignField: 'orgId', +// justOne: true +// }); + +try { + OrgSchema.index({ + teamId: 1, + path: 1 + }); + OrgSchema.index( + { + teamId: 1, + pathId: 1 + }, + { + unique: true + } + ); +} catch (error) { + console.log(error); +} + +export const MongoOrgModel = getMongoModel(OrgCollectionName, OrgSchema); diff --git a/packages/service/support/permission/schema.ts b/packages/service/support/permission/schema.ts index ff5491d65..10b4a0cdb 100644 --- a/packages/service/support/permission/schema.ts +++ b/packages/service/support/permission/schema.ts @@ -6,6 +6,7 @@ import { connectionMongo, getMongoModel } from '../../common/mongo'; import type { ResourcePermissionType } from '@fastgpt/global/support/permission/type'; import { PerResourceTypeEnum } from '@fastgpt/global/support/permission/constant'; import { MemberGroupCollectionName } from './memberGroup/memberGroupSchema'; +import { OrgCollectionName } from '@fastgpt/global/support/user/team/org/constant'; const { Schema } = connectionMongo; export const ResourcePermissionCollectionName = 'resource_permissions'; @@ -23,6 +24,10 @@ export const ResourcePermissionSchema = new Schema({ type: Schema.Types.ObjectId, ref: MemberGroupCollectionName }, + orgId: { + type: Schema.Types.ObjectId, + ref: OrgCollectionName + }, resourceType: { type: String, enum: Object.values(PerResourceTypeEnum), @@ -51,6 +56,12 @@ ResourcePermissionSchema.virtual('group', { foreignField: '_id', justOne: true }); +ResourcePermissionSchema.virtual('org', { + ref: OrgCollectionName, + localField: 'orgId', + foreignField: '_id', + justOne: true +}); try { ResourcePermissionSchema.index( @@ -70,6 +81,23 @@ try { } ); + ResourcePermissionSchema.index( + { + resourceType: 1, + teamId: 1, + resourceId: 1, + orgId: 1 + }, + { + unique: true, + partialFilterExpression: { + orgId: { + $exists: true + } + } + } + ); + ResourcePermissionSchema.index( { resourceType: 1, @@ -87,6 +115,7 @@ try { } ); + // Delete tmb permission ResourcePermissionSchema.index({ resourceType: 1, teamId: 1, diff --git a/packages/service/support/permission/teamLimit.ts b/packages/service/support/permission/teamLimit.ts index 814480ccf..1a383f85b 100644 --- a/packages/service/support/permission/teamLimit.ts +++ b/packages/service/support/permission/teamLimit.ts @@ -19,9 +19,7 @@ export const checkDatasetLimit = async ({ if (!standardConstants) return; if (usedDatasetSize + insertLen >= datasetMaxSize) { - return Promise.reject( - `您的知识库容量为: ${datasetMaxSize}组,已使用: ${usedDatasetSize}组,导入当前文件需要: ${insertLen}组,请增加知识库容量后导入。` - ); + return Promise.reject(TeamErrEnum.datasetSizeNotEnough); } if (usedPoints >= totalPoints) { diff --git a/packages/service/support/user/schema.ts b/packages/service/support/user/schema.ts index 89b5eb58d..10094ee6f 100644 --- a/packages/service/support/user/schema.ts +++ b/packages/service/support/user/schema.ts @@ -3,22 +3,10 @@ const { Schema } = connectionMongo; import { hashStr } from '@fastgpt/global/common/string/tools'; import type { UserModelSchema } from '@fastgpt/global/support/user/type'; import { UserStatusEnum, userStatusMap } from '@fastgpt/global/support/user/constant'; +import { getRandomUserAvatar } from '@fastgpt/global/support/user/utils'; export const userCollectionName = 'users'; -const defaultAvatars = [ - '/imgs/avatar/RoyalBlueAvatar.svg', - '/imgs/avatar/PurpleAvatar.svg', - '/imgs/avatar/AdoraAvatar.svg', - '/imgs/avatar/OrangeAvatar.svg', - '/imgs/avatar/RedAvatar.svg', - '/imgs/avatar/GrayModernAvatar.svg', - '/imgs/avatar/TealAvatar.svg', - '/imgs/avatar/GreenAvatar.svg', - '/imgs/avatar/BrightBlueAvatar.svg', - '/imgs/avatar/BlueAvatar.svg' -]; - const UserSchema = new Schema({ status: { type: String, @@ -47,7 +35,7 @@ const UserSchema = new Schema({ }, avatar: { type: String, - default: defaultAvatars[Math.floor(Math.random() * defaultAvatars.length)] + default: () => getRandomUserAvatar() }, promotionRate: { @@ -78,11 +66,8 @@ const UserSchema = new Schema({ }); try { - // login - UserSchema.index({ username: 1, password: 1 }, { background: true }); - // Admin charts - UserSchema.index({ createTime: -1 }, { background: true }); + UserSchema.index({ createTime: -1 }); } catch (error) { console.log(error); } diff --git a/packages/service/support/user/team/controller.ts b/packages/service/support/user/team/controller.ts index ede448c93..451e02f5b 100644 --- a/packages/service/support/user/team/controller.ts +++ b/packages/service/support/user/team/controller.ts @@ -16,6 +16,8 @@ import { MongoMemberGroupModel } from '../../permission/memberGroup/memberGroupS import { mongoSessionRun } from '../../../common/mongo/sessionRun'; import { DefaultGroupName } from '@fastgpt/global/support/user/team/group/constant'; import { getAIApi, openaiBaseUrl } from '../../../core/ai/config'; +import { createRootOrg } from '../../permission/org/controllers'; +import { refreshSourceAvatar } from '../../../common/file/image/controller'; async function getTeamMember(match: Record): Promise { const tmb = await MongoTeamMember.findOne(match).populate<{ team: TeamSchema }>('team').lean(); @@ -32,6 +34,7 @@ async function getTeamMember(match: Record): Promise Date.now() }, - balance: { - type: Number, - default: 0 - }, + balance: Number, teamDomain: { type: String }, diff --git a/packages/service/support/wallet/usage/schema.ts b/packages/service/support/wallet/usage/schema.ts index fc1a3b500..7416d6b45 100644 --- a/packages/service/support/wallet/usage/schema.ts +++ b/packages/service/support/wallet/usage/schema.ts @@ -61,11 +61,11 @@ const UsageSchema = new Schema({ }); try { - UsageSchema.index({ teamId: 1, tmbId: 1, source: 1, time: -1 }, { background: true }); + UsageSchema.index({ teamId: 1, tmbId: 1, source: 1, time: -1 }); // timer task. clear dead team - // UsageSchema.index({ teamId: 1, time: -1 }, { background: true }); + // UsageSchema.index({ teamId: 1, time: -1 }); - UsageSchema.index({ time: 1 }, { background: true, expireAfterSeconds: 360 * 24 * 60 * 60 }); + UsageSchema.index({ time: 1 }, { expireAfterSeconds: 360 * 24 * 60 * 60 }); } catch (error) { console.log(error); } diff --git a/packages/service/worker/htmlStr2Md/utils.ts b/packages/service/worker/htmlStr2Md/utils.ts index 38112b92d..8384d005a 100644 --- a/packages/service/worker/htmlStr2Md/utils.ts +++ b/packages/service/worker/htmlStr2Md/utils.ts @@ -1,9 +1,27 @@ import TurndownService from 'turndown'; import { ImageType } from '../readFile/type'; import { matchMdImgTextAndUpload } from '@fastgpt/global/common/string/markdown'; +import { getNanoid } from '@fastgpt/global/common/string/tools'; // @ts-ignore const turndownPluginGfm = require('joplin-turndown-plugin-gfm'); +const processBase64Images = (htmlContent: string) => { + const base64Regex = /src="data:([^;]+);base64,([^"]+)"/g; + const images: ImageType[] = []; + + const processedHtml = htmlContent.replace(base64Regex, (match, mime, base64Data) => { + const uuid = `IMAGE_${getNanoid(12)}_IMAGE`; + images.push({ + uuid, + base64: base64Data, + mime + }); + return `src="${uuid}"`; + }); + + return { processedHtml, images }; +}; + export const html2md = ( html: string ): { @@ -25,11 +43,14 @@ export const html2md = ( turndownService.remove(['i', 'script', 'iframe', 'style']); turndownService.use(turndownPluginGfm.gfm); - const { text, imageList } = matchMdImgTextAndUpload(html); + // Base64 img to id, otherwise it will occupy memory when going to md + const { processedHtml, images } = processBase64Images(html); + const md = turndownService.turndown(processedHtml); + const { text, imageList } = matchMdImgTextAndUpload(md); return { - rawText: turndownService.turndown(text), - imageList + rawText: text, + imageList: [...images, ...imageList] }; } catch (error) { console.log('html 2 markdown error', error); diff --git a/packages/service/worker/readFile/extension/rawText.ts b/packages/service/worker/readFile/extension/rawText.ts index 15e0bed83..0f303f745 100644 --- a/packages/service/worker/readFile/extension/rawText.ts +++ b/packages/service/worker/readFile/extension/rawText.ts @@ -24,7 +24,11 @@ export const readFileRawText = ({ buffer, encoding }: ReadRawTextByBuffer): Read return buffer.toString(encoding as BufferEncoding); } - return iconv.decode(buffer, encoding); + if (encoding) { + return iconv.decode(buffer, encoding); + } + + return buffer.toString('utf-8'); } catch (error) { return buffer.toString('utf-8'); } diff --git a/packages/service/worker/readFile/parseOffice.ts b/packages/service/worker/readFile/parseOffice.ts index 05dabf9ec..177f5e2cd 100644 --- a/packages/service/worker/readFile/parseOffice.ts +++ b/packages/service/worker/readFile/parseOffice.ts @@ -44,13 +44,15 @@ const parsePowerPoint = async ({ } // Returning an array of all the xml contents read using fs.readFileSync - const xmlContentArray = files.map((file) => { - try { - return fs.readFileSync(`${decompressPath}/${file.path}`, encoding); - } catch (err) { - return fs.readFileSync(`${decompressPath}/${file.path}`, 'utf-8'); - } - }); + const xmlContentArray = await Promise.all( + files.map((file) => { + try { + return fs.promises.readFile(`${decompressPath}/${file.path}`, encoding); + } catch (err) { + return fs.promises.readFile(`${decompressPath}/${file.path}`, 'utf-8'); + } + }) + ); let responseArr: string[] = []; diff --git a/packages/templates/register.ts b/packages/templates/register.ts index 4a18d4d96..fae3334ea 100644 --- a/packages/templates/register.ts +++ b/packages/templates/register.ts @@ -12,24 +12,24 @@ const getTemplateNameList = () => { return fs.readdirSync(templatesPath) as string[]; }; -const getFileTemplates = (): AppTemplateSchemaType[] => { +const getFileTemplates = async (): Promise => { const templateNames = getTemplateNameList(); - const appMarketTemplates = templateNames.map((name) => { - const fileContent = require(`./src/${name}/template.json`); + return Promise.all( + templateNames.map>(async (name) => { + const fileContent = (await import(`./src/${name}/template.json`))?.default; - return { - ...fileContent, - templateId: `${PluginSourceEnum.community}-${name}`, - isActive: true - }; - }); - - return appMarketTemplates; + return { + ...fileContent, + templateId: `${PluginSourceEnum.community}-${name}`, + isActive: true + }; + }) + ); }; const getAppTemplates = async () => { - const communityTemplates = getFileTemplates(); + const communityTemplates = await getFileTemplates(); const dbTemplates = await MongoAppTemplate.find(); diff --git a/packages/web/components/common/Icon/button.tsx b/packages/web/components/common/Icon/button.tsx index 38cd50a39..9fde10ec4 100644 --- a/packages/web/components/common/Icon/button.tsx +++ b/packages/web/components/common/Icon/button.tsx @@ -18,7 +18,6 @@ const MyIconButton = ({ }: Props) => { return ( import('./icons/common/customTitleLight.svg'), 'common/data': () => import('./icons/common/data.svg'), 'common/dingtalkFill': () => import('./icons/common/dingtalkFill.svg'), + 'common/downArrowFill': () => import('./icons/common/downArrowFill.svg'), 'common/editor/resizer': () => import('./icons/common/editor/resizer.svg'), 'common/errorFill': () => import('./icons/common/errorFill.svg'), 'common/file/move': () => import('./icons/common/file/move.svg'), @@ -95,8 +96,10 @@ export const iconPaths = { 'common/variable': () => import('./icons/common/variable.svg'), 'common/viewLight': () => import('./icons/common/viewLight.svg'), 'common/voiceLight': () => import('./icons/common/voiceLight.svg'), + 'common/wallet': () => import('./icons/common/wallet.svg'), 'common/warn': () => import('./icons/common/warn.svg'), 'common/wechatFill': () => import('./icons/common/wechatFill.svg'), + 'common/wecom': () => import('./icons/common/wecom.svg'), configmap: () => import('./icons/configmap.svg'), copy: () => import('./icons/copy.svg'), 'core/app/aiFill': () => import('./icons/core/app/aiFill.svg'), @@ -346,6 +349,8 @@ export const iconPaths = { history: () => import('./icons/history.svg'), infoRounded: () => import('./icons/infoRounded.svg'), kbTest: () => import('./icons/kbTest.svg'), + key: () => import('./icons/key.svg'), + keyPrimary: () => import('./icons/keyPrimary.svg'), menu: () => import('./icons/menu.svg'), minus: () => import('./icons/minus.svg'), 'modal/AddClb': () => import('./icons/modal/AddClb.svg'), @@ -408,7 +413,6 @@ export const iconPaths = { 'support/bill/shoppingCart': () => import('./icons/support/bill/shoppingCart.svg'), 'support/bill/wallet': () => import('./icons/support/bill/wallet.svg'), 'support/outlink/apikeyFill': () => import('./icons/support/outlink/apikeyFill.svg'), - 'support/outlink/apikeyLight': () => import('./icons/support/outlink/apikeyLight.svg'), 'support/outlink/iframeLight': () => import('./icons/support/outlink/iframeLight.svg'), 'support/outlink/share': () => import('./icons/support/outlink/share.svg'), 'support/outlink/shareLight': () => import('./icons/support/outlink/shareLight.svg'), @@ -416,7 +420,6 @@ export const iconPaths = { 'support/permission/privateLight': () => import('./icons/support/permission/privateLight.svg'), 'support/permission/publicLight': () => import('./icons/support/permission/publicLight.svg'), 'support/team/group': () => import('./icons/support/team/group.svg'), - 'support/team/key': () => import('./icons/support/team/key.svg'), 'support/team/memberLight': () => import('./icons/support/team/memberLight.svg'), 'support/usage/usageRecordLight': () => import('./icons/support/usage/usageRecordLight.svg'), 'support/user/informLight': () => import('./icons/support/user/informLight.svg'), diff --git a/packages/web/components/common/Icon/icons/common/downArrowFill.svg b/packages/web/components/common/Icon/icons/common/downArrowFill.svg new file mode 100644 index 000000000..d0f5035e4 --- /dev/null +++ b/packages/web/components/common/Icon/icons/common/downArrowFill.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/packages/web/components/common/Icon/icons/common/wallet.svg b/packages/web/components/common/Icon/icons/common/wallet.svg new file mode 100644 index 000000000..add3e9257 --- /dev/null +++ b/packages/web/components/common/Icon/icons/common/wallet.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/packages/web/components/common/Icon/icons/common/wecom.svg b/packages/web/components/common/Icon/icons/common/wecom.svg new file mode 100644 index 000000000..1345e42ca --- /dev/null +++ b/packages/web/components/common/Icon/icons/common/wecom.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/packages/web/components/common/Icon/icons/support/team/key.svg b/packages/web/components/common/Icon/icons/key.svg similarity index 100% rename from packages/web/components/common/Icon/icons/support/team/key.svg rename to packages/web/components/common/Icon/icons/key.svg diff --git a/packages/web/components/common/Icon/icons/keyPrimary.svg b/packages/web/components/common/Icon/icons/keyPrimary.svg new file mode 100644 index 000000000..836c66079 --- /dev/null +++ b/packages/web/components/common/Icon/icons/keyPrimary.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/packages/web/components/common/Icon/icons/support/outlink/apikeyLight.svg b/packages/web/components/common/Icon/icons/support/outlink/apikeyLight.svg deleted file mode 100644 index dee84de25..000000000 --- a/packages/web/components/common/Icon/icons/support/outlink/apikeyLight.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - \ No newline at end of file diff --git a/packages/web/components/common/Tabs/FillRowTabs.tsx b/packages/web/components/common/Tabs/FillRowTabs.tsx index 7388af742..f09834955 100644 --- a/packages/web/components/common/Tabs/FillRowTabs.tsx +++ b/packages/web/components/common/Tabs/FillRowTabs.tsx @@ -1,15 +1,15 @@ -import React from 'react'; +import React, { forwardRef } from 'react'; import { Flex, Box, BoxProps } from '@chakra-ui/react'; import MyIcon from '../Icon'; -type Props = Omit & { +type Props = Omit & { list: { icon?: string; label: string | React.ReactNode; - value: string; + value: T; }[]; - value: string; - onChange: (e: string) => void; + value: T; + onChange: (e: T) => void; }; const FillRowTabs = ({ list, value, onChange, py = '7px', px = '12px', ...props }: Props) => { @@ -61,4 +61,6 @@ const FillRowTabs = ({ list, value, onChange, py = '7px', px = '12px', ...props ); }; -export default FillRowTabs; +export default forwardRef(FillRowTabs) as ( + props: Props & { ref?: React.Ref } +) => JSX.Element; diff --git a/packages/web/i18n/en/account.json b/packages/web/i18n/en/account.json index b115fa506..58155816a 100644 --- a/packages/web/i18n/en/account.json +++ b/packages/web/i18n/en/account.json @@ -1,7 +1,14 @@ { + "active_model": "Available models", + "add_default_model": "Add a preset model", "api_key": "API key", "bills_and_invoices": "Bills", + "channel": "Channel", "confirm_logout": "Confirm to log out?", + "create_channel": "Add new channel", + "create_model": "Add new model", + "custom_model": "custom model", + "default_model": "Default model", "logout": "Sign out", "model_provider": "Model Provider", "notifications": "Notify", diff --git a/packages/web/i18n/en/account_info.json b/packages/web/i18n/en/account_info.json index dbda14415..442a6191b 100644 --- a/packages/web/i18n/en/account_info.json +++ b/packages/web/i18n/en/account_info.json @@ -10,9 +10,6 @@ "avatar_selection_exception": "Abnormal avatar selection", "balance": "balance", "billing_standard": "Standards", - "bind_notification_error": "Abnormal binding notification account", - "bind_notification_hint": "Please bind the notification receiving account to ensure that you can normally receive notifications such as package expiration reminders and ensure the normal operation of your services.", - "bind_notification_success": "Binding notification account successful", "cancel": "Cancel", "change": "change", "choose_avatar": "Click to select avatar", @@ -40,7 +37,6 @@ "month": "moon", "new_password": "New Password", "notification_receiving": "Notify", - "notification_receiving_hint": "Notification reception", "old_password": "Old Password", "openai_account_configuration": "OpenAI account configuration", "openai_account_setting_exception": "Setting OpenAI account exception", @@ -49,8 +45,8 @@ "package_expiry_time": "Expired", "package_usage_rules": "Package usage rules: The system will give priority to using more advanced packages, and the original unused packages will take effect later.", "password": "Password", - "password_length_error": "Password must be at least 4 characters and at most 60 characters", "password_mismatch": "Password Inconsistency: Two passwords are inconsistent", + "password_tip": "Password must be at least 6 characters long and contain at least two combinations: numbers, letters, or special characters", "password_update_error": "Exception when changing password", "password_update_success": "Password changed successfully", "pending_usage": "To be used", diff --git a/packages/web/i18n/en/account_team.json b/packages/web/i18n/en/account_team.json index 453b0a14f..8641c3c8f 100644 --- a/packages/web/i18n/en/account_team.json +++ b/packages/web/i18n/en/account_team.json @@ -1,10 +1,16 @@ { "action": "operate", "confirm_delete_group": "Confirm to delete group?", - "confirm_leave_team": "Confirmed to leave the team? \n \nAfter you log out, all your resources in the team (applications, knowledge bases, folders, managed groups, etc.) will be transferred to the team owner.", + "confirm_delete_member": "Confirm to delete member?", + "confirm_delete_org": "Confirm to delete organization?", + "confirm_leave_team": "Confirmed to leave the team? \nAfter exiting, all your resources in the team are transferred to the team owner.", "create_group": "Create group", + "create_org": "Create organization", + "create_sub_org": "Create sub-organization", "delete": "delete", + "delete_org": "Delete organization", "edit_info": "Edit information", + "edit_org_info": "Edit organization information", "group": "group", "group_name": "Group name", "label_sync": "Tag sync", @@ -12,8 +18,14 @@ "manage_member": "Managing members", "member": "member", "member_group": "Belonging to member group", + "move_member": "Move member", + "move_org": "Move organization", + "org": "organization", + "org_description": "Organization description", + "org_name": "Organization name", "owner": "owner", "permission": "Permissions", + "remark": "remark", "remove_tip": "Confirm to remove {{username}} from the team?", "retain_admin_permissions": "Keep administrator rights", "search_member_group_name": "Search member/group name", diff --git a/packages/web/i18n/en/common.json b/packages/web/i18n/en/common.json index 76e00a859..08c7a7448 100644 --- a/packages/web/i18n/en/common.json +++ b/packages/web/i18n/en/common.json @@ -74,11 +74,19 @@ "code_error.team_error.ai_points_not_enough": "Insufficient AI Points", "code_error.team_error.app_amount_not_enough": "Application Limit Reached", "code_error.team_error.cannot_delete_default_group": "Cannot delete default group", + "code_error.team_error.cannot_delete_non_empty_org": "Cannot delete non-empty organization", + "code_error.team_error.cannot_modify_root_org": "Cannot modify root organization", + "code_error.team_error.cannot_move_to_sub_path": "Cannot move to same or subdirectory", "code_error.team_error.dataset_amount_not_enough": "Dataset Limit Reached", "code_error.team_error.dataset_size_not_enough": "Insufficient Dataset Capacity, Please Expand", "code_error.team_error.group_name_duplicate": "Duplicate group name", "code_error.team_error.group_name_empty": "Group name cannot be empty", "code_error.team_error.group_not_exist": "Group does not exist", + "code_error.team_error.not_user": "The member cannot be found", + "code_error.team_error.org_member_duplicated": "Duplicate organization member", + "code_error.team_error.org_member_not_exist": "Organization member does not exist", + "code_error.team_error.org_not_exist": "Organization does not exist", + "code_error.team_error.org_parent_not_exist": "Parent organization does not exist", "code_error.team_error.over_size": "error.team.overSize", "code_error.team_error.plugin_amount_not_enough": "Plugin Limit Reached", "code_error.team_error.re_rank_not_enough": "Unauthorized to Use Re-Rank", @@ -87,7 +95,7 @@ "code_error.team_error.website_sync_not_enough": "Unauthorized to Use Website Sync", "code_error.token_error_code.403": "Invalid Login Status, Please Re-login", "code_error.user_error.balance_not_enough": "Insufficient Account Balance", - "code_error.user_error.bin_visitor": "Identity Verification Failed", + "code_error.account_error": "Incorrect account name or password", "code_error.user_error.bin_visitor_guest": "You Are Currently a Guest, Unauthorized to Operate", "code_error.user_error.un_auth_user": "User Not Found", "common.Action": "Action", @@ -873,9 +881,11 @@ "error.code_error": "Verification code error", "error.fileNotFound": "File not found~", "error.inheritPermissionError": "Inherit permission Error", + "error.invalid_params": "Invalid parameter", "error.missingParams": "Insufficient parameters", "error.too_many_request": "Too many request", "error.upload_file_error_filename": "{{name}} Upload Failed", + "error.upload_image_error": "File upload failed", "error.username_empty": "Account cannot be empty", "extraction_results": "Extraction Results", "field_name": "Field Name", @@ -1028,7 +1038,15 @@ "support.user.Price": "Pricing", "support.user.User self info": "Profile", "support.user.auth.Sending Code": "Sending Code", + "support.user.auth.get_code": "Get Verification Code", + "support.user.auth.get_code_again": "s Get Again", "support.user.captcha_placeholder": "Please enter the verification code", + "support.user.info.bind_notification_error": "Abnormal binding notification account", + "support.user.info.bind_notification_hint": "Please bind the notification receiving account to ensure that you can receive notifications such as package expiration reminders, etc., to ensure the normal operation of your service.", + "support.user.info.bind_notification_success": "Binding notification account successful", + "support.user.info.code_required": "Verification code cannot be empty", + "support.user.info.notification_receiving_hint": "Notification reception", + "support.user.info.verification_code": "Verification Code", "support.user.inform.System message": "System Message", "support.user.login.Email": "Email", "support.user.login.Github": "GitHub Login", @@ -1041,7 +1059,7 @@ "support.user.login.Provider error": "Login Error, Please Try Again", "support.user.login.Username": "Username", "support.user.login.Wechat": "WeChat Login", - "support.user.login.can_not_login": "Cannot Log In, Click to Contact", + "support.user.login.can_not_login": "Cannot log in? Click here to contact us", "support.user.login.error": "Login Error", "support.user.login.security_failed": "Security Verification Failed", "support.user.login.wx_qr_login": "WeChat QR Code Login", @@ -1053,10 +1071,14 @@ "support.wallet.Ai point every thousand tokens_input": "Input:{{points}} points/1K tokens", "support.wallet.Ai point every thousand tokens_output": "Output:{{points}} points/1K tokens", "support.wallet.Amount": "Amount", + "support.wallet.App_amount_not_sufficient": "The number of your applications has reached the limit. Please upgrade your plan to continue using.", "support.wallet.Buy": "Buy", + "support.wallet.Dataset_amount_not_sufficient": "The number of your datasets has reached the limit. Please upgrade your plan to continue using.", + "support.wallet.Dataset_not_sufficient": "Your dataset capacity is insufficient. Please upgrade your plan or purchase additional dataset capacity to continue using.", "support.wallet.Not sufficient": "Insufficient AI Points, Please Upgrade Your Package or Purchase Additional AI Points to Continue Using.", "support.wallet.Plan expired time": "Package Expiration Time", "support.wallet.Standard Plan Detail": "Package Details", + "support.wallet.Team_member_over_size": "The number of your team members has reached the limit. Please upgrade your plan to continue using.", "support.wallet.To read plan": "View Package", "support.wallet.amount_0": "Purchase Quantity Cannot Be 0", "support.wallet.apply_invoice": "Apply for Invoice", @@ -1166,6 +1188,7 @@ "tag_list": "Tag List", "team_tag": "Team Tag", "textarea_variable_picker_tip": "Enter \"/\" to select a variable", + "unauth_token": "The certificate has expired, please log in again", "unit.character": "Character", "unit.minute": "Minute", "unit.seconds": "Second", diff --git a/packages/web/i18n/en/login.json b/packages/web/i18n/en/login.json index a1256d494..8dfe1b826 100644 --- a/packages/web/i18n/en/login.json +++ b/packages/web/i18n/en/login.json @@ -1,13 +1,14 @@ { "Chinese_ip_tip": "It is detected that you are a mainland Chinese IP, click to jump to visit the mainland China version.", "Login": "Login", - "forget_password": "Find password", + "forget_password": "Find Password", "login_failed": "Login failed", "login_success": "Login successful", "no_remind": "Don't remind again", "password_condition": "Password maximum 60 characters", - "policy_tip": "By useing, you agree to our", - "privacy": "Privacy policy", + "password_tip": "Password must be at least 6 characters long and contain at least two combinations: numbers, letters, or special characters", + "policy_tip": "By using this service, you agree to our", + "privacy": "Privacy Policy", "redirect": "Jump", "register": "Register", "root_password_placeholder": "The root user password is the value of the environment variable DEFAULT_ROOT_PSW", @@ -16,4 +17,4 @@ "agree": "agree", "cookies_tip": " This website uses cookies to provide a better service experience. By continuing to use the site, you agree to our Cookie Policy.", "privacy_policy": "Privacy Policy" -} \ No newline at end of file +} diff --git a/packages/web/i18n/en/user.json b/packages/web/i18n/en/user.json index 5f2ba68ee..091cffd3c 100644 --- a/packages/web/i18n/en/user.json +++ b/packages/web/i18n/en/user.json @@ -28,7 +28,6 @@ "login.Dingtalk": "DingTalk Login", "manage_team": "Manage team", "name": "Name", - "notification.Bind Notification Pipe Hint": "Please bind a notification receiving account to ensure you receive notifications such as plan expiration reminders, ensuring your service runs smoothly.", "notification.remind_owner_bind": "Please remind the creator to bind a notification account", "operations": "Actions", "owner": "owner", @@ -38,9 +37,6 @@ "password.confirm": "Confirm Password", "password.email_phone_error": "Invalid Email/Phone Number Format", "password.email_phone_void": "Email/Phone Number Cannot Be Empty", - "password.get_code": "Get Verification Code", - "password.get_code_again": "Get Again in s", - "password.new_password": "New Password (4-20 characters)", "password.not_match": "Passwords Do Not Match", "password.password_condition": "Password must be between 4 and 20 characters", "password.password_required": "Password Cannot Be Empty", @@ -50,6 +46,7 @@ "password.to_login": "Go to Login", "password.verification_code": "Verification Code", "permission.Manage": "Admin", + "permission.Add": "Add Permissions", "permission.Manage tip": "Team admin with full permissions", "permission.Read": "Read Only", "permission.Read desc": "Members can only read related resources, cannot create new resources", @@ -61,6 +58,7 @@ "permission_des.manage": "Can create resources, invite, and delete members", "permission_des.read": "Members can only read related resources and cannot create new resources.", "permission_des.write": "In addition to readable resources, you can also create new resources", + "permission_add_tip": "After adding, you can check the permissions for them.", "permissions": "Permissions", "personal_information": "Me", "personalization": "Personalization", @@ -68,7 +66,7 @@ "register.confirm": "Confirm Registration", "register.register_account": "Register {{account}} Account", "register.success": "Registration Successful", - "register.to_login": "Already have an account? Login", + "register.to_login": "Already have an account? Go to Login", "search_user": "Search Username", "sso_auth_failed": "SSO authentication failed", "synchronization.button": "Sync Now", @@ -85,6 +83,7 @@ "team.Update Team": "Update team information", "team.add_collaborator": "Add Collaborator", "team.add_writer": "Add writable members", + "team.add_permission": "Add permissions", "team.avatar_and_name": "avatar", "team.belong_to_group": "Member group", "team.group.avatar": "Group avatar", @@ -106,10 +105,11 @@ "team.group.role.admin": "administrator", "team.group.role.member": "member", "team.group.role.owner": "owner", - "team.group.search_placeholder": "Search member/group name", + "search_group_org_user": "Search member/group/org name", "team.group.set_as_admin": "Set as administrator", "team.group.toast.can_not_delete_owner": "Owner cannot be deleted, please transfer first", "team.group.transfer_owner": "transfer owner", + "team.org.org": "Organization", "team.manage_collaborators": "Manage Collaborators", "team.no_collaborators": "No Collaborators", "team.write_role_member": "", diff --git a/packages/web/i18n/en/workflow.json b/packages/web/i18n/en/workflow.json index a76add2cc..9ee85b932 100644 --- a/packages/web/i18n/en/workflow.json +++ b/packages/web/i18n/en/workflow.json @@ -49,7 +49,7 @@ "execution_error": "Execution Error", "extraction_requirements_description": "Extraction Requirements Description", "extraction_requirements_description_detail": "Provide AI with some background knowledge or requirements to guide it in completing the task better.\\nThis input box can use global variables.", - "extraction_requirements_placeholder": "For example: \\n1. The current time is: {{cTime}}. You are a lab reservation assistant, and your task is to help users reserve a lab by extracting the corresponding reservation information from the text.\\n2. You are a Google search assistant, and you need to extract suitable search terms from the text.", + "extraction_requirements_placeholder": "For example: 1. The current time is: {{cTime}}. \nYou are a laboratory reservation assistant. Your task is to help users make laboratory reservations and obtain the corresponding reservation information from the text.\n\n2. You are the Google Search Assistant and need to extract appropriate search terms from text.", "feedback_text": "Feedback Text", "field_description": "Field Description", "field_description_placeholder": "Describe the function of this input field. If it is a tool call parameter, this description will affect the quality of the model generation.", diff --git a/packages/web/i18n/zh-CN/account.json b/packages/web/i18n/zh-CN/account.json index 85b0e4954..5eae52e1f 100644 --- a/packages/web/i18n/zh-CN/account.json +++ b/packages/web/i18n/zh-CN/account.json @@ -1,7 +1,14 @@ { + "active_model": "可用模型", + "add_default_model": "添加预设模型", "api_key": "API 密钥", "bills_and_invoices": "账单与发票", + "channel": "渠道", "confirm_logout": "确认退出登录?", + "create_channel": "新增渠道", + "create_model": "新增模型", + "custom_model": "自定义模型", + "default_model": "预设模型", "logout": "登出", "model_provider": "模型提供商", "notifications": "通知", diff --git a/packages/web/i18n/zh-CN/account_info.json b/packages/web/i18n/zh-CN/account_info.json index 6059523dd..efd52c90a 100644 --- a/packages/web/i18n/zh-CN/account_info.json +++ b/packages/web/i18n/zh-CN/account_info.json @@ -10,9 +10,6 @@ "avatar_selection_exception": "头像选择异常", "balance": "余额", "billing_standard": "计费标准", - "bind_notification_error": "绑定通知账号异常", - "bind_notification_hint": "请绑定通知接收账号,以确保您能正常接收套餐过期提醒等通知,保障您的服务正常运行。", - "bind_notification_success": "绑定通知账号成功", "cancel": "取消", "change": "变更", "choose_avatar": "点击选择头像", @@ -40,15 +37,14 @@ "month": "月", "new_password": "新密码", "notification_receiving": "通知接收", - "notification_receiving_hint": "通知接收", "old_password": "旧密码", "package_and_usage": "套餐与用量", "package_details": "套餐详情", "package_expiry_time": "套餐到期时间", "package_usage_rules": "套餐使用规则:系统优先使用更高级的套餐,原未用完的套餐将延后生效", "password": "密码", - "password_length_error": "密码最少 4 位最多 60 位", "password_mismatch": "密码不一致: 两次密码不一致", + "password_tip": "密码至少 6 位,且至少包含两种组合:数字、字母或特殊字符", "password_update_error": "修改密码异常", "password_update_success": "修改密码成功", "pending_usage": "待使用", diff --git a/packages/web/i18n/zh-CN/account_team.json b/packages/web/i18n/zh-CN/account_team.json index 720dff39f..e562ef7c9 100644 --- a/packages/web/i18n/zh-CN/account_team.json +++ b/packages/web/i18n/zh-CN/account_team.json @@ -1,29 +1,39 @@ -{ - "total_team_members": "共 {{amount}} 名成员", - "member": "成员", - "group": "群组", - "permission": "权限", - "user_name": "用户名", - "member_group": "所属成员组", - "action": "操作", - "waiting": "待接受", - "remove_tip": "确认将 {{username}} 移出团队?", - - "confirm_leave_team": "确认离开该团队? \n 退出后,您在该团队所有的资源( 应用、知识库、文件夹、管理的群组等)均转让给团队所有者。", - "leave_team_failed": "离开团队异常", - "label_sync": "标签同步", - "user_team_invite_member": "邀请成员", - "user_team_leave_team": "离开团队", - "user_team_leave_team_failed": "离开团队失败", - "create_group": "创建群组", - "search_member_group_name": "搜索成员/群组名称", - "confirm_delete_group": "确认删除群组?", - "group_name": "群组名称", - "owner": "所有者", - "manage_member": "管理成员", - "edit_info": "编辑信息", - - "transfer_ownership": "转让所有者", - "delete": "删除", - "retain_admin_permissions": "保留管理员权限" -} +{ + "action": "操作", + "confirm_delete_group": "确认删除群组?", + "confirm_delete_member": "确认删除成员?", + "confirm_delete_org": "确认删除该部门?", + "confirm_leave_team": "确认离开该团队? \n退出后,您在该团队所有的资源均转让给团队所有者。", + "create_group": "创建群组", + "create_org": "创建部门", + "create_sub_org": "创建子部门", + "delete": "删除", + "delete_org": "删除部门", + "edit_info": "编辑信息", + "edit_org_info": "编辑部门信息", + "group": "群组", + "group_name": "群组名称", + "label_sync": "标签同步", + "leave_team_failed": "离开团队异常", + "manage_member": "管理成员", + "member": "成员", + "member_group": "所属群组", + "move_member": "移动成员", + "move_org": "移动部门", + "org": "部门", + "org_description": "介绍", + "org_name": "部门名称", + "owner": "所有者", + "permission": "权限", + "remark": "备注", + "remove_tip": "确认将 {{username}} 移出团队?", + "retain_admin_permissions": "保留管理员权限", + "search_member_group_name": "搜索成员/群组名称", + "total_team_members": "共 {{amount}} 名成员", + "transfer_ownership": "转让所有者", + "user_name": "用户名", + "user_team_invite_member": "邀请成员", + "user_team_leave_team": "离开团队", + "user_team_leave_team_failed": "离开团队失败", + "waiting": "待接受" +} diff --git a/packages/web/i18n/zh-CN/common.json b/packages/web/i18n/zh-CN/common.json index 5720977c1..f4c97061f 100644 --- a/packages/web/i18n/zh-CN/common.json +++ b/packages/web/i18n/zh-CN/common.json @@ -78,11 +78,19 @@ "code_error.team_error.ai_points_not_enough": "", "code_error.team_error.app_amount_not_enough": "应用数量已达上限~", "code_error.team_error.cannot_delete_default_group": "不能删除默认群组", + "code_error.team_error.cannot_delete_non_empty_org": "不能删除非空部门", + "code_error.team_error.cannot_modify_root_org": "不能修改根部门", + "code_error.team_error.cannot_move_to_sub_path": "不能移动到相同或子目录", "code_error.team_error.dataset_amount_not_enough": "知识库数量已达上限~", "code_error.team_error.dataset_size_not_enough": "知识库容量不足,请先扩容~", "code_error.team_error.group_name_duplicate": "群组名称重复", "code_error.team_error.group_name_empty": "群组名称不能为空", "code_error.team_error.group_not_exist": "群组不存在", + "code_error.team_error.not_user": "找不到该成员", + "code_error.team_error.org_member_duplicated": "重复的部门成员", + "code_error.team_error.org_member_not_exist": "部门成员不存在", + "code_error.team_error.org_not_exist": "部门不存在", + "code_error.team_error.org_parent_not_exist": "父部门不存在", "code_error.team_error.over_size": "error.team.overSize", "code_error.team_error.plugin_amount_not_enough": "插件数量已达上限~", "code_error.team_error.re_rank_not_enough": "无权使用检索重排~", @@ -91,7 +99,7 @@ "code_error.team_error.website_sync_not_enough": "无权使用Web站点同步~", "code_error.token_error_code.403": "登录状态无效,请重新登录", "code_error.user_error.balance_not_enough": "账号余额不足~", - "code_error.user_error.bin_visitor": "您的身份校验未通过", + "code_error.account_error": "账号名或密码错误", "code_error.user_error.bin_visitor_guest": "您当前身份为游客,无权操作", "code_error.user_error.un_auth_user": "找不到该用户", "common.Action": "操作", @@ -876,9 +884,11 @@ "error.code_error": "验证码错误", "error.fileNotFound": "文件找不到了~", "error.inheritPermissionError": "权限继承错误", + "error.invalid_params": "参数无效", "error.missingParams": "参数缺失", "error.too_many_request": "请求太频繁了,请稍后重试", "error.upload_file_error_filename": "{{name}} 上传失败", + "error.upload_image_error": "上传文件失败", "error.username_empty": "账号不能为空", "extraction_results": "提取结果", "field_name": "字段名", @@ -1031,7 +1041,15 @@ "support.user.Price": "计费标准", "support.user.User self info": "个人信息", "support.user.auth.Sending Code": "正在发送", + "support.user.auth.get_code": "获取验证码", + "support.user.auth.get_code_again": "s后重新获取", "support.user.captcha_placeholder": "请输入验证码", + "support.user.info.bind_notification_error": "绑定通知账号异常", + "support.user.info.bind_notification_hint": "请绑定通知接收账号,以确保您能正常接收套餐过期提醒等通知,保障您的服务正常运行。", + "support.user.info.bind_notification_success": "绑定通知账号成功", + "support.user.info.code_required": "验证码不能为空", + "support.user.info.notification_receiving_hint": "通知接收", + "support.user.info.verification_code": "验证码", "support.user.inform.System message": "系统消息", "support.user.login.Email": "邮箱", "support.user.login.Github": "GitHub 登录", @@ -1056,10 +1074,14 @@ "support.wallet.Ai point every thousand tokens_input": "输入:{{points}} 积分/1K tokens", "support.wallet.Ai point every thousand tokens_output": "输出:{{points}} 积分/1K tokens", "support.wallet.Amount": "金额", + "support.wallet.App_amount_not_sufficient": "您的应用数量已达上限,请升级套餐后继续使用。", "support.wallet.Buy": "购买", + "support.wallet.Dataset_amount_not_sufficient": "您的知识库数量已达上限,请升级套餐后继续使用。", + "support.wallet.Dataset_not_sufficient": "您的知识库容量不足,请先升级套餐或购买额外知识库容量后继续使用。", "support.wallet.Not sufficient": "您的 AI 积分不足,请先升级套餐或购买额外 AI 积分后继续使用。", "support.wallet.Plan expired time": "套餐到期时间", "support.wallet.Standard Plan Detail": "套餐详情", + "support.wallet.Team_member_over_size": "您的团队成员数量已达上限,请升级套餐后继续使用。", "support.wallet.To read plan": "查看套餐", "support.wallet.amount_0": "购买数量不能为0", "support.wallet.apply_invoice": "申请开票", @@ -1169,6 +1191,7 @@ "tag_list": "标签列表", "team_tag": "团队标签", "textarea_variable_picker_tip": "输入\"/\"可选择变量", + "unauth_token": "凭证已过期,请重新登录", "unit.character": "字符", "unit.minute": "分钟", "unit.seconds": "秒", diff --git a/packages/web/i18n/zh-CN/login.json b/packages/web/i18n/zh-CN/login.json index 92eb9606b..f3cc74a89 100644 --- a/packages/web/i18n/zh-CN/login.json +++ b/packages/web/i18n/zh-CN/login.json @@ -1,19 +1,21 @@ { + "Chinese_ip_tip": "检测到您是中国大陆 IP,点击跳转访问中国大陆版。", "Login": "登录", + "agree": "同意", + "cookies_tip": "本网站使用 cookies 提供更好的服务体验。继续使用即表示您同意我们的 Cookie 政策。", "forget_password": "忘记密码?", "login_failed": "登录异常", "login_success": "登录成功", + "no_remind": "不再提醒", "password_condition": "密码最多 60 位", + "password_tip": "密码至少 6 位,且至少包含两种组合:数字、字母或特殊字符", "policy_tip": "使用即代表你同意我们的", "privacy": "隐私协议", + "privacy_policy": "隐私政策", + "redirect": "跳转", "register": "注册账号", "root_password_placeholder": "root 用户密码为环境变量 DEFAULT_ROOT_PSW 的值", "terms": "服务协议", "use_root_login": "使用 root 用户登录", - "redirect": "跳转", - "no_remind": "不再提醒", - "Chinese_ip_tip": "检测到您是中国大陆 IP,点击跳转访问中国大陆版。", - "agree": "同意", - "cookies_tip": "本网站使用 cookies 提供更好的服务体验。继续使用即表示您同意我们的 Cookie 政策。", - "privacy_policy": "隐私政策" -} \ No newline at end of file + "wecom": "企业微信" +} diff --git a/packages/web/i18n/zh-CN/user.json b/packages/web/i18n/zh-CN/user.json index 0c3e50126..e0ddec790 100644 --- a/packages/web/i18n/zh-CN/user.json +++ b/packages/web/i18n/zh-CN/user.json @@ -28,7 +28,6 @@ "login.Dingtalk": "钉钉登录", "manage_team": "管理团队", "name": "名称", - "notification.Bind Notification Pipe Hint": "请绑定通知接收账号,以确保您能正常接收套餐过期提醒等通知,保障您的服务正常运行。", "notification.remind_owner_bind": "请提醒创建者绑定通知账号", "operations": "操作", "owner": "所有者", @@ -38,9 +37,6 @@ "password.confirm": "确认密码", "password.email_phone_error": "邮箱/手机号格式错误", "password.email_phone_void": "邮箱/手机号不能为空", - "password.get_code": "获取验证码", - "password.get_code_again": "s后重新获取", - "password.new_password": "新密码(4~20位)", "password.not_match": "两次密码不一致", "password.password_condition": "密码最少 4 位最多 20 位", "password.password_required": "密码不能为空", @@ -53,6 +49,7 @@ "permission.Manage tip": "团队管理员,拥有全部权限", "permission.Read": "仅读", "permission.Read desc": "成员仅可阅读相关资源,无法新建资源", + "permission.Add": "添加权限", "permission.Write": "可写", "permission.Write tip": "除了可读资源外,还可以新建新的资源", "permission.only_collaborators": "仅协作者访问", @@ -61,6 +58,7 @@ "permission_des.manage": "可创建资源、邀请、删除成员", "permission_des.read": "成员仅可阅读相关资源,无法新建资源", "permission_des.write": "除了可读资源外,还可以新建新的资源", + "permission_add_tip": "添加后,您可为其勾选权限。", "permissions": "权限", "personal_information": "个人信息", "personalization": "个性化", @@ -85,8 +83,9 @@ "team.Update Team": "更新团队信息", "team.add_collaborator": "添加协作者", "team.add_writer": "添加可写成员", + "team.add_permission": "添加权限", "team.avatar_and_name": "头像 & 名称", - "team.belong_to_group": "所属成员组", + "team.belong_to_group": "所属群组", "team.group.avatar": "群头像", "team.group.create": "创建群组", "team.group.create_failed": "创建群组失败", @@ -106,10 +105,11 @@ "team.group.role.admin": "管理员", "team.group.role.member": "成员", "team.group.role.owner": "所有者", - "team.group.search_placeholder": "搜索成员/群组名称", + "search_group_org_user": "搜索成员/部门/群组名称", "team.group.set_as_admin": "设为管理员", "team.group.toast.can_not_delete_owner": "不能删除所有者, 请先转让", "team.group.transfer_owner": "转让所有者", + "team.org.org": "部门", "team.manage_collaborators": "管理协作者", "team.no_collaborators": "暂无协作者", "team.write_role_member": "可写权限", diff --git a/packages/web/i18n/zh-CN/workflow.json b/packages/web/i18n/zh-CN/workflow.json index 4b7b14ac4..47696b48d 100644 --- a/packages/web/i18n/zh-CN/workflow.json +++ b/packages/web/i18n/zh-CN/workflow.json @@ -49,7 +49,7 @@ "execution_error": "运行错误", "extraction_requirements_description": "提取要求描述", "extraction_requirements_description_detail": "给AI一些对应的背景知识或要求描述,引导AI更好的完成任务。\\n该输入框可使用全局变量。", - "extraction_requirements_placeholder": "例如: \\n1. 当前时间为: {{cTime}}。你是一个实验室预约助手,你的任务是帮助用户预约实验室,从文本中获取对应的预约信息。\\n2. 你是谷歌搜索助手,需要从文本中提取出合适的搜索词。", + "extraction_requirements_placeholder": "例如: 1. 当前时间为: {{cTime}}。你是一个实验室预约助手,你的任务是帮助用户预约实验室,从文本中获取对应的预约信息。\n2. 你是谷歌搜索助手,需要从文本中提取出合适的搜索词。", "feedback_text": "反馈的文本", "field_description": "字段描述", "field_description_placeholder": "描述该输入字段的功能,如果为工具调用参数,则该描述会影响模型生成的质量", diff --git a/packages/web/i18n/zh-Hant/account.json b/packages/web/i18n/zh-Hant/account.json index 395ebe1d2..59130d9da 100644 --- a/packages/web/i18n/zh-Hant/account.json +++ b/packages/web/i18n/zh-Hant/account.json @@ -1,7 +1,14 @@ { + "active_model": "可用模型", + "add_default_model": "新增預設模型", "api_key": "API 金鑰", "bills_and_invoices": "帳單與發票", + "channel": "頻道", "confirm_logout": "確認登出登入?", + "create_channel": "新增頻道", + "create_model": "新增模型", + "custom_model": "自訂模型", + "default_model": "預設模型", "logout": "登出", "model_provider": "模型提供者", "notifications": "通知", diff --git a/packages/web/i18n/zh-Hant/account_info.json b/packages/web/i18n/zh-Hant/account_info.json index a2792aaad..e7e34366d 100644 --- a/packages/web/i18n/zh-Hant/account_info.json +++ b/packages/web/i18n/zh-Hant/account_info.json @@ -10,9 +10,6 @@ "avatar_selection_exception": "頭像選擇異常", "balance": "餘額", "billing_standard": "計費標準", - "bind_notification_error": "綁定通知帳號異常", - "bind_notification_hint": "請綁定通知接收帳號,確保您能正常接收套餐過期提醒等通知,保障您的服務正常運作。", - "bind_notification_success": "綁定通知帳號成功", "cancel": "取消", "change": "變更", "choose_avatar": "點選選擇頭像", @@ -40,7 +37,6 @@ "month": "月", "new_password": "新密碼", "notification_receiving": "通知接收", - "notification_receiving_hint": "通知接收", "old_password": "舊密碼", "openai_account_configuration": "OpenAI 帳號配置", "openai_account_setting_exception": "設定 OpenAI 帳號異常", @@ -49,8 +45,8 @@ "package_expiry_time": "套餐到期時間", "package_usage_rules": "套餐使用規則:系統優先使用更進階的套餐,原未用完的套餐將延遲生效", "password": "密碼", - "password_length_error": "密碼最少 4 位最多 60 位", "password_mismatch": "密碼不一致: 兩次密碼不一致", + "password_tip": "密碼至少 6 位,且至少包含兩種組合:數字、字母或特殊字符", "password_update_error": "修改密碼異常", "password_update_success": "修改密碼成功", "pending_usage": "待使用", diff --git a/packages/web/i18n/zh-Hant/account_team.json b/packages/web/i18n/zh-Hant/account_team.json index c02d361e1..94a21818b 100644 --- a/packages/web/i18n/zh-Hant/account_team.json +++ b/packages/web/i18n/zh-Hant/account_team.json @@ -1,10 +1,16 @@ { "action": "操作", "confirm_delete_group": "確認刪除群組?", - "confirm_leave_team": "確認離開該團隊? \n \n退出後,您在該團隊所有的資源( 應用程式、知識庫、資料夾、管理的群組等)均轉讓給團隊所有者。", + "confirm_delete_member": "確認刪除成員?", + "confirm_delete_org": "確認刪除該部門?", + "confirm_leave_team": "確認離開該團隊? \n退出後,您在該團隊所有的資源轉讓給團隊所有者。", "create_group": "建立群組", + "create_org": "創建部門", + "create_sub_org": "創建子部門", "delete": "刪除", + "delete_org": "刪除部門", "edit_info": "編輯訊息", + "edit_org_info": "編輯部門資訊", "group": "群組", "group_name": "群組名稱", "label_sync": "標籤同步", @@ -12,8 +18,14 @@ "manage_member": "管理成員", "member": "成員", "member_group": "所屬成員組", + "move_member": "移動成員", + "move_org": "行動部門", + "org": "組織", + "org_description": "介紹", + "org_name": "部門名稱", "owner": "擁有者", "permission": "權限", + "remark": "備註", "remove_tip": "確認將 {{username}} 移出團隊?", "retain_admin_permissions": "保留管理員權限", "search_member_group_name": "搜尋成員/群組名稱", diff --git a/packages/web/i18n/zh-Hant/common.json b/packages/web/i18n/zh-Hant/common.json index f046d02c5..1604a0ffd 100644 --- a/packages/web/i18n/zh-Hant/common.json +++ b/packages/web/i18n/zh-Hant/common.json @@ -74,11 +74,19 @@ "code_error.team_error.ai_points_not_enough": "AI 點數不足", "code_error.team_error.app_amount_not_enough": "已達應用程式數量上限", "code_error.team_error.cannot_delete_default_group": "無法刪除預設群組", + "code_error.team_error.cannot_delete_non_empty_org": "無法刪除非空組織", + "code_error.team_error.cannot_modify_root_org": "無法修改根組織", + "code_error.team_error.cannot_move_to_sub_path": "無法移動到相同或子目錄", "code_error.team_error.dataset_amount_not_enough": "已達知識庫數量上限", "code_error.team_error.dataset_size_not_enough": "知識庫容量不足,請先擴充容量", "code_error.team_error.group_name_duplicate": "群組名稱重複", "code_error.team_error.group_name_empty": "群組名稱不能為空", "code_error.team_error.group_not_exist": "群組不存在", + "code_error.team_error.not_user": "找不到該成員", + "code_error.team_error.org_member_duplicated": "重複的組織成員", + "code_error.team_error.org_member_not_exist": "組織成員不存在", + "code_error.team_error.org_not_exist": "組織不存在", + "code_error.team_error.org_parent_not_exist": "父組織不存在", "code_error.team_error.over_size": "error.team.overSize", "code_error.team_error.plugin_amount_not_enough": "已達外掛程式數量上限", "code_error.team_error.re_rank_not_enough": "無權使用結果重新排名", @@ -87,7 +95,7 @@ "code_error.team_error.website_sync_not_enough": "無權使用網站同步", "code_error.token_error_code.403": "登入狀態無效,請重新登入", "code_error.user_error.balance_not_enough": "帳戶餘額不足", - "code_error.user_error.bin_visitor": "身份驗證未通過", + "code_error.account_error": "帳號名稱或密碼錯誤", "code_error.user_error.bin_visitor_guest": "您目前身份為訪客,無權操作", "code_error.user_error.un_auth_user": "找不到此使用者", "common.Action": "操作", @@ -874,9 +882,11 @@ "error.code_error": "驗證碼錯誤", "error.fileNotFound": "找不到檔案", "error.inheritPermissionError": "繼承權限錯誤", + "error.invalid_params": "參數無效", "error.missingParams": "參數不足", "error.too_many_request": "請求太頻繁了,請稍後重試", "error.upload_file_error_filename": "{{name}} 上傳失敗", + "error.upload_image_error": "上傳文件失敗", "error.username_empty": "帳號不能為空", "extraction_results": "提取結果", "field_name": "欄位名稱", @@ -1028,7 +1038,15 @@ "support.user.Price": "計費標準", "support.user.User self info": "個人資訊", "support.user.auth.Sending Code": "正在傳送驗證碼", + "support.user.auth.get_code": "取得驗證碼", + "support.user.auth.get_code_again": "秒後重新取得", "support.user.captcha_placeholder": "請輸入驗證碼", + "support.user.info.bind_notification_error": "綁定通知帳號異常", + "support.user.info.bind_notification_hint": "請綁定通知接收帳號,確保您能正常接收套餐過期提醒等通知,保障您的服務正常運作。", + "support.user.info.bind_notification_success": "綁定通知帳號成功", + "support.user.info.code_required": "驗證碼不能為空", + "support.user.info.notification_receiving_hint": "通知接收", + "support.user.info.verification_code": "驗證碼", "support.user.inform.System message": "系統訊息", "support.user.login.Email": "電子郵件", "support.user.login.Github": "GitHub 登入", @@ -1053,10 +1071,14 @@ "support.wallet.Ai point every thousand tokens_input": "輸入:{{points}} 积分/1K tokens", "support.wallet.Ai point every thousand tokens_output": "輸出:{{points}} 积分/1K tokens", "support.wallet.Amount": "金額", + "support.wallet.App_amount_not_sufficient": "您的應用數量已達上限,請升級套餐後繼續使用。", "support.wallet.Buy": "購買", + "support.wallet.Dataset_amount_not_sufficient": "您的知識庫數量已達上限,請升級套餐後繼續使用。", + "support.wallet.Dataset_not_sufficient": "您的知識庫容量不足,請先升級套餐或購買額外知識庫容量後繼續使用。", "support.wallet.Not sufficient": "您的 AI 點數不足,請先升級方案或購買額外 AI 點數後繼續使用。", "support.wallet.Plan expired time": "方案到期時間", "support.wallet.Standard Plan Detail": "方案詳細資訊", + "support.wallet.Team_member_over_size": "您的團隊成員數量已達上限,請升級套餐後繼續使用。", "support.wallet.To read plan": "檢視方案", "support.wallet.amount_0": "購買數量不能為 0", "support.wallet.apply_invoice": "申請發票", @@ -1166,6 +1188,7 @@ "tag_list": "標籤列表", "team_tag": "團隊標籤", "textarea_variable_picker_tip": "輸入「/」以選擇變數", + "unauth_token": "憑證已過期,請重新登入", "unit.character": "字元", "unit.minute": "分鐘", "unit.seconds": "秒", diff --git a/packages/web/i18n/zh-Hant/login.json b/packages/web/i18n/zh-Hant/login.json index db2689743..51bafc851 100644 --- a/packages/web/i18n/zh-Hant/login.json +++ b/packages/web/i18n/zh-Hant/login.json @@ -1,19 +1,20 @@ { "Chinese_ip_tip": "偵測到您使用中國大陸 IP,點選這裡前往中國大陸版本。", "Login": "登入", + "agree": "同意", + "cookies_tip": "本網站使用 cookies 提供更好的服務體驗。繼續使用即表示您同意我們的 Cookie 政策。", "forget_password": "忘記密碼?", "login_failed": "登入失敗", "login_success": "登入成功", "no_remind": "不再提醒", "password_condition": "密碼最多 60 個字元", + "password_tip": "密碼至少 6 位,且至少包含兩種組合:數字、字母或特殊字符", "policy_tip": "使用即代表您同意我們的", "privacy": "隱私權政策", + "privacy_policy": "隱私權政策", "redirect": "跳轉", "register": "註冊帳號", "root_password_placeholder": "root 使用者密碼為環境變數 DEFAULT_ROOT_PSW 的值", "terms": "服務條款", - "use_root_login": "使用 root 使用者登入", - "agree": "同意", - "cookies_tip": "本網站使用 cookies 提供更好的服務體驗。繼續使用即表示您同意我們的 Cookie 政策。", - "privacy_policy": "隱私權政策" -} \ No newline at end of file + "use_root_login": "使用 root 使用者登入" +} diff --git a/packages/web/i18n/zh-Hant/user.json b/packages/web/i18n/zh-Hant/user.json index f743d765a..049178369 100644 --- a/packages/web/i18n/zh-Hant/user.json +++ b/packages/web/i18n/zh-Hant/user.json @@ -28,7 +28,6 @@ "login.Dingtalk": "釘釘登入", "manage_team": "管理團隊", "name": "名稱", - "notification.Bind Notification Pipe Hint": "請綁定通知接收帳號,以確保您能正常接收方案到期提醒等通知,保障您的服務正常運作。", "notification.remind_owner_bind": "請提醒建立者綁定通知帳號", "operations": "操作", "owner": "擁有者", @@ -38,9 +37,6 @@ "password.confirm": "確認密碼", "password.email_phone_error": "電子郵件/手機號碼格式錯誤", "password.email_phone_void": "電子郵件/手機號碼不能空白", - "password.get_code": "取得驗證碼", - "password.get_code_again": "秒後重新取得", - "password.new_password": "新密碼(4 至 20 字元)", "password.not_match": "兩次輸入的密碼不相符", "password.password_condition": "密碼長度需介於 4 至 20 字元之間", "password.password_required": "密碼不能空白", @@ -53,6 +49,7 @@ "permission.Manage tip": "團隊管理員,擁有完整權限", "permission.Read": "唯讀", "permission.Read desc": "成員僅能閱讀相關資源,無法建立新資源", + "permission.Add": "新增權限", "permission.Write": "可寫入", "permission.Write tip": "除了可讀取資源外,還可以建立新的資源", "permission.only_collaborators": "僅協作者可存取", @@ -61,6 +58,7 @@ "permission_des.manage": "可建立資源、邀請及刪除成員", "permission_des.read": "成員僅能閱讀相關資源,無法建立新資源", "permission_des.write": "除了可讀取資源外,還可以建立新的資源", + "permission_add_tip": "添加後,您可為其勾選權限。", "permissions": "權限", "personal_information": "個人資料", "personalization": "個人化", @@ -85,6 +83,7 @@ "team.Update Team": "更新團隊資訊", "team.add_collaborator": "新增協作者", "team.add_writer": "新增可寫入成員", + "team.add_permission": "新增權限", "team.avatar_and_name": "頭像與名稱", "team.belong_to_group": "所屬成員群組", "team.group.avatar": "群組頭像", @@ -106,10 +105,11 @@ "team.group.role.admin": "管理員", "team.group.role.member": "成員", "team.group.role.owner": "擁有者", - "team.group.search_placeholder": "搜尋成員/群組名稱", + "search_group_org_user": "搜尋成員/部門/群組名稱", "team.group.set_as_admin": "設為管理員", "team.group.toast.can_not_delete_owner": "無法刪除擁有者,請先轉移擁有權", "team.group.transfer_owner": "轉移擁有者", + "team.org.org": "組織", "team.manage_collaborators": "管理協作者", "team.no_collaborators": "目前沒有協作者", "team.write_role_member": "可寫入權限", diff --git a/packages/web/i18n/zh-Hant/workflow.json b/packages/web/i18n/zh-Hant/workflow.json index d8ec45aed..765d16439 100644 --- a/packages/web/i18n/zh-Hant/workflow.json +++ b/packages/web/i18n/zh-Hant/workflow.json @@ -49,7 +49,7 @@ "execution_error": "執行錯誤", "extraction_requirements_description": "擷取需求描述", "extraction_requirements_description_detail": "提供 AI 相對應的背景知識或需求描述,引導 AI 更好地完成任務。\\n這個輸入框可以使用全域變數。", - "extraction_requirements_placeholder": "例如:\\n1. 目前時間為:{{cTime}}。您是一位實驗室預約助理,您的任務是協助使用者預約實驗室,從文字中取得對應的預約資訊。\\n2. 您是 Google 搜尋助理,需要從文字中擷取出合適的搜尋詞。", + "extraction_requirements_placeholder": "例如: 1. 目前時間為: {{cTime}}。\n你是實驗室預約助手,你的任務是幫助使用者預約實驗室,從文字中取得對應的預約資訊。\n\n2. 你是Google搜尋助手,需要從文字中提取出合適的搜尋字詞。", "feedback_text": "回饋文字", "field_description": "欄位描述", "field_description_placeholder": "描述這個輸入欄位的功能,如果是工具呼叫參數,這個描述會影響模型產生的品質", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b94bfee3b..e9216fe5d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -139,6 +139,9 @@ importers: '@node-rs/jieba': specifier: 1.10.0 version: 1.10.0 + '@wecom/jssdk': + specifier: ^2.2.5 + version: 2.2.5 '@xmldom/xmldom': specifier: ^0.8.10 version: 0.8.10 @@ -581,7 +584,7 @@ importers: version: 1.77.8 ts-jest: specifier: ^29.1.0 - version: 29.2.2(@babel/core@7.24.9)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.9))(jest@29.7.0(@types/node@20.14.11)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)))(typescript@5.5.3) + version: 29.2.2(@babel/core@7.24.9)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.9))(jest@29.7.0(@types/node@20.14.11)(babel-plugin-macros@3.1.0))(typescript@5.5.3) use-context-selector: specifier: ^1.4.4 version: 1.4.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(scheduler@0.23.2) @@ -721,7 +724,7 @@ importers: version: 6.3.4 ts-jest: specifier: ^29.1.0 - version: 29.2.2(@babel/core@7.24.9)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.9))(jest@29.7.0(@types/node@20.14.11)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)))(typescript@5.5.3) + version: 29.2.2(@babel/core@7.24.9)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.9))(jest@29.7.0(@types/node@20.14.11)(babel-plugin-macros@3.1.0))(typescript@5.5.3) ts-loader: specifier: ^9.4.3 version: 9.5.1(typescript@5.5.3)(webpack@5.92.1) @@ -2022,7 +2025,7 @@ packages: '@emotion/use-insertion-effect-with-fallbacks@1.0.1': resolution: {integrity: sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==} peerDependencies: - react: '>=16.8.0' + react: 18.3.1 '@emotion/utils@1.2.1': resolution: {integrity: sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg==} @@ -2645,8 +2648,8 @@ packages: resolution: {integrity: sha512-RFkU9/i7cN2bsq/iTkurMWOEErmYcY6JiQI3Jn+WeR/FGISH8JbHERjpS9oRuSOPvDMJI0Z8nJeKkbOs9sBYQw==} peerDependencies: monaco-editor: '>= 0.25.0 < 1' - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + react: 18.3.1 + react-dom: 18.3.1 '@mongodb-js/saslprep@1.1.9': resolution: {integrity: sha512-tVkljjeEaAhCqTzajSdgbQ6gE6f3oneVwa3iXR6csiEwXXOFsiC6Uh9iAjAhXPtqa/XMDHWjjeNH/77m/Yq2dw==} @@ -2997,8 +3000,8 @@ packages: '@reactflow/node-resizer@2.2.14': resolution: {integrity: sha512-fwqnks83jUlYr6OHcdFEedumWKChTHRGw/kbCxj0oqBd+ekfs+SIp4ddyNU0pdx96JIm5iNFS0oNrmEiJbbSaA==} peerDependencies: - react: '>=17' - react-dom: '>=17' + react: 18.3.1 + react-dom: 18.3.1 '@reactflow/node-toolbar@1.3.14': resolution: {integrity: sha512-rbynXQnH/xFNu4P9H+hVqlEUafDCkEoCy0Dg9mG22Sg+rY/0ck6KkrAQrYrTgXusd+cEJOMK0uOOFCK2/5rSGQ==} @@ -3715,6 +3718,9 @@ packages: '@webassemblyjs/wast-printer@1.12.1': resolution: {integrity: sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==} + '@wecom/jssdk@2.2.5': + resolution: {integrity: sha512-qOBAsfqaiYM8jZHWYs/atHSpJhsLdZVNaxHQdmEQ7ZWul/GZMt4P5VY8Nf7GII7GhG8z/k+r37Dto6qtAaRqow==} + '@xmldom/xmldom@0.8.10': resolution: {integrity: sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==} engines: {node: '>=10.0.0'} @@ -7137,8 +7143,8 @@ packages: peerDependencies: '@opentelemetry/api': ^1.1.0 '@playwright/test': ^1.41.2 - react: ^18.2.0 - react-dom: ^18.2.0 + react: 18.3.1 + react-dom: 18.3.1 sass: ^1.3.0 peerDependenciesMeta: '@opentelemetry/api': @@ -7793,8 +7799,8 @@ packages: react-photo-view@1.2.6: resolution: {integrity: sha512-Fq17yxkMIv0oFp7HOJr39HgCZRP6A9K5T5rixJ4flSUYT2OO3V8vNxEExjhIKgIrfmTu+mDnHYEsI9RRWi1JHw==} peerDependencies: - react: '>=16.8.0' - react-dom: '>=16.8.0' + react: 18.3.1 + react-dom: 18.3.1 react-redux@7.2.9: resolution: {integrity: sha512-Gx4L3uM182jEEayZfRbI/G11ZpYdNAnBs70lFVMNdHJI76XYtR+7m0MN+eAs7UHBPhWXcnFPaS+9owSCJQHNpQ==} @@ -7812,8 +7818,8 @@ packages: resolution: {integrity: sha512-DtSYaao4mBmX+HDo5YWYdBWQwYIQQshUV/dVxFxK+KM26Wjwp1gZ6rv6OC3oujI6Bfu6Xyg3TwK533AQutsn/g==} engines: {node: '>=10'} peerDependencies: - '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 - react: ^16.8.0 || ^17.0.0 || ^18.0.0 + '@types/react': 18.3.1 + react: 18.3.1 peerDependenciesMeta: '@types/react': optional: true @@ -7832,8 +7838,8 @@ packages: resolution: {integrity: sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==} engines: {node: '>=10'} peerDependencies: - '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 - react: ^16.8.0 || ^17.0.0 || ^18.0.0 + '@types/react': 18.3.1 + react: 18.3.1 peerDependenciesMeta: '@types/react': optional: true @@ -8862,8 +8868,8 @@ packages: resolution: {integrity: sha512-elOQwe6Q8gqZgDA8mrh44qRTQqpIHDcZ3hXTLjBe1i4ph8XpNJnO+aQf3NaG+lriLopI4HMx9VjQLfPQ6vhnoA==} engines: {node: '>=10'} peerDependencies: - '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 - react: ^16.8.0 || ^17.0.0 || ^18.0.0 + '@types/react': 18.3.1 + react: 18.3.1 peerDependenciesMeta: '@types/react': optional: true @@ -8913,8 +8919,8 @@ packages: resolution: {integrity: sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==} engines: {node: '>=10'} peerDependencies: - '@types/react': ^16.9.0 || ^17.0.0 || ^18.0.0 - react: ^16.8.0 || ^17.0.0 || ^18.0.0 + '@types/react': 18.3.1 + react: 18.3.1 peerDependenciesMeta: '@types/react': optional: true @@ -12919,6 +12925,8 @@ snapshots: '@webassemblyjs/ast': 1.12.1 '@xtuc/long': 4.2.2 + '@wecom/jssdk@2.2.5': {} + '@xmldom/xmldom@0.8.10': {} '@xtuc/ieee754@1.2.0': {} @@ -14545,7 +14553,11 @@ snapshots: debug: 4.3.5 enhanced-resolve: 5.17.0 eslint: 8.56.0 +<<<<<<< HEAD eslint-module-utils: 2.8.1(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.56.0))(eslint@8.56.0))(eslint@8.56.0) +======= + eslint-module-utils: 2.8.1(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0) +>>>>>>> 29ab002e3 (feat: support wecom sso (#3518)) eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.5.3))(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0) fast-glob: 3.3.2 get-tsconfig: 4.7.5 @@ -14557,7 +14569,7 @@ snapshots: - eslint-import-resolver-webpack - supports-color - eslint-module-utils@2.8.1(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.56.0))(eslint@8.56.0))(eslint@8.56.0): + eslint-module-utils@2.8.1(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0): dependencies: debug: 3.2.7 optionalDependencies: @@ -14578,7 +14590,7 @@ snapshots: doctrine: 2.1.0 eslint: 8.56.0 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.8.1(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.56.0))(eslint@8.56.0))(eslint@8.56.0) + eslint-module-utils: 2.8.1(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0) hasown: 2.0.2 is-core-module: 2.14.0 is-glob: 4.0.3 @@ -18992,7 +19004,7 @@ snapshots: ts-dedent@2.2.0: {} - ts-jest@29.2.2(@babel/core@7.24.9)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.9))(jest@29.7.0(@types/node@20.14.11)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)))(typescript@5.5.3): + ts-jest@29.2.2(@babel/core@7.24.9)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.9))(jest@29.7.0(@types/node@20.14.11)(babel-plugin-macros@3.1.0))(typescript@5.5.3): dependencies: bs-logger: 0.2.6 ejs: 3.1.10 diff --git a/projects/app/Dockerfile b/projects/app/Dockerfile index 1417f8ae4..0ffa7b37a 100644 --- a/projects/app/Dockerfile +++ b/projects/app/Dockerfile @@ -81,6 +81,9 @@ COPY --from=builder /app/projects/app/package.json ./package.json COPY ./projects/app/data /app/data RUN chown -R nextjs:nodejs /app/data +# Add tmp directory permission control +RUN mkdir -p /tmp && chmod 666 /tmp + ENV NODE_ENV=production ENV NEXT_TELEMETRY_DISABLED=1 ENV PORT=3000 diff --git a/projects/app/package.json b/projects/app/package.json index 59beab69b..6029415bf 100644 --- a/projects/app/package.json +++ b/projects/app/package.json @@ -1,6 +1,6 @@ { "name": "app", - "version": "4.8.17", + "version": "4.8.18", "private": false, "scripts": { "dev": "next dev", diff --git a/projects/app/public/imgs/avatar/defaultOrgAvatar.svg b/projects/app/public/imgs/avatar/defaultOrgAvatar.svg new file mode 100644 index 000000000..38b019594 --- /dev/null +++ b/projects/app/public/imgs/avatar/defaultOrgAvatar.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/projects/app/public/imgs/modal/key.svg b/projects/app/public/imgs/modal/key.svg deleted file mode 100644 index 8b86419a3..000000000 --- a/projects/app/public/imgs/modal/key.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/projects/app/public/js/iframe.js b/projects/app/public/js/iframe.js index 1bafd2dfa..c47b58108 100644 --- a/projects/app/public/js/iframe.js +++ b/projects/app/public/js/iframe.js @@ -44,6 +44,21 @@ function embedChatbot() { document.body.appendChild(iframe); + const observer = new MutationObserver((mutations) => { + mutations.forEach((mutation) => { + if (mutation.type === 'attributes' && mutation.attributeName === 'data-bot-src') { + const newBotSrc = script.getAttribute('data-bot-src'); + if (newBotSrc) { + iframe.src = newBotSrc; + } + } + }); + }); + observer.observe(script, { + attributes: true, + attributeFilter: ['data-bot-src'] + }); + let chatBtnDragged = false; let chatBtnDown = false; let chatBtnMouseX; @@ -96,3 +111,4 @@ function embedChatbot() { document.body.appendChild(ChatBtn); } window.addEventListener('load', embedChatbot); + diff --git a/projects/app/src/components/Layout/index.tsx b/projects/app/src/components/Layout/index.tsx index 2cebee18e..0fe546023 100644 --- a/projects/app/src/components/Layout/index.tsx +++ b/projects/app/src/components/Layout/index.tsx @@ -19,6 +19,9 @@ const UpdateInviteModal = dynamic(() => import('@/components/support/user/team/U const NotSufficientModal = dynamic(() => import('@/components/support/wallet/NotSufficientModal')); const SystemMsgModal = dynamic(() => import('@/components/support/user/inform/SystemMsgModal')); const ImportantInform = dynamic(() => import('@/components/support/user/inform/ImportantInform')); +const UpdateNotification = dynamic( + () => import('@/components/support/user/inform/UpdateNotificationModal') +); const pcUnShowLayoutRoute: Record = { '/': true, @@ -48,9 +51,9 @@ export const navbarWidth = '64px'; const Layout = ({ children }: { children: JSX.Element }) => { const router = useRouter(); const { Loading } = useLoading(); - const { loading, feConfigs, isNotSufficientModal } = useSystemStore(); + const { loading, feConfigs, notSufficientModalType } = useSystemStore(); const { isPc } = useSystem(); - const { userInfo } = useUserStore(); + const { userInfo, isUpdateNotification, setIsUpdateNotification } = useUserStore(); const { setUserDefaultLng } = useI18nLng(); const isChatPage = useMemo( @@ -68,6 +71,11 @@ const Layout = ({ children }: { children: JSX.Element }) => { const isHideNavbar = !!pcUnShowLayoutRoute[router.pathname]; + const showUpdateNotification = + isUpdateNotification && + !userInfo?.team.notificationAccount && + !!userInfo?.team.permission.isOwner; + useMount(() => { setUserDefaultLng(); }); @@ -113,8 +121,11 @@ const Layout = ({ children }: { children: JSX.Element }) => { {feConfigs?.isPlus && ( <> {!!userInfo && } - {isNotSufficientModal && } + {notSufficientModalType && } {!!userInfo && } + {showUpdateNotification && ( + setIsUpdateNotification(false)} /> + )} {!!userInfo && importantInforms.length > 0 && ( )} diff --git a/projects/app/src/components/common/Modal/EditResourceModal.tsx b/projects/app/src/components/common/Modal/EditResourceModal.tsx index 95aaf218c..5fd5e0f4f 100644 --- a/projects/app/src/components/common/Modal/EditResourceModal.tsx +++ b/projects/app/src/components/common/Modal/EditResourceModal.tsx @@ -1,17 +1,13 @@ -import React, { useCallback } from 'react'; +import React from 'react'; import { ModalFooter, ModalBody, Input, Button, Box, Textarea, HStack } from '@chakra-ui/react'; import MyModal from '@fastgpt/web/components/common/MyModal/index'; import { useTranslation } from 'next-i18next'; import { useRequest2 } from '@fastgpt/web/hooks/useRequest'; import FormLabel from '@fastgpt/web/components/common/MyBox/FormLabel'; import { useForm } from 'react-hook-form'; -import { compressImgFileAndUpload } from '@/web/common/file/controller'; -import { MongoImageTypeEnum } from '@fastgpt/global/common/file/image/constants'; import { useSelectFile } from '@/web/common/file/hooks/useSelectFile'; -import { getErrText } from '@fastgpt/global/common/error/utils'; import MyTooltip from '@fastgpt/web/components/common/MyTooltip'; import Avatar from '@fastgpt/web/components/common/Avatar'; -import { useToast } from '@fastgpt/web/hooks/useToast'; export type EditResourceInfoFormType = { id: string; @@ -31,7 +27,6 @@ const EditResourceModal = ({ onEdit: (data: EditResourceInfoFormType) => any; }) => { const { t } = useTranslation(); - const { toast } = useToast(); const { register, watch, setValue, handleSubmit } = useForm({ defaultValues: defaultForm }); @@ -46,31 +41,14 @@ const EditResourceModal = ({ } ); - const { File, onOpen: onOpenSelectFile } = useSelectFile({ + const { + File, + onOpen: onOpenSelectFile, + onSelectImage + } = useSelectFile({ fileType: '.jpg,.png', multiple: false }); - const onSelectFile = useCallback( - async (e: File[]) => { - const file = e[0]; - if (!file) return; - try { - const src = await compressImgFileAndUpload({ - type: MongoImageTypeEnum.appAvatar, - file, - maxW: 300, - maxH: 300 - }); - setValue('avatar', src); - } catch (err: any) { - toast({ - title: getErrText(err, t('common:common.error.Select avatar failed')), - status: 'warning' - }); - } - }, - [setValue, t, toast] - ); return ( @@ -108,7 +86,15 @@ const EditResourceModal = ({ - + + onSelectImage(e, { + maxH: 300, + maxW: 300, + callback: (e) => setValue('avatar', e) + }) + } + /> ); }; diff --git a/projects/app/src/components/common/folder/SlideCard.tsx b/projects/app/src/components/common/folder/SlideCard.tsx index 90773bed3..0f39051c0 100644 --- a/projects/app/src/components/common/folder/SlideCard.tsx +++ b/projects/app/src/components/common/folder/SlideCard.tsx @@ -7,7 +7,6 @@ import MyDivider from '@fastgpt/web/components/common/MyDivider'; import { useTranslation } from 'next-i18next'; import { useConfirm } from '@fastgpt/web/hooks/useConfirm'; import { PermissionValueType } from '@fastgpt/global/support/permission/type'; -import DefaultPermissionList from '@/components/support/permission/DefaultPerList'; import CollaboratorContextProvider, { MemberManagerInputPropsType } from '../../support/permission/MemberManager/context'; @@ -24,7 +23,6 @@ const FolderSlideCard = ({ deleteTip, onDelete, - defaultPer, managePer, isInheritPermission, resumeInheritPermission, @@ -39,11 +37,6 @@ const FolderSlideCard = ({ deleteTip: string; onDelete: () => void; - defaultPer?: { - value: PermissionValueType; - defaultValue: PermissionValueType; - onChange: (v: PermissionValueType) => Promise; - }; managePer: MemberManagerInputPropsType; isInheritPermission?: boolean; diff --git a/projects/app/src/components/core/chat/ChatContainer/ChatBox/index.tsx b/projects/app/src/components/core/chat/ChatContainer/ChatBox/index.tsx index d2a363db0..939d152aa 100644 --- a/projects/app/src/components/core/chat/ChatContainer/ChatBox/index.tsx +++ b/projects/app/src/components/core/chat/ChatContainer/ChatBox/index.tsx @@ -104,14 +104,9 @@ const ChatBox = ({ showVoiceIcon = true, showEmptyIntro = false, active = true, - shareId, - outLinkUid, - teamId, - teamToken, onStartChat }: Props) => { const ScrollContainerRef = useRef(null); - const router = useRouter(); const { t } = useTranslation(); const { toast } = useToast(); const { feConfigs } = useSystemStore(); @@ -925,10 +920,6 @@ const ChatBox = ({ isLastChild={index === chatRecords.length - 1} {...{ showVoiceIcon, - shareId, - outLinkUid, - teamId, - teamToken, statusBoxData, questionGuides, onMark: onMark( @@ -1004,17 +995,13 @@ const ChatBox = ({ onCloseUserLike, onMark, onReadUserDislike, - outLinkUid, questionGuides, retryInput, - shareId, showEmpty, showMarkIcon, showVoiceIcon, statusBoxData, t, - teamId, - teamToken, userAvatar, variableList?.length, welcomeText diff --git a/projects/app/src/components/support/apikey/Table.tsx b/projects/app/src/components/support/apikey/Table.tsx index cc048d934..38e606375 100644 --- a/projects/app/src/components/support/apikey/Table.tsx +++ b/projects/app/src/components/support/apikey/Table.tsx @@ -250,7 +250,7 @@ const ApiKeyTable = ({ tips, appId }: { tips: string; appId?: string }) => { {t('common:support.openapi.New api key')} @@ -330,7 +330,7 @@ function EditKeyModal({ return ( diff --git a/projects/app/src/components/support/permission/ConfigPerModal/index.tsx b/projects/app/src/components/support/permission/ConfigPerModal/index.tsx index e5cd606af..b2575f336 100644 --- a/projects/app/src/components/support/permission/ConfigPerModal/index.tsx +++ b/projects/app/src/components/support/permission/ConfigPerModal/index.tsx @@ -44,7 +44,7 @@ const ConfigPerModal = ({ <> diff --git a/projects/app/src/components/support/permission/MemberManager/AddMemberModal.tsx b/projects/app/src/components/support/permission/MemberManager/AddMemberModal.tsx deleted file mode 100644 index e113fec3d..000000000 --- a/projects/app/src/components/support/permission/MemberManager/AddMemberModal.tsx +++ /dev/null @@ -1,308 +0,0 @@ -import { - Flex, - Box, - ModalBody, - Checkbox, - ModalFooter, - Button, - Grid, - HStack -} from '@chakra-ui/react'; -import MyModal from '@fastgpt/web/components/common/MyModal'; -import MyIcon from '@fastgpt/web/components/common/Icon'; -import { useContextSelector } from 'use-context-selector'; -import MyAvatar from '@fastgpt/web/components/common/Avatar'; -import { useMemo, useState } from 'react'; -import PermissionSelect from './PermissionSelect'; -import PermissionTags from './PermissionTags'; -import { CollaboratorContext } from './context'; -import { useUserStore } from '@/web/support/user/useUserStore'; -import { ChevronDownIcon } from '@chakra-ui/icons'; -import { useRequest2 } from '@fastgpt/web/hooks/useRequest'; -import { useTranslation } from 'next-i18next'; -import SearchInput from '@fastgpt/web/components/common/Input/SearchInput'; -import { DefaultGroupName } from '@fastgpt/global/support/user/team/group/constant'; - -export type AddModalPropsType = { - onClose: () => void; - mode?: 'member' | 'all'; -}; - -function AddMemberModal({ onClose, mode = 'member' }: AddModalPropsType) { - const { t } = useTranslation(); - const { userInfo, loadAndGetTeamMembers, loadAndGetGroups, myGroups } = useUserStore(); - - const { permissionList, collaboratorList, onUpdateCollaborators, getPerLabelList, permission } = - useContextSelector(CollaboratorContext, (v) => v); - const [searchText, setSearchText] = useState(''); - - const { data: [members = [], groups = []] = [], loading: loadingMembersAndGroups } = useRequest2( - async () => { - if (!userInfo?.team?.teamId) return [[], []]; - return await Promise.all([loadAndGetTeamMembers(true), loadAndGetGroups(true)]); - }, - { - manual: false, - refreshDeps: [userInfo?.team?.teamId] - } - ); - - const filterMembers = useMemo(() => { - return members.filter((item) => { - if (item.tmbId === userInfo?.team?.tmbId) return false; - if (!searchText) return true; - return item.memberName.includes(searchText); - }); - }, [members, searchText, userInfo?.team?.tmbId]); - - const filterGroups = useMemo(() => { - if (mode !== 'all') return []; - return groups.filter((item) => { - if (permission.isOwner) return true; // owner can see all groups - if (myGroups.find((i) => String(i._id) === String(item._id))) return false; - if (!searchText) return true; - return item.name.includes(searchText); - }); - }, [groups, searchText, myGroups, mode, permission]); - - const [selectedMemberIdList, setSelectedMembers] = useState([]); - const [selectedGroupIdList, setSelectedGroupIdList] = useState([]); - const [selectedPermission, setSelectedPermission] = useState(permissionList['read'].value); - const perLabel = useMemo(() => { - return getPerLabelList(selectedPermission).join('、'); - }, [getPerLabelList, selectedPermission]); - - const { runAsync: onConfirm, loading: isUpdating } = useRequest2( - () => - onUpdateCollaborators({ - members: selectedMemberIdList, - groups: selectedGroupIdList, - permission: selectedPermission - }), - { - successToast: t('common:common.Add Success'), - errorToast: 'Error', - onSuccess() { - onClose(); - } - } - ); - - return ( - - - - - setSearchText(e.target.value)} - /> - - - {filterGroups.map((group) => { - const onChange = () => { - setSelectedGroupIdList((state) => { - if (state.includes(group._id)) { - return state.filter((v) => v !== group._id); - } - return [...state, group._id]; - }); - }; - const collaborator = collaboratorList.find((v) => v.groupId === group._id); - return ( - - - - - {group.name === DefaultGroupName ? userInfo?.team.teamName : group.name} - - {!!collaborator && ( - - )} - - ); - })} - {filterMembers.map((member) => { - const onChange = () => { - setSelectedMembers((state) => { - if (state.includes(member.tmbId)) { - return state.filter((v) => v !== member.tmbId); - } - return [...state, member.tmbId]; - }); - }; - const collaborator = collaboratorList.find((v) => v.tmbId === member.tmbId); - return ( - - } - /> - - - {member.memberName} - - {!!collaborator && ( - - )} - - ); - })} - - - - - {t('user:has_chosen') + ': '}{' '} - {selectedMemberIdList.length + selectedGroupIdList.length} - - - {selectedGroupIdList.map((groupId) => { - const onChange = () => { - setSelectedGroupIdList((state) => { - if (state.includes(groupId)) { - return state.filter((v) => v !== groupId); - } - return [...state, groupId]; - }); - }; - const group = groups.find((v) => String(v._id) === groupId); - return ( - - - - {group?.name === DefaultGroupName ? userInfo?.team.teamName : group?.name} - - - - ); - })} - {selectedMemberIdList.map((tmbId) => { - const member = filterMembers.find((v) => v.tmbId === tmbId); - return member ? ( - - setSelectedMembers(selectedMemberIdList.filter((v) => v !== tmbId)) - } - > - - - {member.memberName} - - - - ) : null; - })} - - - - - - - {t(perLabel as any)} - - - } - onChange={(v) => setSelectedPermission(v)} - /> - - - - ); -} - -export default AddMemberModal; diff --git a/projects/app/src/components/support/permission/MemberManager/ManageModal.tsx b/projects/app/src/components/support/permission/MemberManager/ManageModal.tsx index 37dc4260e..b7e95d1a2 100644 --- a/projects/app/src/components/support/permission/MemberManager/ManageModal.tsx +++ b/projects/app/src/components/support/permission/MemberManager/ManageModal.tsx @@ -1,19 +1,19 @@ -import { ModalBody, Table, TableContainer, Tbody, Th, Thead, Tr, Td, Flex } from '@chakra-ui/react'; +import { useUserStore } from '@/web/support/user/useUserStore'; +import { Flex, ModalBody, Table, TableContainer, Tbody, Td, Th, Thead, Tr } from '@chakra-ui/react'; +import type { RequireOnlyOne } from '@fastgpt/global/common/type/utils'; +import { DefaultGroupName } from '@fastgpt/global/support/user/team/group/constant'; +import Avatar from '@fastgpt/web/components/common/Avatar'; +import EmptyTip from '@fastgpt/web/components/common/EmptyTip'; +import MyIcon from '@fastgpt/web/components/common/Icon'; +import Loading from '@fastgpt/web/components/common/MyLoading'; import MyModal from '@fastgpt/web/components/common/MyModal'; +import { useRequest2 } from '@fastgpt/web/hooks/useRequest'; +import { useTranslation } from 'next-i18next'; import React from 'react'; import { useContextSelector } from 'use-context-selector'; import PermissionSelect from './PermissionSelect'; import PermissionTags from './PermissionTags'; -import Avatar from '@fastgpt/web/components/common/Avatar'; import { CollaboratorContext } from './context'; -import MyIcon from '@fastgpt/web/components/common/Icon'; -import { useRequest2 } from '@fastgpt/web/hooks/useRequest'; -import { useUserStore } from '@/web/support/user/useUserStore'; -import EmptyTip from '@fastgpt/web/components/common/EmptyTip'; -import Loading from '@fastgpt/web/components/common/MyLoading'; -import { useTranslation } from 'next-i18next'; -import { DefaultGroupName } from '@fastgpt/global/support/user/team/group/constant'; -import { RequireOnlyOne } from '@fastgpt/global/common/type/utils'; export type ManageModalProps = { onClose: () => void; }; @@ -65,7 +65,7 @@ function ManageModal({ onClose }: ManageModalProps) { > - + {item.name === DefaultGroupName ? userInfo?.team.teamName : item.name} @@ -85,14 +85,20 @@ function ManageModal({ onClose }: ManageModalProps) { onUpdate({ members: item.tmbId ? [item.tmbId] : undefined, groups: item.groupId ? [item.groupId] : undefined, + orgs: item.orgId ? [item.orgId] : undefined, permission }); }} onDelete={() => { onDelete({ tmbId: item.tmbId, - groupId: item.groupId - } as RequireOnlyOne<{ tmbId: string; groupId: string }>); + groupId: item.groupId, + orgId: item.orgId + } as RequireOnlyOne<{ + tmbId: string; + groupId: string; + orgId: string; + }>); }} /> )} diff --git a/projects/app/src/components/support/permission/MemberManager/MemberListCard.tsx b/projects/app/src/components/support/permission/MemberManager/MemberListCard.tsx index 477c777f7..fe85f36a3 100644 --- a/projects/app/src/components/support/permission/MemberManager/MemberListCard.tsx +++ b/projects/app/src/components/support/permission/MemberManager/MemberListCard.tsx @@ -1,13 +1,13 @@ -import { Box, BoxProps, Flex } from '@chakra-ui/react'; +import { useUserStore } from '@/web/support/user/useUserStore'; +import { Box, type BoxProps, Flex } from '@chakra-ui/react'; +import { DefaultGroupName } from '@fastgpt/global/support/user/team/group/constant'; +import Avatar from '@fastgpt/web/components/common/Avatar'; import MyBox from '@fastgpt/web/components/common/MyBox'; +import Tag, { type TagProps } from '@fastgpt/web/components/common/Tag'; +import { useTranslation } from 'next-i18next'; import React from 'react'; import { useContextSelector } from 'use-context-selector'; import { CollaboratorContext } from './context'; -import Tag, { TagProps } from '@fastgpt/web/components/common/Tag'; -import Avatar from '@fastgpt/web/components/common/Avatar'; -import { useTranslation } from 'next-i18next'; -import { DefaultGroupName } from '@fastgpt/global/support/user/team/group/constant'; -import { useUserStore } from '@/web/support/user/useUserStore'; export type MemberListCardProps = BoxProps & { tagStyle?: Omit }; @@ -31,12 +31,12 @@ const MemberListCard = ({ tagStyle, ...props }: MemberListCardProps) => { {collaboratorList?.map((member) => { return ( - + {member.name === DefaultGroupName ? userInfo?.team.teamName : member.name} diff --git a/projects/app/src/components/support/permission/MemberManager/MemberModal.tsx b/projects/app/src/components/support/permission/MemberManager/MemberModal.tsx new file mode 100644 index 000000000..e51049b33 --- /dev/null +++ b/projects/app/src/components/support/permission/MemberManager/MemberModal.tsx @@ -0,0 +1,512 @@ +import { useUserStore } from '@/web/support/user/useUserStore'; +import { ChevronDownIcon } from '@chakra-ui/icons'; +import { + Box, + Button, + Checkbox, + Flex, + Grid, + HStack, + ModalBody, + ModalFooter, + Tag, + Text +} from '@chakra-ui/react'; +import { DefaultGroupName } from '@fastgpt/global/support/user/team/group/constant'; +import MyAvatar from '@fastgpt/web/components/common/Avatar'; +import MyIcon from '@fastgpt/web/components/common/Icon'; +import SearchInput from '@fastgpt/web/components/common/Input/SearchInput'; +import MyModal from '@fastgpt/web/components/common/MyModal'; +import { useRequest2 } from '@fastgpt/web/hooks/useRequest'; +import { useTranslation } from 'next-i18next'; +import { useMemo, useRef, useState } from 'react'; +import PermissionSelect from './PermissionSelect'; +import PermissionTags from './PermissionTags'; +import { + DEFAULT_ORG_AVATAR, + DEFAULT_TEAM_AVATAR, + DEFAULT_USER_AVATAR +} from '@fastgpt/global/common/system/constants'; +import Path from '@/components/common/folder/Path'; +import { getOrgChildrenPath } from '@fastgpt/global/support/user/team/org/constant'; +import { ParentTreePathItemType } from '@fastgpt/global/common/parentFolder/type'; +import { OrgType } from '@fastgpt/global/support/user/team/org/type'; +import { useContextSelector } from 'use-context-selector'; +import { CollaboratorContext } from './context'; + +const HoverBoxStyle = { + bgColor: 'myGray.50', + cursor: 'pointer' +}; + +function MemberModal({ + onClose, + addPermissionOnly: addOnly = false +}: { + onClose: () => void; + addPermissionOnly?: boolean; +}) { + const { t } = useTranslation(); + const { userInfo, loadAndGetTeamMembers, loadAndGetGroups, loadAndGetOrgs } = useUserStore(); + + const collaboratorList = useContextSelector(CollaboratorContext, (v) => v.collaboratorList); + + const [searchText, setSearchText] = useState(''); + const [filterClass, setFilterClass] = useState<'member' | 'org' | 'group'>(); + + const { data: [members = [], groups = [], orgs = []] = [], loading: loadingMembersAndGroups } = + useRequest2( + async () => { + if (!userInfo?.team?.teamId) return [[], []]; + return Promise.all([ + loadAndGetTeamMembers(true), + loadAndGetGroups(true), + loadAndGetOrgs(true) + ]); + }, + { + manual: false, + refreshDeps: [userInfo?.team?.teamId] + } + ); + + const [parentPath, setParentPath] = useState(''); + const paths = useMemo(() => { + const splitPath = parentPath.split('/').filter(Boolean); + return splitPath + .map((id) => { + const org = orgs.find((org) => org.pathId === id)!; + + if (org.path === '') return; + + return { + parentId: getOrgChildrenPath(org), + parentName: org.name + }; + }) + .filter(Boolean) as ParentTreePathItemType[]; + }, [parentPath, orgs]); + + const [selectedOrgIdList, setSelectedOrgIdList] = useState([]); + const currentOrg = useMemo(() => { + const splitPath = parentPath.split('/'); + const currentOrgId = splitPath[splitPath.length - 1]; + if (!currentOrgId) return; + + return orgs.find((org) => org.pathId === currentOrgId); + }, [orgs, parentPath]); + const filterOrgs: (OrgType & { count?: number })[] = useMemo(() => { + if (searchText) return orgs.filter((item) => item.name.includes(searchText)); + if (!searchText && filterClass !== 'org') return []; + if (parentPath === '') { + setParentPath(`/${orgs[0].pathId}`); + return []; + } + return orgs + .filter((org) => org.path === parentPath) + .map((item) => ({ + ...item, + count: + item.members.length + orgs.filter((org) => org.path === getOrgChildrenPath(item)).length + })); + }, [orgs, searchText, filterClass, parentPath]); + + const [selectedMemberIdList, setSelectedMembers] = useState([]); + const filterMembers = useMemo(() => { + if (searchText) return members.filter((item) => item.memberName.includes(searchText)); + if (!searchText && filterClass !== 'member' && filterClass !== 'org') return []; + + if (currentOrg && filterClass === 'org') { + return members.filter((item) => currentOrg.members.find((v) => v.tmbId === item.tmbId)); + } + + return members; + }, [members, searchText, filterClass, currentOrg]); + + const [selectedGroupIdList, setSelectedGroupIdList] = useState([]); + const filterGroups = useMemo(() => { + if (searchText) return groups.filter((item) => item.name.includes(searchText)); + if (!searchText && filterClass !== 'group') return []; + + return groups; + }, [groups, searchText, filterClass]); + + const permissionList = useContextSelector(CollaboratorContext, (v) => v.permissionList); + const getPerLabelList = useContextSelector(CollaboratorContext, (v) => v.getPerLabelList); + const [selectedPermission, setSelectedPermission] = useState( + permissionList?.read?.value + ); + const perLabel = useMemo(() => { + if (selectedPermission === undefined) return ''; + return getPerLabelList(selectedPermission!).join('、'); + }, [getPerLabelList, selectedPermission]); + + const onUpdateCollaborators = useContextSelector( + CollaboratorContext, + (v) => v.onUpdateCollaborators + ); + const { runAsync: onConfirm, loading: isUpdating } = useRequest2( + () => + onUpdateCollaborators({ + members: selectedMemberIdList, + groups: selectedGroupIdList, + orgs: selectedOrgIdList, + permission: selectedPermission! + }), + { + successToast: t('common:common.Add Success'), + onSuccess() { + onClose(); + } + } + ); + + const entryList = useRef([ + { label: t('user:team.group.members'), icon: DEFAULT_USER_AVATAR, value: 'member' }, + { label: t('user:team.org.org'), icon: DEFAULT_ORG_AVATAR, value: 'org' }, + { label: t('user:team.group.group'), icon: DEFAULT_TEAM_AVATAR, value: 'group' } + ]); + + const selectedList = useMemo(() => { + const selectedOrgs = orgs.filter((org) => selectedOrgIdList.includes(org._id)); + const selectedGroups = groups.filter((group) => selectedGroupIdList.includes(group._id)); + const selectedMembers = members.filter((member) => selectedMemberIdList.includes(member.tmbId)); + + return [ + ...selectedOrgs.map((item) => ({ + id: `org-${item._id}`, + avatar: item.avatar, + name: item.name, + onDelete: () => setSelectedOrgIdList(selectedOrgIdList.filter((v) => v !== item._id)) + })), + ...selectedGroups.map((item) => ({ + id: `group-${item._id}`, + avatar: item.avatar, + name: item.name === DefaultGroupName ? userInfo?.team.teamName : item.name, + onDelete: () => setSelectedGroupIdList(selectedGroupIdList.filter((v) => v !== item._id)) + })), + ...selectedMembers.map((item) => ({ + id: `member-${item.tmbId}`, + avatar: item.avatar, + name: item.memberName, + onDelete: () => setSelectedMembers(selectedMemberIdList.filter((v) => v !== item.tmbId)) + })) + ]; + }, [ + orgs, + groups, + members, + selectedOrgIdList, + selectedGroupIdList, + selectedMemberIdList, + userInfo?.team.teamName + ]); + + return ( + + + + + setSearchText(e.target.value)} + /> + + + {!searchText && !filterClass && ( + <> + {entryList.current.map((item) => { + return ( + setFilterClass(item.value as any)} + > + + + {item.label} + + + + ); + })} + + )} + + {/* Path */} + {!searchText && filterClass && ( + + { + if (parentId === '') { + setFilterClass(undefined); + setParentPath(''); + } else if ( + parentId === 'member' || + parentId === 'org' || + parentId === 'group' + ) { + setFilterClass(parentId); + setParentPath(''); + } else { + setParentPath(parentId); + } + }} + rootName={t('common:common.Team')} + /> + + )} + + + {filterMembers.map((member) => { + const collaborator = collaboratorList?.find((v) => v.tmbId === member.tmbId); + const disabled = addOnly && collaborator !== undefined; + const onChange = () => { + if (disabled) return; + setSelectedMembers((state) => { + if (state.includes(member.tmbId)) { + return state.filter((v) => v !== member.tmbId); + } + return [...state, member.tmbId]; + }); + }; + return ( + + + + + {member.memberName} + + + + ); + })} + {filterOrgs.map((org) => { + const collaborator = collaboratorList?.find((v) => v.orgId === org._id); + const disabled = addOnly && collaborator !== undefined; + const onChange = () => { + if (disabled) return; + setSelectedOrgIdList((state) => { + if (state.includes(org._id)) { + return state.filter((v) => v !== org._id); + } + return [...state, org._id]; + }); + }; + return ( + + + + + {org.name} + {org.count && ( + + {org.count} + + )} + + + {org.count && ( + { + e.stopPropagation(); + setParentPath(getOrgChildrenPath(org)); + }} + /> + )} + + ); + })} + {filterGroups.map((group) => { + const collaborator = collaboratorList?.find((v) => v.groupId === group._id); + const disabled = addOnly && collaborator !== undefined; + const onChange = () => { + if (disabled) return; + setSelectedGroupIdList((state) => { + if (state.includes(group._id)) { + return state.filter((v) => v !== group._id); + } + return [...state, group._id]; + }); + }; + return ( + + + + + {group.name === DefaultGroupName ? userInfo?.team.teamName : group.name} + + + + ); + })} + + + + + + + {`${t('user:has_chosen')}: `} + {selectedMemberIdList.length + selectedGroupIdList.length + selectedOrgIdList.length} + + + {selectedList.map((item) => { + return ( + + + + {item.name} + + + + ); + })} + + + + + + {!addOnly && !!permissionList && ( + + {t(perLabel as any)} + + + } + onChange={(v) => setSelectedPermission(v)} + /> + )} + {addOnly && ( + + + {t('user:permission_add_tip')} + + )} + + + + ); +} + +export default MemberModal; diff --git a/projects/app/src/components/support/permission/MemberManager/PermissionSelect.tsx b/projects/app/src/components/support/permission/MemberManager/PermissionSelect.tsx index 5b8562b65..3cfd56963 100644 --- a/projects/app/src/components/support/permission/MemberManager/PermissionSelect.tsx +++ b/projects/app/src/components/support/permission/MemberManager/PermissionSelect.tsx @@ -49,13 +49,16 @@ function PermissionSelect({ onDelete }: PermissionSelectProps) { const { t } = useTranslation(); - const { permission, permissionList } = useContextSelector(CollaboratorContext, (v) => v); const ref = useRef(null); const closeTimer = useRef(); + const { permission, permissionList } = useContextSelector(CollaboratorContext, (v) => v); + const [isOpen, setIsOpen] = useState(false); const permissionSelectList = useMemo(() => { + if (!permissionList) return { singleCheckBoxList: [], multipleCheckBoxList: [] }; + const list = Object.entries(permissionList).map(([_, value]) => { return { name: value.name, @@ -77,6 +80,8 @@ function PermissionSelect({ }; }, [permission.isOwner, permissionList]); const selectedSingleValue = useMemo(() => { + if (!permissionList) return undefined; + const per = new Permission({ per: value }); if (per.hasManagePer) return permissionList['manage'].value; @@ -107,7 +112,7 @@ function PermissionSelect({ } }); - return ( + return selectedSingleValue !== undefined ? (

- ); + ) : null; } export default React.memo(PermissionSelect); diff --git a/projects/app/src/components/support/permission/MemberManager/PermissionTags.tsx b/projects/app/src/components/support/permission/MemberManager/PermissionTags.tsx index 7d9f7de16..5bda6929c 100644 --- a/projects/app/src/components/support/permission/MemberManager/PermissionTags.tsx +++ b/projects/app/src/components/support/permission/MemberManager/PermissionTags.tsx @@ -7,12 +7,15 @@ import { CollaboratorContext } from './context'; import { useTranslation } from 'next-i18next'; export type PermissionTagsProp = { - permission: PermissionValueType; + permission?: PermissionValueType; }; function PermissionTags({ permission }: PermissionTagsProp) { const { getPerLabelList } = useContextSelector(CollaboratorContext, (v) => v); const { t } = useTranslation(); + + if (permission === undefined) return null; + const perTagList = getPerLabelList(permission); return ( diff --git a/projects/app/src/components/support/permission/MemberManager/context.tsx b/projects/app/src/components/support/permission/MemberManager/context.tsx index 5ec06bd93..683830b15 100644 --- a/projects/app/src/components/support/permission/MemberManager/context.tsx +++ b/projects/app/src/components/support/permission/MemberManager/context.tsx @@ -1,32 +1,37 @@ import { useDisclosure } from '@chakra-ui/react'; -import { +import type { CollaboratorItemType, UpdateClbPermissionProps } from '@fastgpt/global/support/permission/collaborator'; import { PermissionList } from '@fastgpt/global/support/permission/constant'; import { Permission } from '@fastgpt/global/support/permission/controller'; -import { PermissionListType, PermissionValueType } from '@fastgpt/global/support/permission/type'; -import { ReactNode, useCallback } from 'react'; +import type { + PermissionListType, + PermissionValueType +} from '@fastgpt/global/support/permission/type'; +import { type ReactNode, useCallback } from 'react'; import { createContext } from 'use-context-selector'; import dynamic from 'next/dynamic'; -import MemberListCard, { MemberListCardProps } from './MemberListCard'; +import MemberListCard, { type MemberListCardProps } from './MemberListCard'; import { useRequest2 } from '@fastgpt/web/hooks/useRequest'; import { useSystemStore } from '@/web/common/system/useSystemStore'; import { useConfirm } from '@fastgpt/web/hooks/useConfirm'; import { useI18n } from '@/web/context/I18n'; -import { RequireOnlyOne } from '@fastgpt/global/common/type/utils'; -const AddMemberModal = dynamic(() => import('./AddMemberModal')); +import type { RequireOnlyOne } from '@fastgpt/global/common/type/utils'; + +const MemberModal = dynamic(() => import('./MemberModal')); const ManageModal = dynamic(() => import('./ManageModal')); export type MemberManagerInputPropsType = { permission: Permission; onGetCollaboratorList: () => Promise; - permissionList: PermissionListType; + permissionList?: PermissionListType; onUpdateCollaborators: (props: UpdateClbPermissionProps) => Promise; - onDelOneCollaborator: (props: RequireOnlyOne<{ tmbId: string; groupId: string }>) => Promise; + onDelOneCollaborator: ( + props: RequireOnlyOne<{ tmbId: string; groupId: string; orgId: string }> + ) => Promise; refreshDeps?: any[]; - mode?: 'member' | 'all'; }; export type MemberManagerPropsType = MemberManagerInputPropsType & { @@ -46,19 +51,19 @@ type CollaboratorContextType = MemberManagerPropsType & {}; export const CollaboratorContext = createContext({ collaboratorList: [], permissionList: PermissionList, - onUpdateCollaborators: function () { + onUpdateCollaborators: () => { throw new Error('Function not implemented.'); }, - onDelOneCollaborator: function () { + onDelOneCollaborator: () => { throw new Error('Function not implemented.'); }, - getPerLabelList: function (): string[] { + getPerLabelList: (): string[] => { throw new Error('Function not implemented.'); }, - refetchCollaboratorList: function (): void { + refetchCollaboratorList: (): void => { throw new Error('Function not implemented.'); }, - onGetCollaboratorList: function (): Promise { + onGetCollaboratorList: (): Promise => { throw new Error('Function not implemented.'); }, isFetchingCollaborator: false, @@ -76,19 +81,20 @@ const CollaboratorContextProvider = ({ refreshDeps = [], isInheritPermission, hasParent, - mode = 'member' + addPermissionOnly }: MemberManagerInputPropsType & { children: (props: ChildrenProps) => ReactNode; refetchResource?: () => void; isInheritPermission?: boolean; hasParent?: boolean; + addPermissionOnly?: boolean; }) => { const onUpdateCollaboratorsThen = async (props: UpdateClbPermissionProps) => { await onUpdateCollaborators(props); refetchCollaboratorList(); }; const onDelOneCollaboratorThen = async ( - props: RequireOnlyOne<{ tmbId: string; groupId: string }> + props: RequireOnlyOne<{ tmbId: string; groupId: string; orgId: string }> ) => { await onDelOneCollaborator(props); refetchCollaboratorList(); @@ -116,6 +122,8 @@ const CollaboratorContextProvider = ({ const getPerLabelList = useCallback( (per: PermissionValueType) => { + if (!permissionList) return []; + const Per = new Permission({ per }); const labels: string[] = []; @@ -123,7 +131,7 @@ const CollaboratorContextProvider = ({ labels.push(permissionList['manage'].name); } else if (Per.hasWritePer) { labels.push(permissionList['write'].name); - } else { + } else if (Per.hasReadPer) { labels.push(permissionList['read'].name); } @@ -198,12 +206,12 @@ const CollaboratorContextProvider = ({ MemberListCard })} {isOpenAddMember && ( - { onCloseAddMember(); refetchResource?.(); }} - mode={mode} + addPermissionOnly={addPermissionOnly} /> )} {isOpenManageModal && ( diff --git a/projects/app/src/pages/account/info/components/UpdateNotificationModal.tsx b/projects/app/src/components/support/user/inform/UpdateNotificationModal.tsx similarity index 79% rename from projects/app/src/pages/account/info/components/UpdateNotificationModal.tsx rename to projects/app/src/components/support/user/inform/UpdateNotificationModal.tsx index 5adbb505f..e6e220196 100644 --- a/projects/app/src/pages/account/info/components/UpdateNotificationModal.tsx +++ b/projects/app/src/components/support/user/inform/UpdateNotificationModal.tsx @@ -38,8 +38,8 @@ const UpdateNotificationModal = ({ onClose }: { onClose: () => void }) => { initUserInfo(); onClose(); }, - successToast: t('account_info:bind_notification_success'), - errorToast: t('account_info:bind_notification_error') + successToast: t('common:support.user.info.bind_notification_success'), + errorToast: t('common:support.user.info.bind_notification_error') } ); @@ -49,9 +49,9 @@ const UpdateNotificationModal = ({ onClose }: { onClose: () => void }) => { ?.map((item) => { switch (item) { case 'email': - return t('account_info:email_label'); + return t('common:support.user.login.Email'); case 'phone': - return t('account_info:phone_label'); + return t('common:support.user.login.Phone number'); } }) .join('/'); @@ -62,16 +62,16 @@ const UpdateNotificationModal = ({ onClose }: { onClose: () => void }) => { isOpen iconSrc="common/settingLight" w={'32rem'} - title={t('account_info:notification_receiving_hint')} + title={t('common:support.user.info.notification_receiving_hint')} > - {t('account_info:bind_notification_hint')} + {t('common:support.user.info.bind_notification_hint')} - {t('account_info:user_account')} + {t('common:user.Account')} void }) => { > - {t('account_info:verification_code')} + {t('common:support.user.info.verification_code')} @@ -93,14 +93,14 @@ const UpdateNotificationModal = ({ onClose }: { onClose: () => void }) => { diff --git a/projects/app/src/components/support/wallet/NotSufficientModal/index.tsx b/projects/app/src/components/support/wallet/NotSufficientModal/index.tsx index 94721c957..fa4590428 100644 --- a/projects/app/src/components/support/wallet/NotSufficientModal/index.tsx +++ b/projects/app/src/components/support/wallet/NotSufficientModal/index.tsx @@ -1,35 +1,153 @@ -import React from 'react'; +import React, { useMemo, useState } from 'react'; import MyModal from '@fastgpt/web/components/common/MyModal'; import { useTranslation } from 'next-i18next'; -import { Button, ModalBody, ModalFooter } from '@chakra-ui/react'; -import { useRouter } from 'next/router'; -import { useSystemStore } from '@/web/common/system/useSystemStore'; +import { Box, Button, Flex, ModalBody, ModalFooter, useDisclosure } from '@chakra-ui/react'; +import { NotSufficientModalType, useSystemStore } from '@/web/common/system/useSystemStore'; +import ExtraPlan from '@/pages/price/components/ExtraPlan'; +import StandardPlan from '@/pages/price/components/Standard'; +import FillRowTabs from '@fastgpt/web/components/common/Tabs/FillRowTabs'; +import FormLabel from '@fastgpt/web/components/common/MyBox/FormLabel'; +import { useUserStore } from '@/web/support/user/useUserStore'; +import { standardSubLevelMap } from '@fastgpt/global/support/wallet/sub/constants'; +import { TeamErrEnum } from '@fastgpt/global/common/error/code/team'; +import { useMount } from 'ahooks'; -const NotSufficientModal = () => { +const NotSufficientModal = ({ type }: { type: NotSufficientModalType }) => { const { t } = useTranslation(); - const router = useRouter(); - const { setIsNotSufficientModal } = useSystemStore(); + const { setNotSufficientModalType } = useSystemStore(); - const onClose = () => setIsNotSufficientModal(false); + const onClose = () => setNotSufficientModalType(undefined); + + const { + isOpen: isRechargeModalOpen, + onOpen: onRechargeModalOpen, + onClose: onRechargeModalClose + } = useDisclosure(); + + const textMap = { + [TeamErrEnum.aiPointsNotEnough]: t('common:support.wallet.Not sufficient'), + [TeamErrEnum.datasetSizeNotEnough]: t('common:support.wallet.Dataset_not_sufficient'), + [TeamErrEnum.datasetAmountNotEnough]: t('common:support.wallet.Dataset_amount_not_sufficient'), + [TeamErrEnum.teamMemberOverSize]: t('common:support.wallet.Team_member_over_size'), + [TeamErrEnum.appAmountNotEnough]: t('common:support.wallet.App_amount_not_sufficient') + }; return ( - - {t('common:support.wallet.Not sufficient')} - - - - - + <> + + {textMap[type]} + + + + + + + {isRechargeModalOpen && ( + + )} + ); }; export default NotSufficientModal; + +const RechargeModal = ({ + onClose, + onPaySuccess +}: { + onClose: () => void; + onPaySuccess: () => void; +}) => { + const { t } = useTranslation(); + const { teamPlanStatus, initTeamPlanStatus } = useUserStore(); + + useMount(() => { + initTeamPlanStatus(); + }); + + const planName = useMemo(() => { + if (!teamPlanStatus?.standard?.currentSubLevel) return ''; + return standardSubLevelMap[teamPlanStatus.standard.currentSubLevel].label; + }, [teamPlanStatus?.standard?.currentSubLevel]); + + const [tab, setTab] = useState<'standard' | 'extra'>('standard'); + + return ( + + + + + {t('common:support.wallet.subscription.Current plan')} + + + {t(planName as any)} + + + + + + {t('common:info.resource')} + + + {`${t('common:support.user.team.Dataset usage')}:`} + {`${teamPlanStatus?.usedDatasetSize} / ${teamPlanStatus?.datasetMaxSize || t('account_info:unlimited')}`} + {`${t('common:support.wallet.subscription.AI points usage')}:`} + {`${Math.round(teamPlanStatus?.usedPoints || 0)} / ${teamPlanStatus?.totalPoints || t('account_info:unlimited')}`} + + + + { + setTab(e as 'standard' | 'extra'); + }} + /> + + + {tab === 'standard' ? ( + + ) : ( + + )} + + + + ); +}; diff --git a/projects/app/src/components/support/wallet/QRCodePayModal.tsx b/projects/app/src/components/support/wallet/QRCodePayModal.tsx index 013a91b93..6b3fe5bd5 100644 --- a/projects/app/src/components/support/wallet/QRCodePayModal.tsx +++ b/projects/app/src/components/support/wallet/QRCodePayModal.tsx @@ -1,5 +1,5 @@ import MyModal from '@fastgpt/web/components/common/MyModal'; -import React, { useEffect, useRef } from 'react'; +import React, { useCallback, useEffect, useRef } from 'react'; import { useTranslation } from 'next-i18next'; import { Box, ModalBody } from '@chakra-ui/react'; import { checkBalancePayResult } from '@/web/support/wallet/bill/api'; @@ -7,6 +7,8 @@ import { useToast } from '@fastgpt/web/hooks/useToast'; import { useRouter } from 'next/router'; import { getErrText } from '@fastgpt/global/common/error/utils'; import LightTip from '@fastgpt/web/components/common/LightTip'; +import Script from 'next/script'; +import { getWebReqUrl } from '@fastgpt/web/common/system/utils'; export type QRPayProps = { readPrice: number; @@ -23,25 +25,25 @@ const QRCodePayModal = ({ billId, onSuccess }: QRPayProps & { tip?: string; onSuccess?: () => any }) => { - const router = useRouter(); const { t } = useTranslation(); const { toast } = useToast(); const dom = useRef(null); + const drawCode = useCallback(() => { + if (dom.current && window.QRCode && !dom.current.innerHTML) { + new window.QRCode(dom.current, { + text: codeUrl, + width: qrCodeSize, + height: qrCodeSize, + colorDark: '#000000', + colorLight: '#ffffff', + correctLevel: window.QRCode.CorrectLevel.H + }); + } + }, [codeUrl]); + useEffect(() => { let timer: NodeJS.Timeout; - const drawCode = () => { - if (dom.current && window.QRCode && !dom.current.innerHTML) { - new window.QRCode(dom.current, { - text: codeUrl, - width: qrCodeSize, - height: qrCodeSize, - colorDark: '#000000', - colorLight: '#ffffff', - correctLevel: window.QRCode.CorrectLevel.H - }); - } - }; const check = async () => { try { const res = await checkBalancePayResult(billId); @@ -52,9 +54,6 @@ const QRCodePayModal = ({ title: res, status: 'success' }); - setTimeout(() => { - router.reload(); - }, 1000); return; } catch (error) { toast({ @@ -73,18 +72,26 @@ const QRCodePayModal = ({ check(); return () => clearTimeout(timer); - }, [billId, onSuccess, toast]); + }, [billId, drawCode, onSuccess, toast]); return ( - - - {tip && } - - - {t('common:pay.wechat', { price: readPrice })} - - - + <> + + + + + {tip && } + + + {t('common:pay.wechat', { price: readPrice })} + + + + ); }; diff --git a/projects/app/src/pages/account/components/AccountContainer.tsx b/projects/app/src/pages/account/components/AccountContainer.tsx index 8d75c5333..cdbf1445c 100644 --- a/projects/app/src/pages/account/components/AccountContainer.tsx +++ b/projects/app/src/pages/account/components/AccountContainer.tsx @@ -94,7 +94,7 @@ const AccountContainer = ({ ...(userInfo?.team?.permission.hasManagePer ? [ { - icon: 'support/outlink/apikeyLight', + icon: 'key', label: t('account:api_key'), value: TabEnum.apikey } diff --git a/projects/app/src/pages/account/components/TeamSelector.tsx b/projects/app/src/pages/account/components/TeamSelector.tsx index 27ef88953..c3cd03c2a 100644 --- a/projects/app/src/pages/account/components/TeamSelector.tsx +++ b/projects/app/src/pages/account/components/TeamSelector.tsx @@ -75,7 +75,7 @@ const TeamSelector = ({ key={'manage'} alignItems={'center'} borderRadius={'md'} - cursor={'default'} + cursor={'pointer'} gap={3} onClick={() => router.push('/account/team')} > diff --git a/projects/app/src/pages/account/info/components/UpdatePswModal.tsx b/projects/app/src/pages/account/info/components/UpdatePswModal.tsx index e8518e926..092625db5 100644 --- a/projects/app/src/pages/account/info/components/UpdatePswModal.tsx +++ b/projects/app/src/pages/account/info/components/UpdatePswModal.tsx @@ -3,8 +3,10 @@ import { ModalBody, Box, Flex, Input, ModalFooter, Button } from '@chakra-ui/rea import MyModal from '@fastgpt/web/components/common/MyModal'; import { useTranslation } from 'next-i18next'; import { useForm } from 'react-hook-form'; -import { useRequest } from '@fastgpt/web/hooks/useRequest'; +import { useRequest2 } from '@fastgpt/web/hooks/useRequest'; import { updatePasswordByOld } from '@/web/support/user/api'; +import { PasswordRule } from '@/web/support/user/login/constants'; +import { useToast } from '@fastgpt/web/hooks/useToast'; type FormType = { oldPsw: string; @@ -14,7 +16,9 @@ type FormType = { const UpdatePswModal = ({ onClose }: { onClose: () => void }) => { const { t } = useTranslation(); - const { register, handleSubmit } = useForm({ + const { toast } = useToast(); + + const { register, handleSubmit, getValues } = useForm({ defaultValues: { oldPsw: '', newPsw: '', @@ -22,19 +26,25 @@ const UpdatePswModal = ({ onClose }: { onClose: () => void }) => { } }); - const { mutate: onSubmit, isLoading } = useRequest({ - mutationFn: (data: FormType) => { - if (data.newPsw !== data.confirmPsw) { - return Promise.reject(t('account_info:password_mismatch')); - } - return updatePasswordByOld(data); - }, + const { runAsync: onSubmit, loading: isLoading } = useRequest2(updatePasswordByOld, { onSuccess() { onClose(); }, successToast: t('account_info:password_update_success'), errorToast: t('account_info:password_update_error') }); + const onSubmitErr = (err: Record) => { + const val = Object.values(err)[0]; + if (!val) return; + if (val.message) { + toast({ + status: 'warning', + title: val.message, + duration: 3000, + isClosable: true + }); + } + }; return ( void }) => { > - {t('account_info:old_password') + ':'} + + {t('account_info:old_password') + ':'} + - {t('account_info:new_password') + ':'} + + {t('account_info:new_password') + ':'} + - {t('account_info:confirm_password') + ':'} + + {t('account_info:confirm_password') + ':'} + (getValues('newPsw') === val ? true : t('user:password.not_match')) })} > @@ -81,7 +96,7 @@ const UpdatePswModal = ({ onClose }: { onClose: () => void }) => { - diff --git a/projects/app/src/pages/account/info/index.tsx b/projects/app/src/pages/account/info/index.tsx index d16b3ea13..48c71cc31 100644 --- a/projects/app/src/pages/account/info/index.tsx +++ b/projects/app/src/pages/account/info/index.tsx @@ -9,8 +9,7 @@ import { Link, Progress, Grid, - BoxProps, - FlexProps + BoxProps } from '@chakra-ui/react'; import { useForm } from 'react-hook-form'; import { UserUpdateParams } from '@/types/user'; @@ -20,7 +19,6 @@ import type { UserType } from '@fastgpt/global/support/user/type.d'; import { useQuery } from '@tanstack/react-query'; import dynamic from 'next/dynamic'; import { useSelectFile } from '@/web/common/file/hooks/useSelectFile'; -import { compressImgFileAndUpload } from '@/web/common/file/controller'; import { useSystemStore } from '@/web/common/system/useSystemStore'; import { useTranslation } from 'next-i18next'; import Avatar from '@fastgpt/web/components/common/Avatar'; @@ -29,7 +27,6 @@ import MyTooltip from '@fastgpt/web/components/common/MyTooltip'; import { formatStorePrice2Read } from '@fastgpt/global/support/wallet/usage/tools'; import { putUpdateMemberName } from '@/web/support/user/team/api'; import { getDocPath } from '@/web/common/system/doc'; -import { MongoImageTypeEnum } from '@fastgpt/global/common/file/image/constants'; import { StandardSubLevelEnum, standardSubLevelMap @@ -49,7 +46,9 @@ import TeamSelector from '../components/TeamSelector'; const StandDetailModal = dynamic(() => import('./components/standardDetailModal'), { ssr: false }); const ConversionModal = dynamic(() => import('./components/ConversionModal')); const UpdatePswModal = dynamic(() => import('./components/UpdatePswModal')); -const UpdateNotification = dynamic(() => import('./components/UpdateNotificationModal')); +const UpdateNotification = dynamic( + () => import('@/components/support/user/inform/UpdateNotificationModal') +); const CommunityModal = dynamic(() => import('@/components/CommunityModal')); const ModelPriceModal = dynamic(() => @@ -131,7 +130,11 @@ const MyInfo = ({ onOpenContact }: { onOpenContact: () => void }) => { onClose: onCloseUpdateNotification, onOpen: onOpenUpdateNotification } = useDisclosure(); - const { File, onOpen: onOpenSelectFile } = useSelectFile({ + const { + File, + onOpen: onOpenSelectFile, + onSelectImage + } = useSelectFile({ fileType: '.jpg,.png', multiple: false }); @@ -151,32 +154,6 @@ const MyInfo = ({ onOpenContact }: { onOpenContact: () => void }) => { [reset, t, toast, updateUserInfo] ); - const onSelectFile = useCallback( - async (e: File[]) => { - const file = e[0]; - if (!file || !userInfo) return; - try { - const src = await compressImgFileAndUpload({ - type: MongoImageTypeEnum.userAvatar, - file, - maxW: 300, - maxH: 300 - }); - - onclickSave({ - ...userInfo, - avatar: src - }); - } catch (err: any) { - toast({ - title: typeof err === 'string' ? err : t('account_info:avatar_selection_exception'), - status: 'warning' - }); - } - }, - [onclickSave, t, toast, userInfo] - ); - const labelStyles: BoxProps = { flex: '0 0 80px', fontSize: 'sm', @@ -329,7 +306,21 @@ const MyInfo = ({ onOpenContact }: { onOpenContact: () => void }) => { )} {isOpenUpdatePsw && } {isOpenUpdateNotification && } - + + onSelectImage(e, { + maxW: 300, + maxH: 300, + callback: (src) => { + if (!userInfo) return; + onclickSave({ + ...userInfo, + avatar: src + }); + } + }) + } + /> ); }; diff --git a/projects/app/src/pages/account/model/components/DefaultModal.tsx b/projects/app/src/pages/account/model/components/DefaultModal.tsx new file mode 100644 index 000000000..2568c9500 --- /dev/null +++ b/projects/app/src/pages/account/model/components/DefaultModal.tsx @@ -0,0 +1,84 @@ +import React, { useMemo, useState } from 'react'; +import MyModal from '@fastgpt/web/components/common/MyModal'; +import { useTranslation } from 'next-i18next'; +import { Box, Flex, ModalBody } from '@chakra-ui/react'; +import { MultipleRowArraySelect } from '@fastgpt/web/components/common/MySelect/MultipleRowSelect'; +import { useSystemStore } from '@/web/common/system/useSystemStore'; +import { ModelProviderList } from '@fastgpt/global/core/ai/provider'; +import Avatar from '@fastgpt/web/components/common/Avatar'; +import { HUGGING_FACE_ICON } from '@fastgpt/global/common/system/constants'; +import { getModelFromList } from '@fastgpt/global/core/ai/model'; + +const DefaultModal = ({ onClose }: { onClose: () => void }) => { + const { t } = useTranslation(); + const { llmModelList, vectorModelList, whisperModel, audioSpeechModelList, reRankModelList } = + useSystemStore(); + const [value, setValue] = useState([]); + + const modelList = useMemo(() => { + return [ + ...llmModelList, + ...vectorModelList, + ...audioSpeechModelList, + ...reRankModelList, + whisperModel + ].map((item) => ({ + provider: item.provider, + name: item.name, + model: item.model + })); + }, [llmModelList, vectorModelList, whisperModel, audioSpeechModelList, reRankModelList]); + + const selectorList = useMemo(() => { + const renderList = ModelProviderList.map<{ + label: React.JSX.Element; + value: string; + children: { label: string | React.ReactNode; value: string }[]; + }>((provider) => ({ + label: ( + + + {t(provider.name as any)} + + ), + value: provider.id, + children: [] + })); + + for (const item of modelList) { + const modelData = getModelFromList(modelList, item.model); + const provider = + renderList.find((item) => item.value === (modelData?.provider || 'Other')) ?? + renderList[renderList.length - 1]; + + provider.children.push({ + label: modelData.name, + value: modelData.model + }); + } + + return renderList.filter((item) => item.children.length > 0); + }, [modelList, t]); + + console.log(selectorList); + + return ( + + 11 + + ); +}; + +export default DefaultModal; diff --git a/projects/app/src/pages/account/model/index.tsx b/projects/app/src/pages/account/model/index.tsx index 6af07f087..c0c1b5f50 100644 --- a/projects/app/src/pages/account/model/index.tsx +++ b/projects/app/src/pages/account/model/index.tsx @@ -1,15 +1,72 @@ import { serviceSideProps } from '@fastgpt/web/common/system/nextjs'; -import React from 'react'; +import React, { useState } from 'react'; import AccountContainer from '../components/AccountContainer'; -import { Box } from '@chakra-ui/react'; +import { Box, Button, Flex, useDisclosure } from '@chakra-ui/react'; import ModelTable from '@/components/core/ai/ModelTable'; +import { useUserStore } from '@/web/support/user/useUserStore'; +import FillRowTabs from '@fastgpt/web/components/common/Tabs/FillRowTabs'; +import { useTranslation } from 'next-i18next'; +import MyMenu from '@fastgpt/web/components/common/MyMenu'; +import dynamic from 'next/dynamic'; + +const DefaultModal = dynamic(() => import('./components/DefaultModal'), { + ssr: false +}); const ModelProvider = () => { + const { t } = useTranslation(); + const { userInfo } = useUserStore(); + const isRoot = userInfo?.username === 'root'; + + const [tab, setTab] = useState<'model' | 'channel'>('model'); + + const { isOpen: isOpenDefault, onOpen: onOpenDefault, onClose: onCloseDefault } = useDisclosure(); + return ( - - - + + {/* Header */} + {/* + + list={[ + { label: t('account:active_model'), value: 'model' }, + { label: t('account:channel'), value: 'channel' } + ]} + value={tab} + px={8} + py={1} + onChange={setTab} + /> + + {tab === 'model' && ( + {t('account:create_model')}} + menuList={[ + { + children: [ + { + label: t('account:default_model'), + onClick: onOpenDefault + }, + { + label: t('account:custom_model') + } + ] + } + ]} + /> + )} + {tab === 'channel' && } + */} + + {tab === 'model' && } + {/* {tab === 'channel' && } */} + + + + {isOpenDefault && } ); }; diff --git a/projects/app/src/pages/account/team/components/EditInfoModal.tsx b/projects/app/src/pages/account/team/components/EditInfoModal.tsx index 120d8a24b..d171089ea 100644 --- a/projects/app/src/pages/account/team/components/EditInfoModal.tsx +++ b/projects/app/src/pages/account/team/components/EditInfoModal.tsx @@ -1,10 +1,8 @@ -import React, { useCallback } from 'react'; +import React from 'react'; import { useForm } from 'react-hook-form'; import { useTranslation } from 'next-i18next'; import { useSelectFile } from '@/web/common/file/hooks/useSelectFile'; -import { compressImgFileAndUpload } from '@/web/common/file/controller'; import { useToast } from '@fastgpt/web/hooks/useToast'; -import { getErrText } from '@fastgpt/global/common/error/utils'; import { useRequest } from '@fastgpt/web/hooks/useRequest'; import MyModal from '@fastgpt/web/components/common/MyModal'; import { Box, Button, Flex, Input, ModalBody, ModalFooter } from '@chakra-ui/react'; @@ -12,7 +10,6 @@ import MyTooltip from '@fastgpt/web/components/common/MyTooltip'; import Avatar from '@fastgpt/web/components/common/Avatar'; import { postCreateTeam, putUpdateTeam } from '@/web/support/user/team/api'; import { CreateTeamProps } from '@fastgpt/global/support/user/team/controller.d'; -import { MongoImageTypeEnum } from '@fastgpt/global/common/file/image/constants'; import { DEFAULT_TEAM_AVATAR } from '@fastgpt/global/common/system/constants'; export type EditTeamFormDataType = CreateTeamProps & { @@ -41,33 +38,15 @@ function EditModal({ }); const avatar = watch('avatar'); - const { File, onOpen: onOpenSelectFile } = useSelectFile({ + const { + File, + onOpen: onOpenSelectFile, + onSelectImage + } = useSelectFile({ fileType: '.jpg,.png,.svg', multiple: false }); - const onSelectFile = useCallback( - async (e: File[]) => { - const file = e[0]; - if (!file) return; - try { - const src = await compressImgFileAndUpload({ - type: MongoImageTypeEnum.teamAvatar, - file, - maxW: 300, - maxH: 300 - }); - setValue('avatar', src); - } catch (err: any) { - toast({ - title: getErrText(err, t('common:common.Select File Failed')), - status: 'warning' - }); - } - }, - [setValue, t, toast] - ); - const { mutate: onclickCreate, isLoading: creating } = useRequest({ mutationFn: async (data: CreateTeamProps) => { return postCreateTeam(data); @@ -154,7 +133,15 @@ function EditModal({ )} - + + onSelectImage(e, { + maxH: 300, + maxW: 300, + callback: (e) => setValue('avatar', e) + }) + } + /> ); } diff --git a/projects/app/src/pages/account/team/components/GroupManage/GroupInfoModal.tsx b/projects/app/src/pages/account/team/components/GroupManage/GroupInfoModal.tsx index 8959d1420..c2fb98e06 100644 --- a/projects/app/src/pages/account/team/components/GroupManage/GroupInfoModal.tsx +++ b/projects/app/src/pages/account/team/components/GroupManage/GroupInfoModal.tsx @@ -6,9 +6,7 @@ import FormLabel from '@fastgpt/web/components/common/MyBox/FormLabel'; import { useTranslation } from 'next-i18next'; import React, { useMemo } from 'react'; import { useSelectFile } from '@/web/common/file/hooks/useSelectFile'; -import { compressImgFileAndUpload } from '@/web/common/file/controller'; import { useRequest2 } from '@fastgpt/web/hooks/useRequest'; -import { MongoImageTypeEnum } from '@fastgpt/global/common/file/image/constants'; import { useForm } from 'react-hook-form'; import { useContextSelector } from 'use-context-selector'; import { TeamContext } from '../context'; @@ -23,7 +21,11 @@ export type GroupFormType = { function GroupInfoModal({ onClose, editGroupId }: { onClose: () => void; editGroupId?: string }) { const { refetchGroups, groups, refetchMembers } = useContextSelector(TeamContext, (v) => v); const { t } = useTranslation(); - const { File: AvatarSelect, onOpen: onOpenSelectAvatar } = useSelectFile({ + const { + File: AvatarSelect, + onOpen: onOpenSelectAvatar, + onSelectImage + } = useSelectFile({ fileType: '.jpg, .jpeg, .png', multiple: false }); @@ -41,13 +43,10 @@ function GroupInfoModal({ onClose, editGroupId }: { onClose: () => void; editGro const { loading: uploadingAvatar, run: onSelectAvatar } = useRequest2( async (file: File[]) => { - const src = await compressImgFileAndUpload({ - type: MongoImageTypeEnum.groupAvatar, - file: file[0], + return onSelectImage(file, { maxW: 300, maxH: 300 }); - return src; }, { onSuccess: (src: string) => { diff --git a/projects/app/src/pages/account/team/components/GroupManage/index.tsx b/projects/app/src/pages/account/team/components/GroupManage/index.tsx index 895d9112c..ba25e90b6 100644 --- a/projects/app/src/pages/account/team/components/GroupManage/index.tsx +++ b/projects/app/src/pages/account/team/components/GroupManage/index.tsx @@ -1,6 +1,8 @@ import AvatarGroup from '@fastgpt/web/components/common/Avatar/AvatarGroup'; import { Box, + Button, + Flex, HStack, Table, TableContainer, @@ -26,19 +28,35 @@ import MemberTag from '../../../../../components/support/user/team/Info/MemberTa import MyTooltip from '@fastgpt/web/components/common/MyTooltip'; import dynamic from 'next/dynamic'; import { useState } from 'react'; +import IconButton from '../OrgManage/IconButton'; const ChangeOwnerModal = dynamic(() => import('./GroupTransferOwnerModal')); +const GroupInfoModal = dynamic(() => import('./GroupInfoModal')); +const ManageGroupMemberModal = dynamic(() => import('./GroupManageMember')); -function MemberTable({ - onEditGroup, - onManageMember -}: { - onEditGroup: (groupId: string) => void; - onManageMember: (groupId: string) => void; -}) { +function MemberTable({ Tabs }: { Tabs: React.ReactNode }) { const { t } = useTranslation(); const { userInfo } = useUserStore(); + const [editGroupId, setEditGroupId] = useState(); + const { + isOpen: isOpenGroupInfo, + onOpen: onOpenGroupInfo, + onClose: onCloseGroupInfo + } = useDisclosure(); + const { + isOpen: isOpenManageGroupMember, + onOpen: onOpenManageGroupMember, + onClose: onCloseManageGroupMember + } = useDisclosure(); + const onEditGroup = (groupId: string) => { + setEditGroupId(groupId); + onOpenGroupInfo(); + }; + const onManageMember = (groupId: string) => { + setEditGroupId(groupId); + onOpenManageGroupMember(); + }; const { ConfirmModal: ConfirmDeleteGroupModal, openConfirm: openDeleteGroupModal } = useConfirm({ type: 'delete', @@ -72,145 +90,184 @@ function MemberTable({ onOpen: onOpenChangeOwner, onClose: onCloseChangeOwner } = useDisclosure(); - const onChangeOwner = (groupId: string) => { setEditGroupId(groupId); onOpenChangeOwner(); }; return ( - - - - - - - - - - - - - {groups?.map((group) => ( - - + + ))} + +
- {t('account_team:group_name')} - {t('account_team:owner')}{t('account_team:member')} - {t('common:common.Action')} -
- + <> + + {Tabs} + {userInfo?.team.permission.hasManagePer && ( + + )} + + + + + + + + + + + + + + + {groups?.map((group) => ( + + + - - - + + - - ))} - -
+ {t('account_team:group_name')} + {t('account_team:owner')}{t('account_team:member')} + {t('common:common.Action')} +
+ + + + ({group.name === DefaultGroupName ? members.length : group.members.length}) + + + item.role === 'owner')?.memberName ?? '' + : members.find( + (item) => + item.tmbId === + group.members.find((item) => item.role === 'owner')?.tmbId + )?.memberName ?? '' + } + avatar={ + group.name === DefaultGroupName + ? members.find((item) => item.role === 'owner')?.avatar ?? '' + : members.find( + (i) => + i.tmbId === + group.members.find((item) => item.role === 'owner')?.tmbId + )?.avatar ?? '' } - avatar={group.avatar} /> - - ({group.name === DefaultGroupName ? members.length : group.members.length}) - - - - item.role === 'owner')?.memberName ?? '' - : members.find( - (item) => - item.tmbId === - group.members.find((item) => item.role === 'owner')?.tmbId - )?.memberName ?? '' - } - avatar={ - group.name === DefaultGroupName - ? members.find((item) => item.role === 'owner')?.avatar ?? '' - : members.find( - (i) => - i.tmbId === group.members.find((item) => item.role === 'owner')?.tmbId - )?.avatar ?? '' - } - /> - - {group.name === DefaultGroupName ? ( - v.avatar)} groupId={group._id} /> - ) : hasGroupManagePer(group) ? ( - - onManageMember(group._id)}> - members.find((m) => m.tmbId === v.tmbId)?.avatar ?? '' - )} - groupId={group._id} - /> - - - ) : ( - members.find((m) => m.tmbId === v.tmbId)?.avatar ?? '' - )} - groupId={group._id} - /> - )} - - {hasGroupManagePer(group) && group.name !== DefaultGroupName && ( - } - menuList={[ - { - children: [ - { - label: t('account_team:edit_info'), - icon: 'edit', - onClick: () => { - onEditGroup(group._id); - } - }, - { - label: t('account_team:manage_member'), - icon: 'support/team/group', - onClick: () => { - onManageMember(group._id); - } - }, - ...(isGroupOwner(group) - ? [ - { - label: t('account_team:transfer_ownership'), - icon: 'modal/changePer', - onClick: () => { - onChangeOwner(group._id); + + {group.name === DefaultGroupName ? ( + v.avatar)} groupId={group._id} /> + ) : hasGroupManagePer(group) ? ( + + onManageMember(group._id)}> + members.find((m) => m.tmbId === v.tmbId)?.avatar ?? '' + )} + groupId={group._id} + /> + + + ) : ( + members.find((m) => m.tmbId === v.tmbId)?.avatar ?? '' + )} + groupId={group._id} + /> + )} + + {hasGroupManagePer(group) && group.name !== DefaultGroupName && ( + } + menuList={[ + { + children: [ + { + label: t('account_team:edit_info'), + icon: 'edit', + onClick: () => { + onEditGroup(group._id); + } + }, + { + label: t('account_team:manage_member'), + icon: 'support/team/group', + onClick: () => { + onManageMember(group._id); + } + }, + ...(isGroupOwner(group) + ? [ + { + label: t('account_team:transfer_ownership'), + icon: 'modal/changePer', + onClick: () => { + onChangeOwner(group._id); + }, + type: 'primary' as MenuItemType }, - type: 'primary' as MenuItemType - }, - { - label: t('common:common.Delete'), - icon: 'delete', - onClick: () => { - openDeleteGroupModal(() => delDeleteGroup(group._id))(); - }, - type: 'danger' as MenuItemType - } - ] - : []) - ] - } - ]} - /> - )} -
-
+ { + label: t('common:common.Delete'), + icon: 'delete', + onClick: () => { + openDeleteGroupModal(() => delDeleteGroup(group._id))(); + }, + type: 'danger' as MenuItemType + } + ] + : []) + ] + } + ]} + /> + )} +
+
+
+ {isOpenChangeOwner && editGroupId && ( )} - + {isOpenGroupInfo && ( + { + onCloseGroupInfo(); + setEditGroupId(undefined); + }} + editGroupId={editGroupId} + /> + )} + {isOpenManageGroupMember && ( + { + onCloseManageGroupMember(); + setEditGroupId(undefined); + }} + editGroupId={editGroupId} + /> + )} + ); } diff --git a/projects/app/src/pages/account/team/components/MemberTable.tsx b/projects/app/src/pages/account/team/components/MemberTable.tsx index b42dc837d..08b9af2bc 100644 --- a/projects/app/src/pages/account/team/components/MemberTable.tsx +++ b/projects/app/src/pages/account/team/components/MemberTable.tsx @@ -1,106 +1,224 @@ import Avatar from '@fastgpt/web/components/common/Avatar'; -import { Box, HStack, Table, TableContainer, Tbody, Td, Th, Thead, Tr } from '@chakra-ui/react'; +import { + Box, + Button, + Flex, + HStack, + Table, + TableContainer, + Tbody, + Td, + Th, + Thead, + Tr, + useDisclosure +} from '@chakra-ui/react'; import { TeamMemberRoleEnum } from '@fastgpt/global/support/user/team/constant'; import { useTranslation } from 'next-i18next'; import { useUserStore } from '@/web/support/user/useUserStore'; import { useConfirm } from '@fastgpt/web/hooks/useConfirm'; -import MyBox from '@fastgpt/web/components/common/MyBox'; import { delRemoveMember } from '@/web/support/user/team/api'; import Tag from '@fastgpt/web/components/common/Tag'; import Icon from '@fastgpt/web/components/common/Icon'; import GroupTags from '@/components/support/permission/Group/GroupTags'; import { useContextSelector } from 'use-context-selector'; import { TeamContext } from './context'; +import { useSystemStore } from '@/web/common/system/useSystemStore'; +import MyIcon from '@fastgpt/web/components/common/Icon'; +import dynamic from 'next/dynamic'; +import { useToast } from '@fastgpt/web/hooks/useToast'; +import { TeamErrEnum } from '@fastgpt/global/common/error/code/team'; +import { useRequest2 } from '@fastgpt/web/hooks/useRequest'; +import { delLeaveTeam } from '@/web/support/user/team/api'; -function MemberTable() { - const { userInfo } = useUserStore(); +const InviteModal = dynamic(() => import('./InviteModal')); +const TeamTagModal = dynamic(() => import('@/components/support/user/team/TeamTagModal')); + +function MemberTable({ Tabs }: { Tabs: React.ReactNode }) { const { t } = useTranslation(); + const { toast } = useToast(); + const { userInfo, teamPlanStatus } = useUserStore(); + const { feConfigs, setNotSufficientModalType } = useSystemStore(); + + const { groups, refetchGroups, myTeams, refetchTeams, members, refetchMembers, onSwitchTeam } = + useContextSelector(TeamContext, (v) => v); + + const { + isOpen: isOpenTeamTagsAsync, + onOpen: onOpenTeamTagsAsync, + onClose: onCloseTeamTagsAsync + } = useDisclosure(); + const { isOpen: isOpenInvite, onOpen: onOpenInvite, onClose: onCloseInvite } = useDisclosure(); const { ConfirmModal: ConfirmRemoveMemberModal, openConfirm: openRemoveMember } = useConfirm({ type: 'delete' }); - const { members, groups, refetchMembers, refetchGroups } = useContextSelector( - TeamContext, - (v) => v + const { runAsync: onLeaveTeam } = useRequest2( + async () => { + const defaultTeam = myTeams.find((item) => item.defaultTeam) || myTeams[0]; + // change to personal team + onSwitchTeam(defaultTeam.teamId); + return delLeaveTeam(); + }, + { + onSuccess() { + refetchTeams(); + }, + errorToast: t('account_team:user_team_leave_team_failed') + } ); + const { ConfirmModal: ConfirmLeaveTeamModal, openConfirm: openLeaveConfirm } = useConfirm({ + content: t('account_team:confirm_leave_team') + }); return ( - - - - - - - - - - - - {members?.map((item) => ( - - - - - - ))} - -
- {t('account_team:user_name')} - {t('account_team:member_group')} - {t('common:common.Action')} -
- - - - {item.memberName} - {item.status === 'waiting' && ( - - {t('account_team:waiting')} - - )} - - - - group.members.map((m) => m.tmbId).includes(item.tmbId)) - .map((g) => g.name)} - max={3} - /> - - {userInfo?.team.permission.hasManagePer && - item.role !== TeamMemberRoleEnum.owner && - item.tmbId !== userInfo?.team.tmbId && ( - { - openRemoveMember( - () => - delRemoveMember(item.tmbId).then(() => - Promise.all([refetchGroups(), refetchMembers()]) - ), - undefined, - t('account_team:remove_tip', { - username: item.memberName - }) - )(); - }} - /> - )} -
+ <> + + {Tabs} + + {userInfo?.team.permission.hasManagePer && feConfigs?.show_team_chat && ( + + )} + {userInfo?.team.permission.hasManagePer && ( + + )} + {!userInfo?.team.permission.isOwner && ( + + )} + + - -
-
+ + + + + + + + + + + + {members?.map((item) => ( + + + + + + ))} + +
+ {t('account_team:user_name')} + {t('account_team:member_group')} + {t('common:common.Action')} +
+ + + + {item.memberName} + {item.status === 'waiting' && ( + + {t('account_team:waiting')} + + )} + + + + group.members.map((m) => m.tmbId).includes(item.tmbId)) + .map((g) => g.name)} + max={3} + /> + + {userInfo?.team.permission.hasManagePer && + item.role !== TeamMemberRoleEnum.owner && + item.tmbId !== userInfo?.team.tmbId && ( + { + openRemoveMember( + () => + delRemoveMember(item.tmbId).then(() => + Promise.all([refetchGroups(), refetchMembers()]) + ), + undefined, + t('account_team:remove_tip', { + username: item.memberName + }) + )(); + }} + /> + )} +
+ + +
+
+ + + {isOpenInvite && userInfo?.team?.teamId && ( + + )} + {isOpenTeamTagsAsync && } + ); } diff --git a/projects/app/src/pages/account/team/components/OrgManage/IconButton.tsx b/projects/app/src/pages/account/team/components/OrgManage/IconButton.tsx new file mode 100644 index 000000000..cb543dc1a --- /dev/null +++ b/projects/app/src/pages/account/team/components/OrgManage/IconButton.tsx @@ -0,0 +1,31 @@ +import { IconProps } from '@chakra-ui/react'; +import MyIcon from '@fastgpt/web/components/common/Icon'; +import type { IconNameType } from '@fastgpt/web/components/common/Icon/type'; + +function IconButton({ + name, + w = '1rem', + h = '1rem', + ...props +}: { + name: IconNameType; +} & IconProps) { + return ( + + ); +} + +export default IconButton; diff --git a/projects/app/src/pages/account/team/components/OrgManage/OrgInfoModal.tsx b/projects/app/src/pages/account/team/components/OrgManage/OrgInfoModal.tsx new file mode 100644 index 000000000..c2e49b368 --- /dev/null +++ b/projects/app/src/pages/account/team/components/OrgManage/OrgInfoModal.tsx @@ -0,0 +1,162 @@ +import { useSelectFile } from '@/web/common/file/hooks/useSelectFile'; +import { postCreateOrg, putUpdateOrg } from '@/web/support/user/team/org/api'; +import { Button, HStack, Input, ModalBody, ModalFooter, Textarea } from '@chakra-ui/react'; +import { DEFAULT_ORG_AVATAR } from '@fastgpt/global/common/system/constants'; +import Avatar from '@fastgpt/web/components/common/Avatar'; +import FormLabel from '@fastgpt/web/components/common/MyBox/FormLabel'; +import MyModal from '@fastgpt/web/components/common/MyModal'; +import { useRequest2 } from '@fastgpt/web/hooks/useRequest'; +import { useTranslation } from 'next-i18next'; +import dynamic from 'next/dynamic'; +import { useForm } from 'react-hook-form'; + +export type OrgFormType = { + _id: string; + avatar: string; + description?: string; + name: string; + path: string; + parentId?: string; +}; + +export const defaultOrgForm: OrgFormType = { + _id: '', + avatar: '', + description: '', + name: '', + path: '' +}; + +function OrgInfoModal({ + editOrg, + onClose, + onSuccess +}: { + editOrg: OrgFormType; + onClose: () => void; + onSuccess: () => void; +}) { + const { t } = useTranslation(); + + const isEdit = !!editOrg._id; + + const { register, handleSubmit, setValue, watch } = useForm({ + defaultValues: { + name: editOrg.name, + avatar: editOrg.avatar, + description: editOrg.description + } + }); + const avatar = watch('avatar'); + + const { run: onCreate, loading: isLoadingCreate } = useRequest2( + async (data: OrgFormType) => { + if (!editOrg.parentId) return; + return postCreateOrg({ + name: data.name, + avatar: data.avatar, + parentId: editOrg.parentId, + description: data.description + }); + }, + { + successToast: t('common:common.Create Success'), + onSuccess: () => { + onClose(); + onSuccess(); + } + } + ); + + const { run: onUpdate, loading: isLoadingUpdate } = useRequest2( + async (data: OrgFormType) => { + if (!editOrg._id) return; + return putUpdateOrg({ + orgId: editOrg._id, + name: data.name, + avatar: data.avatar, + description: data.description + }); + }, + { + successToast: t('common:common.Update Success'), + onSuccess: () => { + onClose(); + onSuccess(); + } + } + ); + + const { + File: AvatarSelect, + onOpen: onOpenSelectAvatar, + onSelectImage + } = useSelectFile({ + fileType: '.jpg, .jpeg, .png', + multiple: false + }); + const { loading: uploadingAvatar, run: onSelectAvatar } = useRequest2( + async (file: File[]) => { + return onSelectImage(file, { + maxW: 300, + maxH: 300 + }); + }, + { + onSuccess: (src: string) => { + setValue('avatar', src); + } + } + ); + + const isLoading = uploadingAvatar || isLoadingUpdate || isLoadingCreate; + + return ( + + + {t('user:team.avatar_and_name')} + + + + + {t('account_team:org_description')} +