Compare commits
18 Commits
v4.8.4-fix
...
v4.8.5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a3b0ef066b | ||
|
|
9d084b633c | ||
|
|
4b4bea196a | ||
|
|
e247545afa | ||
|
|
93b44fc8f5 | ||
|
|
9aa6fd4904 | ||
|
|
c8bc9838e3 | ||
|
|
5c8c7fb9f2 | ||
|
|
d902d29c71 | ||
|
|
9d29b471bc | ||
|
|
4a33e04a08 | ||
|
|
a9ab9ebe8e | ||
|
|
24596a6e21 | ||
|
|
5cc01b8509 | ||
|
|
980b4d3db5 | ||
|
|
2b25e3cc2d | ||
|
|
565bfc8486 | ||
|
|
b17d14bb7d |
96
.github/workflows/build-sandbox-image.yml
vendored
@@ -10,6 +10,7 @@ jobs:
|
||||
build-fastgpt-sandbox-images:
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
# install env
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
@@ -30,22 +31,53 @@ jobs:
|
||||
key: ${{ runner.os }}-buildx-${{ github.sha }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-buildx-
|
||||
|
||||
# login docker
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GH_PAT }}
|
||||
- name: Set DOCKER_REPO_TAGGED based on branch or tag
|
||||
- name: Login to Ali Hub
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: registry.cn-hangzhou.aliyuncs.com
|
||||
username: ${{ secrets.ALI_HUB_USERNAME }}
|
||||
password: ${{ secrets.ALI_HUB_PASSWORD }}
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_HUB_NAME }}
|
||||
password: ${{ secrets.DOCKER_HUB_PASSWORD }}
|
||||
|
||||
# Set tag
|
||||
- name: Set image name and tag
|
||||
run: |
|
||||
if [[ "${{ github.ref_name }}" == "main" ]]; then
|
||||
echo "DOCKER_REPO_TAGGED=ghcr.io/${{ github.repository_owner }}/fastgpt-sandbox:latest" >> $GITHUB_ENV
|
||||
echo "Git_Tag=ghcr.io/${{ github.repository_owner }}/fastgpt-sandbox:latest" >> $GITHUB_ENV
|
||||
echo "Git_Latest=ghcr.io/${{ github.repository_owner }}/fastgpt-sandbox:latest" >> $GITHUB_ENV
|
||||
echo "Ali_Tag=${{ secrets.ALI_IMAGE_NAME }}/fastgpt-sandbox:latest" >> $GITHUB_ENV
|
||||
echo "Ali_Latest=${{ secrets.ALI_IMAGE_NAME }}/fastgpt-sandbox:latest" >> $GITHUB_ENV
|
||||
echo "Docker_Hub_Tag=${{ secrets.DOCKER_IMAGE_NAME }}/fastgpt-sandbox:latest" >> $GITHUB_ENV
|
||||
echo "Docker_Hub_Latest=${{ secrets.DOCKER_IMAGE_NAME }}/fastgpt-sandbox:latest" >> $GITHUB_ENV
|
||||
else
|
||||
echo "DOCKER_REPO_TAGGED=ghcr.io/${{ github.repository_owner }}/fastgpt-sandbox:${{ github.ref_name }}" >> $GITHUB_ENV
|
||||
echo "Git_Tag=ghcr.io/${{ github.repository_owner }}/fastgpt-sandbox:${{ github.ref_name }}" >> $GITHUB_ENV
|
||||
echo "Git_Latest=ghcr.io/${{ github.repository_owner }}/fastgpt-sandbox:latest" >> $GITHUB_ENV
|
||||
echo "Ali_Tag=${{ secrets.ALI_IMAGE_NAME }}/fastgpt-sandbox:${{ github.ref_name }}" >> $GITHUB_ENV
|
||||
echo "Ali_Latest=${{ secrets.ALI_IMAGE_NAME }}/fastgpt-sandbox:latest" >> $GITHUB_ENV
|
||||
echo "Docker_Hub_Tag=${{ secrets.DOCKER_IMAGE_NAME }}/fastgpt-sandbox:${{ github.ref_name }}" >> $GITHUB_ENV
|
||||
echo "Docker_Hub_Latest=${{ secrets.DOCKER_IMAGE_NAME }}/fastgpt-sandbox:latest" >> $GITHUB_ENV
|
||||
fi
|
||||
|
||||
- name: Build and publish image for main branch or tag push event
|
||||
env:
|
||||
DOCKER_REPO_TAGGED: ${{ env.DOCKER_REPO_TAGGED }}
|
||||
Git_Tag: ${{ env.Git_Tag }}
|
||||
Git_Latest: ${{ env.Git_Latest }}
|
||||
Ali_Tag: ${{ env.Ali_Tag }}
|
||||
Ali_Latest: ${{ env.Ali_Latest }}
|
||||
Docker_Hub_Tag: ${{ env.Docker_Hub_Tag }}
|
||||
Docker_Hub_Latest: ${{ env.Docker_Hub_Latest }}
|
||||
run: |
|
||||
docker buildx build \
|
||||
-f projects/sandbox/Dockerfile \
|
||||
@@ -55,54 +87,10 @@ jobs:
|
||||
--push \
|
||||
--cache-from=type=local,src=/tmp/.buildx-cache \
|
||||
--cache-to=type=local,dest=/tmp/.buildx-cache \
|
||||
-t ${DOCKER_REPO_TAGGED} \
|
||||
-t ${Git_Tag} \
|
||||
-t ${Git_Latest} \
|
||||
-t ${Ali_Tag} \
|
||||
-t ${Ali_Latest} \
|
||||
-t ${Docker_Hub_Tag} \
|
||||
-t ${Docker_Hub_Latest} \
|
||||
.
|
||||
push-to-ali-hub:
|
||||
needs: build-fastgpt-sandbox-images
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
- name: Login to Ali Hub
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: registry.cn-hangzhou.aliyuncs.com
|
||||
username: ${{ secrets.ALI_HUB_USERNAME }}
|
||||
password: ${{ secrets.ALI_HUB_PASSWORD }}
|
||||
- name: Set DOCKER_REPO_TAGGED based on branch or tag
|
||||
run: |
|
||||
if [[ "${{ github.ref_name }}" == "main" ]]; then
|
||||
echo "IMAGE_TAG=latest" >> $GITHUB_ENV
|
||||
else
|
||||
echo "IMAGE_TAG=${{ github.ref_name }}" >> $GITHUB_ENV
|
||||
fi
|
||||
- name: Pull image from GitHub Container Registry
|
||||
run: docker pull ghcr.io/${{ github.repository_owner }}/fastgpt-sandbox:${{env.IMAGE_TAG}}
|
||||
- name: Tag image with Docker Hub repository name and version tag
|
||||
run: docker tag ghcr.io/${{ github.repository_owner }}/fastgpt-sandbox:${{env.IMAGE_TAG}} ${{ secrets.ALI_IMAGE_NAME }}/fastgpt-sandbox:${{env.IMAGE_TAG}}
|
||||
- name: Push image to Docker Hub
|
||||
run: docker push ${{ secrets.ALI_IMAGE_NAME }}/fastgpt-sandbox:${{env.IMAGE_TAG}}
|
||||
push-to-docker-hub:
|
||||
needs: build-fastgpt-sandbox-images
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_HUB_NAME }}
|
||||
password: ${{ secrets.DOCKER_HUB_PASSWORD }}
|
||||
- name: Set DOCKER_REPO_TAGGED based on branch or tag
|
||||
run: |
|
||||
if [[ "${{ github.ref_name }}" == "main" ]]; then
|
||||
echo "IMAGE_TAG=latest" >> $GITHUB_ENV
|
||||
else
|
||||
echo "IMAGE_TAG=${{ github.ref_name }}" >> $GITHUB_ENV
|
||||
fi
|
||||
- name: Pull image from GitHub Container Registry
|
||||
run: docker pull ghcr.io/${{ github.repository_owner }}/fastgpt-sandbox:${{env.IMAGE_TAG}}
|
||||
- name: Tag image with Docker Hub repository name and version tag
|
||||
run: docker tag ghcr.io/${{ github.repository_owner }}/fastgpt-sandbox:${{env.IMAGE_TAG}} ${{ secrets.DOCKER_IMAGE_NAME }}/fastgpt-sandbox:${{env.IMAGE_TAG}}
|
||||
- name: Push image to Docker Hub
|
||||
run: docker push ${{ secrets.DOCKER_IMAGE_NAME }}/fastgpt-sandbox:${{env.IMAGE_TAG}}
|
||||
|
||||
91
.github/workflows/fastgpt-image.yml
vendored
@@ -11,6 +11,7 @@ jobs:
|
||||
build-fastgpt-images:
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
# install env
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
@@ -31,19 +32,45 @@ jobs:
|
||||
key: ${{ runner.os }}-buildx-${{ github.sha }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-buildx-
|
||||
|
||||
# login docker
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GH_PAT }}
|
||||
- name: Set DOCKER_REPO_TAGGED based on branch or tag
|
||||
- name: Login to Ali Hub
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: registry.cn-hangzhou.aliyuncs.com
|
||||
username: ${{ secrets.ALI_HUB_USERNAME }}
|
||||
password: ${{ secrets.ALI_HUB_PASSWORD }}
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_HUB_NAME }}
|
||||
password: ${{ secrets.DOCKER_HUB_PASSWORD }}
|
||||
|
||||
# Set tag
|
||||
- name: Set image name and tag
|
||||
run: |
|
||||
if [[ "${{ github.ref_name }}" == "main" ]]; then
|
||||
echo "DOCKER_REPO_TAGGED=ghcr.io/${{ github.repository_owner }}/fastgpt:latest" >> $GITHUB_ENV
|
||||
echo "Git_Tag=ghcr.io/${{ github.repository_owner }}/fastgpt:latest" >> $GITHUB_ENV
|
||||
echo "Git_Latest=ghcr.io/${{ github.repository_owner }}/fastgpt:latest" >> $GITHUB_ENV
|
||||
echo "Ali_Tag=${{ secrets.ALI_IMAGE_NAME }}/fastgpt:latest" >> $GITHUB_ENV
|
||||
echo "Ali_Latest=${{ secrets.ALI_IMAGE_NAME }}/fastgpt:latest" >> $GITHUB_ENV
|
||||
echo "Docker_Hub_Tag=${{ secrets.DOCKER_IMAGE_NAME }}/fastgpt:latest" >> $GITHUB_ENV
|
||||
echo "Docker_Hub_Latest=${{ secrets.DOCKER_IMAGE_NAME }}/fastgpt:latest" >> $GITHUB_ENV
|
||||
else
|
||||
echo "DOCKER_REPO_TAGGED=ghcr.io/${{ github.repository_owner }}/fastgpt:${{ github.ref_name }}" >> $GITHUB_ENV
|
||||
echo "Git_Tag=ghcr.io/${{ github.repository_owner }}/fastgpt:${{ github.ref_name }}" >> $GITHUB_ENV
|
||||
echo "Git_Latest=ghcr.io/${{ github.repository_owner }}/fastgpt:latest" >> $GITHUB_ENV
|
||||
echo "Ali_Tag=${{ secrets.ALI_IMAGE_NAME }}/fastgpt:${{ github.ref_name }}" >> $GITHUB_ENV
|
||||
echo "Ali_Latest=${{ secrets.ALI_IMAGE_NAME }}/fastgpt:latest" >> $GITHUB_ENV
|
||||
echo "Docker_Hub_Tag=${{ secrets.DOCKER_IMAGE_NAME }}/fastgpt:${{ github.ref_name }}" >> $GITHUB_ENV
|
||||
echo "Docker_Hub_Latest=${{ secrets.DOCKER_IMAGE_NAME }}/fastgpt:latest" >> $GITHUB_ENV
|
||||
fi
|
||||
|
||||
- name: Build and publish image for main branch or tag push event
|
||||
env:
|
||||
DOCKER_REPO_TAGGED: ${{ env.DOCKER_REPO_TAGGED }}
|
||||
@@ -56,56 +83,10 @@ jobs:
|
||||
--push \
|
||||
--cache-from=type=local,src=/tmp/.buildx-cache \
|
||||
--cache-to=type=local,dest=/tmp/.buildx-cache \
|
||||
-t ${DOCKER_REPO_TAGGED} \
|
||||
-t ${Git_Tag} \
|
||||
-t ${Git_Latest} \
|
||||
-t ${Ali_Tag} \
|
||||
-t ${Ali_Latest} \
|
||||
-t ${Docker_Hub_Tag} \
|
||||
-t ${Docker_Hub_Latest} \
|
||||
.
|
||||
push-to-docker-hub:
|
||||
needs: build-fastgpt-images
|
||||
runs-on: ubuntu-20.04
|
||||
if: github.repository == 'labring/FastGPT'
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_HUB_NAME }}
|
||||
password: ${{ secrets.DOCKER_HUB_PASSWORD }}
|
||||
- name: Set DOCKER_REPO_TAGGED based on branch or tag
|
||||
run: |
|
||||
if [[ "${{ github.ref_name }}" == "main" ]]; then
|
||||
echo "IMAGE_TAG=latest" >> $GITHUB_ENV
|
||||
else
|
||||
echo "IMAGE_TAG=${{ github.ref_name }}" >> $GITHUB_ENV
|
||||
fi
|
||||
- name: Pull image from GitHub Container Registry
|
||||
run: docker pull ghcr.io/${{ github.repository_owner }}/fastgpt:${{env.IMAGE_TAG}}
|
||||
- name: Tag image with Docker Hub repository name and version tag
|
||||
run: docker tag ghcr.io/${{ github.repository_owner }}/fastgpt:${{env.IMAGE_TAG}} ${{ secrets.DOCKER_IMAGE_NAME }}/fastgpt:${{env.IMAGE_TAG}}
|
||||
- name: Push image to Docker Hub
|
||||
run: docker push ${{ secrets.DOCKER_IMAGE_NAME }}/fastgpt:${{env.IMAGE_TAG}}
|
||||
push-to-ali-hub:
|
||||
needs: build-fastgpt-images
|
||||
if: github.repository == 'labring/FastGPT'
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
- name: Login to Ali Hub
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: registry.cn-hangzhou.aliyuncs.com
|
||||
username: ${{ secrets.ALI_HUB_USERNAME }}
|
||||
password: ${{ secrets.ALI_HUB_PASSWORD }}
|
||||
- name: Set DOCKER_REPO_TAGGED based on branch or tag
|
||||
run: |
|
||||
if [[ "${{ github.ref_name }}" == "main" ]]; then
|
||||
echo "IMAGE_TAG=latest" >> $GITHUB_ENV
|
||||
else
|
||||
echo "IMAGE_TAG=${{ github.ref_name }}" >> $GITHUB_ENV
|
||||
fi
|
||||
- name: Pull image from GitHub Container Registry
|
||||
run: docker pull ghcr.io/${{ github.repository_owner }}/fastgpt:${{env.IMAGE_TAG}}
|
||||
- name: Tag image with Docker Hub repository name and version tag
|
||||
run: docker tag ghcr.io/${{ github.repository_owner }}/fastgpt:${{env.IMAGE_TAG}} ${{ secrets.ALI_IMAGE_NAME }}/fastgpt:${{env.IMAGE_TAG}}
|
||||
- name: Push image to Docker Hub
|
||||
run: docker push ${{ secrets.ALI_IMAGE_NAME }}/fastgpt:${{env.IMAGE_TAG}}
|
||||
|
||||
5
.vscode/settings.json
vendored
@@ -1,10 +1,11 @@
|
||||
{
|
||||
"editor.formatOnSave": true,
|
||||
"editor.mouseWheelZoom": true,
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"prettier.prettierPath": "../node_modules/prettier",
|
||||
"typescript.tsdk": "node_modules/typescript/lib",
|
||||
"prettier.prettierPath": "",
|
||||
"i18n-ally.localesPaths": [
|
||||
"projects/app/i18n",
|
||||
"packages/web/i18n",
|
||||
],
|
||||
"i18n-ally.enabledParsers": ["json", "yaml", "js", "ts"],
|
||||
"i18n-ally.keystyle": "nested",
|
||||
|
||||
2
LICENSE
@@ -5,7 +5,7 @@ The FastGPT is licensed under the Apache License 2.0, with the following additio
|
||||
1. FastGPT is permitted to be used for commercialization. You can use FastGPT as a "backend-as-a-service" for your other applications, or delivering it to enterprises as an application development platform. However, when the following conditions are met, you must contact the producer to obtain a commercial license:
|
||||
|
||||
a. Multi-tenant SaaS service: Unless explicitly authorized by FastGPT in writing, you may not use the FastGPT.AI source code to operate a multi-tenant SaaS service that is similar to the FastGPT.
|
||||
b. LOGO and copyright information: In the process of using FastGPT, you may not remove or moFastGPT the LOGO or copyright information in the FastGPT console.
|
||||
b. LOGO and copyright information: In the process of using FastGPT, you may not remove or modify the LOGO or copyright information in the FastGPT console.
|
||||
|
||||
Please contact yujinlong@sealos.io by email to inquire about licensing matters.
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 67 KiB After Width: | Height: | Size: 209 KiB |
@@ -148,6 +148,9 @@ llm模型全部合并
|
||||
- /imgs/model/openai.svg - OpenAI GPT
|
||||
- /imgs/model/qwen.svg - 通义千问
|
||||
- /imgs/model/yi.svg - 零一万物
|
||||
- /imgs/model/gemini.svg - gemini
|
||||
- /imgs/model/deepseek.svg - deepseek
|
||||
- /imgs/model/minimax.svg - minimax
|
||||
-
|
||||
|
||||
## 特殊模型
|
||||
|
||||
@@ -363,3 +363,14 @@ mongo连接失败,查看mongo的运行状态**对应日志**。
|
||||
### 无法导出知识库、无法使用语音输入/播报
|
||||
|
||||
没配置 SSL 证书,无权使用部分功能。
|
||||
|
||||
### 登录提示 Network Error
|
||||
|
||||
由于服务初始化错误,系统重启导致。
|
||||
|
||||
* 90%是由于配置文件写不对,导致 JSON 解析报错
|
||||
* 剩下的基本是因为向量数据库连不上
|
||||
|
||||
### 如何修改密码
|
||||
|
||||
修改`docker-compose.yml`文件中`DEFAULT_ROOT_PSW`并重启即可,密码会自动更新。
|
||||
@@ -31,7 +31,9 @@ images: []
|
||||
### 页面崩溃
|
||||
|
||||
1. 关闭翻译
|
||||
2. 检查配置文件是否正常加载,如果没有正常加载会导致缺失系统信息,在某些操作下会导致空指针。(95%情况是配置文件不对,可以F12打开控制台,看具体的空指针情况)
|
||||
2. 检查配置文件是否正常加载,如果没有正常加载会导致缺失系统信息,在某些操作下会导致空指针。
|
||||
* 95%情况是配置文件不对。会提示 xxx undefined
|
||||
* 提示`URI malformed`,请 Issue 反馈具体操作和页面,这是由于特殊字符串编码解析报错。
|
||||
3. 某些api不兼容问题(较少)
|
||||
|
||||
### 开启内容补全后,响应速度变慢
|
||||
|
||||
62
docSite/content/zh-cn/docs/development/upgrading/485.md
Normal file
@@ -0,0 +1,62 @@
|
||||
---
|
||||
title: 'V4.8.5(进行中)'
|
||||
description: 'FastGPT V4.8.5 更新说明'
|
||||
icon: 'upgrade'
|
||||
draft: false
|
||||
toc: true
|
||||
weight: 819
|
||||
---
|
||||
|
||||
## 升级指南
|
||||
|
||||
### 1. 做好数据库备份
|
||||
|
||||
### 2. 修改镜像
|
||||
|
||||
- fastgpt 镜像 tag 修改成 v4.8.5-alpha
|
||||
- 商业版镜像 tag 修改成 v4.8.5 -alpha
|
||||
|
||||
### 3. 执行初始化
|
||||
|
||||
从任意终端,发起 1 个 HTTP 请求。其中 {{rootkey}} 替换成环境变量里的 `rootkey`;{{host}} 替换成**FastGPT 域名**。
|
||||
|
||||
```bash
|
||||
curl --location --request POST 'https://{{host}}/api/admin/initv485' \
|
||||
--header 'rootkey: {{rootkey}}' \
|
||||
--header 'Content-Type: application/json'
|
||||
```
|
||||
|
||||
会把插件的数据表合并到应用中,插件表不会删除。
|
||||
|
||||
------
|
||||
|
||||
**商业版用户执行额外的初始化**
|
||||
|
||||
从任意终端,发起 1 个 HTTP 请求。其中 {{rootkey}} 替换成环境变量里的 `rootkey`;{{host}} 替换成**FastGPT 商业版的域名**:
|
||||
|
||||
```bash
|
||||
curl --location --request POST 'https://{{host}}/api/admin/init/485' \
|
||||
--header 'rootkey: {{rootkey}}' \
|
||||
--header 'Content-Type: application/json'
|
||||
```
|
||||
|
||||
会重置知识库权限系统。
|
||||
|
||||
## V4.8.5 更新说明
|
||||
|
||||
1. 新增 - 合并插件和应用,统一成工作台
|
||||
2. 新增 - 应用创建副本功能
|
||||
3. 新增 - 应用创建模板
|
||||
4. 新增 - 支持代码运行结果作为工具输出。
|
||||
5. 新增 - Markdown 图片输出,支持移动端放大缩放。
|
||||
6. 优化 - 原文件编码存取
|
||||
7. 优化 - 知识库删除后,简易模式会过滤掉删除的知识库,避免错误判断。
|
||||
8. 优化 - 文件夹读取,支持单个文件夹超出 100 个文件
|
||||
9. 优化 - 问答拆分/手动录入,当有`a`字段时,自动将`q`作为补充索引。
|
||||
10. 优化 - 对话框页面代码
|
||||
11. 修复 - SSR渲染
|
||||
12. 优化 - 工作流新节点自动增加序号名
|
||||
13. 修复 - 定时任务无法实际关闭
|
||||
14. 修复 - 输入引导特殊字符导致正则报错
|
||||
15. 修复 - 文件包含特殊字符`%`,且为转义时会导致页面崩溃
|
||||
16. 修复 - 自定义输入选择知识库引用时页面崩溃
|
||||
@@ -9,7 +9,7 @@ weight: 506
|
||||
|
||||
# FastGPT 三分钟接入微信/企业微信
|
||||
私人微信和企业微信接入的方式基本一样,不同的地方会刻意指出。
|
||||
[查看视频教程](https://www.bilibili.com/video/BV1cu411F7FN/?spm_id_from=333.1007.top_right_bar_window_history.content.click&vd_source=903c2b09b7412037c2eddc6a8fb9828b)
|
||||
[查看视频教程](https://www.bilibili.com/video/BV1rJ4m1w7xk/)
|
||||
## 创建APIKey
|
||||
首先找到我们需要接入的应用,然后点击「外部使用」->「API访问」创建一个APIKey并保存。
|
||||
|
||||
@@ -27,7 +27,7 @@ weight: 506
|
||||
|
||||
## sealos部署服务
|
||||
|
||||
[访问sealos](https://cloud.sealos.io/) 登陆进来之后打开「应用管理」-> 「新建应用」。
|
||||
[访问sealos](https://cloud.sealos.run/) 登陆进来之后打开「应用管理」-> 「新建应用」。
|
||||
- 应用名:称随便填写
|
||||
- 镜像名:私人微信填写 aibotk/wechat-assistant 企业微信填写 aibotk/worker-assistant
|
||||
- cpu和内存建议 1c1g
|
||||
@@ -38,14 +38,14 @@ weight: 506
|
||||
|
||||

|
||||
|
||||
这里需要填写四个环境变量:
|
||||
这里需要填写三个环境变量:
|
||||
```
|
||||
AIBOTK_KEY=微秘书 APIKEY
|
||||
AIBOTK_SECRET=微秘书 APISECRET
|
||||
WORK_PRO_TOKEN=你申请的企微 token (企业微信需要填写,私人微信不需要)
|
||||
```
|
||||
|
||||
这里最后两个变量只有部署企业微信才需要,私人微信只需要填写前两个即可。
|
||||
这里最后的企业微信 Token 在微秘书的->会员开通栏目中自行购买。
|
||||
|
||||

|
||||
|
||||
@@ -55,9 +55,7 @@ WORK_PRO_TOKEN=你申请的企微 token (企业微信需要填写,私人
|
||||
|
||||

|
||||
|
||||
`WORK_PRO_TOKEN` [点击这里](https://tss.rpachat.com/?aff=aibotk)申请 token 然后填入即可。
|
||||
|
||||
`WECHATY_PUPPET_SERVICE_AUTHORITY`的值复制过去就可以。
|
||||
`WORK_PRO_TOKEN` 微秘书的会员中心中自行购买即可。
|
||||
|
||||
填写完毕后点右上角「部署」,等待应用状态变为运行中。
|
||||
|
||||
|
||||
@@ -272,7 +272,7 @@ Response:
|
||||
{
|
||||
"key": "Authorization",
|
||||
"type": "string",
|
||||
"value": "Bearer sk-zsfBsxEU3ApSFGYxF4CdB97e9556412588421823371b9f7b"
|
||||
"value": "Bearer "
|
||||
}
|
||||
],
|
||||
"label": "",
|
||||
|
||||
@@ -26,456 +26,378 @@ weight: 404
|
||||
{{% details title="编排配置" closed="true" %}}
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"nodeId": "userGuide",
|
||||
"name": "core.module.template.App system setting",
|
||||
"intro": "core.app.tip.userGuideTip",
|
||||
"avatar": "/imgs/workflow/userGuide.png",
|
||||
"flowNodeType": "userGuide",
|
||||
"position": {
|
||||
"x": -92.26884681344463,
|
||||
"y": 710.9354029649536
|
||||
{
|
||||
"nodes": [
|
||||
{
|
||||
"nodeId": "userGuide",
|
||||
"name": "系统配置",
|
||||
"intro": "可以配置应用的系统参数",
|
||||
"avatar": "/imgs/workflow/userGuide.png",
|
||||
"flowNodeType": "userGuide",
|
||||
"position": {
|
||||
"x": 303.41163758039283,
|
||||
"y": -552.297639861266
|
||||
},
|
||||
"version": "481",
|
||||
"inputs": [],
|
||||
"outputs": []
|
||||
},
|
||||
"inputs": [
|
||||
{
|
||||
"key": "welcomeText",
|
||||
"type": "hidden",
|
||||
"valueType": "string",
|
||||
"label": "core.app.Welcome Text",
|
||||
"showTargetInApp": false,
|
||||
"showTargetInPlugin": false,
|
||||
"value": "",
|
||||
"connected": false
|
||||
{
|
||||
"nodeId": "workflowStartNodeId",
|
||||
"name": "流程开始",
|
||||
"intro": "",
|
||||
"avatar": "/imgs/workflow/userChatInput.svg",
|
||||
"flowNodeType": "workflowStart",
|
||||
"position": {
|
||||
"x": 529.3935295017156,
|
||||
"y": 197.114018410347
|
||||
},
|
||||
{
|
||||
"key": "variables",
|
||||
"type": "hidden",
|
||||
"valueType": "any",
|
||||
"label": "core.module.Variable",
|
||||
"value": [],
|
||||
"showTargetInApp": false,
|
||||
"showTargetInPlugin": false,
|
||||
"connected": false
|
||||
},
|
||||
{
|
||||
"key": "questionGuide",
|
||||
"valueType": "boolean",
|
||||
"type": "switch",
|
||||
"label": "",
|
||||
"showTargetInApp": false,
|
||||
"showTargetInPlugin": false,
|
||||
"value": false,
|
||||
"connected": false
|
||||
},
|
||||
{
|
||||
"key": "tts",
|
||||
"type": "hidden",
|
||||
"valueType": "any",
|
||||
"label": "",
|
||||
"showTargetInApp": false,
|
||||
"showTargetInPlugin": false,
|
||||
"value": {
|
||||
"type": "web"
|
||||
},
|
||||
"connected": false
|
||||
}
|
||||
],
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"nodeId": "userChatInput",
|
||||
"name": "core.module.template.Chat entrance",
|
||||
"intro": "当用户发送一个内容后,流程将会从这个模块开始执行。",
|
||||
"avatar": "/imgs/workflow/userChatInput.svg",
|
||||
"flowNodeType": "questionInput",
|
||||
"position": {
|
||||
"x": 241.60980819261408,
|
||||
"y": 1330.9528898009685
|
||||
},
|
||||
"inputs": [
|
||||
{
|
||||
"key": "userChatInput",
|
||||
"type": "systemInput",
|
||||
"valueType": "string",
|
||||
"label": "core.module.input.label.user question",
|
||||
"showTargetInApp": false,
|
||||
"showTargetInPlugin": false,
|
||||
"connected": false
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"key": "userChatInput",
|
||||
"label": "core.module.input.label.user question",
|
||||
"type": "source",
|
||||
"valueType": "string",
|
||||
"targets": [
|
||||
{
|
||||
"nodeId": "n84rvg",
|
||||
"key": "userChatInput"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nodeId": "n84rvg",
|
||||
"name": "工具调用(实验)",
|
||||
"intro": "通过AI模型自动选择一个或多个功能块进行调用,也可以对插件进行调用。",
|
||||
"avatar": "/imgs/workflow/tool.svg",
|
||||
"flowNodeType": "tools",
|
||||
"showStatus": true,
|
||||
"position": {
|
||||
"x": 809.4264785615641,
|
||||
"y": 873.3971746859133
|
||||
},
|
||||
"inputs": [
|
||||
{
|
||||
"key": "model",
|
||||
"type": "settingLLMModel",
|
||||
"label": "core.module.input.label.aiModel",
|
||||
"required": true,
|
||||
"valueType": "string",
|
||||
"showTargetInApp": false,
|
||||
"showTargetInPlugin": false,
|
||||
"llmModelType": "all",
|
||||
"value": "gpt-3.5-turbo",
|
||||
"connected": false
|
||||
},
|
||||
{
|
||||
"key": "temperature",
|
||||
"type": "hidden",
|
||||
"label": "",
|
||||
"value": 0,
|
||||
"valueType": "number",
|
||||
"min": 0,
|
||||
"max": 10,
|
||||
"step": 1,
|
||||
"showTargetInApp": false,
|
||||
"showTargetInPlugin": false,
|
||||
"connected": false
|
||||
},
|
||||
{
|
||||
"key": "maxToken",
|
||||
"type": "hidden",
|
||||
"label": "",
|
||||
"value": 2000,
|
||||
"valueType": "number",
|
||||
"min": 100,
|
||||
"max": 4000,
|
||||
"step": 50,
|
||||
"showTargetInApp": false,
|
||||
"showTargetInPlugin": false,
|
||||
"connected": false
|
||||
},
|
||||
{
|
||||
"key": "systemPrompt",
|
||||
"type": "textarea",
|
||||
"max": 3000,
|
||||
"valueType": "string",
|
||||
"label": "core.ai.Prompt",
|
||||
"description": "core.app.tip.chatNodeSystemPromptTip",
|
||||
"placeholder": "core.app.tip.chatNodeSystemPromptTip",
|
||||
"showTargetInApp": true,
|
||||
"showTargetInPlugin": true,
|
||||
"connected": false
|
||||
},
|
||||
{
|
||||
"key": "history",
|
||||
"type": "numberInput",
|
||||
"label": "core.module.input.label.chat history",
|
||||
"required": true,
|
||||
"min": 0,
|
||||
"max": 30,
|
||||
"valueType": "chatHistory",
|
||||
"value": 6,
|
||||
"showTargetInApp": true,
|
||||
"showTargetInPlugin": true,
|
||||
"connected": false
|
||||
},
|
||||
{
|
||||
"key": "userChatInput",
|
||||
"type": "custom",
|
||||
"label": "",
|
||||
"required": true,
|
||||
"valueType": "string",
|
||||
"showTargetInApp": true,
|
||||
"showTargetInPlugin": true,
|
||||
"connected": true
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"key": "userChatInput",
|
||||
"label": "core.module.input.label.user question",
|
||||
"type": "hidden",
|
||||
"valueType": "string",
|
||||
"targets": []
|
||||
},
|
||||
{
|
||||
"key": "selectedTools",
|
||||
"valueType": "tools",
|
||||
"type": "hidden",
|
||||
"targets": [
|
||||
{
|
||||
"nodeId": "3mbu91",
|
||||
"key": "selectedTools"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "finish",
|
||||
"label": "",
|
||||
"description": "",
|
||||
"valueType": "boolean",
|
||||
"type": "hidden",
|
||||
"targets": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nodeId": "3mbu91",
|
||||
"name": "HTTP 请求",
|
||||
"intro": "调用飞书webhook,发送一个通知",
|
||||
"avatar": "/imgs/workflow/http.png",
|
||||
"flowNodeType": "httpRequest468",
|
||||
"showStatus": true,
|
||||
"position": {
|
||||
"x": 1483.6437630977423,
|
||||
"y": 798.9716928475544
|
||||
},
|
||||
"inputs": [
|
||||
|
||||
{
|
||||
"key": "system_httpMethod",
|
||||
"type": "custom",
|
||||
"valueType": "string",
|
||||
"label": "",
|
||||
"value": "POST",
|
||||
"required": true,
|
||||
"showTargetInApp": false,
|
||||
"showTargetInPlugin": false,
|
||||
"connected": false
|
||||
},
|
||||
{
|
||||
"key": "system_httpReqUrl",
|
||||
"type": "hidden",
|
||||
"valueType": "string",
|
||||
"label": "",
|
||||
"description": "core.module.input.description.Http Request Url",
|
||||
"placeholder": "https://api.ai.com/getInventory",
|
||||
"required": false,
|
||||
"showTargetInApp": false,
|
||||
"showTargetInPlugin": false,
|
||||
"value": "这里填写你的飞书机器人地址",
|
||||
"connected": false
|
||||
},
|
||||
{
|
||||
"key": "system_httpHeader",
|
||||
"type": "custom",
|
||||
"valueType": "any",
|
||||
"value": [],
|
||||
"label": "",
|
||||
"description": "core.module.input.description.Http Request Header",
|
||||
"placeholder": "core.module.input.description.Http Request Header",
|
||||
"required": false,
|
||||
"showTargetInApp": false,
|
||||
"showTargetInPlugin": false,
|
||||
"connected": false
|
||||
},
|
||||
{
|
||||
"key": "system_httpParams",
|
||||
"type": "hidden",
|
||||
"valueType": "any",
|
||||
"value": [],
|
||||
"label": "",
|
||||
"required": false,
|
||||
"showTargetInApp": false,
|
||||
"showTargetInPlugin": false,
|
||||
"connected": false
|
||||
},
|
||||
{
|
||||
"key": "system_httpJsonBody",
|
||||
"type": "hidden",
|
||||
"valueType": "any",
|
||||
"value": "{\r\n \"msg_type\": \"text\",\r\n \"content\": {\r\n \"text\": \"{{text}}\"\r\n }\r\n}",
|
||||
"label": "",
|
||||
"required": false,
|
||||
"showTargetInApp": false,
|
||||
"showTargetInPlugin": false,
|
||||
"connected": false
|
||||
},
|
||||
{
|
||||
"key": "DYNAMIC_INPUT_KEY",
|
||||
"type": "target",
|
||||
"valueType": "any",
|
||||
"label": "core.workflow.inputType.dynamicTargetInput",
|
||||
"description": "core.module.input.description.dynamic input",
|
||||
"required": false,
|
||||
"showTargetInApp": false,
|
||||
"showTargetInPlugin": true,
|
||||
"hideInApp": true,
|
||||
"connected": false
|
||||
},
|
||||
{
|
||||
"key": "system_addInputParam",
|
||||
"type": "addInputParam",
|
||||
"valueType": "any",
|
||||
"label": "",
|
||||
"required": false,
|
||||
"showTargetInApp": false,
|
||||
"showTargetInPlugin": false,
|
||||
"editField": {
|
||||
"key": true,
|
||||
"description": true,
|
||||
"dataType": true
|
||||
},
|
||||
"defaultEditField": {
|
||||
"label": "",
|
||||
"key": "",
|
||||
"description": "",
|
||||
"inputType": "target",
|
||||
"valueType": "string"
|
||||
},
|
||||
"connected": false
|
||||
},
|
||||
{
|
||||
"valueType": "string",
|
||||
"type": "hidden",
|
||||
"key": "text",
|
||||
"label": "text",
|
||||
"toolDescription": "需要发送的通知内容",
|
||||
"required": true,
|
||||
"connected": false
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"key": "httpRawResponse",
|
||||
"label": "原始响应",
|
||||
"description": "HTTP请求的原始响应。只能接受字符串或JSON类型响应数据。",
|
||||
"valueType": "any",
|
||||
"type": "source",
|
||||
"targets": [
|
||||
{
|
||||
"nodeId": "rzx4mj",
|
||||
"key": "switch"
|
||||
},
|
||||
{
|
||||
"nodeId": "psdhs1",
|
||||
"key": "switch"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "system_addOutputParam",
|
||||
"type": "addOutputParam",
|
||||
"valueType": "any",
|
||||
"label": "",
|
||||
"targets": [],
|
||||
"editField": {
|
||||
"key": true,
|
||||
"description": true,
|
||||
"dataType": true,
|
||||
"defaultValue": true
|
||||
},
|
||||
"defaultEditField": {
|
||||
"label": "",
|
||||
"key": "",
|
||||
"description": "",
|
||||
"outputType": "source",
|
||||
"valueType": "string"
|
||||
"version": "481",
|
||||
"inputs": [
|
||||
{
|
||||
"key": "userChatInput",
|
||||
"renderTypeList": [
|
||||
"reference",
|
||||
"textarea"
|
||||
],
|
||||
"valueType": "string",
|
||||
"label": "用户问题",
|
||||
"required": true,
|
||||
"toolDescription": "用户问题"
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"id": "userChatInput",
|
||||
"key": "userChatInput",
|
||||
"label": "core.module.input.label.user question",
|
||||
"valueType": "string",
|
||||
"type": "static"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nodeId": "u6IAOEssxoZT",
|
||||
"name": "工具调用(实验)",
|
||||
"intro": "通过AI模型自动选择一个或多个功能块进行调用,也可以对插件进行调用。",
|
||||
"avatar": "/imgs/workflow/tool.svg",
|
||||
"flowNodeType": "tools",
|
||||
"showStatus": true,
|
||||
"position": {
|
||||
"x": 1003.146243538873,
|
||||
"y": 48.52327869406625
|
||||
},
|
||||
{
|
||||
"type": "source",
|
||||
"valueType": "string",
|
||||
"key": "prompt",
|
||||
"label": "prompt",
|
||||
"description": "",
|
||||
"required": false,
|
||||
"edit": true,
|
||||
"editField": {
|
||||
"key": true,
|
||||
"description": true,
|
||||
"dataType": true,
|
||||
"defaultValue": true
|
||||
"version": "481",
|
||||
"inputs": [
|
||||
{
|
||||
"key": "model",
|
||||
"renderTypeList": [
|
||||
"settingLLMModel",
|
||||
"reference"
|
||||
],
|
||||
"label": "core.module.input.label.aiModel",
|
||||
"valueType": "string",
|
||||
"llmModelType": "all",
|
||||
"value": "gpt-3.5-turbo"
|
||||
},
|
||||
"targets": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nodeId": "rzx4mj",
|
||||
"name": "工具调用终止",
|
||||
"intro": "该模块需配置工具调用使用。当该模块被执行时,本次工具调用将会强制结束,并且不再调用AI针对工具调用结果回答问题。",
|
||||
"avatar": "/imgs/workflow/toolStop.svg",
|
||||
"flowNodeType": "stopTool",
|
||||
"position": {
|
||||
"x": 2145.5070710160267,
|
||||
"y": 1306.3581817783079
|
||||
{
|
||||
"key": "temperature",
|
||||
"renderTypeList": [
|
||||
"hidden"
|
||||
],
|
||||
"label": "",
|
||||
"value": 0,
|
||||
"valueType": "number",
|
||||
"min": 0,
|
||||
"max": 10,
|
||||
"step": 1
|
||||
},
|
||||
{
|
||||
"key": "maxToken",
|
||||
"renderTypeList": [
|
||||
"hidden"
|
||||
],
|
||||
"label": "",
|
||||
"value": 2000,
|
||||
"valueType": "number",
|
||||
"min": 100,
|
||||
"max": 4000,
|
||||
"step": 50
|
||||
},
|
||||
{
|
||||
"key": "systemPrompt",
|
||||
"renderTypeList": [
|
||||
"textarea",
|
||||
"reference"
|
||||
],
|
||||
"max": 3000,
|
||||
"valueType": "string",
|
||||
"label": "core.ai.Prompt",
|
||||
"description": "core.app.tip.chatNodeSystemPromptTip",
|
||||
"placeholder": "core.app.tip.chatNodeSystemPromptTip"
|
||||
},
|
||||
{
|
||||
"key": "history",
|
||||
"renderTypeList": [
|
||||
"numberInput",
|
||||
"reference"
|
||||
],
|
||||
"valueType": "chatHistory",
|
||||
"label": "core.module.input.label.chat history",
|
||||
"description": "最多携带多少轮对话记录",
|
||||
"required": true,
|
||||
"min": 0,
|
||||
"max": 50,
|
||||
"value": 6
|
||||
},
|
||||
{
|
||||
"key": "userChatInput",
|
||||
"renderTypeList": [
|
||||
"reference",
|
||||
"textarea"
|
||||
],
|
||||
"valueType": "string",
|
||||
"label": "用户问题",
|
||||
"required": true,
|
||||
"value": [
|
||||
"workflowStartNodeId",
|
||||
"userChatInput"
|
||||
]
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"id": "answerText",
|
||||
"key": "answerText",
|
||||
"label": "core.module.output.label.Ai response content",
|
||||
"description": "core.module.output.description.Ai response content",
|
||||
"valueType": "string",
|
||||
"type": "static"
|
||||
}
|
||||
]
|
||||
},
|
||||
"inputs": [
|
||||
{
|
||||
"key": "switch",
|
||||
"type": "triggerAndFinish",
|
||||
"label": "",
|
||||
"description": "core.module.input.description.Trigger",
|
||||
"valueType": "any",
|
||||
"showTargetInApp": true,
|
||||
"showTargetInPlugin": true,
|
||||
"connected": true
|
||||
}
|
||||
],
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"nodeId": "psdhs1",
|
||||
"name": "指定回复",
|
||||
"intro": "该模块可以直接回复一段指定的内容。常用于引导、提示。非字符串内容传入时,会转成字符串进行输出。",
|
||||
"avatar": "/imgs/workflow/reply.png",
|
||||
"flowNodeType": "answerNode",
|
||||
"position": {
|
||||
"x": 2117.0429459850598,
|
||||
"y": 1658.4125434513746
|
||||
},
|
||||
"inputs": [
|
||||
{
|
||||
"key": "switch",
|
||||
"type": "triggerAndFinish",
|
||||
"label": "",
|
||||
"description": "core.module.input.description.Trigger",
|
||||
"valueType": "any",
|
||||
"showTargetInApp": true,
|
||||
"showTargetInPlugin": true,
|
||||
"connected": true
|
||||
{
|
||||
"nodeId": "fvY5hb0K646V",
|
||||
"name": "工具调用终止",
|
||||
"intro": "该模块需配置工具调用使用。当该模块被执行时,本次工具调用将会强制结束,并且不再调用AI针对工具调用结果回答问题。",
|
||||
"avatar": "/imgs/workflow/toolStop.svg",
|
||||
"flowNodeType": "stopTool",
|
||||
"position": {
|
||||
"x": 2367.838362362707,
|
||||
"y": 732.355988936165
|
||||
},
|
||||
"version": "481",
|
||||
"inputs": [],
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"nodeId": "x9rN2a4WnZmt",
|
||||
"name": "HTTP 请求",
|
||||
"intro": "向飞书发送一个webhooks通知信息。",
|
||||
"avatar": "/imgs/workflow/http.png",
|
||||
"flowNodeType": "httpRequest468",
|
||||
"showStatus": true,
|
||||
"position": {
|
||||
"x": 1623.9214305901633,
|
||||
"y": 22.777089001645862
|
||||
},
|
||||
"version": "481",
|
||||
"inputs": [
|
||||
{
|
||||
"key": "system_addInputParam",
|
||||
"renderTypeList": [
|
||||
"addInputParam"
|
||||
],
|
||||
"valueType": "dynamic",
|
||||
"label": "",
|
||||
"required": false,
|
||||
"description": "core.module.input.description.HTTP Dynamic Input",
|
||||
"editField": {
|
||||
"key": true,
|
||||
"valueType": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"valueType": "string",
|
||||
"renderTypeList": [
|
||||
"reference"
|
||||
],
|
||||
"key": "text",
|
||||
"label": "text",
|
||||
"toolDescription": "发送的消息",
|
||||
"required": true,
|
||||
"canEdit": true,
|
||||
"editField": {
|
||||
"key": true,
|
||||
"description": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"key": "system_httpMethod",
|
||||
"renderTypeList": [
|
||||
"custom"
|
||||
],
|
||||
"valueType": "string",
|
||||
"label": "",
|
||||
"value": "POST",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"key": "system_httpReqUrl",
|
||||
"renderTypeList": [
|
||||
"hidden"
|
||||
],
|
||||
"valueType": "string",
|
||||
"label": "",
|
||||
"description": "core.module.input.description.Http Request Url",
|
||||
"placeholder": "https://api.ai.com/getInventory",
|
||||
"required": false,
|
||||
"value": ""
|
||||
},
|
||||
{
|
||||
"key": "system_httpHeader",
|
||||
"renderTypeList": [
|
||||
"custom"
|
||||
],
|
||||
"valueType": "any",
|
||||
"value": [],
|
||||
"label": "",
|
||||
"description": "core.module.input.description.Http Request Header",
|
||||
"placeholder": "core.module.input.description.Http Request Header",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"key": "system_httpParams",
|
||||
"renderTypeList": [
|
||||
"hidden"
|
||||
],
|
||||
"valueType": "any",
|
||||
"value": [],
|
||||
"label": "",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"key": "system_httpJsonBody",
|
||||
"renderTypeList": [
|
||||
"hidden"
|
||||
],
|
||||
"valueType": "any",
|
||||
"value": "{\r\n \"msg_type\": \"text\",\r\n \"content\": {\r\n \"text\": \"{{text}}\"\r\n }\r\n}",
|
||||
"label": "",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"id": "system_addOutputParam",
|
||||
"key": "system_addOutputParam",
|
||||
"type": "dynamic",
|
||||
"valueType": "dynamic",
|
||||
"label": "",
|
||||
"editField": {
|
||||
"key": true,
|
||||
"valueType": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "error",
|
||||
"key": "error",
|
||||
"label": "请求错误",
|
||||
"description": "HTTP请求错误信息,成功时返回空",
|
||||
"valueType": "object",
|
||||
"type": "static"
|
||||
},
|
||||
{
|
||||
"id": "httpRawResponse",
|
||||
"key": "httpRawResponse",
|
||||
"label": "原始响应",
|
||||
"required": true,
|
||||
"description": "HTTP请求的原始响应。只能接受字符串或JSON类型响应数据。",
|
||||
"valueType": "any",
|
||||
"type": "static"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nodeId": "aGHGqH2oUupj",
|
||||
"name": "指定回复",
|
||||
"intro": "该模块可以直接回复一段指定的内容。常用于引导、提示。非字符串内容传入时,会转成字符串进行输出。",
|
||||
"avatar": "/imgs/workflow/reply.png",
|
||||
"flowNodeType": "answerNode",
|
||||
"position": {
|
||||
"x": 2350.7077940158674,
|
||||
"y": 107.32448732713493
|
||||
},
|
||||
"version": "481",
|
||||
"inputs": [
|
||||
{
|
||||
"key": "text",
|
||||
"renderTypeList": [
|
||||
"textarea",
|
||||
"reference"
|
||||
],
|
||||
"valueType": "any",
|
||||
"required": true,
|
||||
"label": "core.module.input.label.Response content",
|
||||
"description": "core.module.input.description.Response content",
|
||||
"placeholder": "core.module.input.description.Response content",
|
||||
"value": "嘻嘻,发送成功"
|
||||
}
|
||||
],
|
||||
"outputs": []
|
||||
}
|
||||
],
|
||||
"edges": [
|
||||
{
|
||||
"source": "workflowStartNodeId",
|
||||
"target": "u6IAOEssxoZT",
|
||||
"sourceHandle": "workflowStartNodeId-source-right",
|
||||
"targetHandle": "u6IAOEssxoZT-target-left"
|
||||
},
|
||||
{
|
||||
"source": "u6IAOEssxoZT",
|
||||
"target": "x9rN2a4WnZmt",
|
||||
"sourceHandle": "selectedTools",
|
||||
"targetHandle": "selectedTools"
|
||||
},
|
||||
{
|
||||
"source": "x9rN2a4WnZmt",
|
||||
"target": "fvY5hb0K646V",
|
||||
"sourceHandle": "x9rN2a4WnZmt-source-right",
|
||||
"targetHandle": "fvY5hb0K646V-target-left"
|
||||
},
|
||||
{
|
||||
"source": "x9rN2a4WnZmt",
|
||||
"target": "aGHGqH2oUupj",
|
||||
"sourceHandle": "x9rN2a4WnZmt-source-right",
|
||||
"targetHandle": "aGHGqH2oUupj-target-left"
|
||||
}
|
||||
],
|
||||
"chatConfig": {
|
||||
"variables": [
|
||||
{
|
||||
"key": "text",
|
||||
"type": "textarea",
|
||||
"valueType": "any",
|
||||
"label": "core.module.input.label.Response content",
|
||||
"description": "core.module.input.description.Response content",
|
||||
"placeholder": "core.module.input.description.Response content",
|
||||
"showTargetInApp": true,
|
||||
"showTargetInPlugin": true,
|
||||
"value": "笑死发送成功啦",
|
||||
"connected": false
|
||||
"id": "txq1ca",
|
||||
"key": "test",
|
||||
"label": "测试",
|
||||
"type": "custom",
|
||||
"required": true,
|
||||
"maxLen": 50,
|
||||
"enums": [
|
||||
{
|
||||
"value": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"key": "finish",
|
||||
"label": "",
|
||||
"description": "",
|
||||
"valueType": "boolean",
|
||||
"type": "hidden",
|
||||
"targets": []
|
||||
}
|
||||
]
|
||||
"questionGuide": false,
|
||||
"scheduledTriggerConfig": {
|
||||
"cronString": "",
|
||||
"timezone": "Asia/Shanghai",
|
||||
"defaultPrompt": ""
|
||||
},
|
||||
"_id": "66715d4bf577287d39e35ecf"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
{{% /details %}}
|
||||
|
||||
@@ -9,7 +9,7 @@ weight: 301
|
||||
|
||||
FastGPT 从 V4 版本开始采用新的交互方式来构建 AI 应用。使用了 Flow 节点编排(工作流)的方式来实现复杂工作流,提高可玩性和扩展性。但同时也提高了上手的门槛,有一定开发背景的用户使用起来会比较容易。
|
||||
|
||||
[查看视频教程](https://www.bilibili.com/video/BV1aB4y1Z7Hy/?spm_id_from=333.999.list.card_archive.click&vd_source=903c2b09b7412037c2eddc6a8fb9828b)
|
||||
[查看视频教程](https://www.bilibili.com/video/BV1is421u7bQ/)
|
||||
|
||||

|
||||
|
||||
|
||||
@@ -161,7 +161,8 @@ services:
|
||||
|
||||
# oneapi
|
||||
mysql:
|
||||
image: mysql:8.0.36
|
||||
image: registry.cn-hangzhou.aliyuncs.com/fastgpt/mysql:8.0.36 # 阿里云
|
||||
# image: mysql:8.0.36
|
||||
container_name: mysql
|
||||
restart: always
|
||||
ports:
|
||||
@@ -178,6 +179,7 @@ services:
|
||||
oneapi:
|
||||
container_name: oneapi
|
||||
image: ghcr.io/songquanpeng/one-api:latest
|
||||
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/one-api:v0.6.6 # 阿里云
|
||||
ports:
|
||||
- 3001:3000
|
||||
depends_on:
|
||||
|
||||
@@ -118,7 +118,8 @@ services:
|
||||
|
||||
# oneapi
|
||||
mysql:
|
||||
image: mysql:8.0.36
|
||||
image: registry.cn-hangzhou.aliyuncs.com/fastgpt/mysql:8.0.36 # 阿里云
|
||||
# image: mysql:8.0.36
|
||||
container_name: mysql
|
||||
restart: always
|
||||
ports:
|
||||
@@ -135,6 +136,7 @@ services:
|
||||
oneapi:
|
||||
container_name: oneapi
|
||||
image: ghcr.io/songquanpeng/one-api:latest
|
||||
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/one-api:v0.6.6 # 阿里云
|
||||
ports:
|
||||
- 3001:3000
|
||||
depends_on:
|
||||
|
||||
@@ -99,7 +99,8 @@ services:
|
||||
|
||||
# oneapi
|
||||
mysql:
|
||||
image: mysql:8.0.36
|
||||
image: registry.cn-hangzhou.aliyuncs.com/fastgpt/mysql:8.0.36 # 阿里云
|
||||
# image: mysql:8.0.36
|
||||
container_name: mysql
|
||||
restart: always
|
||||
ports:
|
||||
@@ -116,6 +117,7 @@ services:
|
||||
oneapi:
|
||||
container_name: oneapi
|
||||
image: ghcr.io/songquanpeng/one-api:latest
|
||||
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/one-api:v0.6.6 # 阿里云
|
||||
ports:
|
||||
- 3001:3000
|
||||
depends_on:
|
||||
|
||||
10
package.json
@@ -15,17 +15,11 @@
|
||||
"@chakra-ui/cli": "^2.4.1",
|
||||
"husky": "^8.0.3",
|
||||
"i18next": "23.10.0",
|
||||
"lint-staged": "^13.2.1",
|
||||
"lint-staged": "^13.3.0",
|
||||
"next-i18next": "15.2.0",
|
||||
"prettier": "3.2.4",
|
||||
"react-i18next": "13.5.0",
|
||||
"zhlint": "^0.7.1"
|
||||
},
|
||||
"resolutions": {
|
||||
"react": "18.3.1",
|
||||
"react-dom": "18.3.1",
|
||||
"@types/react": "18.3.0",
|
||||
"@types/react-dom": "18.3.0"
|
||||
"zhlint": "^0.7.4"
|
||||
},
|
||||
"lint-staged": {
|
||||
"./**/**/*.{ts,tsx,scss}": "npm run format-code",
|
||||
|
||||
@@ -4,7 +4,8 @@ import { ErrType } from '../errorCode';
|
||||
const startCode = 507000;
|
||||
export enum CommonErrEnum {
|
||||
fileNotFound = 'fileNotFound',
|
||||
unAuthFile = 'unAuthFile'
|
||||
unAuthFile = 'unAuthFile',
|
||||
missingParams = 'missingParams'
|
||||
}
|
||||
const datasetErr = [
|
||||
{
|
||||
@@ -14,6 +15,10 @@ const datasetErr = [
|
||||
{
|
||||
statusText: CommonErrEnum.unAuthFile,
|
||||
message: 'error.unAuthFile'
|
||||
},
|
||||
{
|
||||
statusText: CommonErrEnum.missingParams,
|
||||
message: 'error.missingParams'
|
||||
}
|
||||
];
|
||||
export default datasetErr.reduce((acc, cur, index) => {
|
||||
|
||||
@@ -2,6 +2,7 @@ import { ErrType } from '../errorCode';
|
||||
|
||||
/* dataset: 501000 */
|
||||
export enum DatasetErrEnum {
|
||||
unExist = 'unExistDataset',
|
||||
unAuthDataset = 'unAuthDataset',
|
||||
unCreateCollection = 'unCreateCollection',
|
||||
unAuthDatasetCollection = 'unAuthDatasetCollection',
|
||||
@@ -11,6 +12,10 @@ export enum DatasetErrEnum {
|
||||
unLinkCollection = 'unLinkCollection'
|
||||
}
|
||||
const datasetErr = [
|
||||
{
|
||||
statusText: DatasetErrEnum.unExist,
|
||||
message: 'core.dataset.error.unExistDataset'
|
||||
},
|
||||
{
|
||||
statusText: DatasetErrEnum.unAuthDataset,
|
||||
message: 'core.dataset.error.unAuthDataset'
|
||||
|
||||
@@ -53,4 +53,5 @@ export const uniqueImageTypeList = Object.entries(mongoImageTypeMap)
|
||||
|
||||
export const FolderIcon = 'file/fill/folder';
|
||||
export const FolderImgUrl = '/imgs/files/folder.svg';
|
||||
export const HttpPluginImgUrl = '/imgs/app/httpPluginFill.svg';
|
||||
export const HttpImgUrl = '/imgs/workflow/http.png';
|
||||
|
||||
@@ -350,7 +350,7 @@ export const splitText2Chunks = (props: SplitProps): SplitResponse => {
|
||||
|
||||
return commonSplit(props);
|
||||
});
|
||||
console.log(Date.now() - start);
|
||||
|
||||
return {
|
||||
chunks: splitResult.map((item) => item.chunks).flat(),
|
||||
chars: splitResult.reduce((sum, item) => sum + item.chars, 0)
|
||||
|
||||
@@ -67,6 +67,14 @@ export const getNanoid = (size = 12) => {
|
||||
/* Custom text to reg, need to replace special chats */
|
||||
export const replaceRegChars = (text: string) => text.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
||||
|
||||
export const getRegQueryStr = (text: string, flags = 'i') => {
|
||||
const formatText = replaceRegChars(text);
|
||||
const chars = formatText.split('');
|
||||
const regexPattern = chars.join('.*');
|
||||
|
||||
return new RegExp(regexPattern, flags);
|
||||
};
|
||||
|
||||
/* slice json str */
|
||||
export const sliceJsonStr = (str: string) => {
|
||||
str = str.replace(/(\\n|\\)/g, '').replace(/ /g, '');
|
||||
|
||||
@@ -3,19 +3,10 @@ import { AppTTSConfigType, AppWhisperConfigType } from './type';
|
||||
export enum AppTypeEnum {
|
||||
folder = 'folder',
|
||||
simple = 'simple',
|
||||
advanced = 'advanced'
|
||||
workflow = 'advanced',
|
||||
plugin = 'plugin',
|
||||
httpPlugin = 'httpPlugin'
|
||||
}
|
||||
export const AppTypeMap = {
|
||||
[AppTypeEnum.folder]: {
|
||||
label: 'folder'
|
||||
},
|
||||
[AppTypeEnum.simple]: {
|
||||
label: 'simple'
|
||||
},
|
||||
[AppTypeEnum.advanced]: {
|
||||
label: 'advanced'
|
||||
}
|
||||
};
|
||||
|
||||
export const defaultTTSConfig: AppTTSConfigType = { type: 'web' };
|
||||
|
||||
|
||||
24
packages/global/core/app/controller.d.ts
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
import { ParentIdType } from 'common/parentFolder/type';
|
||||
import { AppSchema } from './type';
|
||||
import { AppTypeEnum } from './constants';
|
||||
|
||||
export type CreateAppProps = {
|
||||
parentId?: ParentIdType;
|
||||
name?: string;
|
||||
avatar?: string;
|
||||
intro?: string;
|
||||
type?: AppTypeEnum;
|
||||
modules: AppSchema['modules'];
|
||||
edges?: AppSchema['edges'];
|
||||
};
|
||||
export type CreateHttpPluginChildrenPros = Omit<CreateAppProps, 'type'> & {
|
||||
parentId: ParentIdType;
|
||||
name: string;
|
||||
intro: string;
|
||||
avatar: string;
|
||||
modules: AppSchema['modules'];
|
||||
edges: AppSchema['edges'];
|
||||
pluginData: {
|
||||
pluginUniId: string;
|
||||
};
|
||||
};
|
||||
@@ -2,19 +2,20 @@ import { getNanoid } from '../../../common/string/tools';
|
||||
import { OpenApiJsonSchema } from './type';
|
||||
import yaml from 'js-yaml';
|
||||
import { OpenAPIV3 } from 'openapi-types';
|
||||
import { PluginTypeEnum } from '../constants';
|
||||
import { FlowNodeInputItemType, FlowNodeOutputItemType } from '../../workflow/type/io.d';
|
||||
import { FlowNodeInputItemType, FlowNodeOutputItemType } from '../../workflow/type/io';
|
||||
import { FlowNodeInputTypeEnum, FlowNodeOutputTypeEnum } from '../../workflow/node/constant';
|
||||
import { NodeInputKeyEnum, WorkflowIOValueTypeEnum } from '../../workflow/constants';
|
||||
import { PluginInputModule } from '../../workflow/template/system/pluginInput';
|
||||
import { PluginOutputModule } from '../../workflow/template/system/pluginOutput';
|
||||
import { HttpModule468 } from '../../workflow/template/system/http468';
|
||||
import { HttpParamAndHeaderItemType } from '../../workflow/api';
|
||||
import { CreateOnePluginParams } from '../controller';
|
||||
import { StoreNodeItemType } from '../../workflow/type';
|
||||
import { HttpImgUrl } from '../../../common/file/image/constants';
|
||||
import SwaggerParser from '@apidevtools/swagger-parser';
|
||||
import { getHandleId } from '../../../core/workflow/utils';
|
||||
import { getHandleId } from '../../workflow/utils';
|
||||
import { CreateHttpPluginChildrenPros } from '../controller';
|
||||
import { AppTypeEnum } from '../constants';
|
||||
import type { StoreEdgeItemType } from '../../workflow/type/edge';
|
||||
|
||||
export const str2OpenApiSchema = async (yamlStr = ''): Promise<OpenApiJsonSchema> => {
|
||||
try {
|
||||
@@ -89,7 +90,7 @@ export const httpApiSchema2Plugins = async ({
|
||||
parentId: string;
|
||||
apiSchemaStr?: string;
|
||||
customHeader?: string;
|
||||
}): Promise<CreateOnePluginParams[]> => {
|
||||
}): Promise<CreateHttpPluginChildrenPros[]> => {
|
||||
const jsonSchema = await str2OpenApiSchema(apiSchemaStr);
|
||||
|
||||
const baseUrl = jsonSchema.serverPath;
|
||||
@@ -400,7 +401,7 @@ export const httpApiSchema2Plugins = async ({
|
||||
}
|
||||
];
|
||||
|
||||
const edges = [
|
||||
const edges: StoreEdgeItemType[] = [
|
||||
{
|
||||
source: pluginInputId,
|
||||
target: httpId,
|
||||
@@ -420,9 +421,12 @@ export const httpApiSchema2Plugins = async ({
|
||||
avatar: HttpImgUrl,
|
||||
intro: item.description,
|
||||
parentId,
|
||||
type: PluginTypeEnum.http,
|
||||
type: AppTypeEnum.plugin,
|
||||
modules,
|
||||
edges
|
||||
edges,
|
||||
pluginData: {
|
||||
pluginUniId: item.name
|
||||
}
|
||||
};
|
||||
});
|
||||
};
|
||||
11
packages/global/core/app/type.d.ts
vendored
@@ -21,10 +21,16 @@ export type AppSchema = {
|
||||
name: string;
|
||||
avatar: string;
|
||||
intro: string;
|
||||
updateTime: number;
|
||||
updateTime: Date;
|
||||
|
||||
modules: StoreNodeItemType[];
|
||||
edges: StoreEdgeItemType[];
|
||||
pluginData?: {
|
||||
nodeVersion?: string;
|
||||
pluginUniId?: string; // plugin unique id(plugin name)
|
||||
apiSchemaStr?: string; // api schema string
|
||||
customHeaders?: string;
|
||||
};
|
||||
|
||||
// App system config
|
||||
chatConfig: AppChatConfigType;
|
||||
@@ -38,12 +44,15 @@ export type AppSchema = {
|
||||
|
||||
export type AppListItemType = {
|
||||
_id: string;
|
||||
tmbId: string;
|
||||
name: string;
|
||||
avatar: string;
|
||||
intro: string;
|
||||
type: AppTypeEnum;
|
||||
updateTime: Date;
|
||||
defaultPermission: PermissionValueType;
|
||||
permission: AppPermission;
|
||||
pluginData?: AppSchema['pluginData'];
|
||||
};
|
||||
|
||||
export type AppDetailType = AppSchema & {
|
||||
|
||||
@@ -99,7 +99,7 @@ export const appWorkflow2Form = ({
|
||||
if (!node.pluginId) return;
|
||||
|
||||
defaultAppForm.selectedTools.push({
|
||||
id: node.pluginId,
|
||||
id: node.nodeId,
|
||||
pluginId: node.pluginId,
|
||||
name: node.name,
|
||||
avatar: node.avatar,
|
||||
|
||||
8
packages/global/core/app/version.d.ts
vendored
@@ -1,12 +1,12 @@
|
||||
import { StoreNodeItemType } from '../workflow/type';
|
||||
import { StoreEdgeItemType } from '../workflow/type/edge';
|
||||
import { AppChatConfigType } from './type';
|
||||
import { AppChatConfigType, AppSchema } from './type';
|
||||
|
||||
export type AppVersionSchemaType = {
|
||||
_id: string;
|
||||
appId: string;
|
||||
time: Date;
|
||||
nodes: StoreNodeItemType[];
|
||||
edges: StoreEdgeItemType[];
|
||||
chatConfig: AppChatConfigType;
|
||||
nodes: AppSchema['modules'];
|
||||
edges: AppSchema['edges'];
|
||||
chatConfig: AppSchema['chatConfig'];
|
||||
};
|
||||
|
||||
6
packages/global/core/dataset/api.d.ts
vendored
@@ -1,20 +1,22 @@
|
||||
import { DatasetDataIndexItemType, DatasetSchemaType } from './type';
|
||||
import { TrainingModeEnum, DatasetCollectionTypeEnum } from './constants';
|
||||
import type { LLMModelItemType } from '../ai/model.d';
|
||||
import { ParentIdType } from 'common/parentFolder/type';
|
||||
|
||||
/* ================= dataset ===================== */
|
||||
export type DatasetUpdateBody = {
|
||||
id: string;
|
||||
parentId?: string;
|
||||
parentId?: ParentIdType;
|
||||
name?: string;
|
||||
avatar?: string;
|
||||
intro?: string;
|
||||
permission?: DatasetSchemaType['permission'];
|
||||
permission?: DatasetSchemaType['permission']; // TODO: Should be deleted.
|
||||
agentModel?: LLMModelItemType;
|
||||
status?: DatasetSchemaType['status'];
|
||||
|
||||
websiteConfig?: DatasetSchemaType['websiteConfig'];
|
||||
externalReadUrl?: DatasetSchemaType['externalReadUrl'];
|
||||
defaultPermission?: DatasetSchemaType['defaultPermission'];
|
||||
};
|
||||
|
||||
/* ================= collection ===================== */
|
||||
|
||||
11
packages/global/core/dataset/collaborator.d.ts
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
import { UpdateClbPermissionProps } from '../../support/permission/collaborator';
|
||||
import { PermissionValueType } from '../../support/permission/type';
|
||||
|
||||
export type UpdateDatasetCollaboratorBody = UpdateClbPermissionProps & {
|
||||
datasetId: string;
|
||||
};
|
||||
|
||||
export type DatasetCollaboratorDeleteParams = {
|
||||
datasetId: string;
|
||||
tmbId: string;
|
||||
};
|
||||
19
packages/global/core/dataset/type.d.ts
vendored
@@ -1,3 +1,4 @@
|
||||
import { PermissionValueType } from 'support/permission/type';
|
||||
import type { LLMModelItemType, VectorModelItemType } from '../../core/ai/model.d';
|
||||
import { PermissionTypeEnum } from '../../support/permission/constant';
|
||||
import { PushDatasetDataChunkProps } from './api';
|
||||
@@ -8,6 +9,8 @@ import {
|
||||
SearchScoreTypeEnum,
|
||||
TrainingModeEnum
|
||||
} from './constants';
|
||||
import { DatasetPermission } from '../../support/permission/dataset/controller';
|
||||
import { Permission } from '../../support/permission/controller';
|
||||
|
||||
/* schema */
|
||||
export type DatasetSchemaType = {
|
||||
@@ -24,7 +27,7 @@ export type DatasetSchemaType = {
|
||||
intro: string;
|
||||
type: DatasetTypeEnum;
|
||||
status: `${DatasetStatusEnum}`;
|
||||
permission: `${PermissionTypeEnum}`;
|
||||
permission: DatasetPermission;
|
||||
|
||||
// metadata
|
||||
websiteConfig?: {
|
||||
@@ -32,6 +35,7 @@ export type DatasetSchemaType = {
|
||||
selector: string;
|
||||
};
|
||||
externalReadUrl?: string;
|
||||
defaultPermission: PermissionValueType;
|
||||
};
|
||||
|
||||
export type DatasetCollectionSchemaType = {
|
||||
@@ -132,24 +136,22 @@ export type DatasetListItemType = {
|
||||
name: string;
|
||||
intro: string;
|
||||
type: DatasetTypeEnum;
|
||||
isOwner: boolean;
|
||||
canWrite: boolean;
|
||||
permission: `${PermissionTypeEnum}`;
|
||||
permission: DatasetPermission;
|
||||
vectorModel: VectorModelItemType;
|
||||
defaultPermission: PermissionValueType;
|
||||
};
|
||||
|
||||
export type DatasetItemType = Omit<DatasetSchemaType, 'vectorModel' | 'agentModel'> & {
|
||||
vectorModel: VectorModelItemType;
|
||||
agentModel: LLMModelItemType;
|
||||
isOwner: boolean;
|
||||
canWrite: boolean;
|
||||
};
|
||||
|
||||
/* ================= collection ===================== */
|
||||
export type DatasetCollectionItemType = CollectionWithDatasetType & {
|
||||
canWrite: boolean;
|
||||
sourceName: string;
|
||||
sourceId?: string;
|
||||
file?: DatasetFileSchema;
|
||||
permission: DatasetPermission;
|
||||
};
|
||||
|
||||
/* ================= data ===================== */
|
||||
@@ -177,10 +179,9 @@ export type DatasetFileSchema = {
|
||||
filename: string;
|
||||
contentType: string;
|
||||
metadata: {
|
||||
contentType: string;
|
||||
datasetId: string;
|
||||
teamId: string;
|
||||
tmbId: string;
|
||||
encoding?: string;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -24,13 +24,15 @@ export function getSourceNameIcon({
|
||||
sourceName: string;
|
||||
sourceId?: string;
|
||||
}) {
|
||||
const fileIcon = getFileIcon(decodeURIComponent(sourceName), '');
|
||||
if (fileIcon) {
|
||||
return fileIcon;
|
||||
}
|
||||
if (strIsLink(sourceId)) {
|
||||
return 'common/linkBlue';
|
||||
}
|
||||
try {
|
||||
const fileIcon = getFileIcon(decodeURIComponent(sourceName.replace(/%/g, '%25')), '');
|
||||
if (fileIcon) {
|
||||
return fileIcon;
|
||||
}
|
||||
if (strIsLink(sourceId)) {
|
||||
return 'common/linkBlue';
|
||||
}
|
||||
} catch (error) {}
|
||||
|
||||
return 'file/fill/manual';
|
||||
}
|
||||
|
||||
2
packages/global/core/plugin/controller.d.ts
vendored
@@ -1,7 +1,7 @@
|
||||
import { StoreEdgeItemType } from 'core/workflow/type/edge';
|
||||
import type { StoreNodeItemType } from '../workflow/type';
|
||||
import { PluginTypeEnum } from './constants';
|
||||
import { HttpAuthMethodType } from './httpPlugin/type';
|
||||
import { HttpAuthMethodType } from '../app/httpPlugin/type';
|
||||
|
||||
export type CreateOnePluginParams = {
|
||||
name: string;
|
||||
|
||||
3
packages/global/core/plugin/type.d.ts
vendored
@@ -24,6 +24,7 @@ export type PluginItemSchema = {
|
||||
};
|
||||
version?: 'v1' | 'v2';
|
||||
nodeVersion?: string;
|
||||
inited?: boolean;
|
||||
};
|
||||
|
||||
/* plugin template */
|
||||
@@ -33,7 +34,7 @@ export type PluginTemplateType = PluginRuntimeType & {
|
||||
source: `${PluginSourceEnum}`;
|
||||
templateType: FlowNodeTemplateType['templateType'];
|
||||
intro: string;
|
||||
nodeVersion: string;
|
||||
version: string;
|
||||
};
|
||||
|
||||
export type PluginRuntimeType = {
|
||||
|
||||
@@ -118,3 +118,4 @@ export enum FlowNodeTypeEnum {
|
||||
}
|
||||
|
||||
export const EDGE_TYPE = 'default';
|
||||
export const defaultNodeVersion = '481';
|
||||
|
||||
@@ -24,10 +24,7 @@ import { IfElseNode } from './system/ifElse/index';
|
||||
import { VariableUpdateNode } from './system/variableUpdate';
|
||||
import { CodeNode } from './system/sandbox';
|
||||
|
||||
/* app flow module templates */
|
||||
export const appSystemModuleTemplates: FlowNodeTemplateType[] = [
|
||||
SystemConfigNode,
|
||||
WorkflowStart,
|
||||
const systemNodes: FlowNodeTemplateType[] = [
|
||||
AiChatModule,
|
||||
AssignedAnswerModule,
|
||||
DatasetSearchModule,
|
||||
@@ -44,49 +41,26 @@ export const appSystemModuleTemplates: FlowNodeTemplateType[] = [
|
||||
VariableUpdateNode,
|
||||
CodeNode
|
||||
];
|
||||
/* app flow module templates */
|
||||
export const appSystemModuleTemplates: FlowNodeTemplateType[] = [
|
||||
SystemConfigNode,
|
||||
WorkflowStart,
|
||||
...systemNodes
|
||||
];
|
||||
/* plugin flow module templates */
|
||||
export const pluginSystemModuleTemplates: FlowNodeTemplateType[] = [
|
||||
PluginInputModule,
|
||||
PluginOutputModule,
|
||||
AiChatModule,
|
||||
AssignedAnswerModule,
|
||||
DatasetSearchModule,
|
||||
DatasetConcatModule,
|
||||
RunAppModule,
|
||||
ToolModule,
|
||||
StopToolNode,
|
||||
ClassifyQuestionModule,
|
||||
ContextExtractModule,
|
||||
HttpModule468,
|
||||
AiQueryExtension,
|
||||
LafModule,
|
||||
IfElseNode,
|
||||
VariableUpdateNode,
|
||||
CodeNode
|
||||
...systemNodes
|
||||
];
|
||||
|
||||
/* all module */
|
||||
export const moduleTemplatesFlat: FlowNodeTemplateType[] = [
|
||||
...systemNodes,
|
||||
EmptyNode,
|
||||
SystemConfigNode,
|
||||
WorkflowStart,
|
||||
AiChatModule,
|
||||
DatasetSearchModule,
|
||||
DatasetConcatModule,
|
||||
AssignedAnswerModule,
|
||||
ClassifyQuestionModule,
|
||||
ContextExtractModule,
|
||||
HttpModule468,
|
||||
ToolModule,
|
||||
StopToolNode,
|
||||
AiChatModule,
|
||||
RunAppModule,
|
||||
PluginInputModule,
|
||||
PluginOutputModule,
|
||||
RunPluginModule,
|
||||
AiQueryExtension,
|
||||
LafModule,
|
||||
IfElseNode,
|
||||
VariableUpdateNode,
|
||||
CodeNode
|
||||
RunPluginModule
|
||||
];
|
||||
|
||||
@@ -21,6 +21,8 @@ import { PluginTypeEnum } from '../../plugin/constants';
|
||||
import { RuntimeEdgeItemType, StoreEdgeItemType } from './edge';
|
||||
import { NextApiResponse } from 'next';
|
||||
import { AppDetailType, AppSchema } from '../../app/type';
|
||||
import { ParentIdType } from 'common/parentFolder/type';
|
||||
import { AppTypeEnum } from 'core/app/constants';
|
||||
|
||||
export type FlowNodeCommonType = {
|
||||
flowNodeType: FlowNodeTypeEnum; // render node card
|
||||
@@ -37,8 +39,8 @@ export type FlowNodeCommonType = {
|
||||
|
||||
// plugin data
|
||||
pluginId?: string;
|
||||
pluginType?: `${PluginTypeEnum}`;
|
||||
parentId?: string;
|
||||
pluginType?: AppTypeEnum;
|
||||
// parentId: ParentIdType;
|
||||
};
|
||||
|
||||
export type FlowNodeTemplateType = FlowNodeCommonType & {
|
||||
@@ -65,7 +67,6 @@ export type FlowNodeTemplateType = FlowNodeCommonType & {
|
||||
// action
|
||||
forbidDelete?: boolean; // forbid delete
|
||||
unique?: boolean;
|
||||
nodeVersion?: string;
|
||||
};
|
||||
export type FlowNodeItemType = FlowNodeTemplateType & {
|
||||
nodeId: string;
|
||||
|
||||
@@ -17,6 +17,6 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/js-yaml": "^4.0.9",
|
||||
"@types/node": "^20.8.5"
|
||||
"@types/node": "^20.14.2"
|
||||
}
|
||||
}
|
||||
|
||||
20
packages/global/support/permission/dataset/constant.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import { NullPermission, PermissionKeyEnum, PermissionList } from '../constant';
|
||||
|
||||
export enum DatasetPermissionKeyEnum {}
|
||||
|
||||
export const DatasetPermissionList = {
|
||||
[PermissionKeyEnum.read]: {
|
||||
...PermissionList[PermissionKeyEnum.read],
|
||||
description: '可查看知识库内容'
|
||||
},
|
||||
[PermissionKeyEnum.write]: {
|
||||
...PermissionList[PermissionKeyEnum.write],
|
||||
description: '可增加和变更知识库内容'
|
||||
},
|
||||
[PermissionKeyEnum.manage]: {
|
||||
...PermissionList[PermissionKeyEnum.manage],
|
||||
description: '可管理整个知识库数据和信息'
|
||||
}
|
||||
};
|
||||
|
||||
export const DatasetDefaultPermissionVal = NullPermission;
|
||||
14
packages/global/support/permission/dataset/controller.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { NullPermission } from '../constant';
|
||||
import { PerConstructPros, Permission } from '../controller';
|
||||
export class DatasetPermission extends Permission {
|
||||
constructor(props?: PerConstructPros) {
|
||||
if (!props) {
|
||||
props = {
|
||||
per: NullPermission
|
||||
};
|
||||
} else if (!props?.per) {
|
||||
props.per = NullPermission;
|
||||
}
|
||||
super(props);
|
||||
}
|
||||
}
|
||||
@@ -1,21 +1,7 @@
|
||||
{
|
||||
"extends":"../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"target": "es2015",
|
||||
"lib": ["dom", "dom.iterable", "esnext"],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"strict": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"noEmit": true,
|
||||
"esModuleInterop": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"jsx": "preserve",
|
||||
"incremental": true,
|
||||
"baseUrl": "."
|
||||
},
|
||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "**/*.d.ts"],
|
||||
"exclude": ["node_modules"]
|
||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "**/*.d.ts"]
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"version": "1.0.0",
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.8.5",
|
||||
"@types/node": "^20.14.2",
|
||||
"@fastgpt/global": "workspace:*",
|
||||
"@fastgpt/service": "workspace:*"
|
||||
}
|
||||
|
||||
@@ -8,7 +8,8 @@ import { detectFileEncoding } 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';
|
||||
import { gridFsStream2Buffer } from './utils';
|
||||
import { gridFsStream2Buffer, stream2Encoding } from './utils';
|
||||
import { addLog } from '../../system/log';
|
||||
|
||||
export function getGFSCollection(bucket: `${BucketNameEnum}`) {
|
||||
MongoFileSchema;
|
||||
@@ -44,8 +45,11 @@ export async function uploadFile({
|
||||
const stats = await fsp.stat(path);
|
||||
if (!stats.isFile()) return Promise.reject(`${path} is not a file`);
|
||||
|
||||
const { stream: readStream, encoding } = await stream2Encoding(fs.createReadStream(path));
|
||||
|
||||
metadata.teamId = teamId;
|
||||
metadata.tmbId = tmbId;
|
||||
metadata.encoding = encoding;
|
||||
|
||||
// create a gridfs bucket
|
||||
const bucket = getGridBucket(bucketName);
|
||||
@@ -57,7 +61,7 @@ export async function uploadFile({
|
||||
|
||||
// save to gridfs
|
||||
await new Promise((resolve, reject) => {
|
||||
fs.createReadStream(path)
|
||||
readStream
|
||||
.pipe(stream as any)
|
||||
.on('finish', resolve)
|
||||
.on('error', reject);
|
||||
@@ -113,19 +117,8 @@ export async function getDownloadStream({
|
||||
fileId: string;
|
||||
}) {
|
||||
const bucket = getGridBucket(bucketName);
|
||||
const encodeStream = bucket.openDownloadStream(new Types.ObjectId(fileId), { end: 100 });
|
||||
const rawStream = bucket.openDownloadStream(new Types.ObjectId(fileId));
|
||||
|
||||
/* get encoding */
|
||||
const buffer = await gridFsStream2Buffer(encodeStream);
|
||||
|
||||
const encoding = detectFileEncoding(buffer);
|
||||
|
||||
return {
|
||||
fileStream: rawStream,
|
||||
encoding
|
||||
// encoding: 'utf-8'
|
||||
};
|
||||
return bucket.openDownloadStream(new Types.ObjectId(fileId));
|
||||
}
|
||||
|
||||
export const readFileContentFromMongo = async ({
|
||||
@@ -150,9 +143,8 @@ export const readFileContentFromMongo = async ({
|
||||
filename: fileBuffer.metadata?.filename || ''
|
||||
};
|
||||
}
|
||||
const start = Date.now();
|
||||
|
||||
const [file, { encoding, fileStream }] = await Promise.all([
|
||||
const [file, fileStream] = await Promise.all([
|
||||
getFileById({ bucketName, fileId }),
|
||||
getDownloadStream({ bucketName, fileId })
|
||||
]);
|
||||
@@ -163,8 +155,11 @@ export const readFileContentFromMongo = async ({
|
||||
|
||||
const extension = file?.filename?.split('.')?.pop()?.toLowerCase() || '';
|
||||
|
||||
const start = Date.now();
|
||||
const fileBuffers = await gridFsStream2Buffer(fileStream);
|
||||
// console.log('get file buffer', Date.now() - start);
|
||||
addLog.debug('get file buffer', { time: Date.now() - start });
|
||||
|
||||
const encoding = file?.metadata?.encoding || detectFileEncoding(fileBuffers);
|
||||
|
||||
const { rawText } = await readRawContentByFileBuffer({
|
||||
extension,
|
||||
@@ -177,7 +172,8 @@ export const readFileContentFromMongo = async ({
|
||||
}
|
||||
});
|
||||
|
||||
if (rawText.trim()) {
|
||||
// < 14M
|
||||
if (fileBuffers.length < 14 * 1024 * 1024 && rawText.trim()) {
|
||||
MongoRawTextBuffer.create({
|
||||
sourceId: fileId,
|
||||
rawText,
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
import { detectFileEncoding } from '@fastgpt/global/common/file/tools';
|
||||
import { PassThrough } from 'stream';
|
||||
|
||||
export const gridFsStream2Buffer = (stream: NodeJS.ReadableStream) => {
|
||||
return new Promise<Buffer>((resolve, reject) => {
|
||||
let tmpBuffer: Buffer = Buffer.from([]);
|
||||
@@ -13,3 +16,38 @@ export const gridFsStream2Buffer = (stream: NodeJS.ReadableStream) => {
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
export const stream2Encoding = async (stream: NodeJS.ReadableStream) => {
|
||||
const start = Date.now();
|
||||
const copyStream = stream.pipe(new PassThrough());
|
||||
|
||||
/* get encoding */
|
||||
const buffer = await (() => {
|
||||
return new Promise<Buffer>((resolve, reject) => {
|
||||
let tmpBuffer: Buffer = Buffer.from([]);
|
||||
|
||||
stream.on('data', (chunk) => {
|
||||
if (tmpBuffer.length < 200) {
|
||||
tmpBuffer = Buffer.concat([tmpBuffer, chunk]);
|
||||
|
||||
if (tmpBuffer.length >= 200) {
|
||||
resolve(tmpBuffer);
|
||||
}
|
||||
}
|
||||
});
|
||||
stream.on('end', () => {
|
||||
resolve(tmpBuffer);
|
||||
});
|
||||
stream.on('error', (err) => {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
})();
|
||||
|
||||
const enc = detectFileEncoding(buffer);
|
||||
console.log('Get encoding time', Date.now() - start, enc);
|
||||
return {
|
||||
encoding: enc,
|
||||
stream: copyStream
|
||||
};
|
||||
};
|
||||
|
||||
@@ -13,7 +13,8 @@ export const NextEntry = ({ beforeCallback = [] }: { beforeCallback?: Promise<an
|
||||
return (...args: NextApiHandler[]): NextApiHandler => {
|
||||
return async function api(req: ApiRequestProps, res: NextApiResponse) {
|
||||
const start = Date.now();
|
||||
addLog.info(`Request start ${req.url}`);
|
||||
addLog.debug(`Request start ${req.url}`);
|
||||
|
||||
try {
|
||||
await Promise.all([withNextCors(req, res), ...beforeCallback]);
|
||||
|
||||
@@ -22,10 +23,15 @@ export const NextEntry = ({ beforeCallback = [] }: { beforeCallback?: Promise<an
|
||||
response = await handler(req, res);
|
||||
}
|
||||
|
||||
// Get request duration
|
||||
const duration = Date.now() - start;
|
||||
if (duration < 2000) {
|
||||
addLog.debug(`Request finish ${req.url}, time: ${duration}ms`);
|
||||
} else {
|
||||
addLog.warn(`Request finish ${req.url}, time: ${duration}ms`);
|
||||
}
|
||||
|
||||
const contentType = res.getHeader('Content-Type');
|
||||
|
||||
addLog.info(`Request finish ${req.url}, time: ${Date.now() - start}ms`);
|
||||
|
||||
if ((!contentType || contentType === 'application/json') && !res.writableFinished) {
|
||||
return jsonRes(res, {
|
||||
code: 200,
|
||||
|
||||
@@ -3,4 +3,10 @@ import mongoose from 'mongoose';
|
||||
export default mongoose;
|
||||
export * from 'mongoose';
|
||||
|
||||
export const connectionMongo = global.mongodb || mongoose;
|
||||
export const connectionMongo = (() => {
|
||||
if (!global.mongodb) {
|
||||
global.mongodb = mongoose;
|
||||
}
|
||||
|
||||
return global.mongodb;
|
||||
})();
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
import mongoose from './index';
|
||||
import { addLog } from '../system/log';
|
||||
import { connectionMongo } from './index';
|
||||
import type { Mongoose } from 'mongoose';
|
||||
|
||||
const maxConnecting = Math.max(30, Number(process.env.DB_MAX_LINK || 20));
|
||||
|
||||
/**
|
||||
* connect MongoDB and init data
|
||||
@@ -8,20 +12,27 @@ export async function connectMongo({
|
||||
afterHook
|
||||
}: {
|
||||
beforeHook?: () => any;
|
||||
afterHook?: () => any;
|
||||
}): Promise<void> {
|
||||
if (global.mongodb) {
|
||||
return;
|
||||
afterHook?: () => Promise<any>;
|
||||
}): Promise<Mongoose> {
|
||||
if (connectionMongo.connection.readyState !== 0) {
|
||||
return connectionMongo;
|
||||
}
|
||||
global.mongodb = mongoose;
|
||||
|
||||
beforeHook && (await beforeHook());
|
||||
beforeHook && beforeHook();
|
||||
|
||||
console.log('mongo start connect');
|
||||
try {
|
||||
mongoose.set('strictQuery', true);
|
||||
const maxConnecting = Math.max(30, Number(process.env.DB_MAX_LINK || 20));
|
||||
await mongoose.connect(process.env.MONGODB_URI as string, {
|
||||
connectionMongo.set('strictQuery', true);
|
||||
|
||||
connectionMongo.connection.on('error', (error) => {
|
||||
console.log('mongo error', error);
|
||||
connectionMongo.disconnect();
|
||||
});
|
||||
connectionMongo.connection.on('disconnected', () => {
|
||||
console.log('mongo disconnected');
|
||||
});
|
||||
|
||||
await connectionMongo.connect(process.env.MONGODB_URI as string, {
|
||||
bufferCommands: true,
|
||||
maxConnecting: maxConnecting,
|
||||
maxPoolSize: maxConnecting,
|
||||
@@ -34,22 +45,17 @@ export async function connectMongo({
|
||||
retryReads: true
|
||||
});
|
||||
|
||||
mongoose.connection.on('error', (error) => {
|
||||
console.log('mongo error', error);
|
||||
global.mongodb?.disconnect();
|
||||
global.mongodb = undefined;
|
||||
});
|
||||
mongoose.connection.on('disconnected', () => {
|
||||
console.log('mongo disconnected');
|
||||
global.mongodb = undefined;
|
||||
});
|
||||
|
||||
console.log('mongo connected');
|
||||
} catch (error) {
|
||||
connectionMongo.disconnect();
|
||||
addLog.error('mongo connect error', error);
|
||||
}
|
||||
|
||||
try {
|
||||
afterHook && (await afterHook());
|
||||
} catch (error) {
|
||||
global.mongodb.disconnect();
|
||||
console.log('error->', 'mongo connect error', error);
|
||||
global.mongodb = undefined;
|
||||
addLog.error('mongo connect after hook error', error);
|
||||
}
|
||||
|
||||
return connectionMongo;
|
||||
}
|
||||
|
||||
@@ -85,7 +85,14 @@ export const countGptMessagesTokens = (
|
||||
functionCall
|
||||
});
|
||||
} catch (error) {
|
||||
resolve(0);
|
||||
addLog.error('Count token error', error);
|
||||
const total = messages.reduce((sum, item) => {
|
||||
if (item.content) {
|
||||
return sum + item.content.length;
|
||||
}
|
||||
return sum;
|
||||
}, 0);
|
||||
resolve(total);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
@@ -22,7 +22,7 @@ export const connectPg = async (): Promise<Pool> => {
|
||||
});
|
||||
|
||||
global.pgClient.on('error', async (err) => {
|
||||
console.log(err);
|
||||
addLog.error(`pg error`, err);
|
||||
global.pgClient?.end();
|
||||
global.pgClient = null;
|
||||
|
||||
@@ -36,6 +36,7 @@ export const connectPg = async (): Promise<Pool> => {
|
||||
console.log('pg connected');
|
||||
return global.pgClient;
|
||||
} catch (error) {
|
||||
addLog.error(`pg connect error`, error);
|
||||
global.pgClient?.end();
|
||||
global.pgClient = null;
|
||||
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { MongoPlugin } from './schema';
|
||||
import { FlowNodeTemplateType } from '@fastgpt/global/core/workflow/type/index.d';
|
||||
import { FlowNodeTypeEnum } from '@fastgpt/global/core/workflow/node/constant';
|
||||
import { FlowNodeTypeEnum, defaultNodeVersion } from '@fastgpt/global/core/workflow/node/constant';
|
||||
import { pluginData2FlowNodeIO } from '@fastgpt/global/core/workflow/utils';
|
||||
import { PluginSourceEnum } from '@fastgpt/global/core/plugin/constants';
|
||||
import type { PluginRuntimeType, PluginTemplateType } from '@fastgpt/global/core/plugin/type.d';
|
||||
import { FlowNodeTemplateTypeEnum } from '@fastgpt/global/core/workflow/constants';
|
||||
import { getHandleConfig } from '../../../global/core/workflow/template/utils';
|
||||
import { getHandleConfig } from '@fastgpt/global/core/workflow/template/utils';
|
||||
import { getNanoid } from '@fastgpt/global/common/string/tools';
|
||||
import { cloneDeep } from 'lodash';
|
||||
import { MongoApp } from '../schema';
|
||||
|
||||
/*
|
||||
plugin id rule:
|
||||
@@ -19,6 +19,7 @@ import { cloneDeep } from 'lodash';
|
||||
export async function splitCombinePluginId(id: string) {
|
||||
const splitRes = id.split('-');
|
||||
if (splitRes.length === 1) {
|
||||
// app id
|
||||
return {
|
||||
source: PluginSourceEnum.personal,
|
||||
pluginId: id
|
||||
@@ -33,6 +34,7 @@ export async function splitCombinePluginId(id: string) {
|
||||
|
||||
const getPluginTemplateById = async (id: string): Promise<PluginTemplateType> => {
|
||||
const { source, pluginId } = await splitCombinePluginId(id);
|
||||
|
||||
if (source === PluginSourceEnum.community) {
|
||||
const item = global.communityPlugins?.find((plugin) => plugin.id === pluginId);
|
||||
if (!item) return Promise.reject('plugin not found');
|
||||
@@ -40,8 +42,9 @@ const getPluginTemplateById = async (id: string): Promise<PluginTemplateType> =>
|
||||
return cloneDeep(item);
|
||||
}
|
||||
if (source === PluginSourceEnum.personal) {
|
||||
const item = await MongoPlugin.findById(id).lean();
|
||||
const item = await MongoApp.findById(id).lean();
|
||||
if (!item) return Promise.reject('plugin not found');
|
||||
|
||||
return {
|
||||
id: String(item._id),
|
||||
teamId: String(item.teamId),
|
||||
@@ -54,7 +57,7 @@ const getPluginTemplateById = async (id: string): Promise<PluginTemplateType> =>
|
||||
edges: item.edges,
|
||||
templateType: FlowNodeTemplateTypeEnum.personalPlugin,
|
||||
isTool: true,
|
||||
nodeVersion: item?.nodeVersion || ''
|
||||
version: item?.pluginData?.nodeVersion || defaultNodeVersion
|
||||
};
|
||||
}
|
||||
return Promise.reject('plugin not found');
|
||||
@@ -74,8 +77,7 @@ export async function getPluginPreviewNode({ id }: { id: string }): Promise<Flow
|
||||
intro: plugin.intro,
|
||||
showStatus: plugin.showStatus,
|
||||
isTool: plugin.isTool,
|
||||
nodeVersion: plugin.nodeVersion,
|
||||
version: '481',
|
||||
version: plugin.version,
|
||||
sourceHandle: getHandleConfig(true, true, true, true),
|
||||
targetHandle: getHandleConfig(true, true, true, true),
|
||||
...pluginData2FlowNodeIO(plugin.nodes)
|
||||
@@ -1,8 +1,7 @@
|
||||
import { AppTypeEnum, AppTypeMap } from '@fastgpt/global/core/app/constants';
|
||||
import { AppTypeEnum } from '@fastgpt/global/core/app/constants';
|
||||
import { connectionMongo, type Model } from '../../common/mongo';
|
||||
const { Schema, model, models } = connectionMongo;
|
||||
import type { AppSchema as AppType } from '@fastgpt/global/core/app/type.d';
|
||||
import { PermissionTypeEnum, PermissionTypeMap } from '@fastgpt/global/support/permission/constant';
|
||||
import {
|
||||
TeamCollectionName,
|
||||
TeamMemberCollectionName
|
||||
@@ -43,7 +42,7 @@ const AppSchema = new Schema({
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: AppTypeEnum.advanced,
|
||||
default: AppTypeEnum.workflow,
|
||||
enum: Object.values(AppTypeEnum)
|
||||
},
|
||||
version: {
|
||||
@@ -64,16 +63,11 @@ const AppSchema = new Schema({
|
||||
},
|
||||
|
||||
// role and auth
|
||||
permission: {
|
||||
type: String,
|
||||
enum: Object.keys(PermissionTypeMap),
|
||||
default: PermissionTypeEnum.private
|
||||
},
|
||||
teamTags: {
|
||||
type: [String]
|
||||
},
|
||||
|
||||
// tmp store
|
||||
// save app(Not publish)
|
||||
modules: {
|
||||
type: Array,
|
||||
default: []
|
||||
@@ -83,8 +77,16 @@ const AppSchema = new Schema({
|
||||
default: []
|
||||
},
|
||||
chatConfig: {
|
||||
type: chatConfigType,
|
||||
default: {}
|
||||
type: chatConfigType
|
||||
},
|
||||
// plugin config
|
||||
pluginData: {
|
||||
type: {
|
||||
nodeVersion: String,
|
||||
pluginUniId: String,
|
||||
apiSchemaStr: String, // http plugin
|
||||
customHeaders: String // http plugin
|
||||
}
|
||||
},
|
||||
|
||||
scheduledTriggerConfig: {
|
||||
|
||||
@@ -24,8 +24,7 @@ const AppVersionSchema = new Schema({
|
||||
default: []
|
||||
},
|
||||
chatConfig: {
|
||||
type: chatConfigType,
|
||||
default: {}
|
||||
type: chatConfigType
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
TeamMemberCollectionName
|
||||
} from '@fastgpt/global/support/user/team/constant';
|
||||
import { PermissionTypeEnum, PermissionTypeMap } from '@fastgpt/global/support/permission/constant';
|
||||
import { DatasetDefaultPermissionVal } from '@fastgpt/global/support/permission/dataset/constant';
|
||||
|
||||
export const DatasetCollectionName = 'datasets';
|
||||
|
||||
@@ -90,7 +91,11 @@ const DatasetSchema = new Schema({
|
||||
}
|
||||
}
|
||||
},
|
||||
externalReadUrl: String
|
||||
externalReadUrl: String,
|
||||
defaultPermission: {
|
||||
type: Number,
|
||||
default: DatasetDefaultPermissionVal
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
|
||||
@@ -68,10 +68,13 @@ const PluginSchema = new Schema({
|
||||
nodeVersion: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
|
||||
inited: Boolean
|
||||
});
|
||||
|
||||
try {
|
||||
PluginSchema.index({ type: 1, init: 1 });
|
||||
PluginSchema.index({ teamId: 1, parentId: 1 });
|
||||
PluginSchema.index({ teamId: 1, name: 1, intro: 1 });
|
||||
} catch (error) {
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
import { connectionMongo, type Model } from '../../../common/mongo';
|
||||
const { Schema, model, models } = connectionMongo;
|
||||
import type { PluginItemSchema } from '@fastgpt/global/core/plugin/type.d';
|
||||
|
||||
import { PluginCollectionName } from '../schema';
|
||||
|
||||
export const ModuleCollectionName = 'plugins';
|
||||
|
||||
const PluginStoreSchema = new Schema({
|
||||
pluginId: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: PluginCollectionName,
|
||||
required: true
|
||||
},
|
||||
price: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
updateTime: {
|
||||
type: Date,
|
||||
default: () => new Date()
|
||||
},
|
||||
modules: {
|
||||
type: Array,
|
||||
default: []
|
||||
}
|
||||
});
|
||||
|
||||
export const MongoPluginStore: Model<PluginItemSchema> =
|
||||
models[ModuleCollectionName] || model(ModuleCollectionName, PluginStoreSchema);
|
||||
MongoPluginStore.syncIndexes();
|
||||
@@ -42,6 +42,7 @@ export const dispatchRunCode = async (props: RunCodeType): Promise<RunCodeRespon
|
||||
customOutputs: runResult.data.codeReturn,
|
||||
codeLog: runResult.data.log
|
||||
},
|
||||
[DispatchNodeResponseKeyEnum.toolResponses]: runResult.data.codeReturn,
|
||||
...runResult.data.codeReturn
|
||||
};
|
||||
} else {
|
||||
|
||||
@@ -3,8 +3,7 @@ import { dispatchWorkFlow } from '../index';
|
||||
import { FlowNodeTypeEnum } from '@fastgpt/global/core/workflow/node/constant';
|
||||
import { NodeInputKeyEnum } from '@fastgpt/global/core/workflow/constants';
|
||||
import { DispatchNodeResponseKeyEnum } from '@fastgpt/global/core/workflow/runtime/constants';
|
||||
import { getPluginRuntimeById } from '../../../plugin/controller';
|
||||
import { authPluginCanUse } from '../../../../support/permission/auth/plugin';
|
||||
import { getPluginRuntimeById, splitCombinePluginId } from '../../../app/plugin/controller';
|
||||
import {
|
||||
getDefaultEntryNodeIds,
|
||||
initWorkflowEdgeStatus,
|
||||
@@ -13,6 +12,9 @@ import {
|
||||
import { DispatchNodeResultType } from '@fastgpt/global/core/workflow/runtime/type';
|
||||
import { updateToolInputValue } from '../agent/runTool/utils';
|
||||
import { replaceVariable } from '@fastgpt/global/common/string/tools';
|
||||
import { authAppByTmbId } from '../../../../support/permission/app/auth';
|
||||
import { ReadPermissionVal } from '@fastgpt/global/support/permission/constant';
|
||||
import { PluginSourceEnum } from '@fastgpt/global/core/plugin/constants';
|
||||
|
||||
type RunPluginProps = ModuleDispatchProps<{
|
||||
[key: string]: any;
|
||||
@@ -22,9 +24,9 @@ type RunPluginResponse = DispatchNodeResultType<{}>;
|
||||
export const dispatchRunPlugin = async (props: RunPluginProps): Promise<RunPluginResponse> => {
|
||||
const {
|
||||
node: { pluginId },
|
||||
app: workflowApp,
|
||||
mode,
|
||||
teamId,
|
||||
tmbId,
|
||||
params: data
|
||||
} = props;
|
||||
|
||||
@@ -32,7 +34,15 @@ export const dispatchRunPlugin = async (props: RunPluginProps): Promise<RunPlugi
|
||||
return Promise.reject('pluginId can not find');
|
||||
}
|
||||
|
||||
await authPluginCanUse({ id: pluginId, teamId, tmbId });
|
||||
// auth plugin
|
||||
const { source } = await splitCombinePluginId(pluginId);
|
||||
if (source === PluginSourceEnum.personal) {
|
||||
await authAppByTmbId({
|
||||
appId: pluginId,
|
||||
tmbId: workflowApp.tmbId,
|
||||
per: ReadPermissionVal
|
||||
});
|
||||
}
|
||||
const plugin = await getPluginRuntimeById(pluginId);
|
||||
|
||||
// concat dynamic inputs
|
||||
|
||||
@@ -2,7 +2,6 @@ import type { ChatItemType } from '@fastgpt/global/core/chat/type.d';
|
||||
import type { ModuleDispatchProps } from '@fastgpt/global/core/workflow/type/index.d';
|
||||
import { SelectAppItemType } from '@fastgpt/global/core/workflow/type/index.d';
|
||||
import { dispatchWorkFlow } from '../index';
|
||||
import { MongoApp } from '../../../../core/app/schema';
|
||||
import { responseWrite } from '../../../../common/response';
|
||||
import { ChatRoleEnum } from '@fastgpt/global/core/chat/constants';
|
||||
import { SseResponseEventEnum } from '@fastgpt/global/core/workflow/runtime/constants';
|
||||
@@ -48,7 +47,6 @@ export const dispatchAppRequest = async (props: Props): Promise<Response> => {
|
||||
// 检查该工作流的tmb是否有调用该app的权限(不是校验对话的人,是否有权限)
|
||||
const { app: appData } = await authAppByTmbId({
|
||||
appId: app.id,
|
||||
teamId: workflowApp.teamId,
|
||||
tmbId: workflowApp.tmbId,
|
||||
per: ReadPermissionVal
|
||||
});
|
||||
|
||||
@@ -8,8 +8,7 @@ import {
|
||||
NodeInputKeyEnum
|
||||
} from '@fastgpt/global/core/workflow/constants';
|
||||
import { DispatchNodeResponseKeyEnum } from '@fastgpt/global/core/workflow/runtime/constants';
|
||||
import { splitCombinePluginId } from '../../../plugin/controller';
|
||||
import { authPluginCanUse } from '../../../../support/permission/auth/plugin';
|
||||
import { splitCombinePluginId } from '../../../app/plugin/controller';
|
||||
import { setEntryEntries, DYNAMIC_INPUT_KEY } from '../utils';
|
||||
import { DispatchNodeResultType } from '@fastgpt/global/core/workflow/runtime/type';
|
||||
import { PluginRuntimeType, PluginTemplateType } from '@fastgpt/global/core/plugin/type';
|
||||
@@ -73,8 +72,10 @@ export const dispatchRunPlugin = async (props: RunPluginProps): Promise<RunPlugi
|
||||
return Promise.reject('pluginId can not find');
|
||||
}
|
||||
|
||||
await authPluginCanUse({ id: pluginId, teamId, tmbId });
|
||||
const plugin = await getPluginRuntimeById(pluginId);
|
||||
if (plugin.teamId && plugin.teamId !== teamId) {
|
||||
return Promise.reject('plugin not found');
|
||||
}
|
||||
|
||||
// concat dynamic inputs
|
||||
const inputModule = plugin.modules.find((item) => item.flowType === FlowNodeTypeEnum.pluginInput);
|
||||
|
||||
@@ -15,12 +15,12 @@
|
||||
"decompress": "^4.2.1",
|
||||
"domino-ext": "^2.1.4",
|
||||
"encoding": "^0.1.13",
|
||||
"lodash": "^4.17.21",
|
||||
"file-type": "^19.0.0",
|
||||
"iconv-lite": "^0.6.3",
|
||||
"joplin-turndown-plugin-gfm": "^1.0.12",
|
||||
"json5": "^2.2.3",
|
||||
"jsonwebtoken": "^9.0.2",
|
||||
"lodash": "^4.17.21",
|
||||
"mammoth": "^1.6.0",
|
||||
"mongoose": "^7.0.2",
|
||||
"multer": "1.4.5-lts.1",
|
||||
@@ -39,10 +39,10 @@
|
||||
"@types/cookie": "^0.5.2",
|
||||
"@types/decompress": "^4.2.7",
|
||||
"@types/jsonwebtoken": "^9.0.3",
|
||||
"@types/lodash": "^4.14.191",
|
||||
"@types/multer": "^1.4.10",
|
||||
"@types/node-cron": "^3.0.11",
|
||||
"@types/papaparse": "5.3.7",
|
||||
"@types/lodash": "^4.14.191",
|
||||
"@types/pg": "^8.6.6",
|
||||
"@types/tunnel": "^0.0.4",
|
||||
"@types/turndown": "^5.0.4"
|
||||
|
||||
@@ -12,17 +12,15 @@ import { AuthResponseType } from '../type/auth.d';
|
||||
import { PermissionValueType } from '@fastgpt/global/support/permission/type';
|
||||
|
||||
export const authAppByTmbId = async ({
|
||||
teamId,
|
||||
tmbId,
|
||||
appId,
|
||||
per
|
||||
}: {
|
||||
teamId: string;
|
||||
tmbId: string;
|
||||
appId: string;
|
||||
per: PermissionValueType;
|
||||
}) => {
|
||||
const { permission: tmbPer } = await getTmbInfoByTmbId({ tmbId });
|
||||
const { teamId, permission: tmbPer } = await getTmbInfoByTmbId({ tmbId });
|
||||
|
||||
const app = await (async () => {
|
||||
// get app and per
|
||||
@@ -40,7 +38,7 @@ export const authAppByTmbId = async ({
|
||||
return Promise.reject(AppErrEnum.unExist);
|
||||
}
|
||||
|
||||
const isOwner = tmbPer.isOwner || String(app.tmbId) === tmbId;
|
||||
const isOwner = tmbPer.isOwner || String(app.tmbId) === String(tmbId);
|
||||
const Per = new AppPermission({ per: rp?.permission ?? app.defaultPermission, isOwner });
|
||||
|
||||
if (!Per.checkPer(per)) {
|
||||
@@ -68,10 +66,9 @@ export const authApp = async ({
|
||||
}
|
||||
> => {
|
||||
const result = await parseHeaderCert(props);
|
||||
const { teamId, tmbId } = result;
|
||||
const { tmbId } = result;
|
||||
|
||||
const { app } = await authAppByTmbId({
|
||||
teamId,
|
||||
tmbId,
|
||||
appId,
|
||||
per
|
||||
|
||||
@@ -1,201 +0,0 @@
|
||||
import { AuthModeType } from '../type';
|
||||
import { parseHeaderCert } from '../controller';
|
||||
import { DatasetErrEnum } from '@fastgpt/global/common/error/code/dataset';
|
||||
import { MongoDataset } from '../../../core/dataset/schema';
|
||||
import { getCollectionWithDataset } from '../../../core/dataset/controller';
|
||||
import { PermissionTypeEnum } from '@fastgpt/global/support/permission/constant';
|
||||
import { TeamMemberRoleEnum } from '@fastgpt/global/support/user/team/constant';
|
||||
import { AuthResponseType } from '@fastgpt/global/support/permission/type';
|
||||
import {
|
||||
CollectionWithDatasetType,
|
||||
DatasetFileSchema,
|
||||
DatasetSchemaType
|
||||
} from '@fastgpt/global/core/dataset/type';
|
||||
import { getFileById } from '../../../common/file/gridfs/controller';
|
||||
import { BucketNameEnum } from '@fastgpt/global/common/file/constants';
|
||||
import { getTmbInfoByTmbId } from '../../user/team/controller';
|
||||
import { CommonErrEnum } from '@fastgpt/global/common/error/code/common';
|
||||
import { MongoDatasetCollection } from '../../../core/dataset/collection/schema';
|
||||
|
||||
export async function authDatasetByTmbId({
|
||||
teamId,
|
||||
tmbId,
|
||||
datasetId,
|
||||
per
|
||||
}: {
|
||||
teamId: string;
|
||||
tmbId: string;
|
||||
datasetId: string;
|
||||
per: AuthModeType['per'];
|
||||
}) {
|
||||
const { role } = await getTmbInfoByTmbId({ tmbId });
|
||||
|
||||
const { dataset, isOwner, canWrite } = await (async () => {
|
||||
const dataset = await MongoDataset.findOne({ _id: datasetId, teamId }).lean();
|
||||
|
||||
if (!dataset) {
|
||||
return Promise.reject(DatasetErrEnum.unAuthDataset);
|
||||
}
|
||||
|
||||
const isOwner =
|
||||
role !== TeamMemberRoleEnum.visitor &&
|
||||
(String(dataset.tmbId) === tmbId || role === TeamMemberRoleEnum.owner);
|
||||
const canWrite =
|
||||
isOwner ||
|
||||
(role !== TeamMemberRoleEnum.visitor && dataset.permission === PermissionTypeEnum.public);
|
||||
if (per === 'r') {
|
||||
if (!isOwner && dataset.permission !== PermissionTypeEnum.public) {
|
||||
return Promise.reject(DatasetErrEnum.unAuthDataset);
|
||||
}
|
||||
}
|
||||
if (per === 'w' && !canWrite) {
|
||||
return Promise.reject(DatasetErrEnum.unAuthDataset);
|
||||
}
|
||||
if (per === 'owner' && !isOwner) {
|
||||
return Promise.reject(DatasetErrEnum.unAuthDataset);
|
||||
}
|
||||
|
||||
return { dataset, isOwner, canWrite };
|
||||
})();
|
||||
|
||||
return {
|
||||
dataset,
|
||||
isOwner,
|
||||
canWrite
|
||||
};
|
||||
}
|
||||
export async function authDataset({
|
||||
datasetId,
|
||||
per = 'owner',
|
||||
...props
|
||||
}: AuthModeType & {
|
||||
datasetId: string;
|
||||
}): Promise<
|
||||
AuthResponseType & {
|
||||
dataset: DatasetSchemaType;
|
||||
}
|
||||
> {
|
||||
const result = await parseHeaderCert(props);
|
||||
const { teamId, tmbId } = result;
|
||||
const { dataset, isOwner, canWrite } = await authDatasetByTmbId({
|
||||
teamId,
|
||||
tmbId,
|
||||
datasetId,
|
||||
per
|
||||
});
|
||||
|
||||
return {
|
||||
...result,
|
||||
dataset,
|
||||
isOwner,
|
||||
canWrite
|
||||
};
|
||||
}
|
||||
|
||||
/*
|
||||
Read: in team and dataset permission is public
|
||||
Write: in team, not visitor and dataset permission is public
|
||||
*/
|
||||
export async function authDatasetCollection({
|
||||
collectionId,
|
||||
per = 'owner',
|
||||
...props
|
||||
}: AuthModeType & {
|
||||
collectionId: string;
|
||||
}): Promise<
|
||||
AuthResponseType & {
|
||||
collection: CollectionWithDatasetType;
|
||||
}
|
||||
> {
|
||||
const { teamId, tmbId } = await parseHeaderCert(props);
|
||||
const { role } = await getTmbInfoByTmbId({ tmbId });
|
||||
|
||||
const { collection, isOwner, canWrite } = await (async () => {
|
||||
const collection = await getCollectionWithDataset(collectionId);
|
||||
|
||||
if (!collection || String(collection.teamId) !== teamId) {
|
||||
return Promise.reject(DatasetErrEnum.unAuthDatasetCollection);
|
||||
}
|
||||
|
||||
const isOwner = String(collection.tmbId) === tmbId || role === TeamMemberRoleEnum.owner;
|
||||
const canWrite =
|
||||
isOwner ||
|
||||
(role !== TeamMemberRoleEnum.visitor &&
|
||||
collection.datasetId.permission === PermissionTypeEnum.public);
|
||||
|
||||
if (per === 'r') {
|
||||
if (!isOwner && collection.datasetId.permission !== PermissionTypeEnum.public) {
|
||||
return Promise.reject(DatasetErrEnum.unAuthDatasetCollection);
|
||||
}
|
||||
}
|
||||
if (per === 'w' && !canWrite) {
|
||||
return Promise.reject(DatasetErrEnum.unAuthDatasetCollection);
|
||||
}
|
||||
if (per === 'owner' && !isOwner) {
|
||||
return Promise.reject(DatasetErrEnum.unAuthDatasetCollection);
|
||||
}
|
||||
|
||||
return {
|
||||
collection,
|
||||
isOwner,
|
||||
canWrite
|
||||
};
|
||||
})();
|
||||
|
||||
return {
|
||||
teamId,
|
||||
tmbId,
|
||||
collection,
|
||||
isOwner,
|
||||
canWrite
|
||||
};
|
||||
}
|
||||
|
||||
export async function authDatasetFile({
|
||||
fileId,
|
||||
per = 'owner',
|
||||
...props
|
||||
}: AuthModeType & {
|
||||
fileId: string;
|
||||
}): Promise<
|
||||
AuthResponseType & {
|
||||
file: DatasetFileSchema;
|
||||
}
|
||||
> {
|
||||
const { teamId, tmbId } = await parseHeaderCert(props);
|
||||
|
||||
const [file, collection] = await Promise.all([
|
||||
getFileById({ bucketName: BucketNameEnum.dataset, fileId }),
|
||||
MongoDatasetCollection.findOne({
|
||||
teamId,
|
||||
fileId
|
||||
})
|
||||
]);
|
||||
|
||||
if (!file) {
|
||||
return Promise.reject(CommonErrEnum.fileNotFound);
|
||||
}
|
||||
|
||||
if (!collection) {
|
||||
return Promise.reject(DatasetErrEnum.unAuthDatasetFile);
|
||||
}
|
||||
|
||||
// file role = collection role
|
||||
try {
|
||||
const { isOwner, canWrite } = await authDatasetCollection({
|
||||
...props,
|
||||
collectionId: collection._id,
|
||||
per
|
||||
});
|
||||
|
||||
return {
|
||||
teamId,
|
||||
tmbId,
|
||||
file,
|
||||
isOwner,
|
||||
canWrite
|
||||
};
|
||||
} catch (error) {
|
||||
return Promise.reject(DatasetErrEnum.unAuthDatasetFile);
|
||||
}
|
||||
}
|
||||
@@ -1,16 +1,18 @@
|
||||
import { AuthResponseType } from '@fastgpt/global/support/permission/type';
|
||||
import { AuthModeType } from '../type';
|
||||
import { DatasetFileSchema } from '@fastgpt/global/core/dataset/type';
|
||||
import { parseHeaderCert } from '../controller';
|
||||
import { getFileById } from '../../../common/file/gridfs/controller';
|
||||
import { BucketNameEnum } from '@fastgpt/global/common/file/constants';
|
||||
import { CommonErrEnum } from '@fastgpt/global/common/error/code/common';
|
||||
import { OwnerPermissionVal, ReadPermissionVal } from '@fastgpt/global/support/permission/constant';
|
||||
import { AuthPropsType, AuthResponseType } from '../type/auth';
|
||||
import { Permission } from '@fastgpt/global/support/permission/controller';
|
||||
|
||||
export async function authFile({
|
||||
fileId,
|
||||
per = 'owner',
|
||||
per = OwnerPermissionVal,
|
||||
...props
|
||||
}: AuthModeType & {
|
||||
}: AuthPropsType & {
|
||||
fileId: string;
|
||||
}): Promise<
|
||||
AuthResponseType & {
|
||||
@@ -29,14 +31,19 @@ export async function authFile({
|
||||
if (file.metadata?.teamId !== teamId) {
|
||||
return Promise.reject(CommonErrEnum.unAuthFile);
|
||||
}
|
||||
if (per === 'owner' && file.metadata?.tmbId !== tmbId) {
|
||||
|
||||
const permission = new Permission({
|
||||
per: ReadPermissionVal,
|
||||
isOwner: file.metadata?.tmbId === tmbId
|
||||
});
|
||||
|
||||
if (!permission.checkPer(per)) {
|
||||
return Promise.reject(CommonErrEnum.unAuthFile);
|
||||
}
|
||||
|
||||
return {
|
||||
...authRes,
|
||||
isOwner: per === 'owner',
|
||||
canWrite: per === 'owner',
|
||||
permission,
|
||||
file
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,84 +0,0 @@
|
||||
import { AuthResponseType } from '@fastgpt/global/support/permission/type';
|
||||
import { AuthModeType } from '../type';
|
||||
import { parseHeaderCert } from '../controller';
|
||||
import { getTmbInfoByTmbId } from '../../user/team/controller';
|
||||
import { TeamMemberRoleEnum } from '@fastgpt/global/support/user/team/constant';
|
||||
import { MongoPlugin } from '../../../core/plugin/schema';
|
||||
import { PluginErrEnum } from '@fastgpt/global/common/error/code/plugin';
|
||||
import { PluginItemSchema } from '@fastgpt/global/core/plugin/type';
|
||||
import { splitCombinePluginId } from '../../../core/plugin/controller';
|
||||
import { PluginSourceEnum } from '@fastgpt/global/core/plugin/constants';
|
||||
|
||||
export async function authPluginCrud({
|
||||
pluginId,
|
||||
per = 'owner',
|
||||
...props
|
||||
}: AuthModeType & {
|
||||
pluginId: string;
|
||||
}): Promise<
|
||||
AuthResponseType & {
|
||||
plugin: PluginItemSchema;
|
||||
}
|
||||
> {
|
||||
const result = await parseHeaderCert(props);
|
||||
const { tmbId, teamId } = result;
|
||||
|
||||
const { role } = await getTmbInfoByTmbId({ tmbId });
|
||||
|
||||
const { plugin, isOwner, canWrite } = await (async () => {
|
||||
const plugin = await MongoPlugin.findOne({ _id: pluginId, teamId });
|
||||
|
||||
if (!plugin) {
|
||||
throw new Error(PluginErrEnum.unExist);
|
||||
}
|
||||
|
||||
const isOwner = String(plugin.tmbId) === tmbId || role === TeamMemberRoleEnum.owner;
|
||||
const canWrite = isOwner;
|
||||
|
||||
if (per === 'w' && !canWrite) {
|
||||
return Promise.reject(PluginErrEnum.unAuth);
|
||||
}
|
||||
if (per === 'owner' && !isOwner) {
|
||||
return Promise.reject(PluginErrEnum.unAuth);
|
||||
}
|
||||
|
||||
return {
|
||||
plugin,
|
||||
isOwner,
|
||||
canWrite
|
||||
};
|
||||
})();
|
||||
|
||||
return {
|
||||
...result,
|
||||
plugin,
|
||||
isOwner,
|
||||
canWrite
|
||||
};
|
||||
}
|
||||
|
||||
export async function authPluginCanUse({
|
||||
id,
|
||||
teamId,
|
||||
tmbId
|
||||
}: {
|
||||
id: string;
|
||||
teamId: string;
|
||||
tmbId: string;
|
||||
}) {
|
||||
const { source, pluginId } = await splitCombinePluginId(id);
|
||||
|
||||
if (source === PluginSourceEnum.community) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (source === PluginSourceEnum.personal) {
|
||||
const { role } = await getTmbInfoByTmbId({ tmbId });
|
||||
const plugin = await MongoPlugin.findOne({ _id: pluginId, teamId });
|
||||
if (!plugin) {
|
||||
return Promise.reject(PluginErrEnum.unExist);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -85,7 +85,7 @@ export async function parseHeaderCert({
|
||||
async function authCookieToken(cookie?: string, token?: string) {
|
||||
// 获取 cookie
|
||||
const cookies = Cookie.parse(cookie || '');
|
||||
const cookieToken = token || cookies.token;
|
||||
const cookieToken = token || cookies[TokenName];
|
||||
|
||||
if (!cookieToken) {
|
||||
return Promise.reject(ERROR_ENUM.unAuthorization);
|
||||
@@ -198,12 +198,16 @@ export async function parseHeaderCert({
|
||||
}
|
||||
|
||||
/* set cookie */
|
||||
export const TokenName = 'fastgpt_token';
|
||||
export const setCookie = (res: NextApiResponse, token: string) => {
|
||||
res.setHeader('Set-Cookie', `token=${token}; Path=/; HttpOnly; Max-Age=604800; Samesite=Strict;`);
|
||||
res.setHeader(
|
||||
'Set-Cookie',
|
||||
`${TokenName}=${token}; Path=/; HttpOnly; Max-Age=604800; Samesite=Strict;`
|
||||
);
|
||||
};
|
||||
/* clear cookie */
|
||||
export const clearCookie = (res: NextApiResponse) => {
|
||||
res.setHeader('Set-Cookie', 'token=; Path=/; Max-Age=0');
|
||||
res.setHeader('Set-Cookie', `${TokenName}=; Path=/; Max-Age=0`);
|
||||
};
|
||||
|
||||
/* file permission */
|
||||
|
||||
215
packages/service/support/permission/dataset/auth.ts
Normal file
@@ -0,0 +1,215 @@
|
||||
import { PermissionValueType } from '@fastgpt/global/support/permission/type';
|
||||
import { getResourcePermission, parseHeaderCert } from '../controller';
|
||||
import { AuthPropsType, AuthResponseType } from '../type/auth';
|
||||
import {
|
||||
CollectionWithDatasetType,
|
||||
DatasetDataItemType,
|
||||
DatasetFileSchema,
|
||||
DatasetSchemaType
|
||||
} from '@fastgpt/global/core/dataset/type';
|
||||
import { getTmbInfoByTmbId } from '../../user/team/controller';
|
||||
import { MongoDataset } from '../../../core/dataset/schema';
|
||||
import { PerResourceTypeEnum } from '@fastgpt/global/support/permission/constant';
|
||||
import { DatasetErrEnum } from '@fastgpt/global/common/error/code/dataset';
|
||||
import { DatasetPermission } from '@fastgpt/global/support/permission/dataset/controller';
|
||||
import { getCollectionWithDataset } from '../../../core/dataset/controller';
|
||||
import { MongoDatasetCollection } from '../../../core/dataset/collection/schema';
|
||||
import { getFileById } from '../../../common/file/gridfs/controller';
|
||||
import { BucketNameEnum } from '@fastgpt/global/common/file/constants';
|
||||
import { CommonErrEnum } from '@fastgpt/global/common/error/code/common';
|
||||
import { MongoDatasetData } from '../../../core/dataset/data/schema';
|
||||
import { DatasetDefaultPermissionVal } from '@fastgpt/global/support/permission/dataset/constant';
|
||||
|
||||
export async function authDatasetByTmbId({
|
||||
tmbId,
|
||||
datasetId,
|
||||
per
|
||||
}: {
|
||||
tmbId: string;
|
||||
datasetId: string;
|
||||
per: PermissionValueType;
|
||||
}) {
|
||||
const { teamId, permission: tmbPer } = await getTmbInfoByTmbId({ tmbId });
|
||||
|
||||
const dataset = await (async () => {
|
||||
// get app and per
|
||||
const [dataset, rp] = await Promise.all([
|
||||
MongoDataset.findOne({ _id: datasetId, teamId }).lean(),
|
||||
getResourcePermission({
|
||||
teamId,
|
||||
tmbId,
|
||||
resourceId: datasetId,
|
||||
resourceType: PerResourceTypeEnum.dataset
|
||||
}) // this could be null
|
||||
]);
|
||||
|
||||
if (!dataset) {
|
||||
return Promise.reject(DatasetErrEnum.unExist);
|
||||
}
|
||||
|
||||
const isOwner = tmbPer.isOwner || String(dataset.tmbId) === String(tmbId);
|
||||
const Per = new DatasetPermission({
|
||||
per: rp?.permission ?? dataset.defaultPermission,
|
||||
isOwner
|
||||
});
|
||||
|
||||
if (!Per.checkPer(per)) {
|
||||
return Promise.reject(DatasetErrEnum.unAuthDataset);
|
||||
}
|
||||
|
||||
return {
|
||||
...dataset,
|
||||
defaultPermission: dataset.defaultPermission ?? DatasetDefaultPermissionVal,
|
||||
permission: Per
|
||||
};
|
||||
})();
|
||||
|
||||
return { dataset };
|
||||
}
|
||||
|
||||
// Auth Dataset
|
||||
export async function authDataset({
|
||||
datasetId,
|
||||
per,
|
||||
...props
|
||||
}: AuthPropsType & {
|
||||
datasetId: string;
|
||||
}): Promise<
|
||||
AuthResponseType<DatasetPermission> & {
|
||||
dataset: DatasetSchemaType;
|
||||
}
|
||||
> {
|
||||
const { teamId, tmbId } = await parseHeaderCert(props);
|
||||
|
||||
const { dataset } = await authDatasetByTmbId({
|
||||
tmbId,
|
||||
datasetId,
|
||||
per
|
||||
});
|
||||
|
||||
return {
|
||||
teamId,
|
||||
tmbId,
|
||||
dataset,
|
||||
permission: dataset.permission
|
||||
};
|
||||
}
|
||||
|
||||
// the temporary solution for authDatasetCollection is getting the
|
||||
export async function authDatasetCollection({
|
||||
collectionId,
|
||||
per,
|
||||
...props
|
||||
}: AuthPropsType & {
|
||||
collectionId: string;
|
||||
}): Promise<
|
||||
AuthResponseType<DatasetPermission> & {
|
||||
collection: CollectionWithDatasetType;
|
||||
}
|
||||
> {
|
||||
const { teamId, tmbId } = await parseHeaderCert(props);
|
||||
const collection = await getCollectionWithDataset(collectionId);
|
||||
|
||||
if (!collection) {
|
||||
return Promise.reject(DatasetErrEnum.unExist);
|
||||
}
|
||||
|
||||
const { dataset } = await authDatasetByTmbId({
|
||||
tmbId,
|
||||
datasetId: collection.datasetId._id,
|
||||
per
|
||||
});
|
||||
|
||||
return {
|
||||
teamId,
|
||||
tmbId,
|
||||
collection,
|
||||
permission: dataset.permission
|
||||
};
|
||||
}
|
||||
|
||||
export async function authDatasetFile({
|
||||
fileId,
|
||||
per,
|
||||
...props
|
||||
}: AuthPropsType & {
|
||||
fileId: string;
|
||||
}): Promise<
|
||||
AuthResponseType<DatasetPermission> & {
|
||||
file: DatasetFileSchema;
|
||||
}
|
||||
> {
|
||||
const { teamId, tmbId } = await parseHeaderCert(props);
|
||||
|
||||
const [file, collection] = await Promise.all([
|
||||
getFileById({ bucketName: BucketNameEnum.dataset, fileId }),
|
||||
MongoDatasetCollection.findOne({
|
||||
teamId,
|
||||
fileId
|
||||
})
|
||||
]);
|
||||
|
||||
if (!file) {
|
||||
return Promise.reject(CommonErrEnum.fileNotFound);
|
||||
}
|
||||
|
||||
if (!collection) {
|
||||
return Promise.reject(DatasetErrEnum.unAuthDatasetFile);
|
||||
}
|
||||
|
||||
try {
|
||||
const { permission } = await authDatasetCollection({
|
||||
...props,
|
||||
collectionId: collection._id,
|
||||
per
|
||||
});
|
||||
|
||||
return {
|
||||
teamId,
|
||||
tmbId,
|
||||
file,
|
||||
permission
|
||||
};
|
||||
} catch (error) {
|
||||
return Promise.reject(DatasetErrEnum.unAuthDatasetFile);
|
||||
}
|
||||
}
|
||||
|
||||
export async function authDatasetData({
|
||||
dataId,
|
||||
...props
|
||||
}: AuthPropsType & {
|
||||
dataId: string;
|
||||
}) {
|
||||
// get mongo dataset.data
|
||||
const datasetData = await MongoDatasetData.findById(dataId);
|
||||
|
||||
if (!datasetData) {
|
||||
return Promise.reject('core.dataset.error.Data not found');
|
||||
}
|
||||
|
||||
const result = await authDatasetCollection({
|
||||
...props,
|
||||
collectionId: datasetData.collectionId
|
||||
});
|
||||
|
||||
const data: DatasetDataItemType = {
|
||||
id: String(datasetData._id),
|
||||
teamId: datasetData.teamId,
|
||||
q: datasetData.q,
|
||||
a: datasetData.a,
|
||||
chunkIndex: datasetData.chunkIndex,
|
||||
indexes: datasetData.indexes,
|
||||
datasetId: String(datasetData.datasetId),
|
||||
collectionId: String(datasetData.collectionId),
|
||||
sourceName: result.collection.name || '',
|
||||
sourceId: result.collection?.fileId || result.collection?.rawLink,
|
||||
isOwner: String(datasetData.tmbId) === String(result.tmbId),
|
||||
canWrite: result.permission.hasWritePer
|
||||
};
|
||||
|
||||
return {
|
||||
...result,
|
||||
datasetData: data
|
||||
};
|
||||
}
|
||||
@@ -31,7 +31,6 @@ export async function authOutLinkCrud({
|
||||
}
|
||||
|
||||
const { app } = await authAppByTmbId({
|
||||
teamId,
|
||||
tmbId,
|
||||
appId: outLink.appId,
|
||||
per: ManagePermissionVal
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { getTeamPlanStatus, getTeamStandPlan } from '../../support/wallet/sub/utils';
|
||||
import { MongoApp } from '../../core/app/schema';
|
||||
import { MongoPlugin } from '../../core/plugin/schema';
|
||||
import { MongoDataset } from '../../core/dataset/schema';
|
||||
import { DatasetTypeEnum } from '@fastgpt/global/core/dataset/constants';
|
||||
import { TeamErrEnum } from '@fastgpt/global/common/error/code/team';
|
||||
@@ -64,26 +63,19 @@ export const checkTeamDatasetLimit = async (teamId: string) => {
|
||||
return Promise.reject(SystemErrEnum.communityVersionNumLimit);
|
||||
}
|
||||
};
|
||||
export const checkTeamAppLimit = async (teamId: string) => {
|
||||
export const checkTeamAppLimit = async (teamId: string, amount = 1) => {
|
||||
const [{ standardConstants }, appCount] = await Promise.all([
|
||||
getTeamStandPlan({ teamId }),
|
||||
MongoApp.count({ teamId, type: { $in: [AppTypeEnum.advanced, AppTypeEnum.simple] } })
|
||||
MongoApp.count({
|
||||
teamId,
|
||||
type: { $in: [AppTypeEnum.simple, AppTypeEnum.workflow, AppTypeEnum.plugin] }
|
||||
})
|
||||
]);
|
||||
|
||||
if (standardConstants && appCount >= standardConstants.maxAppAmount) {
|
||||
if (standardConstants && appCount + amount >= standardConstants.maxAppAmount) {
|
||||
return Promise.reject(TeamErrEnum.appAmountNotEnough);
|
||||
}
|
||||
};
|
||||
export const checkTeamPluginLimit = async (teamId: string) => {
|
||||
const [{ standardConstants }, pluginCount] = await Promise.all([
|
||||
getTeamStandPlan({ teamId }),
|
||||
MongoPlugin.count({ teamId })
|
||||
]);
|
||||
|
||||
if (standardConstants && pluginCount >= standardConstants.maxAppAmount) {
|
||||
return Promise.reject(TeamErrEnum.pluginAmountNotEnough);
|
||||
}
|
||||
};
|
||||
|
||||
export const checkTeamReRankPermission = async (teamId: string) => {
|
||||
const { standardConstants } = await getTeamStandPlan({
|
||||
|
||||
@@ -11,11 +11,11 @@ export type AuthPropsType = {
|
||||
per: PermissionValueType;
|
||||
};
|
||||
|
||||
export type AuthResponseType = {
|
||||
export type AuthResponseType<T = Permission> = {
|
||||
teamId: string;
|
||||
tmbId: string;
|
||||
authType?: `${AuthUserTypeEnum}`;
|
||||
appId?: string;
|
||||
apikey?: string;
|
||||
permission: Permission;
|
||||
permission: T;
|
||||
};
|
||||
|
||||
@@ -1,21 +1,7 @@
|
||||
{
|
||||
"extends":"../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"target": "es2015",
|
||||
"lib": ["dom", "dom.iterable", "esnext"],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"strict": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"noEmit": true,
|
||||
"esModuleInterop": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"jsx": "preserve",
|
||||
"incremental": true,
|
||||
"baseUrl": "."
|
||||
},
|
||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "**/*.d.ts", "../**/*.d.ts"],
|
||||
"exclude": ["node_modules"]
|
||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "**/*.d.ts", "../**/*.d.ts"]
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ export const iconPaths = {
|
||||
'common/inviteLight': () => import('./icons/common/inviteLight.svg'),
|
||||
'common/language/en': () => import('./icons/common/language/en.svg'),
|
||||
'common/language/zh': () => import('./icons/common/language/zh.svg'),
|
||||
'common/leftArrowLight': () => import('./icons/common/leftArrowLight.svg'),
|
||||
'common/linkBlue': () => import('./icons/common/linkBlue.svg'),
|
||||
'common/loading': () => import('./icons/common/loading.svg'),
|
||||
'common/navbar/pluginFill': () => import('./icons/common/navbar/pluginFill.svg'),
|
||||
@@ -83,8 +84,13 @@ export const iconPaths = {
|
||||
'core/app/simpleMode/whisper': () => import('./icons/core/app/simpleMode/whisper.svg'),
|
||||
'core/app/toolCall': () => import('./icons/core/app/toolCall.svg'),
|
||||
'core/app/ttsFill': () => import('./icons/core/app/ttsFill.svg'),
|
||||
'core/app/type/httpPlugin': () => import('./icons/core/app/type/httpPlugin.svg'),
|
||||
'core/app/type/httpPluginFill': () => import('./icons/core/app/type/httpPluginFill.svg'),
|
||||
'core/app/type/plugin': () => import('./icons/core/app/type/plugin.svg'),
|
||||
'core/app/type/pluginFill': () => import('./icons/core/app/type/pluginFill.svg'),
|
||||
'core/app/type/simple': () => import('./icons/core/app/type/simple.svg'),
|
||||
'core/app/type/workflow': () => import('./icons/core/app/type/workflow.svg'),
|
||||
'core/app/type/workflowFill': () => import('./icons/core/app/type/workflowFill.svg'),
|
||||
'core/app/variable/external': () => import('./icons/core/app/variable/external.svg'),
|
||||
'core/app/variable/input': () => import('./icons/core/app/variable/input.svg'),
|
||||
'core/app/variable/select': () => import('./icons/core/app/variable/select.svg'),
|
||||
@@ -194,6 +200,7 @@ export const iconPaths = {
|
||||
'modal/setting': () => import('./icons/modal/setting.svg'),
|
||||
'modal/teamPlans': () => import('./icons/modal/teamPlans.svg'),
|
||||
more: () => import('./icons/more.svg'),
|
||||
moreLine: () => import('./icons/moreLine.svg'),
|
||||
out: () => import('./icons/out.svg'),
|
||||
'phoneTabbar/me': () => import('./icons/phoneTabbar/me.svg'),
|
||||
'phoneTabbar/tool': () => import('./icons/phoneTabbar/tool.svg'),
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
<svg viewBox="0 0 24 25" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd"
|
||||
d="M15.7071 5.79289C16.0976 6.18342 16.0976 6.81658 15.7071 7.20711L10.4142 12.5L15.7071 17.7929C16.0976 18.1834 16.0976 18.8166 15.7071 19.2071C15.3166 19.5976 14.6834 19.5976 14.2929 19.2071L8.29289 13.2071C7.90237 12.8166 7.90237 12.1834 8.29289 11.7929L14.2929 5.79289C14.6834 5.40237 15.3166 5.40237 15.7071 5.79289Z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 463 B |
@@ -0,0 +1,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 14 14" >
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M9.43797 7.11649C9.43734 7.12604 9.43702 7.13567 9.43702 7.14537V8.51808H9.43797V8.8255C9.43797 9.03402 9.60701 9.20306 9.81553 9.20306C10.024 9.20306 10.1931 9.03402 10.1931 8.8255V8.51808H10.4554C10.9537 8.51808 11.3577 8.11411 11.3577 7.61579C11.3577 7.11746 10.9537 6.71349 10.4554 6.71349H9.86889C9.7831 6.71349 9.70315 6.73851 9.63594 6.78165C9.51803 6.84552 9.43797 6.97033 9.43797 7.11384V7.11649ZM10.1931 7.76558V7.46599H10.4554C10.5381 7.46599 10.6052 7.53306 10.6052 7.61579C10.6052 7.69851 10.5381 7.76558 10.4554 7.76558H10.1931Z" />
|
||||
<path d="M2.56416 7.11385C2.56416 6.90532 2.7332 6.73628 2.94172 6.73628C3.15024 6.73628 3.31928 6.90532 3.31928 7.11385V7.55213H3.91782V7.11385C3.91782 6.90532 4.08686 6.73628 4.29538 6.73628C4.5039 6.73628 4.67294 6.90532 4.67294 7.11385V8.8255C4.67294 9.03402 4.5039 9.20306 4.29538 9.20306C4.08686 9.20306 3.91782 9.03402 3.91782 8.8255V8.30725H3.31928V8.8255C3.31928 9.03402 3.15024 9.20306 2.94172 9.20306C2.7332 9.20306 2.56416 9.03402 2.56416 8.8255V7.11385Z" />
|
||||
<path d="M6.56046 6.73628C6.76898 6.73628 6.93802 6.90532 6.93802 7.11385C6.93802 7.32237 6.76898 7.49141 6.56046 7.49141H6.27522V8.8255C6.27522 9.03402 6.10618 9.20306 5.89766 9.20306C5.68914 9.20306 5.5201 9.03402 5.5201 8.8255V7.49141H5.23489C5.02637 7.49141 4.85733 7.32237 4.85733 7.11385C4.85733 6.90532 5.02637 6.73628 5.23489 6.73628H6.56046Z" />
|
||||
<path d="M8.82547 6.73628C9.03399 6.73628 9.20303 6.90532 9.20303 7.11385C9.20303 7.32237 9.03399 7.49141 8.82547 7.49141H8.54023V8.8255C8.54023 9.03402 8.37119 9.20306 8.16267 9.20306C7.95414 9.20306 7.78511 9.03402 7.78511 8.8255V7.49141H7.4999C7.29138 7.49141 7.12234 7.32237 7.12234 7.11385C7.12234 6.90532 7.29138 6.73628 7.4999 6.73628H8.82547Z" />
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M0.583374 7.84518C0.583374 9.89915 2.17044 11.5824 4.18517 11.7356V11.7426H4.29822C4.36018 11.7455 4.42252 11.747 4.4852 11.747C4.54789 11.747 4.61023 11.7455 4.67219 11.7426H9.78743C9.84569 11.7455 9.90433 11.747 9.96332 11.747C11.8706 11.747 13.4167 10.2009 13.4167 8.29361C13.4167 6.89463 12.5849 5.68995 11.3888 5.14721C10.9696 3.48253 9.49728 2.25299 7.74529 2.25299C6.45088 2.25299 5.30912 2.92414 4.63196 3.94606C4.58327 3.94426 4.53434 3.94335 4.4852 3.94335C2.33028 3.94335 0.583374 5.69026 0.583374 7.84518ZM4.32102 10.5759L4.27363 10.5723C2.8625 10.465 1.75004 9.28447 1.75004 7.84518C1.75004 6.33459 2.97461 5.11002 4.4852 5.11002C4.51994 5.11002 4.5545 5.11066 4.58885 5.11193L5.24295 5.13612L5.6045 4.59049C6.07973 3.8733 6.86712 3.41966 7.74529 3.41966C8.93072 3.41966 9.96085 4.2542 10.2574 5.43208L10.3947 5.97729L10.9067 6.20962C11.7013 6.57016 12.25 7.36904 12.25 8.29361C12.25 9.55654 11.2262 10.5803 9.96332 10.5803C9.92383 10.5803 9.88468 10.5794 9.84589 10.5774L9.81668 10.5759H4.64468L4.61721 10.5772C4.57355 10.5793 4.52954 10.5803 4.4852 10.5803C4.44087 10.5803 4.39686 10.5793 4.35319 10.5772L4.32572 10.5759H4.32102Z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.0 KiB |
@@ -0,0 +1,13 @@
|
||||
<svg viewBox="0 0 32 33" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect y="0.75" width="32" height="32" rx="5.70173" fill="url(#paint0_linear_5533_28340)" />
|
||||
<path fill-rule="evenodd" clip-rule="evenodd"
|
||||
d="M5.08823 18.1872C5.08823 21.6801 7.78709 24.5426 11.2132 24.8031V24.815H11.4056C11.5109 24.8199 11.6169 24.8225 11.7234 24.8225C11.83 24.8225 11.9359 24.8199 12.0413 24.815H20.7402C20.8393 24.8199 20.9389 24.8225 21.0392 24.8225C24.2826 24.8225 26.9118 22.1932 26.9118 18.9498C26.9118 16.5708 25.4972 14.5222 23.4633 13.5992C22.7505 10.7684 20.2467 8.67749 17.2673 8.67749C15.0662 8.67749 13.1245 9.81881 11.973 11.5566C11.8902 11.5536 11.807 11.552 11.7234 11.552C8.05891 11.552 5.08823 14.5227 5.08823 18.1872ZM8.27323 20.0908C8.35893 20.1765 8.48035 20.2194 8.63748 20.2194C8.80175 20.2194 8.92496 20.1765 9.00709 20.0908C9.08923 20.0016 9.1303 19.8766 9.1303 19.7159V18.6606H10.6891V19.7159C10.6891 19.8766 10.7302 20.0016 10.8123 20.0908C10.898 20.1765 11.0212 20.2194 11.1819 20.2194C11.339 20.2194 11.4587 20.1765 11.5408 20.0908C11.6265 20.0016 11.6694 19.8766 11.6694 19.7159V16.85C11.6694 16.6858 11.6265 16.5608 11.5408 16.4751C11.4587 16.3894 11.339 16.3465 11.1819 16.3465C11.0212 16.3465 10.898 16.3894 10.8123 16.4751C10.7302 16.5608 10.6891 16.6858 10.6891 16.85V17.8517H9.1303V16.85C9.1303 16.6858 9.08744 16.5608 9.00174 16.4751C8.9196 16.3894 8.79818 16.3465 8.63748 16.3465C8.48035 16.3465 8.35893 16.3894 8.27323 16.4751C8.18752 16.5608 8.14467 16.6858 8.14467 16.85V19.7159C8.14467 19.8766 8.18752 20.0016 8.27323 20.0908ZM13.8021 20.0908C13.8878 20.1765 14.0092 20.2194 14.1663 20.2194C14.3306 20.2194 14.4538 20.1765 14.5359 20.0908C14.6181 20.0016 14.6591 19.8784 14.6591 19.7212V17.1982H15.5001C15.6323 17.1982 15.7322 17.1643 15.8001 17.0964C15.8715 17.025 15.9072 16.925 15.9072 16.7965C15.9072 16.6643 15.8715 16.5643 15.8001 16.4965C15.7322 16.4286 15.6323 16.3947 15.5001 16.3947H12.8325C12.7004 16.3947 12.5986 16.4286 12.5272 16.4965C12.4593 16.5643 12.4254 16.6643 12.4254 16.7965C12.4254 16.925 12.4593 17.025 12.5272 17.0964C12.5986 17.1643 12.7004 17.1982 12.8325 17.1982H13.6735V19.7212C13.6735 19.8784 13.7163 20.0016 13.8021 20.0908ZM18.1154 20.2194C17.9583 20.2194 17.8369 20.1765 17.7512 20.0908C17.6654 20.0016 17.6226 19.8784 17.6226 19.7212V17.1982H16.7816C16.6495 17.1982 16.5477 17.1643 16.4763 17.0964C16.4084 17.025 16.3745 16.925 16.3745 16.7965C16.3745 16.6643 16.4084 16.5643 16.4763 16.4965C16.5477 16.4286 16.6495 16.3947 16.7816 16.3947H19.4492C19.5814 16.3947 19.6813 16.4286 19.7492 16.4965C19.8206 16.5643 19.8563 16.6643 19.8563 16.7965C19.8563 16.925 19.8206 17.025 19.7492 17.0964C19.6813 17.1643 19.5814 17.1982 19.4492 17.1982H18.6082V19.7212C18.6082 19.8784 18.5672 20.0016 18.485 20.0908C18.4029 20.1765 18.2797 20.2194 18.1154 20.2194ZM20.7378 20.0908C20.8235 20.1765 20.9449 20.2194 21.1021 20.2194C21.2663 20.2194 21.3895 20.1765 21.4717 20.0908C21.5538 20.0016 21.5949 19.8784 21.5949 19.7212V18.8695H22.4252C22.8537 18.8695 23.184 18.7606 23.4162 18.5427C23.6518 18.3213 23.7697 18.0178 23.7697 17.6321C23.7697 17.2464 23.6518 16.9447 23.4162 16.7268C23.184 16.5054 22.8537 16.3947 22.4252 16.3947H21.1074C20.9503 16.3947 20.8271 16.4376 20.7378 16.5233C20.6521 16.609 20.6092 16.7322 20.6092 16.8929V19.7212C20.6092 19.8784 20.6521 20.0016 20.7378 20.0908ZM22.2538 18.1142H21.5949V17.15H22.2538C22.4394 17.15 22.5823 17.1893 22.6823 17.2679C22.7823 17.3464 22.8323 17.4678 22.8323 17.6321C22.8323 17.7928 22.7823 17.9142 22.6823 17.9964C22.5823 18.0749 22.4394 18.1142 22.2538 18.1142Z"
|
||||
fill="white" />
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_5533_28340" x1="16" y1="0.75" x2="4.88889" y2="30.0833"
|
||||
gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FBA8E9" />
|
||||
<stop offset="1" stop-color="#FF718A" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.8 KiB |
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 14 15" >
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M6.97746 4.90437L6.94722 3.76877C6.93325 3.24427 6.50299 2.82286 5.97468 2.82286C5.44637 2.82286 5.01612 3.24427 5.00215 3.76877L4.9719 4.90437H2.625C2.46391 4.90437 2.33333 5.03496 2.33333 5.19604V6.53174C3.42082 6.57293 4.2898 7.46755 4.2898 8.56512C4.2898 9.66269 3.42082 10.5573 2.33333 10.5985V11.8618C2.33333 12.0229 2.46391 12.1535 2.625 12.1535H3.99648C4.06812 11.1234 4.92641 10.3101 5.97466 10.3101C7.02292 10.3101 7.88121 11.1234 7.95285 12.1535H9.29071C9.4518 12.1535 9.58238 12.0229 9.58238 11.8618V9.58522L10.712 9.5493C11.2403 9.53249 11.664 9.09811 11.664 8.56522C11.664 8.03233 11.2403 7.59795 10.712 7.58115L9.58238 7.54523V5.19604C9.58238 5.03496 9.4518 4.90437 9.29071 4.90437H6.97746ZM6.79103 13.3201V12.2931C6.79103 11.8422 6.42553 11.4767 5.97466 11.4767C5.5238 11.4767 5.1583 11.8422 5.1583 12.2931V13.3201H2.625C1.81958 13.3201 1.16666 12.6672 1.16666 11.8618V9.43332H2.25493C2.73443 9.43332 3.12313 9.04461 3.12313 8.56512C3.12313 8.08563 2.73443 7.69692 2.25493 7.69692L1.16666 7.69692V5.19604C1.16666 4.39063 1.81958 3.73771 2.625 3.73771H3.83589C3.86665 2.58289 4.81244 1.65619 5.97468 1.65619C7.13692 1.65619 8.08271 2.58289 8.11347 3.73771H9.29071C10.0961 3.73771 10.749 4.39063 10.749 5.19604V6.41507C11.9049 6.45184 12.8307 7.40042 12.8307 8.56522C12.8307 9.73003 11.9049 10.6786 10.749 10.7154V11.8618C10.749 12.6672 10.0961 13.3201 9.29071 13.3201H6.79103Z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
@@ -0,0 +1,13 @@
|
||||
<svg viewBox="0 0 32 33" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect y="0.75" width="32" height="32" rx="5.70173" fill="url(#paint0_linear_5686_3911)" />
|
||||
<path
|
||||
d="M19.7787 26.2528H15.9977V24.31C15.9977 24.2215 15.9896 24.133 15.9735 24.0445C15.9574 23.956 15.9293 23.8716 15.8931 23.7871C15.8569 23.7026 15.8167 23.6262 15.7644 23.5538C15.7121 23.4814 15.6558 23.413 15.5914 23.3487C15.2656 23.0269 14.7909 22.8459 14.2962 22.8539C14.1876 22.8539 14.079 22.866 13.9704 22.8861C13.8618 22.9062 13.7572 22.9344 13.6526 22.9746C13.548 23.0148 13.4515 23.0591 13.355 23.1154C13.2584 23.1717 13.1699 23.236 13.0895 23.3084C12.8682 23.5055 12.6068 23.8394 12.6068 24.3462V26.2528H8.85391C8.77749 26.2528 8.70106 26.2488 8.62464 26.2408C8.54821 26.2327 8.47179 26.2206 8.39536 26.2086C8.31894 26.1925 8.24653 26.1764 8.17011 26.1523C8.0977 26.1281 8.0253 26.104 7.9529 26.0758C7.8805 26.0477 7.81211 26.0115 7.74373 25.9753C7.67535 25.9391 7.611 25.8989 7.54664 25.8546C7.48228 25.8104 7.42194 25.7661 7.36161 25.7179C7.30127 25.6696 7.24496 25.6173 7.18865 25.561C7.13233 25.5047 7.08406 25.4484 7.03177 25.388C6.9835 25.3277 6.93524 25.2673 6.89501 25.203C6.85077 25.1386 6.81054 25.0743 6.77434 25.0059C6.73814 24.9375 6.70596 24.8691 6.67378 24.7967C6.64562 24.7243 6.61747 24.6519 6.59736 24.5795C6.57322 24.5071 6.55713 24.4307 6.54104 24.3543C6.52495 24.2778 6.51289 24.2014 6.50886 24.125C6.50082 24.0486 6.4968 23.9721 6.4968 23.8957V20.1469H8.43558C8.82576 20.1469 9.20386 19.9819 9.50152 19.6803C9.58599 19.5958 9.65839 19.5073 9.72275 19.4067C9.7871 19.3102 9.84342 19.2056 9.88766 19.097C9.93191 18.9884 9.96409 18.8758 9.98822 18.7591C10.0124 18.6425 10.0204 18.5258 10.0204 18.4092C10.0043 17.5082 9.26419 16.7479 8.39938 16.7479H6.4968V12.9589C6.4968 12.806 6.51289 12.6532 6.54104 12.5003C6.57322 12.3475 6.61747 12.2026 6.6778 12.0619C6.73814 11.9211 6.81054 11.7843 6.89903 11.6596C6.98753 11.5309 7.08809 11.4143 7.19669 11.3097C7.30529 11.2051 7.42597 11.1086 7.55468 11.0241C7.6834 10.9396 7.82016 10.8712 7.96094 10.8149C8.10173 10.7586 8.25055 10.7144 8.39938 10.6862C8.54821 10.6581 8.70106 10.642 8.85391 10.646H11.5368V10.0265C11.5368 9.98229 11.5368 9.93402 11.5409 9.88978C11.5449 9.84553 11.5449 9.79726 11.5529 9.75301C11.557 9.70877 11.565 9.6605 11.569 9.61625C11.5771 9.57201 11.5851 9.52374 11.5932 9.47949C11.6012 9.43525 11.6133 9.391 11.6253 9.34675L11.6615 9.21402C11.6736 9.16977 11.6897 9.12552 11.7058 9.08128C11.7219 9.03703 11.738 8.99681 11.754 8.95256C11.7701 8.90831 11.7903 8.86809 11.8104 8.82787C11.8305 8.78764 11.8506 8.7434 11.8747 8.70317C11.8948 8.66295 11.919 8.62273 11.9431 8.5825C11.9672 8.54228 11.9914 8.50608 12.0195 8.46585C12.0437 8.42965 12.0718 8.38943 12.1 8.35323L12.1844 8.24462C12.2126 8.20842 12.2448 8.17624 12.277 8.14004C12.3091 8.10786 12.3413 8.07166 12.3735 8.03948C12.4057 8.0073 12.4419 7.97512 12.4741 7.94696C12.5103 7.91479 12.5424 7.88663 12.5786 7.85847L12.6872 7.774C12.7234 7.74585 12.7637 7.72171 12.7999 7.69758C12.8361 7.67344 12.8763 7.64931 12.9165 7.62517C12.9567 7.60104 12.997 7.58093 13.0372 7.55679C13.0774 7.53668 13.1176 7.51657 13.1619 7.49646C13.2021 7.47635 13.2464 7.46026 13.2906 7.44417C13.3348 7.42808 13.3751 7.41199 13.4193 7.3959C13.4636 7.37981 13.5078 7.36774 13.5521 7.35567L13.6848 7.31947C13.729 7.30741 13.7733 7.29936 13.8216 7.29132C13.8698 7.28327 13.9141 7.27523 13.9583 7.2712C14.0026 7.26718 14.0508 7.25914 14.0951 7.25512C14.1393 7.25109 14.1876 7.24707 14.2318 7.24707H14.3686C15.873 7.27523 17.0998 8.53423 17.0998 10.0627V10.642H19.7787C19.8551 10.642 19.9316 10.646 20.008 10.65C20.0844 10.6581 20.1608 10.6661 20.2332 10.6822C20.3097 10.6983 20.3821 10.7144 20.4545 10.7345C20.5269 10.7546 20.5993 10.7827 20.6717 10.8109C20.7441 10.8391 20.8125 10.8712 20.8808 10.9074C20.9492 10.9436 21.0136 10.9839 21.0779 11.0241C21.1423 11.0643 21.2026 11.1126 21.263 11.1608C21.3233 11.2091 21.3796 11.2614 21.4319 11.3137C21.4842 11.366 21.5365 11.4263 21.5848 11.4826C21.633 11.543 21.6773 11.6033 21.7215 11.6677C21.7658 11.732 21.802 11.7964 21.8382 11.8648C21.8744 11.9331 21.9065 12.0015 21.9347 12.0739C21.9629 12.1463 21.987 12.2187 22.0111 12.2911C22.0312 12.3635 22.0513 12.44 22.0634 12.5124C22.0795 12.5888 22.0876 12.6612 22.0956 12.7376C22.1036 12.814 22.1036 12.8905 22.1036 12.9669V15.6498H22.6829C24.2355 15.6498 25.4985 16.8807 25.4985 18.3931C25.4985 19.9457 24.2516 21.2088 22.7191 21.2088H22.1036V23.8917C22.1077 25.1909 21.0618 26.2528 19.7787 26.2528Z"
|
||||
fill="white" />
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_5686_3911" x1="16" y1="0.75" x2="4.88889" y2="30.0833"
|
||||
gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#61D2C4" />
|
||||
<stop offset="1" stop-color="#40CAA1" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.7 KiB |
@@ -1,15 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 14 15" fill="none">
|
||||
<g clip-path="url(#clip0_5676_3579)">
|
||||
<path
|
||||
d="M6.46665 1.10308C6.74565 0.941999 7.19801 0.941998 7.47701 1.10308L11.7403 3.56452C12.2984 3.88669 12.2984 4.40902 11.7403 4.73119L7.53312 7.16023C7.25411 7.32132 6.80176 7.32132 6.52275 7.16023L2.25942 4.6988C1.70141 4.37663 1.70141 3.85429 2.25941 3.53213L6.46665 1.10308Z" />
|
||||
<path
|
||||
d="M1.49066 6.17483C1.49066 5.7238 1.80731 5.54098 2.19792 5.7665L6.13886 8.0418C6.36206 8.17067 6.54301 8.48407 6.54301 8.74181V12.9081C6.54301 13.3592 6.22636 13.542 5.83575 13.3165L1.89481 11.0411C1.6716 10.9123 1.49066 10.5989 1.49066 10.3411V6.17483Z" />
|
||||
<path
|
||||
d="M7.45634 8.77325C7.45634 8.51552 7.63729 8.20212 7.86049 8.07325L11.8021 5.79758C12.1927 5.57206 12.5093 5.75488 12.5093 6.20591V10.3717C12.5093 10.6295 12.3284 10.9429 12.1052 11.0717L8.1636 13.3474C7.77299 13.5729 7.45634 13.3901 7.45634 12.9391V8.77325Z" />
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_5676_3579">
|
||||
<rect width="14" height="14" fill="white" transform="translate(0 0.213127)" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 14 14">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M6.76503 0.691246C6.92009 0.659355 7.08002 0.659355 7.23508 0.691246C7.41432 0.728111 7.57453 0.817843 7.70189 0.889181C7.71376 0.895824 7.72533 0.902308 7.73661 0.908575L12.0533 3.30672C12.0652 3.31335 12.0775 3.32013 12.0901 3.32707C12.2249 3.40133 12.3945 3.4947 12.5246 3.63597C12.6372 3.75811 12.7224 3.90288 12.7745 4.06058C12.8348 4.24299 12.8341 4.43653 12.8335 4.59045C12.8334 4.60484 12.8334 4.61888 12.8334 4.63253V9.36751C12.8334 9.38116 12.8334 9.3952 12.8335 9.40959C12.8341 9.56351 12.8348 9.75705 12.7745 9.93946C12.7224 10.0972 12.6372 10.2419 12.5246 10.3641C12.3945 10.5053 12.2249 10.5987 12.0901 10.673C12.0775 10.6799 12.0652 10.6867 12.0533 10.6933L7.73661 13.0915C7.72533 13.0977 7.71375 13.1042 7.70189 13.1109C7.57453 13.1822 7.41432 13.2719 7.23508 13.3088C7.08002 13.3407 6.92009 13.3407 6.76503 13.3088C6.58578 13.2719 6.42558 13.1822 6.29821 13.1109C6.28635 13.1042 6.27477 13.0977 6.26349 13.0915L1.94683 10.6933C1.9349 10.6867 1.9226 10.6799 1.91 10.673C1.77517 10.5987 1.60565 10.5053 1.47546 10.3641C1.3629 10.2419 1.27772 10.0972 1.22562 9.93946C1.16535 9.75705 1.16605 9.56351 1.16662 9.40959C1.16667 9.3952 1.16672 9.38116 1.16672 9.36751V4.63253C1.16672 4.61888 1.16667 4.60484 1.16662 4.59045C1.16605 4.43653 1.16535 4.24299 1.22562 4.06058C1.27772 3.90288 1.3629 3.75811 1.47546 3.63597C1.60564 3.4947 1.77517 3.40133 1.91 3.32707C1.9226 3.32013 1.93489 3.31335 1.94683 3.30672L6.26349 0.908575C6.27477 0.902309 6.28635 0.895825 6.29821 0.889182C6.42558 0.817844 6.58578 0.728111 6.76503 0.691246ZM7.00005 1.83693C6.99917 1.83735 6.99823 1.8378 6.99727 1.83826C6.9636 1.8545 6.91848 1.87931 6.83008 1.92843L2.95122 4.08335L7.00003 6.33269L11.0489 4.08334L7.17003 1.92843C7.08163 1.87931 7.0365 1.8545 7.00284 1.83826C7.00187 1.8378 7.00094 1.83735 7.00005 1.83693ZM11.6667 5.07471V9.36751C11.6667 9.47425 11.6665 9.52888 11.6641 9.56843C11.664 9.5696 11.664 9.57071 11.6639 9.57178C11.663 9.57236 11.662 9.57296 11.6611 9.57359C11.6276 9.59488 11.58 9.62163 11.4867 9.67346L7.58338 11.842L7.58337 7.34324L11.6667 5.07471ZM6.4167 7.34324L2.33339 5.07473V9.36751C2.33339 9.47425 2.33363 9.52888 2.33601 9.56844C2.33608 9.5696 2.33615 9.57071 2.33622 9.57178C2.33712 9.57236 2.33806 9.57296 2.33905 9.57359C2.37247 9.59488 2.42011 9.62163 2.51341 9.67346L6.41672 11.842L6.4167 7.34324Z" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 2.4 KiB |
@@ -1,18 +1,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 14 15" fill="none">
|
||||
<path
|
||||
d="M4.35632 8.49118C4.35632 8.79915 4.10666 9.04881 3.79868 9.04881C3.49071 9.04881 3.24105 8.79915 3.24105 8.49118L3.24105 6.36137C3.24105 6.05339 3.49071 5.80373 3.79868 5.80373C4.10666 5.80373 4.35632 6.05339 4.35632 6.36137L4.35632 8.49118Z" />
|
||||
<path fill-rule="evenodd" clip-rule="evenodd"
|
||||
d="M3.79868 5.4847C4.49442 5.4847 5.05843 4.92069 5.05843 4.22495C5.05843 3.52922 4.49442 2.96521 3.79868 2.96521C3.10295 2.96521 2.53894 3.52922 2.53894 4.22495C2.53894 4.92069 3.10295 5.4847 3.79868 5.4847ZM3.79868 6.59996C5.11036 6.59996 6.17369 5.53663 6.17369 4.22495C6.17369 2.91327 5.11036 1.84995 3.79868 1.84995C2.487 1.84995 1.42368 2.91327 1.42368 4.22495C1.42368 5.53663 2.487 6.59996 3.79868 6.59996Z" />
|
||||
<path fill-rule="evenodd" clip-rule="evenodd"
|
||||
d="M6.79074 3.68998C6.79074 3.382 7.0404 3.13234 7.34838 3.13234C7.93704 3.13234 8.52062 3.24176 9.06606 3.45504C9.61153 3.66834 10.1092 3.98174 10.5298 4.37882C10.9505 4.77596 11.286 5.2492 11.5156 5.7724C11.7452 6.29569 11.8639 6.85778 11.8639 7.42627C11.8639 7.73424 11.6142 7.9839 11.3062 7.9839C10.9983 7.9839 10.7486 7.73424 10.7486 7.42627C10.7486 7.01345 10.6625 6.60383 10.4943 6.22051C10.3261 5.83709 10.0786 5.48655 9.76421 5.1898C9.4498 4.89299 9.07481 4.65597 8.65991 4.49373C8.24496 4.33147 7.79922 4.24761 7.34838 4.24761C7.0404 4.24761 6.79074 3.99795 6.79074 3.68998Z" />
|
||||
<path fill-rule="evenodd" clip-rule="evenodd"
|
||||
d="M3.79868 11.8873C4.49442 11.8873 5.05843 11.3233 5.05843 10.6276C5.05843 9.93185 4.49442 9.36785 3.79868 9.36785C3.10295 9.36785 2.53894 9.93185 2.53894 10.6276C2.53894 11.3233 3.10295 11.8873 3.79868 11.8873ZM3.79868 13.0026C5.11036 13.0026 6.17369 11.9393 6.17369 10.6276C6.17369 9.31591 5.11036 8.25258 3.79868 8.25258C2.487 8.25258 1.42368 9.31591 1.42368 10.6276C1.42368 11.9393 2.487 13.0026 3.79868 13.0026Z" />
|
||||
<path fill-rule="evenodd" clip-rule="evenodd"
|
||||
d="M10.7808 9.55902H9.81307C9.47678 9.55902 9.29277 9.55992 9.16063 9.57089C9.15546 9.57132 9.15056 9.57175 9.14592 9.57219C9.14549 9.57682 9.14506 9.58172 9.14463 9.58689C9.13365 9.71903 9.13276 9.90305 9.13276 10.2393V11.207C9.13276 11.5433 9.13365 11.7273 9.14463 11.8595C9.14506 11.8646 9.14549 11.8695 9.14592 11.8742C9.15056 11.8746 9.15546 11.875 9.16063 11.8755C9.29277 11.8864 9.47678 11.8873 9.81307 11.8873H10.7808C11.117 11.8873 11.3011 11.8864 11.4332 11.8755C11.4384 11.875 11.4433 11.8746 11.4479 11.8742C11.4483 11.8695 11.4488 11.8646 11.4492 11.8595C11.4602 11.7273 11.4611 11.5433 11.4611 11.207V10.2393C11.4611 9.90305 11.4602 9.71903 11.4492 9.58689C11.4488 9.58172 11.4483 9.57682 11.4479 9.57219C11.4433 9.57175 11.4384 9.57132 11.4332 9.57089C11.3011 9.55992 11.117 9.55902 10.7808 9.55902ZM8.14306 9.04491C8.01749 9.28663 8.01749 9.6042 8.01749 10.2393V11.207C8.01749 11.8421 8.01749 12.1597 8.14306 12.4014C8.24887 12.6051 8.41495 12.7712 8.61865 12.877C8.86037 13.0026 9.17794 13.0026 9.81307 13.0026H10.7808C11.4159 13.0026 11.7335 13.0026 11.9752 12.877C12.1789 12.7712 12.345 12.6051 12.4508 12.4014C12.5763 12.1597 12.5763 11.8421 12.5763 11.207V10.2393C12.5763 9.6042 12.5763 9.28663 12.4508 9.04491C12.345 8.84122 12.1789 8.67513 11.9752 8.56932C11.7335 8.44375 11.4159 8.44375 10.7808 8.44375H9.81307C9.17794 8.44375 8.86037 8.44375 8.61865 8.56932C8.41495 8.67513 8.24887 8.84122 8.14306 9.04491Z" />
|
||||
<path
|
||||
d="M5.05843 4.22495C5.05843 4.92069 4.49442 5.4847 3.79868 5.4847C3.10295 5.4847 2.53894 4.92069 2.53894 4.22495C2.53894 3.52922 3.10295 2.96521 3.79868 2.96521C4.49442 2.96521 5.05843 3.52922 5.05843 4.22495Z" />
|
||||
<path
|
||||
d="M5.05843 10.6276C5.05843 11.3233 4.49442 11.8873 3.79868 11.8873C3.10295 11.8873 2.53894 11.3233 2.53894 10.6276C2.53894 9.93185 3.10295 9.36785 3.79868 9.36785C4.49442 9.36785 5.05843 9.93185 5.05843 10.6276Z" />
|
||||
<path
|
||||
d="M9.81307 9.55902H10.7808C11.117 9.55902 11.3011 9.55992 11.4332 9.57089L11.4479 9.57219L11.4492 9.58689C11.4602 9.71903 11.4611 9.90305 11.4611 10.2393V11.207C11.4611 11.5433 11.4602 11.7273 11.4492 11.8595L11.4479 11.8742L11.4332 11.8755C11.3011 11.8864 11.117 11.8873 10.7808 11.8873H9.81307C9.47678 11.8873 9.29277 11.8864 9.16063 11.8755L9.14592 11.8742L9.14463 11.8595C9.13365 11.7273 9.13276 11.5433 9.13276 11.207V10.2393C9.13276 9.90305 9.13365 9.71903 9.14463 9.58689L9.14592 9.57219L9.16063 9.57089C9.29277 9.55992 9.47678 9.55902 9.81307 9.55902Z" />
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 14 15" >
|
||||
<path d="M4.35632 8.54584C4.35632 8.85381 4.10666 9.10347 3.79868 9.10347C3.49071 9.10347 3.24105 8.85381 3.24105 8.54584L3.24105 6.41602C3.24105 6.10805 3.49071 5.85839 3.79868 5.85839C4.10666 5.85839 4.35632 6.10805 4.35632 6.41602L4.35632 8.54584Z" />
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M3.79868 5.53935C4.49442 5.53935 5.05843 4.97535 5.05843 4.27961C5.05843 3.58387 4.49442 3.01987 3.79868 3.01987C3.10295 3.01987 2.53894 3.58387 2.53894 4.27961C2.53894 4.97535 3.10295 5.53935 3.79868 5.53935ZM3.79868 6.65462C5.11036 6.65462 6.17369 5.59129 6.17369 4.27961C6.17369 2.96793 5.11036 1.9046 3.79868 1.9046C2.487 1.9046 1.42368 2.96793 1.42368 4.27961C1.42368 5.59129 2.487 6.65462 3.79868 6.65462Z" />
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M6.79074 3.74463C6.79074 3.43666 7.0404 3.187 7.34838 3.187C7.93704 3.187 8.52062 3.29642 9.06606 3.5097C9.61153 3.723 10.1092 4.0364 10.5298 4.43348C10.9505 4.83062 11.286 5.30385 11.5156 5.82705C11.7452 6.35035 11.8639 6.91244 11.8639 7.48093C11.8639 7.7889 11.6142 8.03856 11.3062 8.03856C10.9983 8.03856 10.7486 7.7889 10.7486 7.48093C10.7486 7.06811 10.6625 6.65849 10.4943 6.27517C10.3261 5.89175 10.0786 5.54121 9.76421 5.24446C9.4498 4.94765 9.07481 4.71062 8.65991 4.54838C8.24496 4.38613 7.79922 4.30227 7.34838 4.30227C7.0404 4.30227 6.79074 4.05261 6.79074 3.74463Z" />
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M3.79868 11.942C4.49442 11.942 5.05843 11.378 5.05843 10.6822C5.05843 9.98651 4.49442 9.42251 3.79868 9.42251C3.10295 9.42251 2.53894 9.98651 2.53894 10.6822C2.53894 11.378 3.10295 11.942 3.79868 11.942ZM3.79868 13.0573C5.11036 13.0573 6.17369 11.9939 6.17369 10.6822C6.17369 9.37057 5.11036 8.30724 3.79868 8.30724C2.487 8.30724 1.42368 9.37057 1.42368 10.6822C1.42368 11.9939 2.487 13.0573 3.79868 13.0573Z" />
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M10.7808 9.61368H9.81307C9.47678 9.61368 9.29277 9.61457 9.16063 9.62555C9.15546 9.62598 9.15056 9.62641 9.14592 9.62684C9.14549 9.63148 9.14506 9.63638 9.14463 9.64155C9.13365 9.77368 9.13276 9.9577 9.13276 10.294V11.2617C9.13276 11.598 9.13365 11.782 9.14463 11.9141C9.14506 11.9193 9.14549 11.9242 9.14592 11.9288C9.15056 11.9292 9.15546 11.9297 9.16063 11.9301C9.29277 11.9411 9.47678 11.942 9.81307 11.942H10.7808C11.117 11.942 11.3011 11.9411 11.4332 11.9301C11.4384 11.9297 11.4433 11.9292 11.4479 11.9288C11.4483 11.9242 11.4488 11.9193 11.4492 11.9141C11.4602 11.782 11.4611 11.598 11.4611 11.2617V10.294C11.4611 9.9577 11.4602 9.77368 11.4492 9.64155C11.4488 9.63637 11.4483 9.63148 11.4479 9.62684C11.4433 9.62641 11.4384 9.62598 11.4332 9.62555C11.3011 9.61457 11.117 9.61368 10.7808 9.61368ZM8.14306 9.09957C8.01749 9.34129 8.01749 9.65886 8.01749 10.294V11.2617C8.01749 11.8968 8.01749 12.2144 8.14306 12.4561C8.24887 12.6598 8.41495 12.8259 8.61865 12.9317C8.86037 13.0572 9.17794 13.0573 9.81307 13.0573H10.7808C11.4159 13.0573 11.7335 13.0572 11.9752 12.9317C12.1789 12.8259 12.345 12.6598 12.4508 12.4561C12.5763 12.2144 12.5763 11.8968 12.5763 11.2617V10.294C12.5763 9.65886 12.5763 9.34129 12.4508 9.09957C12.345 8.89587 12.1789 8.72979 11.9752 8.62398C11.7335 8.49841 11.4159 8.49841 10.7808 8.49841H9.81307C9.17794 8.49841 8.86037 8.49841 8.61865 8.62398C8.41495 8.72979 8.24887 8.89587 8.14306 9.09957Z" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 3.3 KiB |
@@ -0,0 +1,34 @@
|
||||
<svg viewBox="0 0 32 33" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect y="0.75" width="32" height="32" rx="5.70173" fill="url(#paint0_linear_5533_28328)" />
|
||||
<path
|
||||
d="M11.6933 18.4849C11.6933 18.9866 11.2866 19.3933 10.7848 19.3933C10.2831 19.3933 9.87642 18.9866 9.87642 18.4849L9.87642 15.0153C9.87642 14.5136 10.2831 14.1069 10.7848 14.1069C11.2866 14.1069 11.6933 14.5136 11.6933 15.0153L11.6933 18.4849Z"
|
||||
fill="white" />
|
||||
<path fill-rule="evenodd" clip-rule="evenodd"
|
||||
d="M10.7848 13.5871C11.9182 13.5871 12.837 12.6683 12.837 11.5349C12.837 10.4015 11.9182 9.48273 10.7848 9.48273C9.65144 9.48273 8.73264 10.4015 8.73264 11.5349C8.73264 12.6683 9.65144 13.5871 10.7848 13.5871ZM10.7848 15.404C12.9217 15.404 14.6539 13.6717 14.6539 11.5349C14.6539 9.39812 12.9217 7.66589 10.7848 7.66589C8.64803 7.66589 6.9158 9.39812 6.9158 11.5349C6.9158 13.6717 8.64803 15.404 10.7848 15.404Z"
|
||||
fill="white" />
|
||||
<path fill-rule="evenodd" clip-rule="evenodd"
|
||||
d="M15.6591 10.6634C15.6591 10.1617 16.0658 9.755 16.5675 9.755C17.5265 9.755 18.4772 9.93326 19.3657 10.2807C20.2543 10.6282 21.065 11.1387 21.7503 11.7856C22.4356 12.4326 22.9822 13.2035 23.3562 14.0558C23.7302 14.9083 23.9235 15.824 23.9235 16.7501C23.9235 17.2518 23.5168 17.6585 23.0151 17.6585C22.5134 17.6585 22.1067 17.2518 22.1067 16.7501C22.1067 16.0776 21.9665 15.4103 21.6925 14.7858C21.4184 14.1612 21.0152 13.5902 20.5031 13.1067C19.9909 12.6232 19.38 12.2371 18.7041 11.9728C18.0281 11.7085 17.302 11.5718 16.5675 11.5718C16.0658 11.5718 15.6591 11.1651 15.6591 10.6634Z"
|
||||
fill="white" />
|
||||
<path fill-rule="evenodd" clip-rule="evenodd"
|
||||
d="M10.7848 24.0175C11.9182 24.0175 12.837 23.0986 12.837 21.9652C12.837 20.8318 11.9182 19.913 10.7848 19.913C9.65144 19.913 8.73264 20.8318 8.73264 21.9652C8.73264 23.0986 9.65144 24.0175 10.7848 24.0175ZM10.7848 25.8343C12.9217 25.8343 14.6539 24.1021 14.6539 21.9652C14.6539 19.8284 12.9217 18.0962 10.7848 18.0962C8.64803 18.0962 6.9158 19.8284 6.9158 21.9652C6.9158 24.1021 8.64803 25.8343 10.7848 25.8343Z"
|
||||
fill="white" />
|
||||
<path fill-rule="evenodd" clip-rule="evenodd"
|
||||
d="M22.1591 20.2245H20.5827C20.0348 20.2245 19.7351 20.2259 19.5198 20.2438C19.5114 20.2445 19.5034 20.2452 19.4958 20.2459C19.4951 20.2535 19.4944 20.2615 19.4937 20.2699C19.4759 20.4851 19.4744 20.7849 19.4744 21.3328V22.9092C19.4744 23.457 19.4759 23.7568 19.4937 23.972C19.4944 23.9805 19.4951 23.9884 19.4958 23.996C19.5034 23.9967 19.5114 23.9974 19.5198 23.9981C19.7351 24.016 20.0348 24.0174 20.5827 24.0174H22.1591C22.7069 24.0174 23.0067 24.016 23.222 23.9981C23.2304 23.9974 23.2384 23.9967 23.2459 23.996C23.2466 23.9884 23.2473 23.9805 23.248 23.972C23.2659 23.7568 23.2674 23.457 23.2674 22.9092V21.3327C23.2674 20.7849 23.2659 20.4851 23.248 20.2699C23.2473 20.2615 23.2466 20.2535 23.2459 20.2459C23.2384 20.2452 23.2304 20.2445 23.222 20.2438C23.0067 20.2259 22.7069 20.2245 22.1591 20.2245ZM17.8621 19.387C17.6576 19.7807 17.6576 20.2981 17.6576 21.3328V22.9092C17.6576 23.9438 17.6576 24.4612 17.8621 24.855C18.0345 25.1868 18.305 25.4574 18.6369 25.6297C19.0307 25.8343 19.548 25.8343 20.5827 25.8343H22.1591C23.1938 25.8343 23.7111 25.8343 24.1049 25.6297C24.4367 25.4574 24.7073 25.1868 24.8796 24.855C25.0842 24.4612 25.0842 23.9438 25.0842 22.9092V21.3327C25.0842 20.2981 25.0842 19.7807 24.8796 19.387C24.7073 19.0551 24.4367 18.7846 24.1049 18.6122C23.7111 18.4076 23.1938 18.4076 22.1591 18.4076H20.5827C19.548 18.4076 19.0307 18.4076 18.6369 18.6122C18.305 18.7846 18.0345 19.0551 17.8621 19.387Z"
|
||||
fill="white" />
|
||||
<path
|
||||
d="M12.837 11.5349C12.837 12.6683 11.9182 13.5871 10.7848 13.5871C9.65144 13.5871 8.73264 12.6683 8.73264 11.5349C8.73264 10.4015 9.65144 9.48273 10.7848 9.48273C11.9182 9.48273 12.837 10.4015 12.837 11.5349Z"
|
||||
fill="white" />
|
||||
<path
|
||||
d="M12.837 21.9652C12.837 23.0986 11.9182 24.0175 10.7848 24.0175C9.65144 24.0175 8.73264 23.0986 8.73264 21.9652C8.73264 20.8318 9.65144 19.913 10.7848 19.913C11.9182 19.913 12.837 20.8318 12.837 21.9652Z"
|
||||
fill="white" />
|
||||
<path
|
||||
d="M20.5827 20.2245H22.1591C22.7069 20.2245 23.0067 20.2259 23.222 20.2438L23.2459 20.2459L23.248 20.2699C23.2659 20.4851 23.2674 20.7849 23.2674 21.3327V22.9092C23.2674 23.457 23.2659 23.7568 23.248 23.972L23.2459 23.996L23.222 23.9981C23.0067 24.016 22.7069 24.0174 22.1591 24.0174H20.5827C20.0348 24.0174 19.7351 24.016 19.5198 23.9981L19.4958 23.996L19.4937 23.972C19.4759 23.7568 19.4744 23.457 19.4744 22.9092V21.3328C19.4744 20.7849 19.4759 20.4851 19.4937 20.2699L19.4958 20.2459L19.5198 20.2438C19.7351 20.2259 20.0348 20.2245 20.5827 20.2245Z"
|
||||
fill="white" />
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_5533_28328" x1="16" y1="0.75" x2="4.88889" y2="30.0833"
|
||||
gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#7895FE" />
|
||||
<stop offset="1" stop-color="#7177FF" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.9 KiB |
@@ -1,3 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="17" height="18" viewBox="0 0 19 20" fill="none">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M13.15 1.98982C12.4865 1.98982 11.8501 2.2534 11.3809 2.72259L3.72259 10.3809C2.94066 11.1628 2.50138 12.2234 2.50138 13.3292C2.50138 14.435 2.94066 15.4955 3.72259 16.2774C4.50451 17.0593 5.56502 17.4986 6.67083 17.4986C7.77664 17.4986 8.83715 17.0593 9.61907 16.2774L17.2774 8.61908C17.6028 8.29364 18.1305 8.29364 18.4559 8.61908C18.7814 8.94452 18.7814 9.47216 18.4559 9.79759L10.7976 17.4559C9.7031 18.5504 8.21866 19.1653 6.67083 19.1653C5.123 19.1653 3.63856 18.5504 2.54407 17.4559C1.44959 16.3614 0.834717 14.877 0.834717 13.3292C0.834717 11.7813 1.44959 10.2969 2.54407 9.20242L10.2024 1.54408C10.9842 0.762333 12.0444 0.323151 13.15 0.323151C14.2556 0.323151 15.3158 0.762332 16.0976 1.54408C16.8793 2.32583 17.3185 3.38611 17.3185 4.49167C17.3185 5.59723 16.8793 6.65751 16.0976 7.43926L8.43092 15.0976C7.96191 15.5666 7.32579 15.8301 6.6625 15.8301C5.99921 15.8301 5.36309 15.5666 4.89407 15.0976C4.42506 14.6286 4.16157 13.9925 4.16157 13.3292C4.16157 12.6659 4.42506 12.0298 4.89407 11.5607L11.9694 4.49373C12.2951 4.16849 12.8227 4.1688 13.1479 4.49443C13.4732 4.82006 13.4729 5.34769 13.1472 5.67294L6.07259 12.7393C5.91635 12.8957 5.82824 13.1081 5.82824 13.3292C5.82824 13.5504 5.91613 13.7626 6.07259 13.9191C6.22904 14.0755 6.44124 14.1634 6.6625 14.1634C6.88376 14.1634 7.09595 14.0755 7.25241 13.9191L14.9191 6.26075C15.3881 5.79159 15.6519 5.15505 15.6519 4.49167C15.6519 3.82814 15.3883 3.19178 14.9191 2.72259C14.4499 2.2534 13.8135 1.98982 13.15 1.98982Z" fill="#485058"/>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 19 20">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M13.15 1.98982C12.4865 1.98982 11.8501 2.2534 11.3809 2.72259L3.72259 10.3809C2.94066 11.1628 2.50138 12.2234 2.50138 13.3292C2.50138 14.435 2.94066 15.4955 3.72259 16.2774C4.50451 17.0593 5.56502 17.4986 6.67083 17.4986C7.77664 17.4986 8.83715 17.0593 9.61907 16.2774L17.2774 8.61908C17.6028 8.29364 18.1305 8.29364 18.4559 8.61908C18.7814 8.94452 18.7814 9.47216 18.4559 9.79759L10.7976 17.4559C9.7031 18.5504 8.21866 19.1653 6.67083 19.1653C5.123 19.1653 3.63856 18.5504 2.54407 17.4559C1.44959 16.3614 0.834717 14.877 0.834717 13.3292C0.834717 11.7813 1.44959 10.2969 2.54407 9.20242L10.2024 1.54408C10.9842 0.762333 12.0444 0.323151 13.15 0.323151C14.2556 0.323151 15.3158 0.762332 16.0976 1.54408C16.8793 2.32583 17.3185 3.38611 17.3185 4.49167C17.3185 5.59723 16.8793 6.65751 16.0976 7.43926L8.43092 15.0976C7.96191 15.5666 7.32579 15.8301 6.6625 15.8301C5.99921 15.8301 5.36309 15.5666 4.89407 15.0976C4.42506 14.6286 4.16157 13.9925 4.16157 13.3292C4.16157 12.6659 4.42506 12.0298 4.89407 11.5607L11.9694 4.49373C12.2951 4.16849 12.8227 4.1688 13.1479 4.49443C13.4732 4.82006 13.4729 5.34769 13.1472 5.67294L6.07259 12.7393C5.91635 12.8957 5.82824 13.1081 5.82824 13.3292C5.82824 13.5504 5.91613 13.7626 6.07259 13.9191C6.22904 14.0755 6.44124 14.1634 6.6625 14.1634C6.88376 14.1634 7.09595 14.0755 7.25241 13.9191L14.9191 6.26075C15.3881 5.79159 15.6519 5.15505 15.6519 4.49167C15.6519 3.82814 15.3883 3.19178 14.9191 2.72259C14.4499 2.2534 13.8135 1.98982 13.15 1.98982Z" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
3
packages/web/components/common/Icon/icons/moreLine.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="none">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M6.66666 3.33333C6.66666 2.59695 7.26361 2 7.99999 2C8.73637 2 9.33332 2.59695 9.33332 3.33333C9.33332 4.06971 8.73637 4.66667 7.99999 4.66667C7.26361 4.66667 6.66666 4.06971 6.66666 3.33333ZM6.66666 8C6.66666 7.26362 7.26361 6.66667 7.99999 6.66667C8.73637 6.66667 9.33332 7.26362 9.33332 8C9.33332 8.73638 8.73637 9.33333 7.99999 9.33333C7.26361 9.33333 6.66666 8.73638 6.66666 8ZM6.66666 12.6667C6.66666 11.9303 7.26361 11.3333 7.99999 11.3333C8.73637 11.3333 9.33332 11.9303 9.33332 12.6667C9.33332 13.403 8.73637 14 7.99999 14C7.26361 14 6.66666 13.403 6.66666 12.6667Z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 709 B |
@@ -1,4 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 14 14" fill="none">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd"
|
||||
d="M6.46554 1.66678L13.5344 1.66678C14.2052 1.66677 14.7588 1.66676 15.2098 1.70361C15.6782 1.74188 16.1088 1.82402 16.5133 2.03009C17.1405 2.34967 17.6504 2.8596 17.97 3.48681C18.1761 3.89126 18.2582 4.32184 18.2965 4.79026C18.3333 5.24125 18.3333 5.79488 18.3333 6.46568V13.5345C18.3333 14.2053 18.3333 14.759 18.2965 15.21C18.2582 15.6784 18.1761 16.109 17.97 16.5134C17.6504 17.1406 17.1405 17.6506 16.5133 17.9701C16.1088 18.1762 15.6782 18.2583 15.2098 18.2966C14.7588 18.3335 14.2052 18.3335 13.5344 18.3334H6.4656C5.79477 18.3335 5.24111 18.3335 4.7901 18.2966C4.32169 18.2583 3.8911 18.1762 3.48666 17.9701C2.85945 17.6506 2.34952 17.1406 2.02994 16.5134C1.82386 16.109 1.74173 15.6784 1.70345 15.21C1.66661 14.759 1.66662 14.2053 1.66663 13.5345L1.66663 6.4657C1.66662 5.79489 1.66661 5.24125 1.70345 4.79026C1.74173 4.32184 1.82386 3.89126 2.02994 3.48681C2.34952 2.8596 2.85945 2.34967 3.48666 2.03009C3.8911 1.82401 4.32169 1.74188 4.79011 1.70361C5.2411 1.66676 5.79474 1.66677 6.46554 1.66678ZM4.92583 3.36474C4.56048 3.39459 4.37364 3.44869 4.24331 3.5151C3.92971 3.67489 3.67474 3.92986 3.51495 4.24346C3.44854 4.37379 3.39444 4.56063 3.36459 4.92598C3.33394 5.30105 3.33329 5.7863 3.33329 6.50011V13.5001C3.33329 14.2139 3.33394 14.6992 3.36459 15.0742C3.39444 15.4396 3.44854 15.6264 3.51495 15.7568C3.67474 16.0704 3.9297 16.3253 4.24331 16.4851C4.37364 16.5515 4.56048 16.6056 4.92583 16.6355C5.3009 16.6661 5.78614 16.6668 6.49996 16.6668H13.5C14.2138 16.6668 14.699 16.6661 15.0741 16.6355C15.4394 16.6056 15.6263 16.5515 15.7566 16.4851C16.0702 16.3253 16.3252 16.0704 16.485 15.7568C16.5514 15.6264 16.6055 15.4396 16.6353 15.0742C16.666 14.6992 16.6666 14.2139 16.6666 13.5001V6.50011C16.6666 5.7863 16.666 5.30105 16.6353 4.92598C16.6055 4.56063 16.5514 4.3738 16.485 4.24346C16.3252 3.92986 16.0702 3.67489 15.7566 3.5151C15.6263 3.44869 15.4394 3.39459 15.0741 3.36474C14.699 3.3341 14.2138 3.33345 13.5 3.33345L6.49996 3.33345C5.78614 3.33345 5.3009 3.33409 4.92583 3.36474ZM6.66663 8.33345C6.66663 6.4925 8.15901 5.00011 9.99996 5.00011C11.8409 5.00011 13.3333 6.4925 13.3333 8.33345C13.3333 9.29727 12.9231 10.1666 12.2703 10.7741C12.2643 10.7796 12.2585 10.785 12.2529 10.7903L12.998 13.0258C13.0006 13.0333 13.0031 13.041 13.0057 13.0487C13.0483 13.1763 13.096 13.3194 13.1259 13.4457C13.1585 13.5836 13.197 13.8044 13.1342 14.0545C13.0565 14.3642 12.8632 14.6323 12.5941 14.804C12.3766 14.9427 12.1549 14.9759 12.0138 14.9886C11.8846 15.0002 11.7337 15.0002 11.5991 15.0001C11.591 15.0001 11.583 15.0001 11.575 15.0001H8.42491C8.41693 15.0001 8.40889 15.0001 8.40079 15.0001C8.26621 15.0002 8.11535 15.0002 7.98615 14.9886C7.84498 14.9759 7.62328 14.9427 7.40587 14.804C7.13671 14.6323 6.94344 14.3642 6.86569 14.0545C6.80289 13.8044 6.84147 13.5836 6.87407 13.4457C6.9039 13.3194 6.95165 13.1763 6.99425 13.0487C6.99681 13.041 6.99936 13.0333 7.00189 13.0258L7.74704 10.7903C7.74138 10.785 7.73558 10.7796 7.72961 10.7741C7.07677 10.1666 6.66663 9.29727 6.66663 8.33345ZM9.99996 6.66678C9.07949 6.66678 8.33329 7.41297 8.33329 8.33345C8.33329 8.8154 8.53679 9.24855 8.86499 9.55396L8.8759 9.56411C8.9552 9.6379 9.03351 9.71076 9.09515 9.77337C9.14953 9.82861 9.25814 9.94083 9.33672 10.0923C9.36955 10.1557 9.41141 10.2452 9.44027 10.3583C9.46912 10.4714 9.47528 10.5701 9.47679 10.6414C9.48006 10.7956 9.44924 10.9258 9.42682 11.0078C9.40609 11.0837 9.37746 11.1696 9.35211 11.2456L8.65615 13.3334H11.3438L10.6478 11.2455C10.6224 11.1695 10.5938 11.0837 10.5731 11.0078C10.5507 10.9258 10.5199 10.7956 10.5231 10.6414C10.5246 10.5701 10.5308 10.4714 10.5597 10.3583C10.5885 10.2452 10.6304 10.1556 10.6632 10.0923C10.7418 9.94083 10.8504 9.82862 10.9048 9.77337C10.9664 9.71074 11.0448 9.63786 11.1241 9.56406L11.1349 9.55396C11.4631 9.24855 11.6666 8.8154 11.6666 8.33345C11.6666 7.41297 10.9204 6.66678 9.99996 6.66678Z" />
|
||||
d="M4.52599 1.16675L9.47417 1.16675C9.94374 1.16674 10.3313 1.16674 10.647 1.19253C10.9749 1.21932 11.2763 1.27681 11.5594 1.42107C11.9984 1.64477 12.3554 2.00173 12.5791 2.44077C12.7233 2.72388 12.7808 3.02529 12.8076 3.35318C12.8334 3.66888 12.8334 4.05642 12.8334 4.52598V9.47419C12.8334 9.94375 12.8334 10.3313 12.8076 10.647C12.7808 10.9749 12.7233 11.2763 12.5791 11.5594C12.3554 11.9984 11.9984 12.3554 11.5594 12.5791C11.2763 12.7233 10.9749 12.7808 10.647 12.8076C10.3313 12.8334 9.94375 12.8334 9.47419 12.8334H4.52603C4.05645 12.8334 3.66889 12.8334 3.35318 12.8076C3.02529 12.7808 2.72388 12.7233 2.44077 12.5791C2.00173 12.3554 1.64477 11.9984 1.42107 11.5594C1.27681 11.2763 1.21932 10.9749 1.19253 10.647C1.16673 10.3313 1.16674 9.94374 1.16675 9.47417L1.16675 4.52599C1.16674 4.05642 1.16673 3.66888 1.19253 3.35318C1.21932 3.02529 1.27681 2.72388 1.42107 2.44077C1.64477 2.00173 2.00173 1.64477 2.44077 1.42107C2.72388 1.27681 3.02529 1.21932 3.35318 1.19253C3.66888 1.16673 4.05642 1.16674 4.52599 1.16675ZM3.44819 2.35532C3.19245 2.37622 3.06166 2.41409 2.97043 2.46057C2.7509 2.57243 2.57243 2.7509 2.46057 2.97043C2.41409 3.06166 2.37622 3.19244 2.35532 3.44819C2.33387 3.71074 2.33342 4.05041 2.33342 4.55008V9.45008C2.33342 9.94975 2.33387 10.2894 2.35532 10.552C2.37622 10.8077 2.41409 10.9385 2.46057 11.0297C2.57243 11.2493 2.7509 11.4277 2.97043 11.5396C3.06166 11.5861 3.19245 11.6239 3.44819 11.6448C3.71074 11.6663 4.05041 11.6667 4.55008 11.6667H9.45008C9.94975 11.6667 10.2894 11.6663 10.552 11.6448C10.8077 11.6239 10.9385 11.5861 11.0297 11.5396C11.2493 11.4277 11.4277 11.2493 11.5396 11.0297C11.5861 10.9385 11.6239 10.8077 11.6448 10.552C11.6663 10.2894 11.6667 9.94975 11.6667 9.45008V4.55008C11.6667 4.05041 11.6663 3.71074 11.6448 3.44819C11.6239 3.19245 11.5861 3.06166 11.5396 2.97043C11.4277 2.7509 11.2493 2.57243 11.0297 2.46058C10.9385 2.41409 10.8077 2.37622 10.552 2.35532C10.2894 2.33387 9.94975 2.33342 9.45008 2.33342L4.55008 2.33342C4.05041 2.33342 3.71074 2.33387 3.44819 2.35532ZM4.66675 5.83341C4.66675 4.54475 5.71142 3.50008 7.00008 3.50008C8.28875 3.50008 9.33341 4.54475 9.33341 5.83341C9.33341 6.50809 9.04631 7.11661 8.58932 7.54186C8.58515 7.54574 8.58108 7.54953 8.57712 7.55321L9.09873 9.11804C9.1005 9.12334 9.10229 9.12869 9.10408 9.13408C9.1339 9.22344 9.16732 9.3236 9.18821 9.41196C9.21103 9.50852 9.23803 9.6631 9.19407 9.83818C9.13965 10.0549 9.00436 10.2426 8.81595 10.3628C8.66376 10.4599 8.50857 10.4831 8.40975 10.492C8.31931 10.5001 8.21371 10.5001 8.1195 10.5001C8.11383 10.5001 8.1082 10.5001 8.10262 10.5001H5.89755C5.89196 10.5001 5.88633 10.5001 5.88066 10.5001C5.78646 10.5001 5.68085 10.5001 5.59042 10.492C5.4916 10.4831 5.33641 10.4599 5.18422 10.3628C4.99581 10.2426 4.86052 10.0549 4.80609 9.83818C4.76213 9.6631 4.78914 9.50852 4.81196 9.41196C4.83284 9.3236 4.86627 9.22343 4.89608 9.13407C4.89788 9.12869 4.89966 9.12334 4.90143 9.11804L5.42304 7.55321C5.41908 7.54953 5.41501 7.54574 5.41084 7.54186C4.95385 7.11661 4.66675 6.50809 4.66675 5.83341ZM7.00008 4.66675C6.35575 4.66675 5.83342 5.18908 5.83342 5.83341C5.83342 6.17079 5.97586 6.47399 6.2056 6.68777L6.21324 6.69488C6.26875 6.74653 6.32357 6.79753 6.36672 6.84136C6.40478 6.88003 6.48081 6.95858 6.53581 7.06465C6.5588 7.10896 6.5881 7.17165 6.6083 7.25081C6.62849 7.32998 6.63281 7.39904 6.63386 7.44895C6.63615 7.55691 6.61458 7.64803 6.59888 7.70549C6.58437 7.75862 6.56433 7.8187 6.54659 7.8719L6.05941 9.33341H7.94075L7.45356 7.87185C7.43582 7.81866 7.41579 7.7586 7.40128 7.70549C7.38558 7.64803 7.36401 7.55691 7.3663 7.44895C7.36736 7.39904 7.37167 7.32998 7.39187 7.25081C7.41207 7.17165 7.44137 7.10896 7.46435 7.06465C7.51935 6.95859 7.59538 6.88004 7.63345 6.84136C7.6766 6.79752 7.73144 6.74651 7.78696 6.69484L7.79456 6.68777C8.0243 6.47399 8.16675 6.17079 8.16675 5.83341C8.16675 5.18908 7.64441 4.66675 7.00008 4.66675Z" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.9 KiB |
@@ -1,6 +1,6 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import type { IconProps } from '@chakra-ui/react';
|
||||
import { Icon } from '@chakra-ui/react';
|
||||
import { Box, Icon } from '@chakra-ui/react';
|
||||
import { iconPaths } from './constants';
|
||||
import type { IconNameType } from './type.d';
|
||||
|
||||
@@ -25,7 +25,9 @@ const MyIcon = ({ name, w = 'auto', h = 'auto', ...props }: { name: IconNameType
|
||||
fill={'currentcolor'}
|
||||
{...props}
|
||||
/>
|
||||
) : null;
|
||||
) : (
|
||||
<Box w={w} h={'1px'}></Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default React.memo(MyIcon);
|
||||
|
||||
24
packages/web/components/common/Image/PhotoView.tsx
Normal file
@@ -0,0 +1,24 @@
|
||||
import React from 'react';
|
||||
import { PhotoProvider, PhotoView } from 'react-photo-view';
|
||||
import 'react-photo-view/dist/react-photo-view.css';
|
||||
import { Box, Image, ImageProps } from '@chakra-ui/react';
|
||||
import { useSystem } from '../../../hooks/useSystem';
|
||||
import Loading from '../MyLoading';
|
||||
|
||||
const MyPhotoView = (props: ImageProps) => {
|
||||
const { isPc } = useSystem();
|
||||
return (
|
||||
<PhotoProvider
|
||||
maskOpacity={0.6}
|
||||
bannerVisible={!isPc}
|
||||
photoClosable
|
||||
loadingElement={<Loading fixed={false} />}
|
||||
>
|
||||
<PhotoView src={props.src}>
|
||||
<Image cursor={'pointer'} {...props} />
|
||||
</PhotoView>
|
||||
</PhotoProvider>
|
||||
);
|
||||
};
|
||||
|
||||
export default MyPhotoView;
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
import MyIcon from '../Icon';
|
||||
import MyDivider from '../MyDivider';
|
||||
import type { IconNameType } from '../Icon/type';
|
||||
import { useSystem } from '../../../hooks/useSystem';
|
||||
|
||||
export type MenuItemType = 'primary' | 'danger';
|
||||
|
||||
@@ -46,12 +47,26 @@ const MyMenu = ({
|
||||
_hover: {
|
||||
backgroundColor: 'primary.50',
|
||||
color: 'primary.600'
|
||||
},
|
||||
_focus: {
|
||||
backgroundColor: 'primary.50',
|
||||
color: 'primary.600'
|
||||
},
|
||||
_active: {
|
||||
backgroundColor: 'primary.50',
|
||||
color: 'primary.600'
|
||||
}
|
||||
},
|
||||
danger: {
|
||||
color: 'red.600',
|
||||
_hover: {
|
||||
background: 'red.1'
|
||||
},
|
||||
_focus: {
|
||||
background: 'red.1'
|
||||
},
|
||||
_active: {
|
||||
background: 'red.1'
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -63,10 +78,14 @@ const MyMenu = ({
|
||||
alignItems: 'center',
|
||||
fontSize: 'sm'
|
||||
};
|
||||
|
||||
const { isPc } = useSystem();
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
const closeTimer = useRef<any>();
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
|
||||
const formatTrigger = !isPc ? 'click' : trigger;
|
||||
|
||||
useOutsideClick({
|
||||
ref: ref,
|
||||
handler: () => {
|
||||
@@ -88,17 +107,19 @@ const MyMenu = ({
|
||||
direction={'ltr'}
|
||||
isLazy
|
||||
lazyBehavior={'keepMounted'}
|
||||
placement="bottom-start"
|
||||
computePositionOnMount
|
||||
>
|
||||
<Box
|
||||
ref={ref}
|
||||
onMouseEnter={() => {
|
||||
if (trigger === 'hover') {
|
||||
if (formatTrigger === 'hover') {
|
||||
setIsOpen(true);
|
||||
}
|
||||
clearTimeout(closeTimer.current);
|
||||
}}
|
||||
onMouseLeave={() => {
|
||||
if (trigger === 'hover') {
|
||||
if (formatTrigger === 'hover') {
|
||||
closeTimer.current = setTimeout(() => {
|
||||
setIsOpen(false);
|
||||
}, 100);
|
||||
@@ -109,7 +130,7 @@ const MyMenu = ({
|
||||
position={'relative'}
|
||||
onClickCapture={(e) => {
|
||||
e.stopPropagation();
|
||||
if (trigger === 'click') {
|
||||
if (formatTrigger === 'click') {
|
||||
setIsOpen(!isOpen);
|
||||
}
|
||||
}}
|
||||
@@ -126,12 +147,11 @@ const MyMenu = ({
|
||||
<Box position={'relative'}>{Button}</Box>
|
||||
</Box>
|
||||
<MenuList
|
||||
minW={isOpen ? `${width}px !important` : 0}
|
||||
minW={isOpen ? `${width}px !important` : '80px'}
|
||||
maxW={'300px'}
|
||||
p={'6px'}
|
||||
border={'1px solid #fff'}
|
||||
boxShadow={
|
||||
'0px 2px 4px rgba(161, 167, 179, 0.25), 0px 0px 1px rgba(121, 141, 159, 0.25);'
|
||||
}
|
||||
boxShadow={'3'}
|
||||
>
|
||||
{menuList.map((item, i) => {
|
||||
return (
|
||||
|
||||
@@ -59,12 +59,12 @@ const MyModal = ({
|
||||
<ModalHeader
|
||||
display={'flex'}
|
||||
alignItems={'center'}
|
||||
fontWeight={500}
|
||||
background={'#FBFBFC'}
|
||||
borderBottom={'1px solid #F4F6F8'}
|
||||
roundedTop={'lg'}
|
||||
py={'10px'}
|
||||
fontSize={'md'}
|
||||
fontWeight={'bold'}
|
||||
>
|
||||
{iconSrc && (
|
||||
<>
|
||||
|
||||
98
packages/web/components/common/MyPopover/PopoverConfirm.tsx
Normal file
@@ -0,0 +1,98 @@
|
||||
import React, { useMemo } from 'react';
|
||||
import MyPopover from './index';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import MyIcon from '../Icon';
|
||||
import { useRequest2 } from '../../../hooks/useRequest';
|
||||
import {
|
||||
Popover,
|
||||
PopoverTrigger,
|
||||
PopoverContent,
|
||||
useDisclosure,
|
||||
PlacementWithLogical,
|
||||
HStack,
|
||||
Box,
|
||||
Button,
|
||||
PopoverArrow
|
||||
} from '@chakra-ui/react';
|
||||
|
||||
const PopoverConfirm = ({
|
||||
content,
|
||||
showCancel,
|
||||
type,
|
||||
Trigger,
|
||||
placement = 'bottom-start',
|
||||
offset,
|
||||
onConfirm
|
||||
}: {
|
||||
content: string;
|
||||
showCancel?: boolean;
|
||||
type?: 'info' | 'delete';
|
||||
Trigger: React.ReactNode;
|
||||
placement?: PlacementWithLogical;
|
||||
offset?: [number, number];
|
||||
onConfirm: () => any;
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const map = useMemo(() => {
|
||||
const map = {
|
||||
info: {
|
||||
variant: 'primary',
|
||||
icon: 'common/confirm/commonTip'
|
||||
},
|
||||
delete: {
|
||||
variant: 'dangerFill',
|
||||
icon: 'common/confirm/deleteTip'
|
||||
}
|
||||
};
|
||||
if (type && map[type]) return map[type];
|
||||
return map.info;
|
||||
}, [type, t]);
|
||||
|
||||
const firstFieldRef = React.useRef(null);
|
||||
const { onOpen, onClose, isOpen } = useDisclosure();
|
||||
|
||||
const { runAsync: onclickConfirm, loading } = useRequest2(onConfirm, {
|
||||
onSuccess: onClose
|
||||
});
|
||||
|
||||
return (
|
||||
<Popover
|
||||
isOpen={isOpen}
|
||||
initialFocusRef={firstFieldRef}
|
||||
onOpen={onOpen}
|
||||
onClose={onClose}
|
||||
placement={placement}
|
||||
offset={offset}
|
||||
closeOnBlur={false}
|
||||
trigger={'click'}
|
||||
openDelay={100}
|
||||
closeDelay={100}
|
||||
isLazy
|
||||
lazyBehavior="keepMounted"
|
||||
arrowSize={10}
|
||||
>
|
||||
<PopoverTrigger>{Trigger}</PopoverTrigger>
|
||||
<PopoverContent p={4}>
|
||||
<PopoverArrow />
|
||||
|
||||
<HStack alignItems={'flex-start'} color={'myGray.700'}>
|
||||
<MyIcon name={map.icon as any} w={'1.5rem'} />
|
||||
<Box fontSize={'sm'}>{content}</Box>
|
||||
</HStack>
|
||||
<HStack mt={1} justifyContent={'flex-end'}>
|
||||
{showCancel && (
|
||||
<Button variant={'whiteBase'} size="sm" onClick={onClose}>
|
||||
{t('common.Cancel')}
|
||||
</Button>
|
||||
)}
|
||||
<Button isLoading={loading} variant={map.variant} size="sm" onClick={onclickConfirm}>
|
||||
{t('common.Confirm')}
|
||||
</Button>
|
||||
</HStack>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
);
|
||||
};
|
||||
|
||||
export default PopoverConfirm;
|
||||
@@ -4,7 +4,8 @@ import {
|
||||
PopoverTrigger,
|
||||
PopoverContent,
|
||||
useDisclosure,
|
||||
PlacementWithLogical
|
||||
PlacementWithLogical,
|
||||
PopoverArrow
|
||||
} from '@chakra-ui/react';
|
||||
|
||||
const MyPopover = ({
|
||||
@@ -40,7 +41,10 @@ const MyPopover = ({
|
||||
lazyBehavior="keepMounted"
|
||||
>
|
||||
<PopoverTrigger>{Trigger}</PopoverTrigger>
|
||||
<PopoverContent p={4}>{children({ onClose })}</PopoverContent>
|
||||
<PopoverContent p={4}>
|
||||
<PopoverArrow />
|
||||
{children({ onClose })}
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -2,7 +2,7 @@ import React from 'react';
|
||||
import { Flex, Box, BoxProps } from '@chakra-ui/react';
|
||||
import MyIcon from '../Icon';
|
||||
|
||||
type Props = BoxProps & {
|
||||
type Props = Omit<BoxProps, 'onChange'> & {
|
||||
list: {
|
||||
icon?: string;
|
||||
label: string | React.ReactNode;
|
||||
@@ -12,7 +12,7 @@ type Props = BoxProps & {
|
||||
onChange: (e: string) => void;
|
||||
};
|
||||
|
||||
const RowTabs = ({ list, value, onChange, py = '7px', px = '12px', ...props }: Props) => {
|
||||
const FillRowTabs = ({ list, value, onChange, py = '7px', px = '12px', ...props }: Props) => {
|
||||
return (
|
||||
<Box
|
||||
display={'inline-flex'}
|
||||
@@ -55,4 +55,4 @@ const RowTabs = ({ list, value, onChange, py = '7px', px = '12px', ...props }: P
|
||||
);
|
||||
};
|
||||
|
||||
export default RowTabs;
|
||||
export default FillRowTabs;
|
||||
@@ -1,18 +1,25 @@
|
||||
import React, { useMemo } from 'react';
|
||||
import { Box, Flex, Grid, Image } from '@chakra-ui/react';
|
||||
import type { GridProps } from '@chakra-ui/react';
|
||||
import type { FlexProps, GridProps } from '@chakra-ui/react';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||
import MyIcon from '../Icon';
|
||||
|
||||
// @ts-ignore
|
||||
interface Props extends GridProps {
|
||||
list: { id: string; icon?: string; label: string | React.ReactNode }[];
|
||||
activeId: string;
|
||||
type Props<ValueType = string> = Omit<GridProps, 'onChange'> & {
|
||||
list: { icon?: string; label: string | React.ReactNode; value: ValueType }[];
|
||||
value: ValueType;
|
||||
size?: 'sm' | 'md' | 'lg';
|
||||
onChange: (id: string) => void;
|
||||
}
|
||||
inlineStyles?: FlexProps;
|
||||
onChange: (value: ValueType) => void;
|
||||
};
|
||||
|
||||
const Tabs = ({ list, size = 'md', activeId, onChange, ...props }: Props) => {
|
||||
const LightRowTabs = <ValueType = string,>({
|
||||
list,
|
||||
size = 'md',
|
||||
value,
|
||||
onChange,
|
||||
inlineStyles,
|
||||
...props
|
||||
}: Props<ValueType>) => {
|
||||
const { t } = useTranslation();
|
||||
const sizeMap = useMemo(() => {
|
||||
switch (size) {
|
||||
@@ -48,14 +55,15 @@ const Tabs = ({ list, size = 'md', activeId, onChange, ...props }: Props) => {
|
||||
>
|
||||
{list.map((item) => (
|
||||
<Flex
|
||||
key={item.id}
|
||||
key={item.value as string}
|
||||
py={sizeMap.inlineP}
|
||||
alignItems={'center'}
|
||||
justifyContent={'center'}
|
||||
borderBottom={'2px solid transparent'}
|
||||
px={3}
|
||||
whiteSpace={'nowrap'}
|
||||
{...(activeId === item.id
|
||||
{...inlineStyles}
|
||||
{...(value === item.value
|
||||
? {
|
||||
color: 'primary.600',
|
||||
cursor: 'default',
|
||||
@@ -66,8 +74,8 @@ const Tabs = ({ list, size = 'md', activeId, onChange, ...props }: Props) => {
|
||||
cursor: 'pointer'
|
||||
})}
|
||||
onClick={() => {
|
||||
if (activeId === item.id) return;
|
||||
onChange(item.id);
|
||||
if (value === item.value) return;
|
||||
onChange(item.value);
|
||||
}}
|
||||
>
|
||||
{item.icon && (
|
||||
@@ -86,4 +94,4 @@ const Tabs = ({ list, size = 'md', activeId, onChange, ...props }: Props) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default Tabs;
|
||||
export default LightRowTabs;
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { useMemo } from 'react';
|
||||
import { Flex, type FlexProps } from '@chakra-ui/react';
|
||||
import { Box, Flex, type FlexProps } from '@chakra-ui/react';
|
||||
|
||||
type ColorSchemaType = 'white' | 'blue' | 'green' | 'red' | 'yellow' | 'gray' | 'purple' | 'adora';
|
||||
|
||||
@@ -7,6 +7,7 @@ export type TagProps = FlexProps & {
|
||||
children: React.ReactNode | React.ReactNode[];
|
||||
colorSchema?: ColorSchemaType;
|
||||
type?: 'fill' | 'borderFill' | 'borderSolid';
|
||||
showDot?: boolean;
|
||||
};
|
||||
|
||||
const colorMap: Record<
|
||||
@@ -59,7 +60,7 @@ const colorMap: Record<
|
||||
}
|
||||
};
|
||||
|
||||
const MyTag = ({ children, colorSchema = 'blue', type = 'fill', ...props }: TagProps) => {
|
||||
const MyTag = ({ children, colorSchema = 'blue', type = 'fill', showDot, ...props }: TagProps) => {
|
||||
const theme = useMemo(() => {
|
||||
return colorMap[colorSchema];
|
||||
}, [colorSchema]);
|
||||
@@ -75,10 +76,11 @@ const MyTag = ({ children, colorSchema = 'blue', type = 'fill', ...props }: TagP
|
||||
whiteSpace={'nowrap'}
|
||||
borderWidth={'1px'}
|
||||
{...theme}
|
||||
{...props}
|
||||
borderColor={type !== 'fill' ? theme.borderColor : 'transparent'}
|
||||
bg={type !== 'borderSolid' ? theme.bg : 'transparent'}
|
||||
{...props}
|
||||
>
|
||||
{showDot && <Box w={1.5} h={1.5} borderRadius={'md'} bg={theme.color} mr={1.5}></Box>}
|
||||
{children}
|
||||
</Flex>
|
||||
);
|
||||
|
||||
@@ -17,12 +17,12 @@ export const useConfirm = (props?: {
|
||||
const map = {
|
||||
common: {
|
||||
title: t('common.confirm.Common Tip'),
|
||||
bg: undefined,
|
||||
variant: 'primary',
|
||||
iconSrc: 'common/confirm/commonTip'
|
||||
},
|
||||
delete: {
|
||||
title: t('common.Delete Warning'),
|
||||
bg: 'red.600',
|
||||
variant: 'dangerFill',
|
||||
iconSrc: 'common/confirm/deleteTip'
|
||||
}
|
||||
};
|
||||
@@ -108,7 +108,7 @@ export const useConfirm = (props?: {
|
||||
|
||||
<Button
|
||||
size={'sm'}
|
||||
bg={bg ? bg : map.bg}
|
||||
variant={map.variant}
|
||||
isDisabled={countDownAmount > 0}
|
||||
ml={3}
|
||||
isLoading={isLoading || requesting}
|
||||
@@ -129,7 +129,7 @@ export const useConfirm = (props?: {
|
||||
</MyModal>
|
||||
);
|
||||
},
|
||||
[customContent, hideFooter, iconSrc, isOpen, map.bg, onClose, showCancel, t, title]
|
||||
[customContent, hideFooter, iconSrc, isOpen, map.variant, onClose, showCancel, t, title]
|
||||
);
|
||||
|
||||
return {
|
||||
|
||||
7
packages/web/hooks/useSystem.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import { useMediaQuery } from '@chakra-ui/react';
|
||||
|
||||
export const useSystem = () => {
|
||||
const [isPc] = useMediaQuery('(min-width: 900px)');
|
||||
|
||||
return { isPc };
|
||||
};
|
||||
@@ -9,14 +9,19 @@
|
||||
"Chat Logs Tips": "Logs will record online, shared and API (chatId required) conversation records for this app",
|
||||
"Chat logs": "Chat Logs",
|
||||
"Confirm Del App Tip": "Confirm to delete this app and all its chat records?",
|
||||
"Confirm copy app tip": "The system will create an application with the same configuration for you, but the permission will not be copied, please confirm!",
|
||||
"Confirm delete folder tip": "Are you sure to delete this folder? All the following applications and corresponding chat records will be deleted, please confirm!",
|
||||
"Connection is invalid": "Connection is invalid",
|
||||
"Connection type is different": "Connection type is different",
|
||||
"Copy Module Config": "Copy Config",
|
||||
"Copy one app": "Copy",
|
||||
"Create bot": "App",
|
||||
"Create copy success": "Create copy success",
|
||||
"Create one ai app": "Create AI app",
|
||||
"Current settings": "Current settings",
|
||||
"Dataset Quote Template": "Knowledge Base QA Mode",
|
||||
"Edit app": "Edit app",
|
||||
"Edit info": "Edit info",
|
||||
"Export Config Successful": "Config copied, please check for important data",
|
||||
"Export Configs": "Export Configs",
|
||||
"Feedback Count": "User Feedback",
|
||||
@@ -34,8 +39,15 @@
|
||||
"My Apps": "My Apps",
|
||||
"Output Field Settings": "Output Field Settings",
|
||||
"Paste Config": "Paste Config",
|
||||
"Publish channel": "Publish channel",
|
||||
"Publish success": "Publish success",
|
||||
"Setting app": "Settings",
|
||||
"Setting plugin": "Setting plugin",
|
||||
"To Chat": "Go to Chat",
|
||||
"To Settings": "View Details",
|
||||
"Transition to workflow": "Transition to workflow",
|
||||
"Transition to workflow create new placeholder": "Create a new application instead of modifying the current one",
|
||||
"Transition to workflow create new tip": "After converting to workflow, it will not be able to convert back to simple mode, please confirm!",
|
||||
"Variable Key Repeat Tip": "Variable key is duplicate",
|
||||
"app": {
|
||||
"modules": {
|
||||
@@ -48,7 +60,7 @@
|
||||
"Confirm Sync": "Using the latest template will overwrite the existing one and may result in the loss of some previous configuration information. Please confirm.",
|
||||
"Custom Title Tip": "This title will be displayed during the conversation",
|
||||
"My Modules": "My Modules",
|
||||
"No Modules": "No modules yet~",
|
||||
"No Modules": "No plugins yet~",
|
||||
"System Module": "System Module",
|
||||
"type": "\"{{type}}\" type\n{{description}}"
|
||||
},
|
||||
@@ -56,7 +68,20 @@
|
||||
"Title is required": "Module name cannot be empty"
|
||||
},
|
||||
"type": {
|
||||
"All": "All",
|
||||
"Create http plugin tip": "Create plug-ins in batches using OpenAPI schema, compatible with GPTs format.",
|
||||
"Create one plugin tip": "The input and output workflows can be customized",
|
||||
"Create plugin bot": "Create plugin bot",
|
||||
"Create simple bot": "Create simple bot",
|
||||
"Create simple bot tip": "Create simple AI applications in form form",
|
||||
"Create workflow bot": "Create workflow bot",
|
||||
"Create workflow tip": "Through the way of low code, build a logically complex multi-round dialogue AI application, recommended for advanced players",
|
||||
"Http plugin": "Http plugin",
|
||||
"Plugin": "Plugin",
|
||||
"Simple bot": "Simple bot",
|
||||
"Workflow bot": "Workflow"
|
||||
},
|
||||
"version": {
|
||||
"Revert success": "Revert success"
|
||||
}
|
||||
}
|
||||
@@ -122,6 +122,7 @@
|
||||
"Status": "Status",
|
||||
"Submit failed": "Submit failed",
|
||||
"Submit success": "Submit success",
|
||||
"Success": "Success",
|
||||
"Sync success": "Sync success",
|
||||
"System Output": "System Output",
|
||||
"System version": "System version",
|
||||
@@ -256,6 +257,7 @@
|
||||
"Quote templates": "Quote content templates",
|
||||
"Random": "Diverge",
|
||||
"Save and preview": "Save and preview",
|
||||
"Saved time": "Saved: {{time}}",
|
||||
"Search team tags": "Search tags",
|
||||
"Select TTS": "Select voice playback mode",
|
||||
"Select app from template": "Select from template",
|
||||
@@ -285,7 +287,6 @@
|
||||
"Whisper": "Voice input",
|
||||
"Whisper Tip": "Configure voice input related parameters",
|
||||
"Whisper config": "Voice input configuration",
|
||||
"create app": "Create your own AI app",
|
||||
"deterministic": "Rigorous",
|
||||
"edit": {
|
||||
"Confirm Save App Tip": "This app may be in advanced arrangement mode, saving will overwrite the advanced arrangement configuration, please confirm!",
|
||||
@@ -1128,6 +1129,7 @@
|
||||
"Create manual collection": "Create manual collection",
|
||||
"Delete Dataset Error": "Delete Dataset Error",
|
||||
"Edit Folder": "Edit Folder",
|
||||
"Edit Info": "Edit Information",
|
||||
"Export": "Export",
|
||||
"Export Dataset Limit Error": "Export Dataset Error",
|
||||
"File Input": "File Input",
|
||||
@@ -1218,6 +1220,7 @@
|
||||
"Module": "Module",
|
||||
"Plugin": "Plugin",
|
||||
"Store": "App Store",
|
||||
"Studio": "Studio",
|
||||
"Tools": "Tools"
|
||||
},
|
||||
"permission": {
|
||||