Compare commits
24 Commits
gru/projec
...
test-gate
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
361e255af8 | ||
|
|
2b888fb0fa | ||
|
|
2128d306ad | ||
|
|
e59816aba4 | ||
|
|
ded0383ac4 | ||
|
|
81202c53a8 | ||
|
|
e74ab643fe | ||
|
|
3b0f0a8108 | ||
|
|
165b783a95 | ||
|
|
d7b9f94270 | ||
|
|
5a5367d30b | ||
|
|
8ed35ffe7e | ||
|
|
0f866fc552 | ||
|
|
05c7ba4483 | ||
|
|
fa80ce3a77 | ||
|
|
830358aa72 | ||
|
|
02b214b3ec | ||
|
|
a171c7b11c | ||
|
|
802de11363 | ||
|
|
b4ecfb0b79 | ||
|
|
331b851a78 | ||
|
|
50d235c42a | ||
|
|
9838593451 | ||
|
|
c25cd48e72 |
3
.vscode/settings.json
vendored
@@ -27,5 +27,8 @@
|
||||
},
|
||||
"markdown.copyFiles.destination": {
|
||||
"/docSite/content/**/*": "${documentWorkspaceFolder}/docSite/assets/imgs/"
|
||||
},
|
||||
"[svg]": {
|
||||
"editor.defaultFormatter": "jock.svg"
|
||||
}
|
||||
}
|
||||
@@ -132,15 +132,15 @@ services:
|
||||
# fastgpt
|
||||
sandbox:
|
||||
container_name: sandbox
|
||||
image: ghcr.io/labring/fastgpt-sandbox:v4.9.9 # git
|
||||
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt-sandbox:v4.9.9 # 阿里云
|
||||
image: ghcr.io/labring/fastgpt-sandbox:v4.9.10-fix2 # git
|
||||
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt-sandbox:v4.9.10-fix2 # 阿里云
|
||||
networks:
|
||||
- fastgpt
|
||||
restart: always
|
||||
fastgpt-mcp-server:
|
||||
container_name: fastgpt-mcp-server
|
||||
image: ghcr.io/labring/fastgpt-mcp_server:v4.9.9 # git
|
||||
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt-mcp_server:v4.9.9 # 阿里云
|
||||
image: ghcr.io/labring/fastgpt-mcp_server:v4.9.10-fix2 # git
|
||||
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt-mcp_server:v4.9.10-fix2 # 阿里云
|
||||
ports:
|
||||
- 3005:3000
|
||||
networks:
|
||||
@@ -150,8 +150,8 @@ services:
|
||||
- FASTGPT_ENDPOINT=http://fastgpt:3000
|
||||
fastgpt:
|
||||
container_name: fastgpt
|
||||
image: ghcr.io/labring/fastgpt:v4.9.9 # git
|
||||
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt:v4.9.9 # 阿里云
|
||||
image: ghcr.io/labring/fastgpt:v4.9.10-fix2 # git
|
||||
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt:v4.9.10-fix2 # 阿里云
|
||||
ports:
|
||||
- 3000:3000
|
||||
networks:
|
||||
|
||||
@@ -109,15 +109,15 @@ services:
|
||||
# fastgpt
|
||||
sandbox:
|
||||
container_name: sandbox
|
||||
image: ghcr.io/labring/fastgpt-sandbox:v4.9.9 # git
|
||||
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt-sandbox:v4.9.9 # 阿里云
|
||||
image: ghcr.io/labring/fastgpt-sandbox:v4.9.10-fix2 # git
|
||||
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt-sandbox:v4.9.10-fix2 # 阿里云
|
||||
networks:
|
||||
- fastgpt
|
||||
restart: always
|
||||
fastgpt-mcp-server:
|
||||
container_name: fastgpt-mcp-server
|
||||
image: ghcr.io/labring/fastgpt-mcp_server:v4.9.9 # git
|
||||
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt-mcp_server:v4.9.9 # 阿里云
|
||||
image: ghcr.io/labring/fastgpt-mcp_server:v4.9.10-fix2 # git
|
||||
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt-mcp_server:v4.9.10-fix2 # 阿里云
|
||||
ports:
|
||||
- 3005:3000
|
||||
networks:
|
||||
@@ -127,8 +127,8 @@ services:
|
||||
- FASTGPT_ENDPOINT=http://fastgpt:3000
|
||||
fastgpt:
|
||||
container_name: fastgpt
|
||||
image: ghcr.io/labring/fastgpt:v4.9.9 # git
|
||||
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt:v4.9.9 # 阿里云
|
||||
image: ghcr.io/labring/fastgpt:v4.9.10-fix2 # git
|
||||
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt:v4.9.10-fix2 # 阿里云
|
||||
ports:
|
||||
- 3000:3000
|
||||
networks:
|
||||
|
||||
@@ -96,15 +96,15 @@ services:
|
||||
# fastgpt
|
||||
sandbox:
|
||||
container_name: sandbox
|
||||
image: ghcr.io/labring/fastgpt-sandbox:v4.9.9 # git
|
||||
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt-sandbox:v4.9.9 # 阿里云
|
||||
image: ghcr.io/labring/fastgpt-sandbox:v4.9.10-fix2 # git
|
||||
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt-sandbox:v4.9.10-fix2 # 阿里云
|
||||
networks:
|
||||
- fastgpt
|
||||
restart: always
|
||||
fastgpt-mcp-server:
|
||||
container_name: fastgpt-mcp-server
|
||||
image: ghcr.io/labring/fastgpt-mcp_server:v4.9.9 # git
|
||||
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt-mcp_server:v4.9.9 # 阿里云
|
||||
image: ghcr.io/labring/fastgpt-mcp_server:v4.9.10-fix2 # git
|
||||
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt-mcp_server:v4.9.10-fix2 # 阿里云
|
||||
ports:
|
||||
- 3005:3000
|
||||
networks:
|
||||
@@ -114,8 +114,8 @@ services:
|
||||
- FASTGPT_ENDPOINT=http://fastgpt:3000
|
||||
fastgpt:
|
||||
container_name: fastgpt
|
||||
image: ghcr.io/labring/fastgpt:v4.9.9 # git
|
||||
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt:v4.9.9 # 阿里云
|
||||
image: ghcr.io/labring/fastgpt:v4.9.10-fix2 # git
|
||||
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt:v4.9.10-fix2 # 阿里云
|
||||
ports:
|
||||
- 3000:3000
|
||||
networks:
|
||||
|
||||
@@ -72,15 +72,15 @@ services:
|
||||
|
||||
sandbox:
|
||||
container_name: sandbox
|
||||
image: ghcr.io/labring/fastgpt-sandbox:v4.9.9 # git
|
||||
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt-sandbox:v4.9.9 # 阿里云
|
||||
image: ghcr.io/labring/fastgpt-sandbox:v4.9.10-fix2 # git
|
||||
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt-sandbox:v4.9.10-fix2 # 阿里云
|
||||
networks:
|
||||
- fastgpt
|
||||
restart: always
|
||||
fastgpt-mcp-server:
|
||||
container_name: fastgpt-mcp-server
|
||||
image: ghcr.io/labring/fastgpt-mcp_server:v4.9.9 # git
|
||||
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt-mcp_server:v4.9.9 # 阿里云
|
||||
image: ghcr.io/labring/fastgpt-mcp_server:v4.9.10-fix2 # git
|
||||
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt-mcp_server:v4.9.10-fix2 # 阿里云
|
||||
ports:
|
||||
- 3005:3000
|
||||
networks:
|
||||
@@ -90,8 +90,8 @@ services:
|
||||
- FASTGPT_ENDPOINT=http://fastgpt:3000
|
||||
fastgpt:
|
||||
container_name: fastgpt
|
||||
image: ghcr.io/labring/fastgpt:v4.9.9 # git
|
||||
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt:v4.9.9 # 阿里云
|
||||
image: ghcr.io/labring/fastgpt:v4.9.10-fix2 # git
|
||||
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt:v4.9.10-fix2 # 阿里云
|
||||
ports:
|
||||
- 3000:3000
|
||||
networks:
|
||||
|
||||
@@ -645,7 +645,7 @@ data 为集合的 ID。
|
||||
{{< /tab >}}
|
||||
{{< /tabs >}}
|
||||
|
||||
### 创建一个外部文件库集合(商业版)
|
||||
### 创建一个外部文件库集合(弃用)
|
||||
|
||||
{{< tabs tabTotal="3" >}}
|
||||
{{< tab tabName="请求示例" >}}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
title: 'V4.9.10(进行中)'
|
||||
title: 'V4.9.10'
|
||||
description: 'FastGPT V4.9.10 更新说明'
|
||||
icon: 'upgrade'
|
||||
draft: false
|
||||
@@ -7,13 +7,28 @@ toc: true
|
||||
weight: 790
|
||||
---
|
||||
|
||||
## 升级指南
|
||||
|
||||
重要提示:本次更新会重新构建全文索引,构建期间,全文检索结果会为空,4c16g 700 万组全文索引大致消耗 25 分钟。如需无缝升级,需自行做表同步工程。
|
||||
|
||||
### 1. 做好数据备份
|
||||
|
||||
### 2. 更新镜像 tag
|
||||
|
||||
- 更新 FastGPT 镜像 tag: v4.9.10-fix2
|
||||
- 更新 FastGPT 商业版镜像 tag: v4.9.10-fix2
|
||||
- mcp_server 无需更新
|
||||
- Sandbox 无需更新
|
||||
- AIProxy 无需更新
|
||||
|
||||
## 🚀 新增内容
|
||||
|
||||
1. 支持 PG 设置`systemEnv.hnswMaxScanTuples`参数,提高迭代搜索的数据总量。
|
||||
2. 工作流调整为单向接入和接出,支持快速的添加下一步节点。
|
||||
3. 开放飞书和语雀知识库到开源版。
|
||||
4. gemini 和 claude 最新模型预设。
|
||||
2. 知识库预处理参数增加 “分块条件”,可控制某些情况下不进行分块处理。
|
||||
3. 知识库预处理参数增加 “段落优先” 模式,可控制最大段落深度。原“长度优先”模式,不再内嵌段落优先逻辑。
|
||||
4. 工作流调整为单向接入和接出,支持快速的添加下一步节点。
|
||||
5. 开放飞书和语雀知识库到开源版。
|
||||
6. gemini 和 claude 最新模型预设。
|
||||
|
||||
## ⚙️ 优化
|
||||
|
||||
@@ -31,4 +46,5 @@ weight: 790
|
||||
3. 工具调用模式,未保存思考输出。
|
||||
4. 知识库 indexSize 参数未生效。
|
||||
5. 工作流嵌套 2 层后,获取预览引用、上下文不正确。
|
||||
6. xlsx 转成 Markdown 时候,前面会多出一个空格。
|
||||
6. xlsx 转成 Markdown 时候,前面会多出一个空格。
|
||||
7. 读取 Markdown 文件时,Base64 图片未进行额外抓换保存。
|
||||
25
docSite/content/zh-cn/docs/development/upgrading/4911.md
Normal file
@@ -0,0 +1,25 @@
|
||||
---
|
||||
title: 'V4.9.11(进行中)'
|
||||
description: 'FastGPT V4.9.11 更新说明'
|
||||
icon: 'upgrade'
|
||||
draft: false
|
||||
toc: true
|
||||
weight: 789
|
||||
---
|
||||
|
||||
|
||||
## 🚀 新增内容
|
||||
|
||||
1. 工作流中增加节点搜索功能。
|
||||
2. 工作流中,子流程版本控制,可选择“保持最新版本”,无需手动更新。
|
||||
|
||||
## ⚙️ 优化
|
||||
|
||||
1. 原文缓存改用 gridfs 存储,提高上限。
|
||||
|
||||
## 🐛 修复
|
||||
|
||||
1. 工作流中,管理员声明的全局系统工具,无法进行版本管理。
|
||||
2. 工具调用节点前,有交互节点时,上下文异常。
|
||||
3. 修复备份导入,小于 1000 字时,无法分块问题。
|
||||
4. 自定义 PDF 解析,无法保存 base64 图片。
|
||||
@@ -4,6 +4,9 @@ import { type ErrType } from '../errorCode';
|
||||
/* dataset: 507000 */
|
||||
const startCode = 507000;
|
||||
export enum CommonErrEnum {
|
||||
methodNotAllowed = 'methodNotAllowed',
|
||||
systemError = 'systemError',
|
||||
unauthorized = 'unauthorized',
|
||||
invalidParams = 'invalidParams',
|
||||
invalidResource = 'invalidResource',
|
||||
fileNotFound = 'fileNotFound',
|
||||
@@ -35,6 +38,22 @@ const datasetErr = [
|
||||
{
|
||||
statusText: CommonErrEnum.inheritPermissionError,
|
||||
message: 'error.inheritPermissionError'
|
||||
},
|
||||
{
|
||||
statusText: CommonErrEnum.methodNotAllowed,
|
||||
message: i18nT('common:code_error.error_message.405')
|
||||
},
|
||||
{
|
||||
statusText: CommonErrEnum.systemError,
|
||||
message: i18nT('common:code_error.error_message.500')
|
||||
},
|
||||
{
|
||||
statusText: CommonErrEnum.unauthorized,
|
||||
message: i18nT('common:code_error.error_message.403')
|
||||
},
|
||||
{
|
||||
statusText: CommonErrEnum.invalidParams,
|
||||
message: i18nT('common:code_error.error_message.422')
|
||||
}
|
||||
];
|
||||
export default datasetErr.reduce((acc, cur, index) => {
|
||||
|
||||
@@ -7,6 +7,10 @@ export const CUSTOM_SPLIT_SIGN = '-----CUSTOM_SPLIT_SIGN-----';
|
||||
type SplitProps = {
|
||||
text: string;
|
||||
chunkSize: number;
|
||||
|
||||
paragraphChunkDeep?: number; // Paragraph deep
|
||||
paragraphChunkMinSize?: number; // Paragraph min size, if too small, it will merge
|
||||
|
||||
maxSize?: number;
|
||||
overlapRatio?: number;
|
||||
customReg?: string[];
|
||||
@@ -108,6 +112,8 @@ const commonSplit = (props: SplitProps): SplitResponse => {
|
||||
let {
|
||||
text = '',
|
||||
chunkSize,
|
||||
paragraphChunkDeep = 5,
|
||||
paragraphChunkMinSize = 100,
|
||||
maxSize = defaultMaxChunkSize,
|
||||
overlapRatio = 0.15,
|
||||
customReg = []
|
||||
@@ -123,7 +129,7 @@ const commonSplit = (props: SplitProps): SplitResponse => {
|
||||
text = text.replace(/(```[\s\S]*?```|~~~[\s\S]*?~~~)/g, function (match) {
|
||||
return match.replace(/\n/g, codeBlockMarker);
|
||||
});
|
||||
// 2. 表格处理 - 单独提取表格出来,进行表头合并
|
||||
// 2. Markdown 表格处理 - 单独提取表格出来,进行表头合并
|
||||
const tableReg =
|
||||
/(\n\|(?:(?:[^\n|]+\|){1,})\n\|(?:[:\-\s]+\|){1,}\n(?:\|(?:[^\n|]+\|)*\n?)*)(?:\n|$)/g;
|
||||
const tableDataList = text.match(tableReg);
|
||||
@@ -143,25 +149,40 @@ const commonSplit = (props: SplitProps): SplitResponse => {
|
||||
text = text.replace(/(\r?\n|\r){3,}/g, '\n\n\n');
|
||||
|
||||
// The larger maxLen is, the next sentence is less likely to trigger splitting
|
||||
const markdownIndex = 4;
|
||||
const forbidOverlapIndex = 8;
|
||||
const customRegLen = customReg.length;
|
||||
const markdownIndex = paragraphChunkDeep - 1;
|
||||
const forbidOverlapIndex = customRegLen + markdownIndex + 4;
|
||||
|
||||
const markdownHeaderRules = ((deep?: number): { reg: RegExp; maxLen: number }[] => {
|
||||
if (!deep || deep === 0) return [];
|
||||
|
||||
const maxDeep = Math.min(deep, 8); // Maximum 8 levels
|
||||
const rules: { reg: RegExp; maxLen: number }[] = [];
|
||||
|
||||
for (let i = 1; i <= maxDeep; i++) {
|
||||
const hashSymbols = '#'.repeat(i);
|
||||
rules.push({
|
||||
reg: new RegExp(`^(${hashSymbols}\\s[^\\n]+\\n)`, 'gm'),
|
||||
maxLen: chunkSize
|
||||
});
|
||||
}
|
||||
|
||||
return rules;
|
||||
})(paragraphChunkDeep);
|
||||
|
||||
const stepReges: { reg: RegExp | string; maxLen: number }[] = [
|
||||
...customReg.map((text) => ({
|
||||
reg: text.replaceAll('\\n', '\n'),
|
||||
maxLen: chunkSize
|
||||
})),
|
||||
{ reg: /^(#\s[^\n]+\n)/gm, maxLen: chunkSize },
|
||||
{ reg: /^(##\s[^\n]+\n)/gm, maxLen: chunkSize },
|
||||
{ reg: /^(###\s[^\n]+\n)/gm, maxLen: chunkSize },
|
||||
{ reg: /^(####\s[^\n]+\n)/gm, maxLen: chunkSize },
|
||||
{ reg: /^(#####\s[^\n]+\n)/gm, maxLen: chunkSize },
|
||||
...markdownHeaderRules,
|
||||
|
||||
{ reg: /([\n](```[\s\S]*?```|~~~[\s\S]*?~~~))/g, maxLen: maxSize }, // code block
|
||||
// HTML Table tag 尽可能保障完整
|
||||
{
|
||||
reg: /(\n\|(?:(?:[^\n|]+\|){1,})\n\|(?:[:\-\s]+\|){1,}\n(?:\|(?:[^\n|]+\|)*\n)*)/g,
|
||||
maxLen: Math.min(chunkSize * 1.5, maxSize)
|
||||
}, // Table 尽可能保证完整性
|
||||
maxLen: chunkSize
|
||||
}, // Markdown Table 尽可能保证完整性
|
||||
{ reg: /(\n{2,})/g, maxLen: chunkSize },
|
||||
{ reg: /([\n])/g, maxLen: chunkSize },
|
||||
// ------ There's no overlap on the top
|
||||
@@ -172,12 +193,10 @@ const commonSplit = (props: SplitProps): SplitResponse => {
|
||||
{ reg: /([,]|,\s)/g, maxLen: chunkSize }
|
||||
];
|
||||
|
||||
const customRegLen = customReg.length;
|
||||
const checkIsCustomStep = (step: number) => step < customRegLen;
|
||||
const checkIsMarkdownSplit = (step: number) =>
|
||||
step >= customRegLen && step <= markdownIndex + customRegLen;
|
||||
|
||||
const checkForbidOverlap = (step: number) => step <= forbidOverlapIndex + customRegLen;
|
||||
const checkForbidOverlap = (step: number) => step <= forbidOverlapIndex;
|
||||
|
||||
// if use markdown title split, Separate record title
|
||||
const getSplitTexts = ({ text, step }: { text: string; step: number }) => {
|
||||
@@ -301,6 +320,7 @@ const commonSplit = (props: SplitProps): SplitResponse => {
|
||||
const splitTexts = getSplitTexts({ text, step });
|
||||
|
||||
const chunks: string[] = [];
|
||||
|
||||
for (let i = 0; i < splitTexts.length; i++) {
|
||||
const item = splitTexts[i];
|
||||
|
||||
@@ -443,7 +463,6 @@ const commonSplit = (props: SplitProps): SplitResponse => {
|
||||
*/
|
||||
export const splitText2Chunks = (props: SplitProps): SplitResponse => {
|
||||
let { text = '' } = props;
|
||||
const start = Date.now();
|
||||
const splitWithCustomSign = text.split(CUSTOM_SPLIT_SIGN);
|
||||
|
||||
const splitResult = splitWithCustomSign.map((item) => {
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
} from './type';
|
||||
|
||||
export enum AppTypeEnum {
|
||||
gate = 'gate',
|
||||
folder = 'folder',
|
||||
simple = 'simple',
|
||||
workflow = 'advanced',
|
||||
|
||||
24
packages/global/core/app/tags.d.ts
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
import { TeamMemberStatusEnum } from 'support/user/team/constant';
|
||||
import type { SourceMemberType } from 'support/user/type';
|
||||
|
||||
export type TagSchemaType = {
|
||||
_id: string;
|
||||
teamId: string;
|
||||
name: string;
|
||||
color: string;
|
||||
createTime: Date;
|
||||
};
|
||||
|
||||
export type TagWithCountType = TagSchemaType & {
|
||||
count: number;
|
||||
};
|
||||
|
||||
export type TagListItemType = {
|
||||
_id: string;
|
||||
teamId: string;
|
||||
name: string;
|
||||
color: string;
|
||||
createTime: Date;
|
||||
count?: number;
|
||||
sourceMember?: SourceMemberType;
|
||||
};
|
||||
1
packages/global/core/app/type.d.ts
vendored
@@ -65,6 +65,7 @@ export type AppListItemType = {
|
||||
inheritPermission?: boolean;
|
||||
private?: boolean;
|
||||
sourceMember: SourceMemberType;
|
||||
tags?: string[];
|
||||
};
|
||||
|
||||
export type AppDetailType = AppSchema & {
|
||||
|
||||
@@ -10,6 +10,8 @@ import { AppTypeEnum } from './constants';
|
||||
import { AppErrEnum } from '../../common/error/code/app';
|
||||
import { PluginErrEnum } from '../../common/error/code/plugin';
|
||||
import { i18nT } from '../../../web/i18n/utils';
|
||||
import appErrList from '../../common/error/code/app';
|
||||
import pluginErrList from '../../common/error/code/plugin';
|
||||
|
||||
export const getDefaultAppForm = (): AppSimpleEditFormType => {
|
||||
return {
|
||||
@@ -44,7 +46,7 @@ export const appWorkflow2Form = ({
|
||||
chatConfig
|
||||
}: {
|
||||
nodes: StoreNodeItemType[];
|
||||
chatConfig: AppChatConfigType;
|
||||
chatConfig?: AppChatConfigType;
|
||||
}) => {
|
||||
const defaultAppForm = getDefaultAppForm();
|
||||
const findInputValueByKey = (inputs: FlowNodeInputItemType[], key: string) => {
|
||||
@@ -170,6 +172,10 @@ export const appWorkflow2Form = ({
|
||||
}
|
||||
});
|
||||
|
||||
if (chatConfig) {
|
||||
defaultAppForm.chatConfig = chatConfig;
|
||||
}
|
||||
|
||||
return defaultAppForm;
|
||||
};
|
||||
|
||||
@@ -190,17 +196,10 @@ export const getAppType = (config?: WorkflowTemplateBasicType | AppSimpleEditFor
|
||||
return '';
|
||||
};
|
||||
|
||||
export const formatToolError = (error?: string) => {
|
||||
const unExistError: Array<string> = [
|
||||
AppErrEnum.unAuthApp,
|
||||
AppErrEnum.unExist,
|
||||
PluginErrEnum.unAuth,
|
||||
PluginErrEnum.unExist
|
||||
];
|
||||
export const formatToolError = (error?: any) => {
|
||||
if (!error || typeof error !== 'string') return;
|
||||
|
||||
if (error && unExistError.includes(error)) {
|
||||
return i18nT('app:un_auth');
|
||||
} else {
|
||||
return error;
|
||||
}
|
||||
const errorText = appErrList[error]?.message || pluginErrList[error]?.message;
|
||||
|
||||
return errorText || error;
|
||||
};
|
||||
|
||||
@@ -120,7 +120,6 @@ export const computeChunkSize = (params: {
|
||||
|
||||
return Math.min(params.chunkSize ?? chunkAutoChunkSize, getLLMMaxChunkSize(params.llmModel));
|
||||
};
|
||||
|
||||
export const computeChunkSplitter = (params: {
|
||||
chunkSettingMode?: ChunkSettingModeEnum;
|
||||
chunkSplitMode?: DataChunkSplitModeEnum;
|
||||
@@ -129,8 +128,21 @@ export const computeChunkSplitter = (params: {
|
||||
if (params.chunkSettingMode === ChunkSettingModeEnum.auto) {
|
||||
return undefined;
|
||||
}
|
||||
if (params.chunkSplitMode === DataChunkSplitModeEnum.size) {
|
||||
if (params.chunkSplitMode !== DataChunkSplitModeEnum.char) {
|
||||
return undefined;
|
||||
}
|
||||
return params.chunkSplitter;
|
||||
};
|
||||
export const computeParagraphChunkDeep = (params: {
|
||||
chunkSettingMode?: ChunkSettingModeEnum;
|
||||
chunkSplitMode?: DataChunkSplitModeEnum;
|
||||
paragraphChunkDeep?: number;
|
||||
}) => {
|
||||
if (params.chunkSettingMode === ChunkSettingModeEnum.auto) {
|
||||
return 5;
|
||||
}
|
||||
if (params.chunkSplitMode === DataChunkSplitModeEnum.paragraph) {
|
||||
return params.paragraphChunkDeep;
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
8
packages/global/core/dataset/type.d.ts
vendored
@@ -9,7 +9,8 @@ import type {
|
||||
DatasetTypeEnum,
|
||||
SearchScoreTypeEnum,
|
||||
TrainingModeEnum,
|
||||
ChunkSettingModeEnum
|
||||
ChunkSettingModeEnum,
|
||||
ChunkTriggerConfigTypeEnum
|
||||
} from './constants';
|
||||
import type { DatasetPermission } from '../../support/permission/dataset/controller';
|
||||
import type { APIFileServer, FeishuServer, YuqueServer } from './apiDataset';
|
||||
@@ -37,11 +38,10 @@ export type ChunkSettingsType = {
|
||||
paragraphChunkAIMode?: ParagraphChunkAIModeEnum;
|
||||
paragraphChunkDeep?: number; // Paragraph deep
|
||||
paragraphChunkMinSize?: number; // Paragraph min size, if too small, it will merge
|
||||
paragraphChunkMaxSize?: number; // Paragraph max size, if too large, it will split
|
||||
// Size split
|
||||
chunkSize?: number;
|
||||
chunkSize?: number; // chunk/qa chunk size, Paragraph max chunk size.
|
||||
// Char split
|
||||
chunkSplitter?: string;
|
||||
chunkSplitter?: string; // chunk/qa chunk splitter
|
||||
indexSize?: number;
|
||||
|
||||
qaPrompt?: string;
|
||||
|
||||
@@ -40,5 +40,6 @@ export function getSourceNameIcon({
|
||||
export const predictDataLimitLength = (mode: TrainingModeEnum, data: any[]) => {
|
||||
if (mode === TrainingModeEnum.qa) return data.length * 20;
|
||||
if (mode === TrainingModeEnum.auto) return data.length * 5;
|
||||
if (mode === TrainingModeEnum.image) return data.length * 2;
|
||||
return data.length;
|
||||
};
|
||||
|
||||
2
packages/global/core/workflow/type/node.d.ts
vendored
@@ -59,7 +59,6 @@ export type FlowNodeCommonType = {
|
||||
};
|
||||
|
||||
export type PluginDataType = {
|
||||
version?: string;
|
||||
diagram?: string;
|
||||
userGuide?: string;
|
||||
courseUrl?: string;
|
||||
@@ -126,6 +125,7 @@ export type FlowNodeItemType = FlowNodeTemplateType & {
|
||||
nodeId: string;
|
||||
parentNodeId?: string;
|
||||
isError?: boolean;
|
||||
searchedText?: string;
|
||||
debugResult?: {
|
||||
status: 'running' | 'success' | 'skipped' | 'failed';
|
||||
message?: string;
|
||||
|
||||
@@ -2,7 +2,18 @@ import { NullPermission, PermissionKeyEnum, PermissionList } from '../constant';
|
||||
import { type PermissionListType } from '../type';
|
||||
import { i18nT } from '../../../../web/i18n/utils';
|
||||
export enum AppPermissionKeyEnum {}
|
||||
export const AppPermissionList: PermissionListType = {
|
||||
|
||||
export enum AppPermissionKeyEnum {
|
||||
log = 'log',
|
||||
quickGate = 'quickGate',
|
||||
featuredGate = 'featuredGate'
|
||||
}
|
||||
|
||||
export const AppLogPermission = 0b100000;
|
||||
export const GateQuickAppPermission = 0b001100;
|
||||
export const GateFeaturedAppPermission = 0b010100;
|
||||
|
||||
export const AppPermissionList: PermissionListType<AppPermissionKeyEnum> = {
|
||||
[PermissionKeyEnum.read]: {
|
||||
...PermissionList[PermissionKeyEnum.read],
|
||||
description: i18nT('app:permission.des.read')
|
||||
@@ -13,8 +24,28 @@ export const AppPermissionList: PermissionListType = {
|
||||
},
|
||||
[PermissionKeyEnum.manage]: {
|
||||
...PermissionList[PermissionKeyEnum.manage],
|
||||
value: 0b111111,
|
||||
description: i18nT('app:permission.des.manage')
|
||||
},
|
||||
[AppPermissionKeyEnum.log]: {
|
||||
name: i18nT('app:permission.name.log'),
|
||||
value: AppLogPermission,
|
||||
checkBoxType: 'multiple',
|
||||
description: i18nT('app:permission.des.log')
|
||||
},
|
||||
[AppPermissionKeyEnum.quickGate]: {
|
||||
name: '门户快捷应用权限',
|
||||
description: '',
|
||||
value: GateQuickAppPermission,
|
||||
checkBoxType: 'hiden'
|
||||
},
|
||||
[AppPermissionKeyEnum.featuredGate]: {
|
||||
name: '门户推荐应用权限',
|
||||
description: '',
|
||||
value: GateFeaturedAppPermission,
|
||||
checkBoxType: 'hiden'
|
||||
}
|
||||
};
|
||||
|
||||
export const AppDefaultPermissionVal = NullPermission;
|
||||
export const AppLogPermissionVal = AppPermissionList[AppPermissionKeyEnum.log].value;
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { type PerConstructPros, Permission } from '../controller';
|
||||
import { AppDefaultPermissionVal } from './constant';
|
||||
import { AppDefaultPermissionVal, AppPermissionList } from './constant';
|
||||
|
||||
export class AppPermission extends Permission {
|
||||
hasLogPer: boolean = false;
|
||||
constructor(props?: PerConstructPros) {
|
||||
if (!props) {
|
||||
props = {
|
||||
@@ -10,6 +11,13 @@ export class AppPermission extends Permission {
|
||||
} else if (!props?.per) {
|
||||
props.per = AppDefaultPermissionVal;
|
||||
}
|
||||
props.permissionList = AppPermissionList;
|
||||
super(props);
|
||||
this.setUpdatePermissionCallback(() => {
|
||||
this.hasReadPer = this.checkPer(AppPermissionList.read.value);
|
||||
this.hasWritePer = this.checkPer(AppPermissionList.write.value);
|
||||
this.hasManagePer = this.checkPer(AppPermissionList.manage.value);
|
||||
this.hasLogPer = this.checkPer(AppPermissionList.log.value);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
import { type PermissionListType, type PermissionValueType } from './type';
|
||||
import { PermissionList, NullPermission, OwnerPermissionVal } from './constant';
|
||||
import {
|
||||
PermissionList,
|
||||
NullPermission,
|
||||
OwnerPermissionVal,
|
||||
ManagePermissionVal
|
||||
} from './constant';
|
||||
|
||||
export type PerConstructPros = {
|
||||
per?: PermissionValueType;
|
||||
@@ -63,6 +68,7 @@ export class Permission {
|
||||
if (perm === OwnerPermissionVal) {
|
||||
return this.value === OwnerPermissionVal;
|
||||
}
|
||||
|
||||
return (this.value & perm) === perm;
|
||||
}
|
||||
|
||||
|
||||
2
packages/global/support/permission/type.d.ts
vendored
@@ -18,7 +18,7 @@ export type PermissionListType<T = {}> = Record<
|
||||
name: string;
|
||||
description: string;
|
||||
value: PermissionValueType;
|
||||
checkBoxType: 'single' | 'multiple';
|
||||
checkBoxType: 'single' | 'multiple' | 'hiden';
|
||||
}
|
||||
>;
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ export const TeamPermissionList: PermissionListType<TeamPermissionKeyEnum> = {
|
||||
},
|
||||
[PermissionKeyEnum.manage]: {
|
||||
...PermissionList[PermissionKeyEnum.manage],
|
||||
value: 0b000001
|
||||
value: 0b000101
|
||||
},
|
||||
[TeamPermissionKeyEnum.appCreate]: {
|
||||
checkBoxType: 'multiple',
|
||||
|
||||
31
packages/global/support/user/team/gate/api.d.ts
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
export type putUpdateGateConfigData = {
|
||||
status?: boolean;
|
||||
tools?: GateTool[];
|
||||
slogan?: string;
|
||||
placeholderText?: string;
|
||||
};
|
||||
|
||||
export type putUpdateGateConfigResponse = {
|
||||
status?: boolean;
|
||||
tools?: string[];
|
||||
slogan?: string;
|
||||
placeholderText?: string;
|
||||
};
|
||||
|
||||
export type putUpdateGateConfigCopyRightData = {
|
||||
name?: string;
|
||||
logo?: string;
|
||||
banner?: string;
|
||||
};
|
||||
|
||||
export type putUpdateGateConfigCopyRightResponse = {
|
||||
name: string;
|
||||
logo: string;
|
||||
banner: string;
|
||||
};
|
||||
|
||||
export type getGateConfigCopyRightResponse = {
|
||||
name: string;
|
||||
logo: string;
|
||||
banner: string;
|
||||
};
|
||||
12
packages/global/support/user/team/gate/type.d.ts
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
export type GateSchemaType = {
|
||||
teamId: string;
|
||||
status: boolean;
|
||||
tools: string[];
|
||||
featuredApps: string[];
|
||||
quickApps: string[];
|
||||
slogan: string;
|
||||
placeholderText: string;
|
||||
name: string;
|
||||
logo: string;
|
||||
banner: string;
|
||||
};
|
||||
@@ -13,6 +13,7 @@ const staticPluginList = [
|
||||
'WeWorkWebhook',
|
||||
'google',
|
||||
'bing',
|
||||
'bocha',
|
||||
'delay'
|
||||
];
|
||||
// Run in worker thread (Have npm packages)
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
{
|
||||
"author": "",
|
||||
"version": "4816",
|
||||
"name": "钉钉 webhook",
|
||||
"avatar": "plugins/dingding",
|
||||
"intro": "向钉钉机器人发起 webhook 请求。",
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
{
|
||||
"author": "Menghuan1918",
|
||||
"version": "488",
|
||||
"name": "PDF识别",
|
||||
"avatar": "plugins/doc2x",
|
||||
"intro": "将PDF文件发送至Doc2X进行解析,返回结构化的LaTeX公式的文本(markdown),支持传入String类型的URL或者流程输出中的文件链接变量",
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
{
|
||||
"author": "Menghuan1918",
|
||||
"version": "488",
|
||||
"name": "Doc2X服务",
|
||||
"avatar": "plugins/doc2x",
|
||||
"intro": "将传入的图片或PDF文件发送至Doc2X进行解析,返回带LaTeX公式的markdown格式的文本。",
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
{
|
||||
"author": "",
|
||||
"version": "4816",
|
||||
"name": "企业微信 webhook",
|
||||
"avatar": "plugins/qiwei",
|
||||
"intro": "向企业微信机器人发起 webhook 请求。只能内部群使用。",
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
{
|
||||
"author": "",
|
||||
"version": "4811",
|
||||
"name": "Bing搜索",
|
||||
"avatar": "core/workflow/template/bing",
|
||||
"intro": "在Bing中搜索。",
|
||||
|
||||
604
packages/plugins/src/bocha/template.json
Normal file
@@ -0,0 +1,604 @@
|
||||
{
|
||||
"author": "",
|
||||
"name": "网络搜索",
|
||||
"avatar": "common/searchLight",
|
||||
"intro": "使用博查AI搜索引擎进行网络搜索。",
|
||||
"showStatus": true,
|
||||
"weight": 10,
|
||||
"courseUrl": "",
|
||||
"isTool": true,
|
||||
"templateType": "search",
|
||||
"workflow": {
|
||||
"nodes": [
|
||||
{
|
||||
"nodeId": "pluginInput",
|
||||
"name": "workflow:template.plugin_start",
|
||||
"intro": "workflow:intro_plugin_input",
|
||||
"avatar": "core/workflow/template/workflowStart",
|
||||
"flowNodeType": "pluginInput",
|
||||
"showStatus": false,
|
||||
"position": {
|
||||
"x": 636.3048409085379,
|
||||
"y": -238.61714728578016
|
||||
},
|
||||
"version": "481",
|
||||
"inputs": [
|
||||
{
|
||||
"renderTypeList": ["input"],
|
||||
"selectedTypeIndex": 0,
|
||||
"valueType": "string",
|
||||
"canEdit": true,
|
||||
"key": "apiKey",
|
||||
"label": "apiKey",
|
||||
"description": "博查API密钥",
|
||||
"defaultValue": "",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"renderTypeList": ["input", "reference"],
|
||||
"selectedTypeIndex": 0,
|
||||
"valueType": "string",
|
||||
"canEdit": true,
|
||||
"key": "query",
|
||||
"label": "query",
|
||||
"description": "搜索查询词",
|
||||
"defaultValue": "",
|
||||
"required": true,
|
||||
"toolDescription": "搜索查询词"
|
||||
},
|
||||
{
|
||||
"renderTypeList": ["input", "reference"],
|
||||
"selectedTypeIndex": 0,
|
||||
"valueType": "string",
|
||||
"canEdit": true,
|
||||
"key": "freshness",
|
||||
"label": "freshness",
|
||||
"description": "搜索指定时间范围内的网页。可填值:oneDay(一天内)、oneWeek(一周内)、oneMonth(一个月内)、oneYear(一年内)、noLimit(不限,默认)、YYYY-MM-DD..YYYY-MM-DD(日期范围)、YYYY-MM-DD(指定日期)",
|
||||
"defaultValue": "noLimit",
|
||||
"required": false,
|
||||
"toolDescription": "搜索时间范围"
|
||||
},
|
||||
{
|
||||
"renderTypeList": ["input", "reference"],
|
||||
"selectedTypeIndex": 0,
|
||||
"valueType": "boolean",
|
||||
"canEdit": true,
|
||||
"key": "summary",
|
||||
"label": "summary",
|
||||
"description": "是否显示文本摘要。true显示,false不显示(默认)",
|
||||
"defaultValue": false,
|
||||
"required": false,
|
||||
"toolDescription": "是否显示文本摘要"
|
||||
},
|
||||
{
|
||||
"renderTypeList": ["input", "reference"],
|
||||
"selectedTypeIndex": 0,
|
||||
"valueType": "string",
|
||||
"canEdit": true,
|
||||
"key": "include",
|
||||
"label": "include",
|
||||
"description": "指定搜索的site范围。多个域名使用|或,分隔,最多20个。例如:qq.com|m.163.com",
|
||||
"defaultValue": "",
|
||||
"required": false,
|
||||
"toolDescription": "指定搜索的site范围"
|
||||
},
|
||||
{
|
||||
"renderTypeList": ["input", "reference"],
|
||||
"selectedTypeIndex": 0,
|
||||
"valueType": "string",
|
||||
"canEdit": true,
|
||||
"key": "exclude",
|
||||
"label": "exclude",
|
||||
"description": "排除搜索的网站范围。多个域名使用|或,分隔,最多20个。例如:qq.com|m.163.com",
|
||||
"defaultValue": "",
|
||||
"required": false,
|
||||
"toolDescription": "排除搜索的网站范围"
|
||||
},
|
||||
{
|
||||
"renderTypeList": ["input", "reference"],
|
||||
"selectedTypeIndex": 0,
|
||||
"valueType": "number",
|
||||
"canEdit": true,
|
||||
"key": "count",
|
||||
"label": "count",
|
||||
"description": "返回结果的条数。可填范围:1-50,默认为10",
|
||||
"defaultValue": 10,
|
||||
"required": false,
|
||||
"min": 1,
|
||||
"max": 50,
|
||||
"toolDescription": "返回结果条数"
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"id": "apiKey",
|
||||
"valueType": "string",
|
||||
"key": "apiKey",
|
||||
"label": "apiKey",
|
||||
"type": "hidden"
|
||||
},
|
||||
{
|
||||
"id": "query",
|
||||
"valueType": "string",
|
||||
"key": "query",
|
||||
"label": "query",
|
||||
"type": "hidden"
|
||||
},
|
||||
{
|
||||
"id": "freshness",
|
||||
"valueType": "string",
|
||||
"key": "freshness",
|
||||
"label": "freshness",
|
||||
"type": "hidden"
|
||||
},
|
||||
{
|
||||
"id": "summary",
|
||||
"valueType": "boolean",
|
||||
"key": "summary",
|
||||
"label": "summary",
|
||||
"type": "hidden"
|
||||
},
|
||||
{
|
||||
"id": "include",
|
||||
"valueType": "string",
|
||||
"key": "include",
|
||||
"label": "include",
|
||||
"type": "hidden"
|
||||
},
|
||||
{
|
||||
"id": "exclude",
|
||||
"valueType": "string",
|
||||
"key": "exclude",
|
||||
"label": "exclude",
|
||||
"type": "hidden"
|
||||
},
|
||||
{
|
||||
"id": "count",
|
||||
"valueType": "number",
|
||||
"key": "count",
|
||||
"label": "count",
|
||||
"type": "hidden"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"nodeId": "pluginOutput",
|
||||
"name": "common:core.module.template.self_output",
|
||||
"intro": "workflow:intro_custom_plugin_output",
|
||||
"avatar": "core/workflow/template/pluginOutput",
|
||||
"flowNodeType": "pluginOutput",
|
||||
"showStatus": false,
|
||||
"position": {
|
||||
"x": 2764.1105686698083,
|
||||
"y": -30.617147285780163
|
||||
},
|
||||
"version": "481",
|
||||
"inputs": [
|
||||
{
|
||||
"renderTypeList": ["reference"],
|
||||
"valueType": "object",
|
||||
"canEdit": true,
|
||||
"key": "result",
|
||||
"label": "result",
|
||||
"isToolOutput": true,
|
||||
"description": "",
|
||||
"value": ["nyA6oA8mF1iW", "httpRawResponse"]
|
||||
}
|
||||
],
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"nodeId": "pluginConfig",
|
||||
"name": "common:core.module.template.system_config",
|
||||
"intro": "",
|
||||
"avatar": "core/workflow/template/systemConfig",
|
||||
"flowNodeType": "pluginConfig",
|
||||
"position": {
|
||||
"x": 184.66337662472682,
|
||||
"y": -216.05298493910115
|
||||
},
|
||||
"version": "4811",
|
||||
"inputs": [],
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"nodeId": "nyA6oA8mF1iW",
|
||||
"name": "HTTP 请求",
|
||||
"intro": "调用博查搜索API",
|
||||
"avatar": "core/workflow/template/httpRequest",
|
||||
"flowNodeType": "httpRequest468",
|
||||
"showStatus": true,
|
||||
"position": {
|
||||
"x": 1335.0647252518884,
|
||||
"y": -455.9043948565971
|
||||
},
|
||||
"version": "481",
|
||||
"inputs": [
|
||||
{
|
||||
"key": "system_addInputParam",
|
||||
"renderTypeList": ["addInputParam"],
|
||||
"valueType": "dynamic",
|
||||
"label": "",
|
||||
"required": false,
|
||||
"description": "common:core.module.input.description.HTTP Dynamic Input",
|
||||
"customInputConfig": {
|
||||
"selectValueTypeList": [
|
||||
"string",
|
||||
"number",
|
||||
"boolean",
|
||||
"object",
|
||||
"arrayString",
|
||||
"arrayNumber",
|
||||
"arrayBoolean",
|
||||
"arrayObject",
|
||||
"arrayAny",
|
||||
"any",
|
||||
"chatHistory",
|
||||
"datasetQuote",
|
||||
"dynamic",
|
||||
"selectDataset",
|
||||
"selectApp"
|
||||
],
|
||||
"showDescription": false,
|
||||
"showDefaultValue": true
|
||||
},
|
||||
"debugLabel": "",
|
||||
"toolDescription": ""
|
||||
},
|
||||
{
|
||||
"key": "system_httpMethod",
|
||||
"renderTypeList": ["custom"],
|
||||
"valueType": "string",
|
||||
"label": "",
|
||||
"value": "POST",
|
||||
"required": true,
|
||||
"debugLabel": "",
|
||||
"toolDescription": ""
|
||||
},
|
||||
{
|
||||
"key": "system_httpTimeout",
|
||||
"renderTypeList": ["custom"],
|
||||
"valueType": "number",
|
||||
"label": "",
|
||||
"value": 30,
|
||||
"min": 5,
|
||||
"max": 600,
|
||||
"required": true,
|
||||
"debugLabel": "",
|
||||
"toolDescription": ""
|
||||
},
|
||||
{
|
||||
"key": "system_httpReqUrl",
|
||||
"renderTypeList": ["hidden"],
|
||||
"valueType": "string",
|
||||
"label": "",
|
||||
"description": "common:core.module.input.description.Http Request Url",
|
||||
"placeholder": "https://api.ai.com/getInventory",
|
||||
"required": false,
|
||||
"value": "https://api.bochaai.com/v1/web-search",
|
||||
"debugLabel": "",
|
||||
"toolDescription": ""
|
||||
},
|
||||
{
|
||||
"key": "system_httpHeader",
|
||||
"renderTypeList": ["custom"],
|
||||
"valueType": "any",
|
||||
"value": [
|
||||
{
|
||||
"key": "Authorization",
|
||||
"type": "string",
|
||||
"value": "Bearer {{$pluginInput.apiKey$}}"
|
||||
},
|
||||
{
|
||||
"key": "Content-Type",
|
||||
"type": "string",
|
||||
"value": "application/json"
|
||||
}
|
||||
],
|
||||
"label": "",
|
||||
"description": "common:core.module.input.description.Http Request Header",
|
||||
"placeholder": "common:core.module.input.description.Http Request Header",
|
||||
"required": false,
|
||||
"debugLabel": "",
|
||||
"toolDescription": ""
|
||||
},
|
||||
{
|
||||
"key": "system_httpParams",
|
||||
"renderTypeList": ["hidden"],
|
||||
"valueType": "any",
|
||||
"value": [],
|
||||
"label": "",
|
||||
"required": false,
|
||||
"debugLabel": "",
|
||||
"toolDescription": ""
|
||||
},
|
||||
{
|
||||
"key": "system_httpJsonBody",
|
||||
"renderTypeList": ["hidden"],
|
||||
"valueType": "any",
|
||||
"value": "{\n \"query\": \"{{query}}\",\n \"freshness\": \"{{freshness}}\",\n \"summary\": {{summary}},\n \"include\": \"{{include}}\",\n \"exclude\": \"{{exclude}}\",\n \"count\": {{count}}\n}",
|
||||
"label": "",
|
||||
"required": false,
|
||||
"debugLabel": "",
|
||||
"toolDescription": ""
|
||||
},
|
||||
{
|
||||
"key": "system_httpFormBody",
|
||||
"renderTypeList": ["hidden"],
|
||||
"valueType": "any",
|
||||
"value": [],
|
||||
"label": "",
|
||||
"required": false,
|
||||
"debugLabel": "",
|
||||
"toolDescription": ""
|
||||
},
|
||||
{
|
||||
"key": "system_httpContentType",
|
||||
"renderTypeList": ["hidden"],
|
||||
"valueType": "string",
|
||||
"value": "json",
|
||||
"label": "",
|
||||
"required": false,
|
||||
"debugLabel": "",
|
||||
"toolDescription": ""
|
||||
},
|
||||
{
|
||||
"valueType": "string",
|
||||
"renderTypeList": ["reference"],
|
||||
"key": "query",
|
||||
"label": "query",
|
||||
"toolDescription": "博查搜索检索词",
|
||||
"required": true,
|
||||
"canEdit": true,
|
||||
"editField": {
|
||||
"key": true,
|
||||
"description": true
|
||||
},
|
||||
"customInputConfig": {
|
||||
"selectValueTypeList": [
|
||||
"string",
|
||||
"number",
|
||||
"boolean",
|
||||
"object",
|
||||
"arrayString",
|
||||
"arrayNumber",
|
||||
"arrayBoolean",
|
||||
"arrayObject",
|
||||
"arrayAny",
|
||||
"any",
|
||||
"chatHistory",
|
||||
"datasetQuote",
|
||||
"dynamic",
|
||||
"selectApp",
|
||||
"selectDataset"
|
||||
],
|
||||
"showDescription": false,
|
||||
"showDefaultValue": true
|
||||
},
|
||||
"value": ["pluginInput", "query"]
|
||||
},
|
||||
{
|
||||
"valueType": "string",
|
||||
"renderTypeList": ["reference"],
|
||||
"key": "freshness",
|
||||
"label": "freshness",
|
||||
"toolDescription": "搜索时间范围",
|
||||
"required": false,
|
||||
"canEdit": true,
|
||||
"editField": {
|
||||
"key": true,
|
||||
"description": true
|
||||
},
|
||||
"customInputConfig": {
|
||||
"selectValueTypeList": [
|
||||
"string",
|
||||
"number",
|
||||
"boolean",
|
||||
"object",
|
||||
"arrayString",
|
||||
"arrayNumber",
|
||||
"arrayBoolean",
|
||||
"arrayObject",
|
||||
"arrayAny",
|
||||
"any",
|
||||
"chatHistory",
|
||||
"datasetQuote",
|
||||
"dynamic",
|
||||
"selectApp",
|
||||
"selectDataset"
|
||||
],
|
||||
"showDescription": false,
|
||||
"showDefaultValue": true
|
||||
},
|
||||
"value": ["pluginInput", "freshness"]
|
||||
},
|
||||
{
|
||||
"valueType": "boolean",
|
||||
"renderTypeList": ["reference"],
|
||||
"key": "summary",
|
||||
"label": "summary",
|
||||
"toolDescription": "是否显示文本摘要",
|
||||
"required": false,
|
||||
"canEdit": true,
|
||||
"editField": {
|
||||
"key": true,
|
||||
"description": true
|
||||
},
|
||||
"customInputConfig": {
|
||||
"selectValueTypeList": [
|
||||
"string",
|
||||
"number",
|
||||
"boolean",
|
||||
"object",
|
||||
"arrayString",
|
||||
"arrayNumber",
|
||||
"arrayBoolean",
|
||||
"arrayObject",
|
||||
"arrayAny",
|
||||
"any",
|
||||
"chatHistory",
|
||||
"datasetQuote",
|
||||
"dynamic",
|
||||
"selectApp",
|
||||
"selectDataset"
|
||||
],
|
||||
"showDescription": false,
|
||||
"showDefaultValue": true
|
||||
},
|
||||
"value": ["pluginInput", "summary"]
|
||||
},
|
||||
{
|
||||
"valueType": "string",
|
||||
"renderTypeList": ["reference"],
|
||||
"key": "include",
|
||||
"label": "include",
|
||||
"toolDescription": "指定搜索的site范围",
|
||||
"required": false,
|
||||
"canEdit": true,
|
||||
"editField": {
|
||||
"key": true,
|
||||
"description": true
|
||||
},
|
||||
"customInputConfig": {
|
||||
"selectValueTypeList": [
|
||||
"string",
|
||||
"number",
|
||||
"boolean",
|
||||
"object",
|
||||
"arrayString",
|
||||
"arrayNumber",
|
||||
"arrayBoolean",
|
||||
"arrayObject",
|
||||
"arrayAny",
|
||||
"any",
|
||||
"chatHistory",
|
||||
"datasetQuote",
|
||||
"dynamic",
|
||||
"selectApp",
|
||||
"selectDataset"
|
||||
],
|
||||
"showDescription": false,
|
||||
"showDefaultValue": true
|
||||
},
|
||||
"value": ["pluginInput", "include"]
|
||||
},
|
||||
{
|
||||
"valueType": "string",
|
||||
"renderTypeList": ["reference"],
|
||||
"key": "exclude",
|
||||
"label": "exclude",
|
||||
"toolDescription": "排除搜索的网站范围",
|
||||
"required": false,
|
||||
"canEdit": true,
|
||||
"editField": {
|
||||
"key": true,
|
||||
"description": true
|
||||
},
|
||||
"customInputConfig": {
|
||||
"selectValueTypeList": [
|
||||
"string",
|
||||
"number",
|
||||
"boolean",
|
||||
"object",
|
||||
"arrayString",
|
||||
"arrayNumber",
|
||||
"arrayBoolean",
|
||||
"arrayObject",
|
||||
"arrayAny",
|
||||
"any",
|
||||
"chatHistory",
|
||||
"datasetQuote",
|
||||
"dynamic",
|
||||
"selectApp",
|
||||
"selectDataset"
|
||||
],
|
||||
"showDescription": false,
|
||||
"showDefaultValue": true
|
||||
},
|
||||
"value": ["pluginInput", "exclude"]
|
||||
},
|
||||
{
|
||||
"valueType": "number",
|
||||
"renderTypeList": ["reference"],
|
||||
"key": "count",
|
||||
"label": "count",
|
||||
"toolDescription": "返回结果条数",
|
||||
"required": false,
|
||||
"canEdit": true,
|
||||
"editField": {
|
||||
"key": true,
|
||||
"description": true
|
||||
},
|
||||
"customInputConfig": {
|
||||
"selectValueTypeList": [
|
||||
"string",
|
||||
"number",
|
||||
"boolean",
|
||||
"object",
|
||||
"arrayString",
|
||||
"arrayNumber",
|
||||
"arrayBoolean",
|
||||
"arrayObject",
|
||||
"arrayAny",
|
||||
"any",
|
||||
"chatHistory",
|
||||
"datasetQuote",
|
||||
"dynamic",
|
||||
"selectApp",
|
||||
"selectDataset"
|
||||
],
|
||||
"showDescription": false,
|
||||
"showDefaultValue": true
|
||||
},
|
||||
"value": ["pluginInput", "count"]
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"id": "error",
|
||||
"key": "error",
|
||||
"label": "workflow:request_error",
|
||||
"description": "HTTP请求错误信息,成功时返回空",
|
||||
"valueType": "object",
|
||||
"type": "static"
|
||||
},
|
||||
{
|
||||
"id": "httpRawResponse",
|
||||
"key": "httpRawResponse",
|
||||
"required": true,
|
||||
"label": "workflow:raw_response",
|
||||
"description": "HTTP请求的原始响应。只能接受字符串或JSON类型响应数据。",
|
||||
"valueType": "any",
|
||||
"type": "static"
|
||||
},
|
||||
{
|
||||
"id": "system_addOutputParam",
|
||||
"key": "system_addOutputParam",
|
||||
"type": "dynamic",
|
||||
"valueType": "dynamic",
|
||||
"label": "",
|
||||
"editField": {
|
||||
"key": true,
|
||||
"valueType": true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"edges": [
|
||||
{
|
||||
"source": "pluginInput",
|
||||
"target": "nyA6oA8mF1iW",
|
||||
"sourceHandle": "pluginInput-source-right",
|
||||
"targetHandle": "nyA6oA8mF1iW-target-left"
|
||||
},
|
||||
{
|
||||
"source": "nyA6oA8mF1iW",
|
||||
"target": "pluginOutput",
|
||||
"sourceHandle": "nyA6oA8mF1iW-source-right",
|
||||
"targetHandle": "pluginOutput-target-left"
|
||||
}
|
||||
]
|
||||
},
|
||||
"chatConfig": {}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
{
|
||||
"author": "silencezhang",
|
||||
"version": "4811",
|
||||
"name": "数据库连接",
|
||||
"avatar": "core/workflow/template/datasource",
|
||||
"intro": "可连接常用数据库,并执行sql",
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
{
|
||||
"author": "collin",
|
||||
"version": "4817",
|
||||
"name": "流程等待",
|
||||
"avatar": "core/workflow/template/sleep",
|
||||
"intro": "让工作流等待指定时间后运行",
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
{
|
||||
"author": "silencezhang",
|
||||
"version": "4817",
|
||||
"name": "基础图表",
|
||||
"avatar": "core/workflow/template/baseChart",
|
||||
"intro": "根据数据生成图表,可根据chartType生成柱状图,折线图,饼图",
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
{
|
||||
"author": "silencezhang",
|
||||
"version": "486",
|
||||
"name": "BI图表功能",
|
||||
"avatar": "core/workflow/template/BI",
|
||||
"intro": "BI图表功能,可以生成一些常用的图表,如饼图,柱状图,折线图等",
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
{
|
||||
"author": "",
|
||||
"version": "486",
|
||||
"name": "DuckDuckGo 网络搜索",
|
||||
"avatar": "core/workflow/template/duckduckgo",
|
||||
"intro": "使用 DuckDuckGo 进行网络搜索",
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
{
|
||||
"author": "",
|
||||
"version": "486",
|
||||
"name": "DuckDuckGo 图片搜索",
|
||||
"avatar": "core/workflow/template/duckduckgo",
|
||||
"intro": "使用 DuckDuckGo 进行图片搜索",
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
{
|
||||
"author": "",
|
||||
"version": "486",
|
||||
"name": "DuckDuckGo 新闻检索",
|
||||
"avatar": "core/workflow/template/duckduckgo",
|
||||
"intro": "使用 DuckDuckGo 进行新闻检索",
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
{
|
||||
"author": "",
|
||||
"version": "486",
|
||||
"name": "DuckDuckGo 视频搜索",
|
||||
"avatar": "core/workflow/template/duckduckgo",
|
||||
"intro": "使用 DuckDuckGo 进行视频搜索",
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
{
|
||||
"author": "",
|
||||
"version": "486",
|
||||
"name": "DuckDuckGo服务",
|
||||
"avatar": "core/workflow/template/duckduckgo",
|
||||
"intro": "DuckDuckGo 服务,包含网络搜索、图片搜索、新闻搜索等。",
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
{
|
||||
"author": "",
|
||||
"version": "488",
|
||||
"name": "飞书 webhook",
|
||||
"avatar": "core/app/templates/plugin-feishu",
|
||||
"intro": "向飞书机器人发起 webhook 请求。",
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
{
|
||||
"author": "",
|
||||
"version": "486",
|
||||
"name": "网页内容抓取",
|
||||
"avatar": "core/workflow/template/fetchUrl",
|
||||
"intro": "可获取一个网页链接内容,并以 Markdown 格式输出,仅支持获取静态网站。",
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
{
|
||||
"author": "",
|
||||
"version": "481",
|
||||
"templateType": "tools",
|
||||
"name": "获取当前时间",
|
||||
"avatar": "core/workflow/template/getTime",
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
{
|
||||
"author": "",
|
||||
"version": "4811",
|
||||
"name": "Google搜索",
|
||||
"avatar": "core/workflow/template/google",
|
||||
"intro": "在google中搜索。",
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
{
|
||||
"author": "",
|
||||
"version": "486",
|
||||
"name": "数学公式执行",
|
||||
"avatar": "core/workflow/template/mathCall",
|
||||
"intro": "用于执行数学表达式的工具,通过 js 的 expr-eval 库运行表达式并返回结果。",
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
{
|
||||
"author": "",
|
||||
"version": "4816",
|
||||
"name": "Search XNG 搜索",
|
||||
"avatar": "core/workflow/template/searxng",
|
||||
"intro": "使用 Search XNG 服务进行搜索。",
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
{
|
||||
"author": "cloudpense",
|
||||
"version": "1.0.0",
|
||||
"name": "Email 邮件发送",
|
||||
"avatar": "plugins/email",
|
||||
"intro": "通过SMTP协议发送电子邮件(nodemailer)",
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
{
|
||||
"author": "",
|
||||
"version": "489",
|
||||
"name": "文本加工",
|
||||
"avatar": "/imgs/workflow/textEditor.svg",
|
||||
"intro": "可对固定或传入的文本进行加工后输出,非字符串类型数据最终会转成字符串类型。",
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
{
|
||||
"author": "",
|
||||
"version": "4811",
|
||||
"name": "Wiki搜索",
|
||||
"avatar": "core/workflow/template/wiki",
|
||||
"intro": "在Wiki中查询释义。",
|
||||
|
||||
178
packages/service/common/buffer/rawText/controller.ts
Normal file
@@ -0,0 +1,178 @@
|
||||
import { retryFn } from '@fastgpt/global/common/system/utils';
|
||||
import { connectionMongo } from '../../mongo';
|
||||
import { MongoRawTextBufferSchema, bucketName } from './schema';
|
||||
import { addLog } from '../../system/log';
|
||||
import { setCron } from '../../system/cron';
|
||||
import { checkTimerLock } from '../../system/timerLock/utils';
|
||||
import { TimerIdEnum } from '../../system/timerLock/constants';
|
||||
|
||||
const getGridBucket = () => {
|
||||
return new connectionMongo.mongo.GridFSBucket(connectionMongo.connection.db!, {
|
||||
bucketName: bucketName
|
||||
});
|
||||
};
|
||||
|
||||
export const addRawTextBuffer = async ({
|
||||
sourceId,
|
||||
sourceName,
|
||||
text,
|
||||
expiredTime
|
||||
}: {
|
||||
sourceId: string;
|
||||
sourceName: string;
|
||||
text: string;
|
||||
expiredTime: Date;
|
||||
}) => {
|
||||
const gridBucket = getGridBucket();
|
||||
const metadata = {
|
||||
sourceId,
|
||||
sourceName,
|
||||
expiredTime
|
||||
};
|
||||
|
||||
const buffer = Buffer.from(text);
|
||||
|
||||
const fileSize = buffer.length;
|
||||
// 单块大小:尽可能大,但不超过 14MB,不小于128KB
|
||||
const chunkSizeBytes = (() => {
|
||||
// 计算理想块大小:文件大小 ÷ 目标块数(10)。 并且每个块需要小于 14MB
|
||||
const idealChunkSize = Math.min(Math.ceil(fileSize / 10), 14 * 1024 * 1024);
|
||||
|
||||
// 确保块大小至少为128KB
|
||||
const minChunkSize = 128 * 1024; // 128KB
|
||||
|
||||
// 取理想块大小和最小块大小中的较大值
|
||||
let chunkSize = Math.max(idealChunkSize, minChunkSize);
|
||||
|
||||
// 将块大小向上取整到最接近的64KB的倍数,使其更整齐
|
||||
chunkSize = Math.ceil(chunkSize / (64 * 1024)) * (64 * 1024);
|
||||
|
||||
return chunkSize;
|
||||
})();
|
||||
|
||||
const uploadStream = gridBucket.openUploadStream(sourceId, {
|
||||
metadata,
|
||||
chunkSizeBytes
|
||||
});
|
||||
|
||||
return retryFn(async () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
uploadStream.end(buffer);
|
||||
uploadStream.on('finish', () => {
|
||||
resolve(uploadStream.id);
|
||||
});
|
||||
uploadStream.on('error', (error) => {
|
||||
addLog.error('addRawTextBuffer error', error);
|
||||
resolve('');
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
export const getRawTextBuffer = async (sourceId: string) => {
|
||||
const gridBucket = getGridBucket();
|
||||
|
||||
return retryFn(async () => {
|
||||
const bufferData = await MongoRawTextBufferSchema.findOne(
|
||||
{
|
||||
'metadata.sourceId': sourceId
|
||||
},
|
||||
'_id metadata'
|
||||
).lean();
|
||||
if (!bufferData) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Read file content
|
||||
const downloadStream = gridBucket.openDownloadStream(bufferData._id);
|
||||
const chunks: Buffer[] = [];
|
||||
|
||||
return new Promise<{
|
||||
text: string;
|
||||
sourceName: string;
|
||||
} | null>((resolve, reject) => {
|
||||
downloadStream.on('data', (chunk) => {
|
||||
chunks.push(chunk);
|
||||
});
|
||||
|
||||
downloadStream.on('end', () => {
|
||||
const buffer = Buffer.concat(chunks);
|
||||
const text = buffer.toString('utf8');
|
||||
resolve({
|
||||
text,
|
||||
sourceName: bufferData.metadata?.sourceName || ''
|
||||
});
|
||||
});
|
||||
|
||||
downloadStream.on('error', (error) => {
|
||||
addLog.error('getRawTextBuffer error', error);
|
||||
resolve(null);
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
export const deleteRawTextBuffer = async (sourceId: string): Promise<boolean> => {
|
||||
const gridBucket = getGridBucket();
|
||||
|
||||
return retryFn(async () => {
|
||||
const buffer = await MongoRawTextBufferSchema.findOne({ 'metadata.sourceId': sourceId });
|
||||
if (!buffer) {
|
||||
return false;
|
||||
}
|
||||
|
||||
await gridBucket.delete(buffer._id);
|
||||
return true;
|
||||
});
|
||||
};
|
||||
|
||||
export const updateRawTextBufferExpiredTime = async ({
|
||||
sourceId,
|
||||
expiredTime
|
||||
}: {
|
||||
sourceId: string;
|
||||
expiredTime: Date;
|
||||
}) => {
|
||||
return retryFn(async () => {
|
||||
return MongoRawTextBufferSchema.updateOne(
|
||||
{ 'metadata.sourceId': sourceId },
|
||||
{ $set: { 'metadata.expiredTime': expiredTime } }
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
export const clearExpiredRawTextBufferCron = async () => {
|
||||
const clearExpiredRawTextBuffer = async () => {
|
||||
addLog.debug('Clear expired raw text buffer start');
|
||||
const gridBucket = getGridBucket();
|
||||
|
||||
return retryFn(async () => {
|
||||
const data = await MongoRawTextBufferSchema.find(
|
||||
{
|
||||
'metadata.expiredTime': { $lt: new Date() }
|
||||
},
|
||||
'_id'
|
||||
).lean();
|
||||
|
||||
for (const item of data) {
|
||||
await gridBucket.delete(item._id);
|
||||
}
|
||||
addLog.debug('Clear expired raw text buffer end');
|
||||
});
|
||||
};
|
||||
|
||||
setCron('*/10 * * * *', async () => {
|
||||
if (
|
||||
await checkTimerLock({
|
||||
timerId: TimerIdEnum.clearExpiredRawTextBuffer,
|
||||
lockMinuted: 9
|
||||
})
|
||||
) {
|
||||
try {
|
||||
await clearExpiredRawTextBuffer();
|
||||
} catch (error) {
|
||||
addLog.error('clearExpiredRawTextBufferCron error', error);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
@@ -1,33 +1,22 @@
|
||||
import { getMongoModel, Schema } from '../../mongo';
|
||||
import { type RawTextBufferSchemaType } from './type';
|
||||
import { getMongoModel, type Types, Schema } from '../../mongo';
|
||||
|
||||
export const collectionName = 'buffer_rawtexts';
|
||||
export const bucketName = 'buffer_rawtext';
|
||||
|
||||
const RawTextBufferSchema = new Schema({
|
||||
sourceId: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
rawText: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
createTime: {
|
||||
type: Date,
|
||||
default: () => new Date()
|
||||
},
|
||||
metadata: Object
|
||||
metadata: {
|
||||
sourceId: { type: String, required: true },
|
||||
sourceName: { type: String, required: true },
|
||||
expiredTime: { type: Date, required: true }
|
||||
}
|
||||
});
|
||||
RawTextBufferSchema.index({ 'metadata.sourceId': 'hashed' });
|
||||
RawTextBufferSchema.index({ 'metadata.expiredTime': -1 });
|
||||
|
||||
try {
|
||||
RawTextBufferSchema.index({ sourceId: 1 });
|
||||
// 20 minutes
|
||||
RawTextBufferSchema.index({ createTime: 1 }, { expireAfterSeconds: 20 * 60 });
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
|
||||
export const MongoRawTextBuffer = getMongoModel<RawTextBufferSchemaType>(
|
||||
collectionName,
|
||||
RawTextBufferSchema
|
||||
);
|
||||
export const MongoRawTextBufferSchema = getMongoModel<{
|
||||
_id: Types.ObjectId;
|
||||
metadata: {
|
||||
sourceId: string;
|
||||
sourceName: string;
|
||||
expiredTime: Date;
|
||||
};
|
||||
}>(`${bucketName}.files`, RawTextBufferSchema);
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
export type RawTextBufferSchemaType = {
|
||||
sourceId: string;
|
||||
rawText: string;
|
||||
createTime: Date;
|
||||
metadata?: {
|
||||
filename: string;
|
||||
};
|
||||
};
|
||||
@@ -6,13 +6,13 @@ import { type DatasetFileSchema } from '@fastgpt/global/core/dataset/type';
|
||||
import { MongoChatFileSchema, MongoDatasetFileSchema } from './schema';
|
||||
import { detectFileEncoding, detectFileEncodingByPath } from '@fastgpt/global/common/file/tools';
|
||||
import { CommonErrEnum } from '@fastgpt/global/common/error/code/common';
|
||||
import { MongoRawTextBuffer } from '../../buffer/rawText/schema';
|
||||
import { readRawContentByFileBuffer } from '../read/utils';
|
||||
import { gridFsStream2Buffer, stream2Encoding } from './utils';
|
||||
import { addLog } from '../../system/log';
|
||||
import { readFromSecondary } from '../../mongo/utils';
|
||||
import { parseFileExtensionFromUrl } from '@fastgpt/global/common/string/tools';
|
||||
import { Readable } from 'stream';
|
||||
import { addRawTextBuffer, getRawTextBuffer } from '../../buffer/rawText/controller';
|
||||
import { addMinutes } from 'date-fns';
|
||||
|
||||
export function getGFSCollection(bucket: `${BucketNameEnum}`) {
|
||||
MongoDatasetFileSchema;
|
||||
@@ -223,15 +223,13 @@ export const readFileContentFromMongo = async ({
|
||||
rawText: string;
|
||||
filename: string;
|
||||
}> => {
|
||||
const bufferId = `${fileId}-${customPdfParse}`;
|
||||
const bufferId = `${String(fileId)}-${customPdfParse}`;
|
||||
// read buffer
|
||||
const fileBuffer = await MongoRawTextBuffer.findOne({ sourceId: bufferId }, undefined, {
|
||||
...readFromSecondary
|
||||
}).lean();
|
||||
const fileBuffer = await getRawTextBuffer(bufferId);
|
||||
if (fileBuffer) {
|
||||
return {
|
||||
rawText: fileBuffer.rawText,
|
||||
filename: fileBuffer.metadata?.filename || ''
|
||||
rawText: fileBuffer.text,
|
||||
filename: fileBuffer?.sourceName
|
||||
};
|
||||
}
|
||||
|
||||
@@ -265,16 +263,13 @@ export const readFileContentFromMongo = async ({
|
||||
}
|
||||
});
|
||||
|
||||
// < 14M
|
||||
if (fileBuffers.length < 14 * 1024 * 1024 && rawText.trim()) {
|
||||
MongoRawTextBuffer.create({
|
||||
sourceId: bufferId,
|
||||
rawText,
|
||||
metadata: {
|
||||
filename: file.filename
|
||||
}
|
||||
});
|
||||
}
|
||||
// Add buffer
|
||||
addRawTextBuffer({
|
||||
sourceId: bufferId,
|
||||
sourceName: file.filename,
|
||||
text: rawText,
|
||||
expiredTime: addMinutes(new Date(), 20)
|
||||
});
|
||||
|
||||
return {
|
||||
rawText,
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
import { Schema, getMongoModel } from '../../mongo';
|
||||
|
||||
const DatasetFileSchema = new Schema({});
|
||||
const ChatFileSchema = new Schema({});
|
||||
const DatasetFileSchema = new Schema({
|
||||
metadata: Object
|
||||
});
|
||||
const ChatFileSchema = new Schema({
|
||||
metadata: Object
|
||||
});
|
||||
|
||||
try {
|
||||
DatasetFileSchema.index({ uploadDate: -1 });
|
||||
DatasetFileSchema.index({ uploadDate: -1 });
|
||||
|
||||
ChatFileSchema.index({ uploadDate: -1 });
|
||||
ChatFileSchema.index({ 'metadata.chatId': 1 });
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
ChatFileSchema.index({ uploadDate: -1 });
|
||||
ChatFileSchema.index({ 'metadata.chatId': 1 });
|
||||
|
||||
export const MongoDatasetFileSchema = getMongoModel('dataset.files', DatasetFileSchema);
|
||||
export const MongoChatFileSchema = getMongoModel('chat.files', ChatFileSchema);
|
||||
|
||||
@@ -1,5 +1,57 @@
|
||||
import { detectFileEncoding } from '@fastgpt/global/common/file/tools';
|
||||
import { PassThrough } from 'stream';
|
||||
import { getGridBucket } from './controller';
|
||||
import { type BucketNameEnum } from '@fastgpt/global/common/file/constants';
|
||||
import { retryFn } from '@fastgpt/global/common/system/utils';
|
||||
|
||||
export const createFileFromText = async ({
|
||||
bucket,
|
||||
filename,
|
||||
text,
|
||||
metadata
|
||||
}: {
|
||||
bucket: `${BucketNameEnum}`;
|
||||
filename: string;
|
||||
text: string;
|
||||
metadata: Record<string, any>;
|
||||
}) => {
|
||||
const gridBucket = getGridBucket(bucket);
|
||||
|
||||
const buffer = Buffer.from(text);
|
||||
|
||||
const fileSize = buffer.length;
|
||||
// 单块大小:尽可能大,但不超过 14MB,不小于128KB
|
||||
const chunkSizeBytes = (() => {
|
||||
// 计算理想块大小:文件大小 ÷ 目标块数(10)。 并且每个块需要小于 14MB
|
||||
const idealChunkSize = Math.min(Math.ceil(fileSize / 10), 14 * 1024 * 1024);
|
||||
|
||||
// 确保块大小至少为128KB
|
||||
const minChunkSize = 128 * 1024; // 128KB
|
||||
|
||||
// 取理想块大小和最小块大小中的较大值
|
||||
let chunkSize = Math.max(idealChunkSize, minChunkSize);
|
||||
|
||||
// 将块大小向上取整到最接近的64KB的倍数,使其更整齐
|
||||
chunkSize = Math.ceil(chunkSize / (64 * 1024)) * (64 * 1024);
|
||||
|
||||
return chunkSize;
|
||||
})();
|
||||
|
||||
const uploadStream = gridBucket.openUploadStream(filename, {
|
||||
metadata,
|
||||
chunkSizeBytes
|
||||
});
|
||||
|
||||
return retryFn(async () => {
|
||||
return new Promise<{ fileId: string }>((resolve, reject) => {
|
||||
uploadStream.end(buffer);
|
||||
uploadStream.on('finish', () => {
|
||||
resolve({ fileId: String(uploadStream.id) });
|
||||
});
|
||||
uploadStream.on('error', reject);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
export const gridFsStream2Buffer = (stream: NodeJS.ReadableStream) => {
|
||||
return new Promise<Buffer>((resolve, reject) => {
|
||||
|
||||
@@ -110,7 +110,7 @@ export const readRawContentByFileBuffer = async ({
|
||||
|
||||
return {
|
||||
rawText: text,
|
||||
formatText: rawText,
|
||||
formatText: text,
|
||||
imageList
|
||||
};
|
||||
};
|
||||
|
||||
@@ -5,7 +5,8 @@ export enum TimerIdEnum {
|
||||
clearExpiredSubPlan = 'clearExpiredSubPlan',
|
||||
updateStandardPlan = 'updateStandardPlan',
|
||||
scheduleTriggerApp = 'scheduleTriggerApp',
|
||||
notification = 'notification'
|
||||
notification = 'notification',
|
||||
clearExpiredRawTextBuffer = 'clearExpiredRawTextBuffer'
|
||||
}
|
||||
|
||||
export enum LockNotificationEnum {
|
||||
|
||||
@@ -30,8 +30,7 @@ import { Types } from 'mongoose';
|
||||
community: community-id
|
||||
commercial: commercial-id
|
||||
*/
|
||||
|
||||
export async function splitCombinePluginId(id: string) {
|
||||
export function splitCombineToolId(id: string) {
|
||||
const splitRes = id.split('-');
|
||||
if (splitRes.length === 1) {
|
||||
// app id
|
||||
@@ -42,7 +41,7 @@ export async function splitCombinePluginId(id: string) {
|
||||
}
|
||||
|
||||
const [source, pluginId] = id.split('-') as [PluginSourceEnum, string];
|
||||
if (!source || !pluginId) return Promise.reject('pluginId not found');
|
||||
if (!source || !pluginId) throw new Error('pluginId not found');
|
||||
|
||||
return { source, pluginId: id };
|
||||
}
|
||||
@@ -54,7 +53,7 @@ const getSystemPluginTemplateById = async (
|
||||
versionId?: string
|
||||
): Promise<ChildAppType> => {
|
||||
const item = getSystemPluginTemplates().find((plugin) => plugin.id === pluginId);
|
||||
if (!item) return Promise.reject(PluginErrEnum.unAuth);
|
||||
if (!item) return Promise.reject(PluginErrEnum.unExist);
|
||||
|
||||
const plugin = cloneDeep(item);
|
||||
|
||||
@@ -64,10 +63,10 @@ const getSystemPluginTemplateById = async (
|
||||
{ pluginId: plugin.id, 'customConfig.associatedPluginId': plugin.associatedPluginId },
|
||||
'associatedPluginId'
|
||||
).lean();
|
||||
if (!systemPlugin) return Promise.reject(PluginErrEnum.unAuth);
|
||||
if (!systemPlugin) return Promise.reject(PluginErrEnum.unExist);
|
||||
|
||||
const app = await MongoApp.findById(plugin.associatedPluginId).lean();
|
||||
if (!app) return Promise.reject(PluginErrEnum.unAuth);
|
||||
if (!app) return Promise.reject(PluginErrEnum.unExist);
|
||||
|
||||
const version = versionId
|
||||
? await getAppVersionById({
|
||||
@@ -77,6 +76,12 @@ const getSystemPluginTemplateById = async (
|
||||
})
|
||||
: await getAppLatestVersion(plugin.associatedPluginId, app);
|
||||
if (!version.versionId) return Promise.reject('App version not found');
|
||||
const isLatest = version.versionId
|
||||
? await checkIsLatestVersion({
|
||||
appId: plugin.associatedPluginId,
|
||||
versionId: version.versionId
|
||||
})
|
||||
: true;
|
||||
|
||||
return {
|
||||
...plugin,
|
||||
@@ -85,12 +90,19 @@ const getSystemPluginTemplateById = async (
|
||||
edges: version.edges,
|
||||
chatConfig: version.chatConfig
|
||||
},
|
||||
version: versionId || String(version.versionId),
|
||||
version: versionId ? version?.versionId : '',
|
||||
versionLabel: version?.versionName,
|
||||
isLatestVersion: isLatest,
|
||||
teamId: String(app.teamId),
|
||||
tmbId: String(app.tmbId)
|
||||
};
|
||||
}
|
||||
return plugin;
|
||||
|
||||
return {
|
||||
...plugin,
|
||||
version: undefined,
|
||||
isLatestVersion: true
|
||||
};
|
||||
};
|
||||
|
||||
/* Format plugin to workflow preview node data */
|
||||
@@ -102,11 +114,11 @@ export async function getChildAppPreviewNode({
|
||||
versionId?: string;
|
||||
}): Promise<FlowNodeTemplateType> {
|
||||
const app: ChildAppType = await (async () => {
|
||||
const { source, pluginId } = await splitCombinePluginId(appId);
|
||||
const { source, pluginId } = splitCombineToolId(appId);
|
||||
|
||||
if (source === PluginSourceEnum.personal) {
|
||||
const item = await MongoApp.findById(appId).lean();
|
||||
if (!item) return Promise.reject('plugin not found');
|
||||
if (!item) return Promise.reject(PluginErrEnum.unExist);
|
||||
|
||||
const version = await getAppVersionById({ appId, versionId, app: item });
|
||||
|
||||
@@ -132,8 +144,8 @@ export async function getChildAppPreviewNode({
|
||||
},
|
||||
templateType: FlowNodeTemplateTypeEnum.teamApp,
|
||||
|
||||
version: version.versionId,
|
||||
versionLabel: version?.versionName || '',
|
||||
version: versionId ? version?.versionId : '',
|
||||
versionLabel: version?.versionName,
|
||||
isLatestVersion: isLatest,
|
||||
|
||||
originCost: 0,
|
||||
@@ -142,7 +154,7 @@ export async function getChildAppPreviewNode({
|
||||
pluginOrder: 0
|
||||
};
|
||||
} else {
|
||||
return getSystemPluginTemplateById(pluginId);
|
||||
return getSystemPluginTemplateById(pluginId, versionId);
|
||||
}
|
||||
})();
|
||||
|
||||
@@ -216,12 +228,12 @@ export async function getChildAppRuntimeById(
|
||||
id: string,
|
||||
versionId?: string
|
||||
): Promise<PluginRuntimeType> {
|
||||
const app: ChildAppType = await (async () => {
|
||||
const { source, pluginId } = await splitCombinePluginId(id);
|
||||
const app = await (async () => {
|
||||
const { source, pluginId } = splitCombineToolId(id);
|
||||
|
||||
if (source === PluginSourceEnum.personal) {
|
||||
const item = await MongoApp.findById(id).lean();
|
||||
if (!item) return Promise.reject('plugin not found');
|
||||
if (!item) return Promise.reject(PluginErrEnum.unExist);
|
||||
|
||||
const version = await getAppVersionById({
|
||||
appId: id,
|
||||
@@ -244,8 +256,6 @@ export async function getChildAppRuntimeById(
|
||||
},
|
||||
templateType: FlowNodeTemplateTypeEnum.teamApp,
|
||||
|
||||
// 用不到
|
||||
version: item?.pluginData?.nodeVersion,
|
||||
originCost: 0,
|
||||
currentCost: 0,
|
||||
hasTokenFee: false,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { type ChatNodeUsageType } from '@fastgpt/global/support/wallet/bill/type';
|
||||
import { type PluginRuntimeType } from '@fastgpt/global/core/plugin/type';
|
||||
import { splitCombinePluginId } from './controller';
|
||||
import { splitCombineToolId } from './controller';
|
||||
import { PluginSourceEnum } from '@fastgpt/global/core/plugin/constants';
|
||||
|
||||
/*
|
||||
@@ -20,7 +20,7 @@ export const computedPluginUsage = async ({
|
||||
childrenUsage: ChatNodeUsageType[];
|
||||
error?: boolean;
|
||||
}) => {
|
||||
const { source } = await splitCombinePluginId(plugin.id);
|
||||
const { source } = splitCombineToolId(plugin.id);
|
||||
const childrenUsages = childrenUsage.reduce((sum, item) => sum + (item.totalPoints || 0), 0);
|
||||
|
||||
if (source !== PluginSourceEnum.personal) {
|
||||
|
||||
@@ -64,7 +64,12 @@ const AppSchema = new Schema({
|
||||
type: Date,
|
||||
default: () => new Date()
|
||||
},
|
||||
|
||||
tags: [
|
||||
{
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: 'app_tags'
|
||||
}
|
||||
],
|
||||
// role and auth
|
||||
teamTags: {
|
||||
type: [String]
|
||||
|
||||
242
packages/service/core/app/tags/controller.ts
Normal file
@@ -0,0 +1,242 @@
|
||||
import { MongoTag } from './schema';
|
||||
import { MongoApp } from '../schema';
|
||||
import { Types } from '../../../common/mongo';
|
||||
|
||||
/**
|
||||
* 创建新标签
|
||||
*/
|
||||
export const createTag = async ({
|
||||
teamId,
|
||||
name,
|
||||
color
|
||||
}: {
|
||||
teamId: string;
|
||||
name: string;
|
||||
color?: string;
|
||||
}) => {
|
||||
const tag = await MongoTag.create({
|
||||
teamId,
|
||||
name,
|
||||
color
|
||||
});
|
||||
|
||||
return tag.toObject();
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取团队所有标签
|
||||
*/
|
||||
export const getTeamTags = async (teamId: string) => {
|
||||
const tags = await MongoTag.find({ teamId }).lean();
|
||||
return tags;
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取标签使用统计
|
||||
*/
|
||||
export const getTagsWithCount = async (teamId: string) => {
|
||||
return MongoTag.aggregate([
|
||||
{ $match: { teamId: new Types.ObjectId(teamId) } },
|
||||
{
|
||||
$lookup: {
|
||||
from: 'apps',
|
||||
localField: '_id',
|
||||
foreignField: 'tags',
|
||||
as: 'apps'
|
||||
}
|
||||
},
|
||||
{
|
||||
$addFields: {
|
||||
count: { $size: '$apps' }
|
||||
}
|
||||
},
|
||||
{
|
||||
$project: {
|
||||
apps: 0
|
||||
}
|
||||
}
|
||||
]);
|
||||
};
|
||||
|
||||
/**
|
||||
* 更新标签
|
||||
*/
|
||||
export const updateTag = async ({
|
||||
tagId,
|
||||
teamId,
|
||||
name,
|
||||
color
|
||||
}: {
|
||||
tagId: string;
|
||||
teamId: string;
|
||||
name?: string;
|
||||
color?: string;
|
||||
}) => {
|
||||
const updateData: Record<string, any> = {};
|
||||
if (name !== undefined) updateData.name = name;
|
||||
if (color !== undefined) updateData.color = color;
|
||||
|
||||
await MongoTag.updateOne({ _id: tagId, teamId }, { $set: updateData });
|
||||
|
||||
return MongoTag.findById(tagId).lean();
|
||||
};
|
||||
|
||||
/**
|
||||
* 删除标签
|
||||
*/
|
||||
export const deleteTag = async ({ tagId, teamId }: { tagId: string; teamId: string }) => {
|
||||
// 先从所有 app 中移除该标签
|
||||
await MongoApp.updateMany({ teamId, tags: tagId }, { $pull: { tags: tagId } });
|
||||
|
||||
// 然后删除标签
|
||||
await MongoTag.deleteOne({ _id: tagId, teamId });
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* 为 app 添加标签
|
||||
*/
|
||||
export const addTagToApp = async ({
|
||||
appId,
|
||||
tagId,
|
||||
teamId
|
||||
}: {
|
||||
appId: string;
|
||||
tagId: string;
|
||||
teamId: string;
|
||||
}) => {
|
||||
// 确认标签存在且属于该团队
|
||||
const tag = await MongoTag.findOne({ _id: tagId, teamId });
|
||||
if (!tag) {
|
||||
throw new Error('Tag not found or not authorized');
|
||||
}
|
||||
|
||||
await MongoApp.updateOne({ _id: appId, teamId }, { $addToSet: { tags: tagId } });
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* 从 app 移除标签
|
||||
*/
|
||||
export const removeTagFromApp = async ({
|
||||
appId,
|
||||
tagId,
|
||||
teamId
|
||||
}: {
|
||||
appId: string;
|
||||
tagId: string;
|
||||
teamId: string;
|
||||
}) => {
|
||||
await MongoApp.updateOne({ _id: appId, teamId }, { $pull: { tags: tagId } });
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* 批量删除标签
|
||||
*/
|
||||
export const batchDeleteTags = async ({ tagIds, teamId }: { tagIds: string[]; teamId: string }) => {
|
||||
if (!tagIds || tagIds.length === 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// 先从所有 app 中移除这些标签
|
||||
await MongoApp.updateMany(
|
||||
{ teamId, tags: { $in: tagIds } },
|
||||
{ $pull: { tags: { $in: tagIds } } }
|
||||
);
|
||||
|
||||
// 然后删除标签
|
||||
const result = await MongoTag.deleteMany({ _id: { $in: tagIds }, teamId });
|
||||
|
||||
return { deletedCount: result.deletedCount };
|
||||
};
|
||||
|
||||
/**
|
||||
* 批量为 app 添加标签
|
||||
*/
|
||||
export const batchAddTagsToApp = async ({
|
||||
appId,
|
||||
tagIds,
|
||||
teamId
|
||||
}: {
|
||||
appId: string;
|
||||
tagIds: string[];
|
||||
teamId: string;
|
||||
}) => {
|
||||
if (!tagIds || tagIds.length === 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// 确认标签存在且属于该团队
|
||||
const tags = await MongoTag.find({ _id: { $in: tagIds }, teamId });
|
||||
if (tags.length !== tagIds.length) {
|
||||
throw new Error('Some tags not found or not authorized');
|
||||
}
|
||||
|
||||
await MongoApp.updateOne({ _id: appId, teamId }, { $addToSet: { tags: { $each: tagIds } } });
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* 批量从 app 移除标签
|
||||
*/
|
||||
export const batchRemoveTagsFromApp = async ({
|
||||
appId,
|
||||
tagIds,
|
||||
teamId
|
||||
}: {
|
||||
appId: string;
|
||||
tagIds: string[];
|
||||
teamId: string;
|
||||
}) => {
|
||||
if (!tagIds || tagIds.length === 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
await MongoApp.updateOne({ _id: appId, teamId }, { $pull: { tags: { $in: tagIds } } });
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* 批量为某一标签添加 app(全量更新)
|
||||
*/
|
||||
export const batchAddAppsToTag = async ({
|
||||
tagId,
|
||||
appIds,
|
||||
teamId
|
||||
}: {
|
||||
tagId: string;
|
||||
appIds: string[];
|
||||
teamId: string;
|
||||
}) => {
|
||||
// 确认标签存在且属于该团队
|
||||
const tag = await MongoTag.findOne({ _id: tagId, teamId });
|
||||
if (!tag) {
|
||||
throw new Error('Tag not found or not authorized');
|
||||
}
|
||||
|
||||
// 如果 appIds 为空数组,则移除该标签的所有应用
|
||||
if (!appIds || appIds.length === 0) {
|
||||
await MongoApp.updateMany({ teamId, tags: tagId }, { $pull: { tags: tagId } });
|
||||
return true;
|
||||
}
|
||||
|
||||
// 确认所有 app 都存在且属于该团队
|
||||
const apps = await MongoApp.find({ _id: { $in: appIds }, teamId });
|
||||
if (apps.length !== appIds.length) {
|
||||
throw new Error('Some apps not found or not authorized');
|
||||
}
|
||||
|
||||
// 先从所有应用中移除该标签
|
||||
await MongoApp.updateMany({ teamId, tags: tagId }, { $pull: { tags: tagId } });
|
||||
|
||||
// 然后为指定的应用添加该标签
|
||||
await MongoApp.updateMany({ _id: { $in: appIds }, teamId }, { $addToSet: { tags: tagId } });
|
||||
|
||||
return true;
|
||||
};
|
||||
37
packages/service/core/app/tags/schema.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import { TeamCollectionName } from '@fastgpt/global/support/user/team/constant';
|
||||
import { getMongoModel, Schema } from '../../../common/mongo';
|
||||
|
||||
export const TagCollectionName = 'app_tags';
|
||||
|
||||
export type TagSchemaType = {
|
||||
_id: string;
|
||||
teamId: string;
|
||||
name: string;
|
||||
color: string;
|
||||
createTime: Date;
|
||||
};
|
||||
|
||||
const TagSchema = new Schema({
|
||||
teamId: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: TeamCollectionName,
|
||||
required: true
|
||||
},
|
||||
name: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
color: {
|
||||
type: String,
|
||||
default: '#3370ff'
|
||||
},
|
||||
createTime: {
|
||||
type: Date,
|
||||
default: () => new Date()
|
||||
}
|
||||
});
|
||||
|
||||
// 创建复合索引:按团队和名称确保唯一性
|
||||
TagSchema.index({ teamId: 1, name: 1 }, { unique: true });
|
||||
|
||||
export const MongoTag = getMongoModel<TagSchemaType>(TagCollectionName, TagSchema);
|
||||
@@ -1,14 +1,13 @@
|
||||
import { MongoDataset } from '../dataset/schema';
|
||||
import { getEmbeddingModel } from '../ai/model';
|
||||
import {
|
||||
AppNodeFlowNodeTypeMap,
|
||||
FlowNodeTypeEnum
|
||||
} from '@fastgpt/global/core/workflow/node/constant';
|
||||
import { FlowNodeTypeEnum } from '@fastgpt/global/core/workflow/node/constant';
|
||||
import { NodeInputKeyEnum } from '@fastgpt/global/core/workflow/constants';
|
||||
import type { StoreNodeItemType } from '@fastgpt/global/core/workflow/type/node';
|
||||
import { MongoAppVersion } from './version/schema';
|
||||
import { checkIsLatestVersion } from './version/controller';
|
||||
import { Types } from '../../common/mongo';
|
||||
import { getChildAppPreviewNode, splitCombineToolId } from './plugin/controller';
|
||||
import { PluginSourceEnum } from '@fastgpt/global/core/plugin/constants';
|
||||
import { authAppByTmbId } from '../../support/permission/app/auth';
|
||||
import { ReadPermissionVal } from '@fastgpt/global/support/permission/constant';
|
||||
import { getErrText } from '@fastgpt/global/common/error/utils';
|
||||
|
||||
export async function listAppDatasetDataByTeamIdAndDatasetIds({
|
||||
teamId,
|
||||
@@ -33,53 +32,58 @@ export async function listAppDatasetDataByTeamIdAndDatasetIds({
|
||||
export async function rewriteAppWorkflowToDetail({
|
||||
nodes,
|
||||
teamId,
|
||||
isRoot
|
||||
isRoot,
|
||||
ownerTmbId
|
||||
}: {
|
||||
nodes: StoreNodeItemType[];
|
||||
teamId: string;
|
||||
isRoot: boolean;
|
||||
ownerTmbId: string;
|
||||
}) {
|
||||
const datasetIdSet = new Set<string>();
|
||||
|
||||
// Add node(App Type) versionlabel and latest sign
|
||||
const appNodes = nodes.filter((node) => AppNodeFlowNodeTypeMap[node.flowNodeType]);
|
||||
const versionIds = appNodes
|
||||
.filter((node) => node.version && Types.ObjectId.isValid(node.version))
|
||||
.map((node) => node.version);
|
||||
/* Add node(App Type) versionlabel and latest sign ==== */
|
||||
await Promise.all(
|
||||
nodes.map(async (node) => {
|
||||
if (!node.pluginId) return;
|
||||
const { source } = splitCombineToolId(node.pluginId);
|
||||
|
||||
if (versionIds.length > 0) {
|
||||
const versionDataList = await MongoAppVersion.find(
|
||||
{
|
||||
_id: { $in: versionIds }
|
||||
},
|
||||
'_id versionName appId time'
|
||||
).lean();
|
||||
try {
|
||||
const [preview] = await Promise.all([
|
||||
getChildAppPreviewNode({
|
||||
appId: node.pluginId,
|
||||
versionId: node.version
|
||||
}),
|
||||
...(source === PluginSourceEnum.personal
|
||||
? [
|
||||
authAppByTmbId({
|
||||
tmbId: ownerTmbId,
|
||||
appId: node.pluginId,
|
||||
per: ReadPermissionVal
|
||||
})
|
||||
]
|
||||
: [])
|
||||
]);
|
||||
|
||||
const versionMap: Record<string, any> = {};
|
||||
|
||||
const isLatestChecks = await Promise.all(
|
||||
versionDataList.map(async (version) => {
|
||||
const isLatest = await checkIsLatestVersion({
|
||||
appId: version.appId,
|
||||
versionId: version._id
|
||||
});
|
||||
|
||||
return { versionId: String(version._id), isLatest };
|
||||
})
|
||||
);
|
||||
const isLatestMap = new Map(isLatestChecks.map((item) => [item.versionId, item.isLatest]));
|
||||
versionDataList.forEach((version) => {
|
||||
versionMap[String(version._id)] = version;
|
||||
});
|
||||
appNodes.forEach((node) => {
|
||||
if (!node.version) return;
|
||||
const versionData = versionMap[String(node.version)];
|
||||
if (versionData) {
|
||||
node.versionLabel = versionData.versionName;
|
||||
node.isLatestVersion = isLatestMap.get(String(node.version)) || false;
|
||||
node.pluginData = {
|
||||
diagram: preview.diagram,
|
||||
userGuide: preview.userGuide,
|
||||
courseUrl: preview.courseUrl,
|
||||
name: preview.name,
|
||||
avatar: preview.avatar
|
||||
};
|
||||
node.versionLabel = preview.versionLabel;
|
||||
node.isLatestVersion = preview.isLatestVersion;
|
||||
node.version = preview.version;
|
||||
} catch (error) {
|
||||
node.pluginData = {
|
||||
error: getErrText(error)
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
/* Add node(App Type) versionlabel and latest sign ==== */
|
||||
|
||||
// Get all dataset ids from nodes
|
||||
nodes.forEach((node) => {
|
||||
|
||||
@@ -68,6 +68,9 @@ export const checkIsLatestVersion = async ({
|
||||
appId: string;
|
||||
versionId: string;
|
||||
}) => {
|
||||
if (!Types.ObjectId.isValid(versionId)) {
|
||||
return false;
|
||||
}
|
||||
const version = await MongoAppVersion.findOne(
|
||||
{
|
||||
appId,
|
||||
|
||||
@@ -34,6 +34,7 @@ import { getTrainingModeByCollection } from './utils';
|
||||
import {
|
||||
computeChunkSize,
|
||||
computeChunkSplitter,
|
||||
computeParagraphChunkDeep,
|
||||
getLLMMaxChunkSize
|
||||
} from '@fastgpt/global/core/dataset/training/utils';
|
||||
import { DatasetDataIndexTypeEnum } from '@fastgpt/global/core/dataset/data/constants';
|
||||
@@ -74,7 +75,12 @@ export const createCollectionAndInsertData = async ({
|
||||
llmModel: getLLMModel(dataset.agentModel)
|
||||
});
|
||||
const chunkSplitter = computeChunkSplitter(createCollectionParams);
|
||||
if (trainingType === DatasetCollectionDataProcessModeEnum.qa) {
|
||||
const paragraphChunkDeep = computeParagraphChunkDeep(createCollectionParams);
|
||||
|
||||
if (
|
||||
trainingType === DatasetCollectionDataProcessModeEnum.qa ||
|
||||
trainingType === DatasetCollectionDataProcessModeEnum.backup
|
||||
) {
|
||||
delete createCollectionParams.chunkTriggerType;
|
||||
delete createCollectionParams.chunkTriggerMinSize;
|
||||
delete createCollectionParams.dataEnhanceCollectionName;
|
||||
@@ -87,7 +93,11 @@ export const createCollectionAndInsertData = async ({
|
||||
// 1. split chunks
|
||||
const chunks = rawText2Chunks({
|
||||
rawText,
|
||||
chunkTriggerType: createCollectionParams.chunkTriggerType,
|
||||
chunkTriggerMinSize: createCollectionParams.chunkTriggerMinSize,
|
||||
chunkSize,
|
||||
paragraphChunkDeep,
|
||||
paragraphChunkMinSize: createCollectionParams.paragraphChunkMinSize,
|
||||
maxSize: getLLMMaxChunkSize(getLLMModel(dataset.agentModel)),
|
||||
overlapRatio: trainingType === DatasetCollectionDataProcessModeEnum.chunk ? 0.2 : 0,
|
||||
customReg: chunkSplitter ? [chunkSplitter] : [],
|
||||
@@ -112,6 +122,7 @@ export const createCollectionAndInsertData = async ({
|
||||
const { _id: collectionId } = await createOneCollection({
|
||||
...createCollectionParams,
|
||||
trainingType,
|
||||
paragraphChunkDeep,
|
||||
chunkSize,
|
||||
chunkSplitter,
|
||||
|
||||
@@ -212,46 +223,19 @@ export type CreateOneCollectionParams = CreateDatasetCollectionParams & {
|
||||
tmbId: string;
|
||||
session?: ClientSession;
|
||||
};
|
||||
export async function createOneCollection({
|
||||
teamId,
|
||||
tmbId,
|
||||
name,
|
||||
parentId,
|
||||
datasetId,
|
||||
type,
|
||||
export async function createOneCollection({ session, ...props }: CreateOneCollectionParams) {
|
||||
const {
|
||||
teamId,
|
||||
parentId,
|
||||
datasetId,
|
||||
tags,
|
||||
|
||||
createTime,
|
||||
updateTime,
|
||||
|
||||
hashRawText,
|
||||
rawTextLength,
|
||||
metadata = {},
|
||||
tags,
|
||||
|
||||
nextSyncTime,
|
||||
|
||||
fileId,
|
||||
rawLink,
|
||||
externalFileId,
|
||||
externalFileUrl,
|
||||
apiFileId,
|
||||
|
||||
// Parse settings
|
||||
customPdfParse,
|
||||
imageIndex,
|
||||
autoIndexes,
|
||||
|
||||
// Chunk settings
|
||||
trainingType,
|
||||
chunkSettingMode,
|
||||
chunkSplitMode,
|
||||
chunkSize,
|
||||
indexSize,
|
||||
chunkSplitter,
|
||||
qaPrompt,
|
||||
|
||||
session
|
||||
}: CreateOneCollectionParams) {
|
||||
fileId,
|
||||
rawLink,
|
||||
externalFileId,
|
||||
externalFileUrl,
|
||||
apiFileId
|
||||
} = props;
|
||||
// Create collection tags
|
||||
const collectionTags = await createOrGetCollectionTags({ tags, teamId, datasetId, session });
|
||||
|
||||
@@ -259,41 +243,18 @@ export async function createOneCollection({
|
||||
const [collection] = await MongoDatasetCollection.create(
|
||||
[
|
||||
{
|
||||
...props,
|
||||
teamId,
|
||||
tmbId,
|
||||
parentId: parentId || null,
|
||||
datasetId,
|
||||
name,
|
||||
type,
|
||||
|
||||
rawTextLength,
|
||||
hashRawText,
|
||||
tags: collectionTags,
|
||||
metadata,
|
||||
|
||||
createTime,
|
||||
updateTime,
|
||||
nextSyncTime,
|
||||
|
||||
...(fileId ? { fileId } : {}),
|
||||
...(rawLink ? { rawLink } : {}),
|
||||
...(externalFileId ? { externalFileId } : {}),
|
||||
...(externalFileUrl ? { externalFileUrl } : {}),
|
||||
...(apiFileId ? { apiFileId } : {}),
|
||||
|
||||
// Parse settings
|
||||
customPdfParse,
|
||||
imageIndex,
|
||||
autoIndexes,
|
||||
|
||||
// Chunk settings
|
||||
trainingType,
|
||||
chunkSettingMode,
|
||||
chunkSplitMode,
|
||||
chunkSize,
|
||||
indexSize,
|
||||
chunkSplitter,
|
||||
qaPrompt
|
||||
...(apiFileId ? { apiFileId } : {})
|
||||
}
|
||||
],
|
||||
{ session, ordered: true }
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
import { BucketNameEnum } from '@fastgpt/global/common/file/constants';
|
||||
import { DatasetSourceReadTypeEnum } from '@fastgpt/global/core/dataset/constants';
|
||||
import {
|
||||
ChunkTriggerConfigTypeEnum,
|
||||
DatasetSourceReadTypeEnum
|
||||
} from '@fastgpt/global/core/dataset/constants';
|
||||
import { readFileContentFromMongo } from '../../common/file/gridfs/controller';
|
||||
import { urlsFetch } from '../../common/string/cheerio';
|
||||
import { type TextSplitProps, splitText2Chunks } from '@fastgpt/global/common/string/textSplitter';
|
||||
@@ -179,11 +182,17 @@ export const readApiServerFileContent = async ({
|
||||
|
||||
export const rawText2Chunks = ({
|
||||
rawText,
|
||||
chunkTriggerType = ChunkTriggerConfigTypeEnum.minSize,
|
||||
chunkTriggerMinSize = 1000,
|
||||
backupParse,
|
||||
chunkSize = 512,
|
||||
...splitProps
|
||||
}: {
|
||||
rawText: string;
|
||||
|
||||
chunkTriggerType?: ChunkTriggerConfigTypeEnum;
|
||||
chunkTriggerMinSize?: number; // maxSize from agent model, not store
|
||||
|
||||
backupParse?: boolean;
|
||||
tableParse?: boolean;
|
||||
} & TextSplitProps): {
|
||||
@@ -213,6 +222,28 @@ export const rawText2Chunks = ({
|
||||
return parseDatasetBackup2Chunks(rawText).chunks;
|
||||
}
|
||||
|
||||
// Chunk condition
|
||||
// 1. 选择最大值条件,只有超过了最大值(默认为模型的最大值*0.7),才会触发分块
|
||||
if (chunkTriggerType === ChunkTriggerConfigTypeEnum.maxSize) {
|
||||
const textLength = rawText.trim().length;
|
||||
const maxSize = splitProps.maxSize ? splitProps.maxSize * 0.7 : 16000;
|
||||
if (textLength < maxSize) {
|
||||
return [
|
||||
{
|
||||
q: rawText,
|
||||
a: ''
|
||||
}
|
||||
];
|
||||
}
|
||||
}
|
||||
// 2. 选择最小值条件,只有超过最小值(手动决定)才会触发分块
|
||||
if (chunkTriggerType !== ChunkTriggerConfigTypeEnum.forceChunk) {
|
||||
const textLength = rawText.trim().length;
|
||||
if (textLength < chunkTriggerMinSize) {
|
||||
return [{ q: rawText, a: '' }];
|
||||
}
|
||||
}
|
||||
|
||||
const { chunks } = splitText2Chunks({
|
||||
text: rawText,
|
||||
chunkSize,
|
||||
|
||||
@@ -47,7 +47,6 @@ export const ChunkSettings = {
|
||||
},
|
||||
paragraphChunkDeep: Number,
|
||||
paragraphChunkMinSize: Number,
|
||||
paragraphChunkMaxSize: Number,
|
||||
chunkSize: Number,
|
||||
chunkSplitter: String,
|
||||
|
||||
|
||||
@@ -658,7 +658,7 @@ export async function searchDatasetData(
|
||||
tokenLen: 0
|
||||
};
|
||||
} catch (error) {
|
||||
addLog.error('multiQueryRecall error', error);
|
||||
addLog.error('Full text search error', error);
|
||||
return {
|
||||
fullTextRecallResults: [],
|
||||
tokenLen: 0
|
||||
|
||||
@@ -86,7 +86,6 @@ export const dispatchRunTools = async (props: DispatchToolModuleProps): Promise<
|
||||
});
|
||||
|
||||
// Check interactive entry
|
||||
const interactiveResponse = lastInteractive;
|
||||
props.node.isEntry = false;
|
||||
const hasReadFilesTool = toolNodes.some(
|
||||
(item) => item.flowNodeType === FlowNodeTypeEnum.readFiles
|
||||
@@ -143,7 +142,7 @@ export const dispatchRunTools = async (props: DispatchToolModuleProps): Promise<
|
||||
})
|
||||
}
|
||||
];
|
||||
if (interactiveResponse) {
|
||||
if (lastInteractive && isEntry) {
|
||||
return value.slice(0, -2);
|
||||
}
|
||||
return value;
|
||||
@@ -183,7 +182,7 @@ export const dispatchRunTools = async (props: DispatchToolModuleProps): Promise<
|
||||
toolModel,
|
||||
maxRunToolTimes: 30,
|
||||
messages: adaptMessages,
|
||||
interactiveEntryToolParams: interactiveResponse?.toolParams
|
||||
interactiveEntryToolParams: lastInteractive?.toolParams
|
||||
});
|
||||
}
|
||||
if (toolModel.functionCall) {
|
||||
@@ -194,7 +193,7 @@ export const dispatchRunTools = async (props: DispatchToolModuleProps): Promise<
|
||||
toolNodes,
|
||||
toolModel,
|
||||
messages: adaptMessages,
|
||||
interactiveEntryToolParams: interactiveResponse?.toolParams
|
||||
interactiveEntryToolParams: lastInteractive?.toolParams
|
||||
});
|
||||
}
|
||||
|
||||
@@ -224,7 +223,7 @@ export const dispatchRunTools = async (props: DispatchToolModuleProps): Promise<
|
||||
toolNodes,
|
||||
toolModel,
|
||||
messages: adaptMessages,
|
||||
interactiveEntryToolParams: interactiveResponse?.toolParams
|
||||
interactiveEntryToolParams: lastInteractive?.toolParams
|
||||
});
|
||||
})();
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@ import type {
|
||||
SystemVariablesType
|
||||
} from '@fastgpt/global/core/workflow/runtime/type';
|
||||
import type { RuntimeNodeItemType } from '@fastgpt/global/core/workflow/runtime/type.d';
|
||||
import type { FlowNodeOutputItemType } from '@fastgpt/global/core/workflow/type/io.d';
|
||||
import type {
|
||||
AIChatItemValueItemType,
|
||||
ChatHistoryItemResType,
|
||||
|
||||
@@ -17,6 +17,7 @@ import { chatValue2RuntimePrompt } from '@fastgpt/global/core/chat/adapt';
|
||||
import { getPluginRunUserQuery } from '@fastgpt/global/core/workflow/utils';
|
||||
import { getPluginInputsFromStoreNodes } from '@fastgpt/global/core/app/plugin/utils';
|
||||
import type { NodeInputKeyEnum } from '@fastgpt/global/core/workflow/constants';
|
||||
import { getUserChatInfoAndAuthTeamPoints } from '../../../../support/permission/auth/team';
|
||||
|
||||
type RunPluginProps = ModuleDispatchProps<{
|
||||
[NodeInputKeyEnum.forbidStream]?: boolean;
|
||||
@@ -73,9 +74,11 @@ export const dispatchRunPlugin = async (props: RunPluginProps): Promise<RunPlugi
|
||||
};
|
||||
});
|
||||
|
||||
const { externalProvider } = await getUserChatInfoAndAuthTeamPoints(runningAppInfo.tmbId);
|
||||
const runtimeVariables = {
|
||||
...filterSystemVariables(props.variables),
|
||||
appId: String(plugin.id)
|
||||
appId: String(plugin.id),
|
||||
...(externalProvider ? externalProvider.externalWorkflowVariables : {})
|
||||
};
|
||||
const { flowResponses, flowUsages, assistantResponses, runTimes } = await dispatchWorkFlow({
|
||||
...props,
|
||||
|
||||
@@ -20,6 +20,7 @@ import { ReadPermissionVal } from '@fastgpt/global/support/permission/constant';
|
||||
import { getAppVersionById } from '../../../app/version/controller';
|
||||
import { parseUrlToFileType } from '@fastgpt/global/common/file/tools';
|
||||
import { type ChildrenInteractive } from '@fastgpt/global/core/workflow/template/system/interactive/type';
|
||||
import { getUserChatInfoAndAuthTeamPoints } from '../../../../support/permission/auth/team';
|
||||
|
||||
type Props = ModuleDispatchProps<{
|
||||
[NodeInputKeyEnum.userChatInput]: string;
|
||||
@@ -97,11 +98,13 @@ export const dispatchRunAppNode = async (props: Props): Promise<Response> => {
|
||||
|
||||
// Rewrite children app variables
|
||||
const systemVariables = filterSystemVariables(variables);
|
||||
const { externalProvider } = await getUserChatInfoAndAuthTeamPoints(appData.tmbId);
|
||||
const childrenRunVariables = {
|
||||
...systemVariables,
|
||||
...childrenAppVariables,
|
||||
histories: chatHistories,
|
||||
appId: String(appData._id)
|
||||
appId: String(appData._id),
|
||||
...(externalProvider ? externalProvider.externalWorkflowVariables : {})
|
||||
};
|
||||
|
||||
const childrenInteractive =
|
||||
|
||||
@@ -5,8 +5,6 @@ import { NodeOutputKeyEnum } from '@fastgpt/global/core/workflow/constants';
|
||||
import { type DispatchNodeResultType } from '@fastgpt/global/core/workflow/runtime/type';
|
||||
import axios from 'axios';
|
||||
import { serverRequestBaseUrl } from '../../../../common/api/serverRequest';
|
||||
import { MongoRawTextBuffer } from '../../../../common/buffer/rawText/schema';
|
||||
import { readFromSecondary } from '../../../../common/mongo/utils';
|
||||
import { getErrText } from '@fastgpt/global/common/error/utils';
|
||||
import { detectFileEncoding, parseUrlToFileType } from '@fastgpt/global/common/file/tools';
|
||||
import { readRawContentByFileBuffer } from '../../../../common/file/read/utils';
|
||||
@@ -14,6 +12,8 @@ import { ChatRoleEnum } from '@fastgpt/global/core/chat/constants';
|
||||
import { type ChatItemType, type UserChatItemValueItemType } from '@fastgpt/global/core/chat/type';
|
||||
import { parseFileExtensionFromUrl } from '@fastgpt/global/common/string/tools';
|
||||
import { addLog } from '../../../../common/system/log';
|
||||
import { addRawTextBuffer, getRawTextBuffer } from '../../../../common/buffer/rawText/controller';
|
||||
import { addMinutes } from 'date-fns';
|
||||
|
||||
type Props = ModuleDispatchProps<{
|
||||
[NodeInputKeyEnum.fileUrlList]: string[];
|
||||
@@ -158,14 +158,12 @@ export const getFileContentFromLinks = async ({
|
||||
parseUrlList
|
||||
.map(async (url) => {
|
||||
// Get from buffer
|
||||
const fileBuffer = await MongoRawTextBuffer.findOne({ sourceId: url }, undefined, {
|
||||
...readFromSecondary
|
||||
}).lean();
|
||||
const fileBuffer = await getRawTextBuffer(url);
|
||||
if (fileBuffer) {
|
||||
return formatResponseObject({
|
||||
filename: fileBuffer.metadata?.filename || url,
|
||||
filename: fileBuffer.sourceName || url,
|
||||
url,
|
||||
content: fileBuffer.rawText
|
||||
content: fileBuffer.text
|
||||
});
|
||||
}
|
||||
|
||||
@@ -220,17 +218,12 @@ export const getFileContentFromLinks = async ({
|
||||
});
|
||||
|
||||
// Add to buffer
|
||||
try {
|
||||
if (buffer.length < 14 * 1024 * 1024 && rawText.trim()) {
|
||||
MongoRawTextBuffer.create({
|
||||
sourceId: url,
|
||||
rawText,
|
||||
metadata: {
|
||||
filename: filename
|
||||
}
|
||||
});
|
||||
}
|
||||
} catch (error) {}
|
||||
addRawTextBuffer({
|
||||
sourceId: url,
|
||||
sourceName: filename,
|
||||
text: rawText,
|
||||
expiredTime: addMinutes(new Date(), 20)
|
||||
});
|
||||
|
||||
return formatResponseObject({ filename, url, content: rawText });
|
||||
} catch (error) {
|
||||
|
||||
@@ -10,7 +10,7 @@ import { AppPermission } from '@fastgpt/global/support/permission/app/controller
|
||||
import { type PermissionValueType } from '@fastgpt/global/support/permission/type';
|
||||
import { AppFolderTypeList } from '@fastgpt/global/core/app/constants';
|
||||
import { type ParentIdType } from '@fastgpt/global/common/parentFolder/type';
|
||||
import { splitCombinePluginId } from '../../../core/app/plugin/controller';
|
||||
import { splitCombineToolId } from '../../../core/app/plugin/controller';
|
||||
import { PluginSourceEnum } from '@fastgpt/global/core/plugin/constants';
|
||||
import { type AuthModeType, type AuthResponseType } from '../type';
|
||||
import { AppDefaultPermissionVal } from '@fastgpt/global/support/permission/app/constant';
|
||||
@@ -24,7 +24,7 @@ export const authPluginByTmbId = async ({
|
||||
appId: string;
|
||||
per: PermissionValueType;
|
||||
}) => {
|
||||
const { source } = await splitCombinePluginId(appId);
|
||||
const { source } = splitCombineToolId(appId);
|
||||
if (source === PluginSourceEnum.personal) {
|
||||
const { app } = await authAppByTmbId({
|
||||
appId,
|
||||
@@ -137,7 +137,7 @@ export const authApp = async ({
|
||||
appId: ParentIdType;
|
||||
per: PermissionValueType;
|
||||
}): Promise<
|
||||
AuthResponseType & {
|
||||
AuthResponseType<AppPermission> & {
|
||||
app: AppDetailType;
|
||||
}
|
||||
> => {
|
||||
|
||||
568
packages/service/support/user/team/gate/controller.ts
Normal file
@@ -0,0 +1,568 @@
|
||||
import { MongoTeamGate } from './schema';
|
||||
import { Types } from '../../../../common/mongo';
|
||||
import type { ClientSession } from '../../../../common/mongo';
|
||||
import { mongoSessionRun } from '../../../../common/mongo/sessionRun';
|
||||
import {
|
||||
GateFeaturedAppPermission,
|
||||
GateQuickAppPermission
|
||||
} from '@fastgpt/global/support/permission/app/constant';
|
||||
import { PerResourceTypeEnum } from '@fastgpt/global/support/permission/constant';
|
||||
import { DefaultGroupName } from '@fastgpt/global/support/user/team/group/constant';
|
||||
import { MongoMemberGroupModel } from '../../../permission/memberGroup/memberGroupSchema';
|
||||
import { MongoResourcePermission } from '../../../permission/schema';
|
||||
|
||||
export const addGatePermission = async ({
|
||||
teamId,
|
||||
appId,
|
||||
per,
|
||||
session
|
||||
}: {
|
||||
teamId: string;
|
||||
appId: string;
|
||||
per: number;
|
||||
session?: ClientSession;
|
||||
}) => {
|
||||
// 1. 先找全员组
|
||||
const teamGroup = await MongoMemberGroupModel.findOne({
|
||||
teamId,
|
||||
name: DefaultGroupName
|
||||
});
|
||||
if (!teamGroup) {
|
||||
return Promise.reject('找不到全员组');
|
||||
}
|
||||
|
||||
// 2. 加权限
|
||||
await MongoResourcePermission.updateOne(
|
||||
{
|
||||
teamId,
|
||||
groupId: teamGroup?._id,
|
||||
resourceType: PerResourceTypeEnum.app,
|
||||
resourceId: appId
|
||||
},
|
||||
{
|
||||
permission: per
|
||||
},
|
||||
{
|
||||
session,
|
||||
upsert: true
|
||||
}
|
||||
);
|
||||
};
|
||||
export const removeGatePermission = async ({
|
||||
teamId,
|
||||
appId,
|
||||
per,
|
||||
session
|
||||
}: {
|
||||
teamId: string;
|
||||
appId: string;
|
||||
per: number;
|
||||
session?: ClientSession;
|
||||
}) => {
|
||||
// 1. 先找全员组
|
||||
const teamGroup = await MongoMemberGroupModel.findOne({
|
||||
teamId,
|
||||
name: DefaultGroupName
|
||||
});
|
||||
if (!teamGroup) {
|
||||
return Promise.reject('找不到全员组');
|
||||
}
|
||||
|
||||
await MongoResourcePermission.deleteOne(
|
||||
{
|
||||
teamId,
|
||||
groupId: teamGroup?._id,
|
||||
resourceType: PerResourceTypeEnum.app,
|
||||
resourceId: appId,
|
||||
permission: per
|
||||
},
|
||||
{
|
||||
session
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* 创建团队门户配置
|
||||
*/
|
||||
export const createGateConfig = async ({ teamId }: { teamId: string }) => {
|
||||
const gate = await MongoTeamGate.create({
|
||||
teamId
|
||||
});
|
||||
|
||||
return gate.toObject();
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取团队门户配置
|
||||
*/
|
||||
export const getGateConfig = async (teamId: string) => {
|
||||
const gate = await MongoTeamGate.findOne({ teamId }).lean();
|
||||
return gate;
|
||||
};
|
||||
|
||||
/**
|
||||
* 更新团队门户配置
|
||||
*/
|
||||
export const updateGateConfig = async ({
|
||||
teamId,
|
||||
status,
|
||||
name,
|
||||
banner,
|
||||
logo,
|
||||
tools,
|
||||
placeholderText
|
||||
}: {
|
||||
teamId: string;
|
||||
status?: boolean;
|
||||
name?: string;
|
||||
banner?: string;
|
||||
logo?: string;
|
||||
tools?: string[];
|
||||
placeholderText?: string;
|
||||
}) => {
|
||||
const updateData: Record<string, any> = {};
|
||||
if (status !== undefined) updateData.status = status;
|
||||
if (name !== undefined) updateData.name = name;
|
||||
if (banner !== undefined) updateData.banner = banner;
|
||||
if (logo !== undefined) updateData.logo = logo;
|
||||
if (tools !== undefined) updateData.tools = tools;
|
||||
if (placeholderText !== undefined) updateData.placeholderText = placeholderText;
|
||||
|
||||
// 使用 upsert 选项,如果不存在则创建
|
||||
await MongoTeamGate.updateOne({ teamId }, { $set: updateData }, { upsert: true });
|
||||
|
||||
return MongoTeamGate.findOne({ teamId }).lean();
|
||||
};
|
||||
|
||||
/**
|
||||
* 删除团队门户配置
|
||||
*/
|
||||
export const deleteGateConfig = async (teamId: string) => {
|
||||
await MongoTeamGate.deleteOne({ teamId });
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* 启用或禁用团队门户
|
||||
*/
|
||||
export const toggleGateStatus = async ({ teamId, status }: { teamId: string; status: boolean }) => {
|
||||
await MongoTeamGate.updateOne({ teamId }, { $set: { status } }, { upsert: true });
|
||||
|
||||
return MongoTeamGate.findOne({ teamId }).lean();
|
||||
};
|
||||
|
||||
/**
|
||||
* 更新门户工具配置
|
||||
*/
|
||||
export const updateGateTools = async ({ teamId, tools }: { teamId: string; tools: string[] }) => {
|
||||
await MongoTeamGate.updateOne({ teamId }, { $set: { tools } }, { upsert: true });
|
||||
|
||||
return MongoTeamGate.findOne({ teamId }).lean();
|
||||
};
|
||||
|
||||
/**
|
||||
* 添加门户工具
|
||||
*/
|
||||
export const addGateTool = async ({ teamId, tool }: { teamId: string; tool: string }) => {
|
||||
await MongoTeamGate.updateOne({ teamId }, { $addToSet: { tools: tool } }, { upsert: true });
|
||||
|
||||
return MongoTeamGate.findOne({ teamId }).lean();
|
||||
};
|
||||
|
||||
/**
|
||||
* 移除门户工具
|
||||
*/
|
||||
export const removeGateTool = async ({ teamId, tool }: { teamId: string; tool: string }) => {
|
||||
await MongoTeamGate.updateOne({ teamId }, { $pull: { tools: tool } });
|
||||
|
||||
return MongoTeamGate.findOne({ teamId }).lean();
|
||||
};
|
||||
|
||||
/**
|
||||
* 更新特色应用列表
|
||||
*/
|
||||
export const updateFeaturedApps = async ({
|
||||
teamId,
|
||||
featuredApps
|
||||
}: {
|
||||
teamId: string;
|
||||
featuredApps: string[];
|
||||
}) => {
|
||||
// 将字符串数组转换为 ObjectId 数组
|
||||
const objectIdArray = featuredApps.map((id) => new Types.ObjectId(id));
|
||||
await MongoTeamGate.updateOne(
|
||||
{ teamId },
|
||||
{ $set: { featuredApps: objectIdArray } },
|
||||
{ upsert: true }
|
||||
);
|
||||
return MongoTeamGate.findOne({ teamId }).lean();
|
||||
};
|
||||
|
||||
/**
|
||||
* 添加特色应用
|
||||
*/
|
||||
export const addFeaturedApp = async ({ teamId, appId }: { teamId: string; appId: string }) => {
|
||||
await MongoTeamGate.updateOne(
|
||||
{ teamId },
|
||||
{ $addToSet: { featuredApps: new Types.ObjectId(appId) } },
|
||||
{ upsert: true }
|
||||
);
|
||||
return MongoTeamGate.findOne({ teamId }).lean();
|
||||
};
|
||||
|
||||
/**
|
||||
* 删除特色应用
|
||||
*/
|
||||
export const removeFeaturedApp = async ({
|
||||
teamId,
|
||||
appId,
|
||||
session
|
||||
}: {
|
||||
teamId: string;
|
||||
appId: string;
|
||||
session?: ClientSession;
|
||||
}) => {
|
||||
await MongoTeamGate.updateOne(
|
||||
{ teamId },
|
||||
{ $pull: { featuredApps: new Types.ObjectId(appId) } },
|
||||
{ session }
|
||||
);
|
||||
return MongoTeamGate.findOne({ teamId }).lean();
|
||||
};
|
||||
|
||||
/**
|
||||
* 移动特色应用位置(原子操作)
|
||||
* @param teamId 团队ID
|
||||
* @param appId 要移动的应用ID
|
||||
* @param toIndex 目标位置索引
|
||||
*/
|
||||
export const moveFeatureAppToPosition = async ({
|
||||
teamId,
|
||||
appId,
|
||||
toIndex
|
||||
}: {
|
||||
teamId: string;
|
||||
appId: string;
|
||||
toIndex: number;
|
||||
}) => {
|
||||
const objectId = new Types.ObjectId(appId);
|
||||
|
||||
// 获取当前配置
|
||||
const config = await MongoTeamGate.findOne({ teamId }).lean();
|
||||
if (!config || !config.featuredApps) {
|
||||
throw new Error('团队配置不存在');
|
||||
}
|
||||
|
||||
const apps = [...config.featuredApps];
|
||||
const currentIndex = apps.findIndex((id) => id.toString() === appId);
|
||||
|
||||
if (currentIndex === -1) {
|
||||
throw new Error('应用不在特色应用列表中');
|
||||
}
|
||||
|
||||
// 移动数组元素
|
||||
const [movedApp] = apps.splice(currentIndex, 1);
|
||||
apps.splice(toIndex, 0, movedApp);
|
||||
|
||||
// 一次性更新
|
||||
await MongoTeamGate.updateOne({ teamId }, { $set: { featuredApps: apps } });
|
||||
|
||||
return MongoTeamGate.findOne({ teamId }).lean();
|
||||
};
|
||||
|
||||
/**
|
||||
* 更新工具排序
|
||||
* @param teamId 团队ID
|
||||
* @param orderedTools 按新顺序排列的工具数组
|
||||
*/
|
||||
export const reorderTools = async ({
|
||||
teamId,
|
||||
orderedTools
|
||||
}: {
|
||||
teamId: string;
|
||||
orderedTools: string[];
|
||||
}) => {
|
||||
await MongoTeamGate.updateOne({ teamId }, { $set: { tools: orderedTools } });
|
||||
return MongoTeamGate.findOne({ teamId }).lean();
|
||||
};
|
||||
|
||||
/**
|
||||
* 批量更新门户配置
|
||||
*/
|
||||
export const batchUpdateGateConfigs = async (
|
||||
configs: {
|
||||
teamId: string;
|
||||
status?: boolean;
|
||||
banner?: string;
|
||||
logo?: string;
|
||||
tools?: string[];
|
||||
placeholderText?: string;
|
||||
}[]
|
||||
) => {
|
||||
const operations = configs.map((config) => {
|
||||
const { teamId, ...updateData } = config;
|
||||
return {
|
||||
updateOne: {
|
||||
filter: { teamId },
|
||||
update: { $set: updateData },
|
||||
upsert: true
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
if (operations.length === 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
await MongoTeamGate.bulkWrite(operations);
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* 批量更新特色应用
|
||||
*/
|
||||
export const batchUpdateFeaturedApps = async (
|
||||
updates: {
|
||||
teamId: string;
|
||||
featuredApps: string[];
|
||||
}[]
|
||||
) => {
|
||||
const operations = updates.map((update) => {
|
||||
const { teamId, featuredApps } = update;
|
||||
// 将字符串数组转换为 ObjectId 数组
|
||||
const objectIdArray = featuredApps.map((id) => new Types.ObjectId(id));
|
||||
return {
|
||||
updateOne: {
|
||||
filter: { teamId },
|
||||
update: { $set: { featuredApps: objectIdArray } },
|
||||
upsert: true
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
if (operations.length === 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const teamId = updates[0]?.teamId;
|
||||
|
||||
const gateConfig = await MongoTeamGate.findOne({ teamId });
|
||||
if (!gateConfig) return Promise.reject('无 gate 配置');
|
||||
|
||||
const updatedAppId = updates[0].featuredApps;
|
||||
const deleteAppId = gateConfig.featuredApps.filter((id) => !updatedAppId.includes(id));
|
||||
|
||||
await mongoSessionRun(async (session) => {
|
||||
await MongoTeamGate.bulkWrite(operations, { session });
|
||||
|
||||
for (const id of deleteAppId) {
|
||||
await removeGatePermission({
|
||||
teamId,
|
||||
appId: id,
|
||||
per: GateFeaturedAppPermission,
|
||||
session
|
||||
});
|
||||
}
|
||||
for (const id of updatedAppId) {
|
||||
await addGatePermission({
|
||||
teamId,
|
||||
appId: id,
|
||||
per: GateFeaturedAppPermission,
|
||||
session
|
||||
});
|
||||
}
|
||||
});
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* 批量更新工具排序
|
||||
*/
|
||||
export const batchUpdateToolsOrder = async (
|
||||
updates: {
|
||||
teamId: string;
|
||||
tools: string[];
|
||||
}[]
|
||||
) => {
|
||||
const operations = updates.map((update) => {
|
||||
const { teamId, tools } = update;
|
||||
return {
|
||||
updateOne: {
|
||||
filter: { teamId },
|
||||
update: { $set: { tools } },
|
||||
upsert: true
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
if (operations.length === 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
await MongoTeamGate.bulkWrite(operations);
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* 批量删除特色应用
|
||||
* @param teamId 团队ID
|
||||
* @param appIds 要删除的应用ID数组
|
||||
*/
|
||||
export const batchDeleteFeaturedApps = async ({
|
||||
teamId,
|
||||
appIds,
|
||||
session
|
||||
}: {
|
||||
teamId: string;
|
||||
appIds: string[];
|
||||
session?: ClientSession;
|
||||
}) => {
|
||||
if (!appIds || appIds.length === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
await MongoTeamGate.updateOne(
|
||||
{ teamId },
|
||||
{ $pull: { featuredApps: { $in: appIds.map((id) => new Types.ObjectId(id)) } } },
|
||||
{
|
||||
session
|
||||
}
|
||||
);
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* 更新快速应用列表
|
||||
*/
|
||||
export const updateQuickApps = async ({
|
||||
teamId,
|
||||
quickApps
|
||||
}: {
|
||||
teamId: string;
|
||||
quickApps: string[];
|
||||
}) => {
|
||||
await MongoTeamGate.updateOne({ teamId }, { $set: { quickApps } }, { upsert: true });
|
||||
return MongoTeamGate.findOne({ teamId }).lean();
|
||||
};
|
||||
|
||||
/**
|
||||
* 添加快速应用
|
||||
*/
|
||||
export const addQuickApp = async ({ teamId, appId }: { teamId: string; appId: string }) => {
|
||||
await MongoTeamGate.updateOne(
|
||||
{ teamId },
|
||||
{ $addToSet: { quickApps: new Types.ObjectId(appId) } },
|
||||
{ upsert: true }
|
||||
);
|
||||
return MongoTeamGate.findOne({ teamId }).lean();
|
||||
};
|
||||
|
||||
/**
|
||||
* 删除快速应用
|
||||
*/
|
||||
export const removeQuickApp = async ({ teamId, appId }: { teamId: string; appId: string }) => {
|
||||
await MongoTeamGate.updateOne({ teamId }, { $pull: { quickApps: new Types.ObjectId(appId) } });
|
||||
return MongoTeamGate.findOne({ teamId }).lean();
|
||||
};
|
||||
|
||||
/**
|
||||
* 移动快速应用位置(原子操作)
|
||||
* @param teamId 团队ID
|
||||
* @param appId 要移动的应用ID
|
||||
* @param toIndex 目标位置索引
|
||||
*/
|
||||
export const moveQuickAppToPosition = async ({
|
||||
teamId,
|
||||
appId,
|
||||
toIndex
|
||||
}: {
|
||||
teamId: string;
|
||||
appId: string;
|
||||
toIndex: number;
|
||||
}) => {
|
||||
const objectId = new Types.ObjectId(appId);
|
||||
|
||||
// 获取当前配置
|
||||
const config = await MongoTeamGate.findOne({ teamId }).lean();
|
||||
if (!config || !config.quickApps) {
|
||||
throw new Error('团队配置不存在');
|
||||
}
|
||||
|
||||
const apps = [...config.quickApps];
|
||||
const currentIndex = apps.findIndex((id) => id.toString() === appId);
|
||||
|
||||
if (currentIndex === -1) {
|
||||
throw new Error('应用不在快速应用列表中');
|
||||
}
|
||||
|
||||
// 移动数组元素
|
||||
const [movedApp] = apps.splice(currentIndex, 1);
|
||||
apps.splice(toIndex, 0, movedApp);
|
||||
|
||||
// 一次性更新
|
||||
await MongoTeamGate.updateOne({ teamId }, { $set: { quickApps: apps } });
|
||||
|
||||
return MongoTeamGate.findOne({ teamId }).lean();
|
||||
};
|
||||
|
||||
/**
|
||||
* 批量更新快速应用
|
||||
*/
|
||||
export const batchUpdateQuickApps = async (teamId: string, quickApps: string[]) => {
|
||||
const gateConfig = await MongoTeamGate.findOne({ teamId });
|
||||
if (!gateConfig) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 计算删除的appId
|
||||
const deleteAppIds = gateConfig.quickApps.filter((id) => !quickApps.includes(id.toString()));
|
||||
|
||||
return mongoSessionRun(async (session) => {
|
||||
// 1. 删除权限
|
||||
for (const id of deleteAppIds) {
|
||||
await removeGatePermission({
|
||||
teamId,
|
||||
appId: id,
|
||||
per: GateQuickAppPermission,
|
||||
session
|
||||
});
|
||||
}
|
||||
// 加权限
|
||||
for (const id of quickApps) {
|
||||
await addGatePermission({
|
||||
teamId,
|
||||
appId: id,
|
||||
per: GateQuickAppPermission,
|
||||
session
|
||||
});
|
||||
}
|
||||
|
||||
gateConfig.quickApps = quickApps;
|
||||
await gateConfig.save({ session });
|
||||
return true;
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 批量删除快速应用
|
||||
* @param teamId 团队ID
|
||||
* @param appIds 要删除的应用ID数组
|
||||
*/
|
||||
export const batchDeleteQuickApps = async ({
|
||||
teamId,
|
||||
appIds
|
||||
}: {
|
||||
teamId: string;
|
||||
appIds: string[];
|
||||
}) => {
|
||||
if (!appIds || appIds.length === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
await MongoTeamGate.updateOne(
|
||||
{ teamId },
|
||||
{ $pull: { quickApps: { $in: appIds.map((id) => new Types.ObjectId(id)) } } }
|
||||
);
|
||||
return true;
|
||||
};
|
||||
45
packages/service/support/user/team/gate/schema.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
import { TeamCollectionName } from '@fastgpt/global/support/user/team/constant';
|
||||
import { Schema, getMongoModel } from '../../../../common/mongo';
|
||||
import type { GateSchemaType } from '@fastgpt/global/support/user/team/gate/type';
|
||||
|
||||
export const gateCollectionName = 'team_gate_config';
|
||||
|
||||
const GateConfigSchema = new Schema({
|
||||
teamId: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: TeamCollectionName
|
||||
},
|
||||
status: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
name: {
|
||||
type: String
|
||||
},
|
||||
banner: {
|
||||
type: String
|
||||
},
|
||||
logo: {
|
||||
type: String
|
||||
},
|
||||
tools: {
|
||||
type: [String]
|
||||
},
|
||||
placeholderText: {
|
||||
type: String
|
||||
},
|
||||
featuredApps: [
|
||||
{
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: 'apps'
|
||||
}
|
||||
],
|
||||
quickApps: [
|
||||
{
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: 'apps'
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
export const MongoTeamGate = getMongoModel<GateSchemaType>(gateCollectionName, GateConfigSchema);
|
||||
@@ -17,6 +17,11 @@ const TeamSchema = new Schema({
|
||||
type: String,
|
||||
default: '/icon/logo.svg'
|
||||
},
|
||||
// todo :banner
|
||||
banner: {
|
||||
type: String,
|
||||
default: '/icon/banner.svg'
|
||||
},
|
||||
createTime: {
|
||||
type: Date,
|
||||
default: () => Date.now()
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import iconv from 'iconv-lite';
|
||||
import { type ReadRawTextByBuffer, type ReadFileResponse } from '../type';
|
||||
import { matchMdImg } from '@fastgpt/global/common/string/markdown';
|
||||
|
||||
const rawEncodingList = [
|
||||
'ascii',
|
||||
@@ -34,7 +35,10 @@ export const readFileRawText = ({ buffer, encoding }: ReadRawTextByBuffer): Read
|
||||
}
|
||||
})();
|
||||
|
||||
const { text, imageList } = matchMdImg(content);
|
||||
|
||||
return {
|
||||
rawText: content
|
||||
rawText: text,
|
||||
imageList
|
||||
};
|
||||
};
|
||||
|
||||
@@ -287,6 +287,7 @@ export const iconPaths = {
|
||||
'core/workflow/template/aiChat': () => import('./icons/core/workflow/template/aiChat.svg'),
|
||||
'core/workflow/template/baseChart': () => import('./icons/core/workflow/template/baseChart.svg'),
|
||||
'core/workflow/template/bing': () => import('./icons/core/workflow/template/bing.svg'),
|
||||
'core/workflow/template/bocha': () => import('./icons/core/workflow/template/bocha.svg'),
|
||||
'core/workflow/template/codeRun': () => import('./icons/core/workflow/template/codeRun.svg'),
|
||||
'core/workflow/template/customFeedback': () =>
|
||||
import('./icons/core/workflow/template/customFeedback.svg'),
|
||||
@@ -473,6 +474,31 @@ export const iconPaths = {
|
||||
'support/user/userLightSmall': () => import('./icons/support/user/userLightSmall.svg'),
|
||||
'support/user/usersFill': () => import('./icons/support/user/usersFill.svg'),
|
||||
'support/user/usersLight': () => import('./icons/support/user/usersLight.svg'),
|
||||
'support/gate/gateLight': () => import('./icons/support/gate/gateLight.svg'),
|
||||
'support/gate/chat/sidebar/chatGray': () =>
|
||||
import('./icons/support/gate/chat/sidebar/chatGray.svg'),
|
||||
'support/gate/chat/historySlider/new_chat': () =>
|
||||
import('./icons/support/gate/chat/historySlider/new_chat.svg'),
|
||||
'support/gate/chat/historySlider/clear-all': () =>
|
||||
import('./icons/support/gate/chat/historySlider/clear-all.svg'),
|
||||
'support/gate/chat/historySlider/chevron-right2': () =>
|
||||
import('./icons/support/gate/chat/historySlider/chevron-right2.svg'),
|
||||
'support/gate/chat/toolkitLine': () => import('./icons/support/gate/chat/toolkitLine.svg'),
|
||||
'support/gate/chat/historySlider/chevron-left2': () =>
|
||||
import('./icons/support/gate/chat/historySlider/chevron-left2.svg'),
|
||||
'support/gate/chat/sidebar/appGray': () =>
|
||||
import('./icons/support/gate/chat/sidebar/appGray.svg'),
|
||||
'support/gate/chat/voiceGray': () => import('./icons/support/gate/chat/voiceGray.svg'),
|
||||
'support/gate/chat/fileGray': () => import('./icons/support/gate/chat/fileGray.svg'),
|
||||
'support/gate/chat/paperclip': () => import('./icons/support/gate/chat/paperclip.svg'),
|
||||
'support/gate/chat/imageGray': () => import('./icons/support/gate/chat/imageGray.svg'),
|
||||
'support/gate/chat/sidebar/CollapseButton': () =>
|
||||
import('./icons/support/gate/chat/sidebar/CollapseButton.svg'),
|
||||
'support/gate/home/savePrimary': () => import('./icons/support/gate/home/savePrimary.svg'),
|
||||
'support/gate/home/shareLight': () => import('./icons/support/gate/home/shareLight.svg'),
|
||||
'support/gate/home/sharePrimary': () => import('./icons/support/gate/home/sharePrimary.svg'),
|
||||
'support/gate/home/upload': () => import('./icons/support/gate/home/upload.svg'),
|
||||
'support/gate/home/add': () => import('./icons/support/gate/home/add.svg'),
|
||||
text: () => import('./icons/text.svg'),
|
||||
union: () => import('./icons/union.svg'),
|
||||
user: () => import('./icons/user.svg'),
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
<svg width="113" height="97" viewBox="0 0 113 97" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M0 31.7259C1.80046 29.9255 3.82784 28.3872 5.96621 27.1988C8.10469 26.0103 10.3126 25.1947 12.4634 24.7992C14.6143 24.4037 16.6664 24.4361 18.5022 24.8938C20.2678 25.334 21.7994 26.1604 23.0183 27.3272L23.021 27.3245L47.189 51.4924L33.4778 65.2037L0 31.7259Z" fill="#C4DEFE"/>
|
||||
<path d="M9.15662 11.5625C11.3617 10.2893 13.7181 9.32825 16.0912 8.73374C18.4645 8.13923 20.8082 7.92284 22.9882 8.09751C25.1681 8.27217 27.1419 8.83457 28.7966 9.75182C30.3881 10.6341 31.6537 11.8287 32.529 13.2712L32.5316 13.2697L32.6082 13.4025C32.6162 13.4162 32.6251 13.4297 32.633 13.4435L49.886 43.3286L33.0941 53.0234L9.15662 11.5625Z" fill="#A6CBFF"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M31.1377 0C33.6839 4.40811e-05 36.2052 0.345872 38.5576 1.01758C40.9099 1.68929 43.0472 2.67394 44.8477 3.91504C46.6482 5.15627 48.0773 6.63021 49.0518 8.25195C49.9888 9.81168 50.4867 11.4792 50.5234 13.166H50.5273V21.4072C56.6623 17.6586 63.874 15.498 71.5898 15.498C93.9304 15.4984 112.042 33.6087 112.042 55.9492C112.042 78.29 93.9305 96.401 71.5898 96.4014C49.3907 96.4014 31.3704 78.5193 31.1426 56.374H31.1377V0ZM71.9473 35.0439C60.1187 35.0441 50.5295 44.6334 50.5293 56.4619C50.5293 63.5338 53.9569 69.8057 59.2412 73.7061C66.4989 79.0625 76.5515 75.3841 85.3955 77.1592C92.613 78.608 97.2369 82.6827 98.3652 83.7686C97.3562 82.731 93.791 78.7138 92.2715 72.3291C89.8011 61.9479 94.8744 49.6043 87.5771 41.8184C83.6695 37.6493 78.1122 35.0441 71.9473 35.0439Z" fill="#006EFF"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.6 KiB |
@@ -0,0 +1,3 @@
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M10.6665 3.0263C10.5079 3.01307 10.2763 3.01095 9.84294 3.01095H7.16646C6.45348 3.01095 5.96581 3.01152 5.58819 3.04048C5.21887 3.06881 5.02616 3.12054 4.89105 3.18516C4.57275 3.3374 4.32387 3.57549 4.17134 3.85649C4.11194 3.96593 4.05991 4.12789 4.03072 4.4633C4.00053 4.81012 3.9998 5.26058 3.9998 5.93236V14.0677C3.9998 14.7394 4.00053 15.1899 4.03072 15.5367C4.05991 15.8721 4.11194 16.0341 4.17134 16.1435C4.32387 16.4245 4.57275 16.6626 4.89105 16.8149C5.02616 16.8795 5.21887 16.9312 5.58819 16.9595C5.96581 16.9885 6.45348 16.9891 7.16646 16.9891H12.4998C13.2128 16.9891 13.7005 16.9885 14.0781 16.9595C14.4474 16.9312 14.6401 16.8795 14.7752 16.8149C15.0935 16.6626 15.3424 16.4245 15.4949 16.1435C15.5543 16.0341 15.6063 15.8721 15.6355 15.5367C15.6657 15.1899 15.6665 14.7394 15.6665 14.0677V8.42632C15.6665 8.04949 15.6642 7.84193 15.654 7.70438L12.8076 7.70439C12.5963 7.70441 12.3934 7.70443 12.2221 7.69129C12.0356 7.67698 11.8167 7.64346 11.5952 7.53756C11.2863 7.38982 11.0253 7.14923 10.8582 6.84149C10.736 6.61626 10.6972 6.39184 10.681 6.2055C10.6664 6.03826 10.6664 5.84201 10.6665 5.64647C10.6665 5.63747 10.6665 5.62847 10.6665 5.61947V3.0263ZM11.8068 1.61342C11.6211 1.53551 11.4284 1.47397 11.2311 1.42951C10.8511 1.34388 10.4571 1.34404 9.92517 1.34426C9.89812 1.34427 9.87072 1.34428 9.84294 1.34428L7.13385 1.34428C6.4615 1.34427 5.90966 1.34427 5.46075 1.37869C4.99631 1.41431 4.57159 1.49047 4.17193 1.68162C3.54942 1.97936 3.03339 2.45928 2.70655 3.0614C2.49347 3.45396 2.40926 3.87156 2.37033 4.31878C2.33311 4.74646 2.33312 5.26987 2.33313 5.89642V14.1036C2.33312 14.7301 2.33311 15.2536 2.37033 15.6812C2.40926 16.1285 2.49347 16.5461 2.70655 16.9386C3.03339 17.5407 3.54942 18.0207 4.17193 18.3184C4.57159 18.5096 4.99631 18.5857 5.46075 18.6213C5.90965 18.6558 6.46147 18.6557 7.13382 18.6557H12.5324C13.2048 18.6557 13.7566 18.6558 14.2055 18.6213C14.67 18.5857 15.0947 18.5096 15.4943 18.3184C16.1168 18.0207 16.6329 17.5407 16.9597 16.9386C17.1728 16.5461 17.257 16.1285 17.2959 15.6812C17.3332 15.2536 17.3331 14.7301 17.3331 14.1036V8.42632C17.3331 8.39763 17.3331 8.3693 17.3332 8.3413C17.3335 7.85013 17.3337 7.46273 17.2381 7.08878C17.1885 6.89509 17.1202 6.70705 17.0344 6.52696C17.0287 6.51433 17.0227 6.50187 17.0163 6.4896C16.9608 6.37678 16.8983 6.26719 16.8292 6.16139C16.6188 5.83909 16.3328 5.57093 15.9611 5.22237C15.9405 5.20307 15.9197 5.18353 15.8986 5.16372L13.2417 2.66977C13.2216 2.65089 13.2018 2.63225 13.1822 2.61385C12.8076 2.26189 12.5241 1.99554 12.186 1.80108C12.0761 1.73786 11.9628 1.68091 11.8466 1.63043C11.8335 1.62442 11.8202 1.61875 11.8068 1.61342ZM12.3331 4.10281V5.61947C12.3331 5.82534 12.3337 5.94445 12.339 6.02864C12.3423 6.02893 12.3458 6.02922 12.3495 6.0295C12.4492 6.03715 12.5869 6.03772 12.8331 6.03772H14.3944L12.3331 4.10281Z" fill="#707070"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.9 KiB |
@@ -0,0 +1,7 @@
|
||||
<svg width="16" height="20" viewBox="0 0 16 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g id="icon/solid/chevron-right2">
|
||||
<path id="Rectangle 3101"
|
||||
d="M11.0474 14.2501C11.0474 15.735 9.25219 16.4786 8.20225 15.4286L3.95213 11.1785C3.30126 10.5276 3.30126 9.47236 3.95213 8.82149L8.20225 4.57138C9.25219 3.52143 11.0474 4.26505 11.0474 5.74989L11.0474 14.2501Z"
|
||||
fill="currentColor" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 444 B |
@@ -0,0 +1,7 @@
|
||||
<svg width="16" height="20" viewBox="0 0 16 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g id="icon/solid/chevron-right2">
|
||||
<path id="Rectangle 3101"
|
||||
d="M4.95255 5.74989C4.95255 4.26505 6.74778 3.52143 7.79772 4.57138L12.0478 8.82149C12.6987 9.47236 12.6987 10.5276 12.0478 11.1785L7.79772 15.4286C6.74778 16.4786 4.95255 15.735 4.95255 14.2501V5.74989Z"
|
||||
fill="currentColor" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 436 B |
@@ -0,0 +1,7 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g id="icon/line/clear-all">
|
||||
<path id="Union" fill-rule="evenodd" clip-rule="evenodd"
|
||||
d="M7.33331 2.63809C7.33331 2.49081 7.4527 2.37142 7.59997 2.37142H8.39997C8.54725 2.37142 8.66664 2.49081 8.66664 2.63809V4.2C8.66664 4.9732 9.29344 5.6 10.0666 5.6L12.861 5.6C13.0083 5.6 13.1277 5.71939 13.1277 5.86666V6.66666C13.1277 6.81394 13.0083 6.93333 12.861 6.93333L3.13891 6.93333C2.99164 6.93333 2.87224 6.81394 2.87224 6.66666V5.86666C2.87224 5.71939 2.99164 5.6 3.13891 5.6L5.93331 5.6C6.70651 5.6 7.33331 4.97319 7.33331 4.2V2.63809ZM7.59997 1.03809C6.71632 1.03809 5.99997 1.75443 5.99997 2.63809V4.2C5.99997 4.23681 5.97012 4.26666 5.93331 4.26666L3.13891 4.26666C2.25526 4.26666 1.53891 4.98301 1.53891 5.86666V6.66666C1.53891 7.41125 2.04753 8.03705 2.73629 8.21558L1.47841 12.628C1.18709 13.6499 1.9545 14.6667 3.01711 14.6667H13.0318C14.0831 14.6667 14.8487 13.6701 14.5778 12.6543L13.384 8.17923C14.0109 7.96253 14.461 7.36717 14.461 6.66666V5.86666C14.461 4.98301 13.7447 4.26666 12.861 4.26666L10.0666 4.26666C10.0298 4.26666 9.99997 4.23681 9.99997 4.2V2.63809C9.99997 1.75443 9.28363 1.03809 8.39997 1.03809H7.59997ZM4.30936 8.26696H11.8226C11.9434 8.26696 12.0491 8.34817 12.0803 8.46489L13.2895 12.9979C13.3347 13.1672 13.207 13.3333 13.0318 13.3333H10.6269C10.627 13.3291 10.6271 13.3249 10.6271 13.3206L10.6409 11.4144C10.6436 11.0462 10.3472 10.7456 9.97907 10.7429C9.61089 10.7403 9.31026 11.0366 9.30759 11.4047L9.2938 13.311C9.29374 13.3184 9.29381 13.3259 9.294 13.3333H6.87303L6.87324 13.3206L6.88704 11.4144C6.88971 11.0462 6.5934 10.7456 6.22522 10.7429C5.85704 10.7403 5.55641 11.0366 5.55374 11.4047L5.53995 13.311C5.53989 13.3184 5.53996 13.3259 5.54015 13.3333H3.01711C2.84 13.3333 2.71211 13.1639 2.76066 12.9936L4.05291 8.46052C4.08557 8.34596 4.19024 8.26696 4.30936 8.26696Z"
|
||||
fill="currentColor" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.9 KiB |
@@ -0,0 +1,8 @@
|
||||
<svg width="19" height="18" viewBox="0 0 19 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M11.3834 2.86546C11.3834 3.27967 11.0476 3.61546 10.6334 3.61546H6.05212C4.39495 3.61546 3.05139 4.95892 3.05139 6.61546V10.3215C3.05158 11.5943 3.84602 12.6857 4.9696 13.1201L5.19885 13.1977L5.54646 13.3005C5.76638 13.3656 5.94445 13.5277 6.02982 13.7406L6.16492 14.0774C6.29685 14.4057 6.68973 14.54 6.99503 14.3611L8.59462 13.4243C8.70956 13.357 8.84034 13.3215 8.97353 13.3215H12.8014C14.4065 13.3215 15.7178 12.0607 15.7985 10.4761L15.8021 10.3215V7.97703C15.8021 7.56281 16.1379 7.22703 16.5521 7.22703C16.9663 7.22703 17.3021 7.56281 17.3021 7.97703V10.3215C17.3019 12.8066 15.2865 14.8215 12.8014 14.8215H9.38096C9.24764 14.8215 9.11674 14.857 9.00172 14.9245L6.57434 16.3471C6.10009 16.625 5.48906 16.4168 5.28381 15.907L4.90857 14.9729C4.82314 14.7602 4.64369 14.6019 4.42992 14.5193C2.74626 13.8685 1.55158 12.2347 1.55139 10.3215V6.61546C1.55139 4.13017 3.56684 2.11546 6.05212 2.11546H10.6334C11.0476 2.11546 11.3834 2.45124 11.3834 2.86546Z"
|
||||
fill="#3370FF" />
|
||||
<path
|
||||
d="M14.9027 1.52901C15.2541 1.52912 15.5392 1.81403 15.5392 2.16549V3.43844H16.8121C17.1636 3.43851 17.4486 3.72344 17.4486 4.07491C17.4485 4.42632 17.1635 4.71132 16.8121 4.71139H15.5392V5.98434C15.5391 6.33571 15.2541 6.62071 14.9027 6.62081C14.5513 6.62081 14.2663 6.33577 14.2662 5.98434V4.71139H12.9933C12.6418 4.71139 12.3569 4.42637 12.3568 4.07491C12.3568 3.7234 12.6418 3.43844 12.9933 3.43844H14.2662V2.16549C14.2662 1.81397 14.5512 1.52901 14.9027 1.52901Z"
|
||||
fill="#3370FF" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.6 KiB |
@@ -0,0 +1,4 @@
|
||||
<svg width="18" height="16" viewBox="0 0 18 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M5.61372 6.52442C6.30407 6.52442 6.86372 5.96478 6.86372 5.27442C6.86372 4.58407 6.30407 4.02442 5.61372 4.02442C4.92336 4.02442 4.36371 4.58407 4.36371 5.27442C4.36371 5.96478 4.92336 6.52442 5.61372 6.52442Z" fill="#707070"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M0.666656 5.31489C0.666656 3.63474 0.666656 2.79466 0.993637 2.15292C1.28126 1.58843 1.7402 1.12949 2.30468 0.841873C2.94642 0.514893 3.7865 0.514893 5.46666 0.514893H12.5333C14.2135 0.514893 15.0536 0.514893 15.6953 0.841873C16.2598 1.12949 16.7187 1.58843 17.0063 2.15292C17.3333 2.79466 17.3333 3.63473 17.3333 5.31489V10.6852C17.3333 12.3654 17.3333 13.2054 17.0063 13.8472C16.7187 14.4117 16.2598 14.8706 15.6953 15.1582C15.0536 15.4852 14.2135 15.4852 12.5333 15.4852H5.46666C3.7865 15.4852 2.94642 15.4852 2.30468 15.1582C1.7402 14.8706 1.28126 14.4117 0.993637 13.8472C0.666656 13.2054 0.666656 12.3654 0.666656 10.6852V5.31489ZM5.46666 2.18156H12.5333C13.4009 2.18156 13.9514 2.18286 14.368 2.2169C14.7652 2.24935 14.8919 2.30306 14.9386 2.32688C15.1895 2.45472 15.3935 2.65869 15.5213 2.90957C15.5452 2.95633 15.5989 3.08303 15.6313 3.48022C15.6654 3.89686 15.6667 4.44731 15.6667 5.31489V10.6852C15.6667 10.6952 15.6667 10.7052 15.6667 10.7152L11.6244 6.67291C11.2989 6.34747 10.7713 6.34747 10.4459 6.67291L3.36552 13.7533C3.17216 13.7239 3.09546 13.6906 3.06134 13.6732C2.81045 13.5454 2.60648 13.3414 2.47865 13.0905C2.45483 13.0438 2.40111 12.9171 2.36866 12.5199C2.33462 12.1032 2.33332 11.5528 2.33332 10.6852V5.31489C2.33332 4.44731 2.33462 3.89686 2.36866 3.48022C2.40111 3.08303 2.45483 2.95633 2.47865 2.90957C2.60648 2.65869 2.81045 2.45472 3.06134 2.32688C3.10809 2.30306 3.23479 2.24935 3.63198 2.2169C4.04863 2.18286 4.59908 2.18156 5.46666 2.18156ZM11.0351 8.44068L5.65725 13.8185H12.5333C13.4009 13.8185 13.9514 13.8172 14.368 13.7832C14.7652 13.7508 14.8919 13.697 14.9386 13.6732C15.1895 13.5454 15.3935 13.3414 15.5213 13.0905C15.5316 13.0704 15.5474 13.0354 15.5647 12.9703L11.0351 8.44068Z" fill="#707070"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.1 KiB |
@@ -0,0 +1,7 @@
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g id="icon/line/paperclip">
|
||||
<path id="Icon (Stroke)" fill-rule="evenodd" clip-rule="evenodd"
|
||||
d="M13.001 3.12035C12.4123 3.12035 11.8477 3.3542 11.4315 3.77046L4.63705 10.5649C3.94333 11.2586 3.55361 12.1995 3.55361 13.1805C3.55361 14.1616 3.94333 15.1025 4.63705 15.7962C5.33077 16.4899 6.27165 16.8796 7.25271 16.8796C8.23377 16.8796 9.17465 16.4899 9.86837 15.7962L16.6628 9.00179C16.9515 8.71306 17.4196 8.71306 17.7084 9.00179C17.9971 9.29051 17.9971 9.75863 17.7084 10.0474L10.9139 16.8418C9.94292 17.8128 8.62594 18.3583 7.25271 18.3583C5.87948 18.3583 4.5625 17.8128 3.59148 16.8418C2.62046 15.8708 2.07495 14.5538 2.07495 13.1805C2.07495 11.8073 2.62046 10.4903 3.59148 9.51931L10.3859 2.72489C11.0795 2.03133 12.0201 1.64169 13.001 1.64169C13.9818 1.64169 14.9225 2.03133 15.6161 2.72489C16.3096 3.41846 16.6993 4.35913 16.6993 5.33997C16.6993 6.32082 16.3096 7.26149 15.6161 7.95506L8.81425 14.7495C8.39814 15.1656 7.83378 15.3993 7.24532 15.3993C6.65685 15.3993 6.09249 15.1656 5.67638 14.7495C5.26028 14.3334 5.02651 13.769 5.02651 13.1805C5.02651 12.5921 5.26028 12.0277 5.67638 11.6116L11.9536 5.34181C12.2425 5.05325 12.7106 5.05353 12.9991 5.34242C13.2877 5.63132 13.2874 6.09943 12.9985 6.38799L6.72195 12.6572C6.58334 12.796 6.50517 12.9844 6.50517 13.1805C6.50517 13.3768 6.58315 13.5651 6.72195 13.7039C6.86076 13.8427 7.04902 13.9207 7.24532 13.9207C7.44162 13.9207 7.62988 13.8427 7.76868 13.7039L14.5705 6.90949C14.9866 6.49326 15.2206 5.92852 15.2206 5.33997C15.2206 4.75129 14.9868 4.18672 14.5705 3.77046C14.1542 3.3542 13.5897 3.12035 13.001 3.12035Z"
|
||||
fill="currentColor" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.7 KiB |
@@ -0,0 +1,8 @@
|
||||
<svg width="18" height="16" viewBox="0 0 18 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M9.91227 5.23185C10.2356 4.95244 10.724 4.98763 11.0036 5.31079C11.2829 5.63414 11.2479 6.12338 10.9246 6.40291L9.16113 7.92797L10.8774 9.51977C11.192 9.81221 11.2103 10.305 10.9181 10.62C10.6259 10.9347 10.1339 10.9531 9.81868 10.6615L7.54085 8.54972C7.37406 8.39504 7.29205 8.18359 7.29346 7.97273C7.2559 7.71942 7.34339 7.45278 7.55143 7.27286L9.91227 5.23185Z"
|
||||
fill="currentcolor" />
|
||||
<path fill-rule="evenodd" clip-rule="evenodd"
|
||||
d="M13.0072 0.108149C15.6489 0.242083 17.7498 2.42669 17.75 5.10164V10.8984L17.7435 11.1555C17.614 13.7122 15.5638 15.7622 13.0072 15.8918L12.75 15.8984H5.25L4.99284 15.8918C2.43607 15.7623 0.385993 13.7123 0.25651 11.1555L0.25 10.8984V5.10164C0.250186 2.42663 2.35104 0.24199 4.99284 0.108149L5.25 0.101639H12.75L13.0072 0.108149ZM5.92546 14.2317H12.75C14.5909 14.2316 16.0833 12.7392 16.0833 10.8984V5.10164C16.0831 3.26092 14.5907 1.76842 12.75 1.76831H5.92546V14.2317ZM4.39225 1.8798C3.02015 2.24419 1.99539 3.4618 1.92074 4.92993L1.91667 5.10164V10.8984C1.91667 12.4427 2.96708 13.7408 4.39225 14.1194V1.8798Z"
|
||||
fill="currentcolor" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
@@ -0,0 +1,14 @@
|
||||
<svg width="19" height="18" viewBox="0 0 19 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd"
|
||||
d="M0.10022 1.2C0.10022 0.537258 0.637478 0 1.30022 0H6.90022C7.56296 0 8.10022 0.537258 8.10022 1.2V6.8C8.10022 7.46274 7.56296 8 6.90022 8H1.30022C0.637478 8 0.10022 7.46274 0.10022 6.8V1.2ZM2.10022 6V2H6.10022V6H2.10022Z"
|
||||
fill="#8A95A7" />
|
||||
<path fill-rule="evenodd" clip-rule="evenodd"
|
||||
d="M10.1002 1.2C10.1002 0.537258 10.6375 0 11.3002 0H16.9002C17.563 0 18.1002 0.537258 18.1002 1.2V6.8C18.1002 7.46274 17.563 8 16.9002 8H11.3002C10.6375 8 10.1002 7.46274 10.1002 6.8V1.2ZM12.1002 6V2H16.1002V6H12.1002Z"
|
||||
fill="#8A95A7" />
|
||||
<path fill-rule="evenodd" clip-rule="evenodd"
|
||||
d="M11.3002 10C10.6375 10 10.1002 10.5373 10.1002 11.2V16.8C10.1002 17.4627 10.6375 18 11.3002 18H16.9002C17.563 18 18.1002 17.4627 18.1002 16.8V11.2C18.1002 10.5373 17.563 10 16.9002 10H11.3002ZM12.1002 12V16H16.1002V12H12.1002Z"
|
||||
fill="#8A95A7" />
|
||||
<path fill-rule="evenodd" clip-rule="evenodd"
|
||||
d="M0.10022 11.2C0.10022 10.5373 0.637478 10 1.30022 10H6.90022C7.56296 10 8.10022 10.5373 8.10022 11.2V16.8C8.10022 17.4627 7.56296 18 6.90022 18H1.30022C0.637478 18 0.10022 17.4627 0.10022 16.8V11.2ZM2.10022 16V12H6.10022V16H2.10022Z"
|
||||
fill="#8A95A7" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
@@ -0,0 +1,18 @@
|
||||
<svg width="20" height="21" viewBox="0 0 20 21" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g id="icon/line/chat">
|
||||
<g id="Union">
|
||||
<path
|
||||
d="M6.18697 8.52243C6.77251 8.52244 7.24715 8.99732 7.24735 9.58281C7.24735 10.1685 6.77263 10.6432 6.18697 10.6432C5.60129 10.6432 5.12659 10.1685 5.12659 9.58281C5.12679 8.99731 5.60142 8.52243 6.18697 8.52243Z"
|
||||
fill="currentColor" />
|
||||
<path
|
||||
d="M10.0004 8.52243C10.586 8.52244 11.0606 8.99732 11.0608 9.58281C11.0608 10.1685 10.5861 10.6432 10.0004 10.6432C9.41477 10.6432 8.94006 10.1685 8.94006 9.58281C8.94027 8.99731 9.4149 8.52243 10.0004 8.52243Z"
|
||||
fill="currentColor" />
|
||||
<path
|
||||
d="M13.8139 8.52243C14.3994 8.52249 14.8741 8.99735 14.8743 9.58281C14.8743 10.1684 14.3995 10.6431 13.8139 10.6432C13.2282 10.6432 12.7535 10.1685 12.7535 9.58281C12.7537 8.99731 13.2284 8.52243 13.8139 8.52243Z"
|
||||
fill="currentColor" />
|
||||
<path fill-rule="evenodd" clip-rule="evenodd"
|
||||
d="M13.7504 2.5247C16.5117 2.52492 18.7504 4.76342 18.7504 7.5247V11.6425C18.7502 14.4037 16.5109 16.6425 13.7496 16.6425H9.94918C9.80105 16.6425 9.65542 16.6824 9.52763 16.7573L6.83069 18.3377C6.30374 18.6465 5.62482 18.4151 5.39677 17.8486L4.9801 16.811C4.88518 16.5747 4.6854 16.3983 4.44788 16.3064C2.57725 15.5833 1.24985 13.7682 1.24963 11.6425V7.5247C1.24963 4.76328 3.48902 2.5247 6.25045 2.5247H13.7504ZM6.25045 4.19137C4.40914 4.19137 2.9163 5.68411 2.9163 7.5247V11.6425C2.91651 13.0567 3.79923 14.2694 5.04765 14.7521L5.30237 14.8383L5.68892 14.9523C5.93318 15.0246 6.1312 15.2049 6.22603 15.4414L6.37577 15.8157C6.52236 16.1805 6.9586 16.3293 7.29781 16.1307L9.07515 15.0898C9.20286 15.015 9.34872 14.9759 9.4967 14.9759H13.7496C15.5331 14.9759 16.9901 13.5749 17.0797 11.8143L17.0838 11.6425V7.5247C17.0838 5.74165 15.6833 4.28501 13.9222 4.19544L13.7504 4.19137H6.25045Z"
|
||||
fill="currentColor" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.0 KiB |
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 18 18" fill="none">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd"
|
||||
d="M12.81 4.4538H12.8072C14.1971 4.45385 14.8993 4.45754 15.4374 4.73173C15.9173 4.97621 16.3074 5.36631 16.5518 5.84612C16.8298 6.3916 16.8298 7.10566 16.8298 8.5338V12.42C16.8298 13.8481 16.8298 14.5622 16.5518 15.1077C16.3074 15.5875 15.9173 15.9776 15.4374 16.2221C14.892 16.5 14.1779 16.5 12.7498 16.5H5.24992C3.82179 16.5 3.10772 16.5 2.56225 16.2221C2.08243 15.9776 1.69233 15.5875 1.44786 15.1077C1.16992 14.5622 1.16992 13.8481 1.16992 12.42V8.5338C1.16992 7.10566 1.16992 6.3916 1.44786 5.84612C1.69233 5.36631 2.08243 4.97621 2.56225 4.73173C3.10772 4.4538 3.82179 4.4538 5.24992 4.4538H5.36574V4.19994C5.36574 2.70877 6.57457 1.49994 8.06574 1.49994H10.11C11.6012 1.49994 12.81 2.70877 12.81 4.19994V4.4538ZM8.06574 2.99994H10.11C10.7727 2.99994 11.31 3.5372 11.31 4.19994V4.4538H6.86574V4.19994C6.86574 3.5372 7.403 2.99994 8.06574 2.99994ZM12.7498 5.9538H5.24992C4.5111 5.9538 4.0472 5.95496 3.69724 5.98356C3.36478 6.01072 3.26927 6.05497 3.24323 6.06824C3.04566 6.16891 2.88503 6.32954 2.78437 6.52711C2.7711 6.55314 2.72684 6.64865 2.69968 6.98111C2.68387 7.17461 2.67645 7.40293 2.67297 7.6933H15.3267C15.3232 7.40293 15.3158 7.17461 15.3 6.98111C15.2728 6.64865 15.2286 6.55314 15.2153 6.52711C15.1147 6.32954 14.954 6.16891 14.7565 6.06824C14.7304 6.05497 14.6349 6.01072 14.3025 5.98356C13.9525 5.95496 13.4886 5.9538 12.7498 5.9538ZM15.3298 9.0433H10.9765V11.392C10.9765 11.6405 10.775 11.842 10.5265 11.842H7.47313C7.2246 11.842 7.02313 11.6405 7.02313 11.392V9.0433H2.66992V12.42C2.66992 13.1588 2.67109 13.6227 2.69968 13.9727C2.72684 14.3052 2.7711 14.4007 2.78437 14.4267C2.88503 14.6243 3.04566 14.7849 3.24323 14.8856C3.26927 14.8988 3.36478 14.9431 3.69723 14.9702C4.0472 14.9988 4.5111 15 5.24992 15H12.7498C13.4886 15 13.9525 14.9988 14.3025 14.9702C14.6349 14.9431 14.7304 14.8988 14.7565 14.8856C14.954 14.7849 15.1147 14.6243 15.2153 14.4267C15.2286 14.4007 15.2728 14.3052 15.3 13.9727C15.3286 13.6227 15.3298 13.1588 15.3298 12.42V9.0433ZM9.62651 9.0433H8.37313V10.492H9.62651V9.0433Z"
|
||||
fill="currentColor" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.2 KiB |
@@ -0,0 +1,5 @@
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd"
|
||||
d="M7.91635 2.02287C8.46897 1.47025 9.21848 1.15979 10 1.15979C10.7815 1.15979 11.531 1.47025 12.0837 2.02287C12.6363 2.57549 12.9467 3.325 12.9467 4.10652V9.99999C12.9467 10.7815 12.6363 11.531 12.0837 12.0836C11.531 12.6363 10.7815 12.9467 10 12.9467C9.21848 12.9467 8.46897 12.6363 7.91635 12.0836C7.36373 11.531 7.05327 10.7815 7.05327 9.99999V4.10652C7.05327 3.325 7.36373 2.57549 7.91635 2.02287ZM10 2.63316C9.60924 2.63316 9.23448 2.78839 8.95817 3.06469C8.68186 3.341 8.52663 3.71576 8.52663 4.10652V9.99999C8.52663 10.3907 8.68186 10.7655 8.95817 11.0418C9.23448 11.3181 9.60924 11.4734 10 11.4734C10.3908 11.4734 10.7655 11.3181 11.0418 11.0418C11.3181 10.7655 11.4734 10.3907 11.4734 9.99999V4.10652C11.4734 3.71576 11.3181 3.341 11.0418 3.06469C10.7655 2.78839 10.3908 2.63316 10 2.63316ZM4.84322 7.78994C5.25008 7.78994 5.5799 8.11976 5.5799 8.52662V9.99999C5.5799 11.1723 6.04559 12.2965 6.87452 13.1255C7.70345 13.9544 8.82772 14.4201 10 14.4201C11.1723 14.4201 12.2966 13.9544 13.1255 13.1255C13.9544 12.2965 14.4201 11.1723 14.4201 9.99999V8.52662C14.4201 8.11976 14.7499 7.78994 15.1568 7.78994C15.5636 7.78994 15.8935 8.11976 15.8935 8.52662V9.99999C15.8935 11.563 15.2725 13.0621 14.1673 14.1673C13.2372 15.0974 12.0281 15.6846 10.7367 15.8472V17.3668H12.9467C13.3536 17.3668 13.6834 17.6966 13.6834 18.1035C13.6834 18.5104 13.3536 18.8402 12.9467 18.8402H7.05327C6.64641 18.8402 6.31659 18.5104 6.31659 18.1035C6.31659 17.6966 6.64641 17.3668 7.05327 17.3668H9.26332V15.8472C7.97191 15.6846 6.76285 15.0974 5.83269 14.1673C4.72745 13.0621 4.10654 11.563 4.10654 9.99999V8.52662C4.10654 8.11976 4.43636 7.78994 4.84322 7.78994Z"
|
||||
fill="currentColor" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.8 KiB |
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">
|
||||
<!-- 保持原路径不变 -->
|
||||
<path fill-rule="evenodd" clip-rule="evenodd"
|
||||
d="M9.57021 1.39896C9.85172 1.32274 10.1484 1.32274 10.4299 1.39896C10.757 1.48751 11.0321 1.70357 11.2481 1.87322C11.2689 1.88955 11.2891 1.90544 11.3088 1.92075L16.8123 6.20128C16.8337 6.21793 16.855 6.23443 16.8761 6.25081C17.1809 6.48733 17.4525 6.6981 17.655 6.97191C17.8327 7.21212 17.9651 7.48272 18.0456 7.77043C18.1374 8.09838 18.137 8.4422 18.1366 8.82801C18.1365 8.85472 18.1365 8.88163 18.1365 8.90875V14.8115C18.1365 15.2387 18.1365 15.6085 18.1116 15.9134C18.0853 16.2355 18.0271 16.5578 17.8688 16.8684C17.6333 17.3306 17.2575 17.7064 16.7954 17.9418C16.4847 18.1001 16.1625 18.1584 15.8403 18.1847C15.5354 18.2096 15.1656 18.2096 14.7385 18.2096H5.26167C4.8345 18.2096 4.4647 18.2096 4.15985 18.1847C3.83769 18.1584 3.51541 18.1001 3.20478 17.9418C2.7426 17.7064 2.36685 17.3306 2.13136 16.8684C1.97308 16.5578 1.91484 16.2355 1.88852 15.9134C1.86362 15.6085 1.86363 15.2387 1.86364 14.8115L1.86364 8.90875C1.86364 8.88163 1.86361 8.85472 1.86358 8.82801C1.86315 8.4422 1.86276 8.09838 1.95456 7.77043C2.03509 7.48272 2.16744 7.21211 2.3451 6.97191C2.54761 6.6981 2.81925 6.48733 3.12405 6.25081C3.14515 6.23443 3.16642 6.21793 3.18782 6.20128L8.69136 1.92075C8.71105 1.90544 8.73129 1.88954 8.75208 1.87322C8.96808 1.70357 9.24317 1.48751 9.57021 1.39896ZM8.39904 16.5429H11.6011V11.3715C11.6011 11.1371 11.6005 11.0071 11.5934 10.9141C11.5005 10.9071 11.3705 10.9065 11.1361 10.9065H8.86404C8.62967 10.9065 8.49969 10.9071 8.40672 10.9141C8.39966 11.0071 8.39904 11.1371 8.39904 11.3715V16.5429ZM13.2678 16.5429L13.2678 11.3451C13.2678 11.1407 13.2678 10.9405 13.2539 10.7706C13.2387 10.5838 13.2026 10.3617 13.0885 10.1379C12.9308 9.82839 12.6792 9.57677 12.3697 9.41907C12.1459 9.30502 11.9238 9.26889 11.7369 9.25362C11.5671 9.23975 11.3668 9.23977 11.1624 9.2398H8.83772C8.63333 9.23977 8.43305 9.23975 8.26321 9.25362C8.07637 9.26889 7.85429 9.30502 7.63045 9.41907C7.32096 9.57676 7.06934 9.82839 6.91165 10.1379C6.79759 10.3617 6.76146 10.5838 6.7462 10.7706C6.73232 10.9405 6.73235 11.1407 6.73237 11.3451L6.73237 16.5429H5.29363C4.82543 16.5429 4.52439 16.5422 4.29557 16.5236C4.07648 16.5057 3.99795 16.4754 3.96143 16.4568C3.81286 16.3811 3.69207 16.2603 3.61637 16.1118C3.59776 16.0753 3.56756 15.9967 3.54965 15.7776C3.53096 15.5488 3.53031 15.2478 3.53031 14.7796V8.90875C3.53031 8.39549 3.53755 8.29823 3.55954 8.21968C3.58542 8.12719 3.62797 8.0402 3.68508 7.96299C3.73358 7.89741 3.80592 7.83198 4.21106 7.51687L9.71459 3.23634C9.86132 3.12222 9.94061 3.06115 10.0001 3.02088C10.0595 3.06115 10.1388 3.12222 10.2856 3.23634L15.7891 7.51687C16.1942 7.83198 16.2666 7.89741 16.3151 7.96299C16.3722 8.0402 16.4147 8.12719 16.4406 8.21968C16.4626 8.29823 16.4698 8.39549 16.4698 8.90875V14.7796C16.4698 15.2478 16.4692 15.5488 16.4505 15.7776C16.4326 15.9967 16.4024 16.0753 16.3838 16.1118C16.3081 16.2603 16.1873 16.3811 16.0387 16.4568C16.0022 16.4754 15.9237 16.5057 15.7046 16.5236C15.4758 16.5422 15.1747 16.5429 14.7065 16.5429H13.2678Z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.1 KiB |
@@ -0,0 +1,3 @@
|
||||
<svg width="21" height="20" viewBox="0 0 21 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M10.5 3.33301C10.9603 3.33301 11.3334 3.7061 11.3334 4.16634V9.16634H16.3334C16.7936 9.16634 17.1667 9.53944 17.1667 9.99967C17.1667 10.4599 16.7936 10.833 16.3334 10.833H11.3334V15.833C11.3334 16.2932 10.9603 16.6663 10.5 16.6663C10.0398 16.6663 9.66671 16.2932 9.66671 15.833V10.833H4.66671C4.20647 10.833 3.83337 10.4599 3.83337 9.99967C3.83337 9.53944 4.20647 9.16634 4.66671 9.16634H9.66671V4.16634C9.66671 3.7061 10.0398 3.33301 10.5 3.33301Z" fill="#3370FF"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 619 B |
@@ -0,0 +1,12 @@
|
||||
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_19520_1493)">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd"
|
||||
d="M6.99991 2.05339C4.26775 2.05339 2.0529 4.26824 2.0529 7.0004C2.0529 9.73256 4.26775 11.9474 6.99991 11.9474C9.73207 11.9474 11.9469 9.73256 11.9469 7.0004C11.9469 4.26824 9.73207 2.05339 6.99991 2.05339ZM0.88623 7.0004C0.88623 3.62391 3.62342 0.886719 6.99991 0.886719C10.3764 0.886719 13.1136 3.62391 13.1136 7.0004C13.1136 10.3769 10.3764 13.1141 6.99991 13.1141C3.62342 13.1141 0.88623 10.3769 0.88623 7.0004ZM6.41657 4.78826C6.41657 4.46609 6.67774 4.20493 6.99991 4.20493H7.00544C7.3276 4.20493 7.58877 4.46609 7.58877 4.78826C7.58877 5.11042 7.3276 5.37159 7.00544 5.37159H6.99991C6.67774 5.37159 6.41657 5.11042 6.41657 4.78826ZM6.99991 6.41706C7.32207 6.41706 7.58324 6.67823 7.58324 7.0004V9.21253C7.58324 9.5347 7.32207 9.79587 6.99991 9.79587C6.67774 9.79587 6.41657 9.5347 6.41657 9.21253V7.0004C6.41657 6.67823 6.67774 6.41706 6.99991 6.41706Z"
|
||||
fill="#3370FF" />
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_19520_1493">
|
||||
<rect width="14" height="14" fill="white" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
@@ -0,0 +1,5 @@
|
||||
<svg width="18" height="19" viewBox="0 0 18 19" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd"
|
||||
d="M11.5538 3.5208C11.4875 3.5049 11.4085 3.50008 11.0059 3.50008H6V5.30008C6 5.52247 6.00058 5.64416 6.00773 5.7316C6.00801 5.73508 6.0083 5.73838 6.00859 5.74149C6.0117 5.74178 6.01499 5.74206 6.01848 5.74235C6.10592 5.74949 6.22761 5.75008 6.45 5.75008H11.55C11.7724 5.75008 11.8941 5.74949 11.9815 5.74235C11.985 5.74206 11.9883 5.74178 11.9914 5.74149C11.9917 5.73838 11.992 5.73508 11.9923 5.7316C11.9994 5.64416 12 5.52247 12 5.30008V3.81211C11.8588 3.67386 11.8143 3.63743 11.7706 3.6106C11.7035 3.56947 11.6303 3.53917 11.5538 3.5208ZM13.2802 2.96965L13.2333 2.92269C13.2184 2.90784 13.2037 2.8931 13.1891 2.87848C12.9735 2.66249 12.7835 2.47206 12.5543 2.33164C12.353 2.20827 12.1335 2.11736 11.9039 2.06224C11.6426 1.9995 11.3735 1.99975 11.0684 2.00004C11.0477 2.00006 11.0269 2.00008 11.0059 2.00008L5.81903 2.00008C5.63224 2.00007 5.45554 2.00007 5.28855 2.00105C5.27578 2.0004 5.26293 2.00008 5.25 2.00008C5.23345 2.00008 5.21702 2.00061 5.20074 2.00167C4.86462 2.00446 4.5692 2.01214 4.31113 2.03322C3.88956 2.06767 3.50203 2.14159 3.13803 2.32706C2.57354 2.61468 2.1146 3.07362 1.82698 3.6381C1.64151 4.00211 1.56759 4.38963 1.53315 4.81121C1.49998 5.2171 1.49999 5.71537 1.5 6.3191V12.681C1.49999 13.2848 1.49998 13.783 1.53315 14.1889C1.56759 14.6105 1.64151 14.998 1.82698 15.362C2.1146 15.9265 2.57354 16.3855 3.13803 16.6731C3.50203 16.8586 3.88956 16.9325 4.31113 16.9669C4.5692 16.988 4.86462 16.9957 5.20074 16.9985C5.21702 16.9995 5.23345 17.0001 5.25 17.0001C5.26293 17.0001 5.27578 16.9997 5.28855 16.9991C5.45553 17.0001 5.63222 17.0001 5.81901 17.0001H12.181C12.3678 17.0001 12.5445 17.0001 12.7115 16.9991C12.7242 16.9997 12.7371 17.0001 12.75 17.0001C12.7666 17.0001 12.783 16.9995 12.7993 16.9985C13.1354 16.9957 13.4308 16.988 13.6889 16.9669C14.1104 16.9325 14.498 16.8586 14.862 16.6731C15.4265 16.3855 15.8854 15.9265 16.173 15.362C16.3585 14.998 16.4324 14.6105 16.4669 14.1889C16.5 13.7831 16.5 13.2848 16.5 12.6811V7.49419C16.5 7.47319 16.5 7.45236 16.5 7.4317C16.5003 7.12653 16.5006 6.85748 16.4378 6.59614C16.3827 6.36656 16.2918 6.14709 16.1684 5.94577C16.028 5.71662 15.8376 5.52655 15.6216 5.31096C15.607 5.29637 15.5922 5.28165 15.5774 5.2668L13.2802 2.96965C13.2803 2.96971 13.2802 2.96958 13.2802 2.96965ZM13.5 5.31074V5.32399C13.5 5.51328 13.5 5.69763 13.4873 5.85375C13.4733 6.02519 13.4402 6.22749 13.3365 6.43106C13.1927 6.71331 12.9632 6.94278 12.681 7.08659C12.4774 7.19031 12.2751 7.22336 12.1037 7.23737C11.9476 7.25012 11.7632 7.2501 11.5739 7.25008L6.45 7.25008C6.44202 7.25008 6.43404 7.25008 6.42608 7.25008C6.23679 7.2501 6.05245 7.25012 5.89633 7.23737C5.72488 7.22336 5.52258 7.19031 5.31902 7.08659C5.03677 6.94278 4.8073 6.7133 4.66349 6.43106C4.55977 6.22749 4.52672 6.02519 4.51271 5.85375C4.49995 5.69763 4.49998 5.51329 4.5 5.324C4.5 5.31603 4.5 5.30806 4.5 5.30008V3.52322C4.47733 3.52479 4.4551 3.52646 4.43328 3.52824C4.10447 3.5551 3.93631 3.6038 3.81902 3.66357C3.53677 3.80738 3.3073 4.03685 3.16349 4.31909C3.10372 4.43639 3.05503 4.60454 3.02816 4.93335C3.00058 5.27092 3 5.70764 3 6.35008V12.6501C3 13.2925 3.00058 13.7292 3.02816 14.0668C3.05503 14.3956 3.10372 14.5638 3.16349 14.6811C3.3073 14.9633 3.53677 15.1928 3.81902 15.3366C3.93631 15.3964 4.10447 15.445 4.43328 15.4719C4.4551 15.4737 4.47733 15.4754 4.5 15.4769L4.5 11.4262C4.49998 11.2369 4.49995 11.0525 4.51271 10.8964C4.52672 10.725 4.55977 10.5227 4.66349 10.3191C4.8073 10.0368 5.03677 9.80738 5.31902 9.66357C5.52258 9.55984 5.72488 9.52679 5.89633 9.51278C6.05245 9.50003 6.2368 9.50005 6.42609 9.50007H11.5739C11.7632 9.50005 11.9475 9.50003 12.1037 9.51278C12.2751 9.52679 12.4774 9.55984 12.681 9.66357C12.9632 9.80738 13.1927 10.0368 13.3365 10.3191C13.4402 10.5227 13.4733 10.725 13.4873 10.8964C13.5 11.0525 13.5 11.2369 13.5 11.4262L13.5 15.4769C13.5227 15.4754 13.5449 15.4737 13.5667 15.4719C13.8955 15.445 14.0637 15.3964 14.181 15.3366C14.4632 15.1928 14.6927 14.9633 14.8365 14.6811C14.8963 14.5638 14.945 14.3956 14.9718 14.0668C14.9994 13.7292 15 13.2925 15 12.6501V7.49419C15 7.0916 14.9952 7.01255 14.9793 6.94631C14.9609 6.86979 14.9306 6.79663 14.8895 6.72952C14.8539 6.67144 14.8014 6.61213 14.5167 6.32746L13.5 5.31074ZM12 15.5001V11.4501C12 11.2277 11.9994 11.106 11.9923 11.0186C11.992 11.0151 11.9917 11.0118 11.9914 11.0087C11.9883 11.0084 11.985 11.0081 11.9815 11.0078C11.8941 11.0007 11.7724 11.0001 11.55 11.0001H6.45C6.22761 11.0001 6.10592 11.0007 6.01848 11.0078C6.01499 11.0081 6.0117 11.0084 6.00859 11.0087C6.0083 11.0118 6.00801 11.0151 6.00773 11.0186C6.00058 11.106 6 11.2277 6 11.4501V15.5001H12Z"
|
||||
fill="#3370FF" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.7 KiB |
@@ -0,0 +1,5 @@
|
||||
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd"
|
||||
d="M6.72916 1.85097L6.69716 1.85085C5.98981 1.84827 5.41301 1.84617 4.94539 1.88309C4.46228 1.92122 4.0275 2.00464 3.62407 2.21292C3.01781 2.52591 2.5263 3.01564 2.21111 3.62075C2.00154 4.02311 1.91644 4.45656 1.8765 4.93842C1.83788 5.40451 1.83788 5.97916 1.83789 6.68347V11.3274C1.83788 12.0263 1.83788 12.5969 1.87635 13.0602C1.91616 13.5396 2.001 13.9708 2.20943 14.3721C2.52252 14.9748 3.01395 15.4662 3.61667 15.7793C4.01791 15.9877 4.44916 16.0726 4.92851 16.1124C5.39183 16.1509 5.96247 16.1508 6.66137 16.1508H11.3384C12.0373 16.1508 12.6079 16.1509 13.0712 16.1124C13.5506 16.0726 13.9818 15.9877 14.3831 15.7793C14.9858 15.4662 15.4772 14.9748 15.7903 14.3721C15.9987 13.9708 16.0836 13.5396 16.1234 13.0602C16.1619 12.5969 16.1619 12.0263 16.1619 11.3274V9.50554C16.1619 9.09133 15.8261 8.75554 15.4119 8.75554C14.9976 8.75554 14.6619 9.09133 14.6619 9.50554V11.2954C14.6619 12.0341 14.6613 12.5422 14.6285 12.9361C14.5966 13.321 14.5379 13.5291 14.4592 13.6806C14.2884 14.0094 14.0204 14.2774 13.6916 14.4482C13.5402 14.5269 13.332 14.5856 12.9471 14.6175C12.5532 14.6502 12.045 14.6508 11.3064 14.6508H6.69339C5.9547 14.6508 5.44655 14.6502 5.05265 14.6175C4.66773 14.5856 4.45958 14.5269 4.30814 14.4482C3.97938 14.2774 3.71132 14.0094 3.54055 13.6806C3.46188 13.5292 3.40317 13.321 3.37121 12.9361C3.33849 12.5422 3.33789 12.034 3.33789 11.2953V6.71554C3.33789 5.97142 3.33849 5.45912 3.37138 5.06231C3.40354 4.67419 3.46264 4.46502 3.54147 4.31369C3.7137 3.98302 3.98088 3.71681 4.31217 3.54578C4.46347 3.46767 4.67333 3.40923 5.06343 3.37843C5.46198 3.34697 5.97664 3.34825 6.72372 3.35096C7.34592 3.35322 7.97166 3.35468 8.54751 3.35468C8.96173 3.35468 9.29751 3.0189 9.29751 2.60468C9.29751 2.19047 8.96173 1.85468 8.54751 1.85468C7.97404 1.85468 7.35021 1.85322 6.72916 1.85097ZM8.26254 8.66553C7.96964 8.95843 7.96964 9.4333 8.26254 9.7262C8.55543 10.0191 9.0303 10.0191 9.3232 9.72619L14.6619 4.38754V6.5054C14.6619 6.91962 14.9976 7.2554 15.4119 7.2554C15.8261 7.2554 16.1619 6.91962 16.1619 6.5054V2.6698C16.1622 2.66102 16.1623 2.6522 16.1623 2.64334C16.1623 2.22913 15.8265 1.89334 15.4123 1.89334C15.4122 1.89334 15.4124 1.89334 15.4123 1.89334H11.5503C11.136 1.89334 10.8003 2.22913 10.8003 2.64334C10.8003 3.05756 11.136 3.39334 11.5503 3.39334H13.5347L8.26254 8.66553Z"
|
||||
fill="white" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.4 KiB |
@@ -0,0 +1,5 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd"
|
||||
d="M5.47674 0.0561965L5.44118 0.0560671C4.65524 0.053204 4.01435 0.0508692 3.49477 0.0918841C2.95798 0.134258 2.47489 0.226947 2.02664 0.458364C1.35301 0.806127 0.806891 1.35027 0.456684 2.02263C0.223824 2.46969 0.129267 2.9513 0.0848958 3.48669C0.0419755 4.00458 0.0419831 4.64308 0.0419925 5.42564V10.5855C0.041983 11.3621 0.0419753 11.9961 0.0847264 12.5109C0.128958 13.0435 0.223226 13.5227 0.454811 13.9685C0.802688 14.6382 1.34873 15.1842 2.01842 15.5321C2.46424 15.7637 2.9434 15.858 3.47601 15.9022C3.99081 15.945 4.62486 15.945 5.40142 15.9449H10.5981C11.3746 15.945 12.0087 15.945 12.5235 15.9022C13.0561 15.858 13.5353 15.7637 13.9811 15.5321C14.6508 15.1842 15.1968 14.6382 15.5447 13.9685C15.7763 13.5227 15.8705 13.0435 15.9148 12.5109C15.9575 11.9962 15.9575 11.3621 15.9575 10.5856V8.56128C15.9575 8.10104 15.5844 7.72795 15.1242 7.72795C14.6639 7.72795 14.2908 8.10104 14.2908 8.56128V10.55C14.2908 11.3708 14.2902 11.9354 14.2538 12.373C14.2183 12.8007 14.1531 13.032 14.0657 13.2002C13.8759 13.5655 13.5781 13.8634 13.2128 14.0531C13.0445 14.1405 12.8132 14.2057 12.3856 14.2413C11.9479 14.2776 11.3833 14.2783 10.5625 14.2783H5.43699C4.61622 14.2783 4.05161 14.2776 3.61395 14.2413C3.18626 14.2057 2.95498 14.1405 2.78671 14.0531C2.42142 13.8634 2.12358 13.5655 1.93383 13.2002C1.84642 13.032 1.78119 12.8007 1.74568 12.373C1.70933 11.9353 1.70866 11.3707 1.70866 10.5499V5.46128C1.70866 4.63448 1.70933 4.06526 1.74587 3.62435C1.78161 3.19311 1.84727 2.9607 1.93485 2.79256C2.12623 2.42514 2.42309 2.12936 2.79119 1.93932C2.95931 1.85253 3.19248 1.7876 3.62592 1.75338C4.06876 1.71843 4.6406 1.71984 5.47069 1.72285C6.16203 1.72536 6.85729 1.72699 7.49713 1.72699C7.95737 1.72699 8.33046 1.3539 8.33046 0.893659C8.33046 0.433422 7.95737 0.0603261 7.49713 0.0603261C6.85993 0.0603261 6.1668 0.0587019 5.47674 0.0561965ZM7.18049 7.62794C6.85505 7.95338 6.85505 8.48101 7.18049 8.80645C7.50592 9.13189 8.03356 9.13189 8.359 8.80645L14.2908 2.87461V5.22779C14.2908 5.68803 14.6639 6.06113 15.1242 6.06113C15.5844 6.06113 15.9575 5.68803 15.9575 5.22779V0.966006C15.9578 0.95625 15.958 0.946452 15.958 0.936614C15.958 0.476377 15.5849 0.103281 15.1247 0.103281C15.1246 0.103281 15.1248 0.103281 15.1247 0.103281H10.8335C10.3733 0.103281 10.0002 0.476377 10.0002 0.936614C10.0002 1.39685 10.3733 1.76995 10.8335 1.76995H13.0385L7.18049 7.62794Z"
|
||||
fill="#3370FF" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.5 KiB |
@@ -0,0 +1,7 @@
|
||||
<svg width="24" height="25" viewBox="0 0 24 25" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g id="icon/line/export">
|
||||
<path id="Icon (Stroke)" fill-rule="evenodd" clip-rule="evenodd"
|
||||
d="M11.2928 2.58684C11.6834 2.19631 12.3165 2.19631 12.707 2.58684L16.707 6.58684C17.0976 6.97736 17.0976 7.61053 16.707 8.00105C16.3165 8.39158 15.6834 8.39158 15.2928 8.00105L12.9999 5.70816V15.2939C12.9999 15.8462 12.5522 16.2939 11.9999 16.2939C11.4477 16.2939 10.9999 15.8462 10.9999 15.2939V5.70816L8.70705 8.00105C8.31652 8.39158 7.68336 8.39158 7.29283 8.00105C6.90231 7.61053 6.90231 6.97736 7.29283 6.58684L11.2928 2.58684ZM2.99994 11.2939C3.55222 11.2939 3.99994 11.7417 3.99994 12.2939V16.4939C3.99994 17.3505 4.00072 17.9328 4.03749 18.3829C4.07331 18.8213 4.13824 19.0455 4.21793 19.2019C4.40967 19.5783 4.71564 19.8842 5.09196 20.076C5.24836 20.1556 5.47256 20.2206 5.91098 20.2564C6.36107 20.2932 6.94336 20.2939 7.79994 20.2939H16.1999C17.0565 20.2939 17.6388 20.2932 18.0889 20.2564C18.5273 20.2206 18.7515 20.1556 18.9079 20.076C19.2842 19.8842 19.5902 19.5783 19.782 19.2019C19.8616 19.0455 19.9266 18.8213 19.9624 18.3829C19.9992 17.9328 19.9999 17.3505 19.9999 16.4939V12.2939C19.9999 11.7417 20.4477 11.2939 20.9999 11.2939C21.5522 11.2939 21.9999 11.7417 21.9999 12.2939V16.5353C22 17.3402 22 18.0046 21.9557 18.5458C21.9098 19.1079 21.8113 19.6246 21.564 20.1099C21.1805 20.8626 20.5686 21.4745 19.8159 21.858C19.3306 22.1053 18.8139 22.2038 18.2518 22.2498C17.7106 22.294 17.0462 22.294 16.2413 22.2939H7.75862C6.95366 22.294 6.2893 22.294 5.74811 22.2498C5.18602 22.2038 4.66931 22.1053 4.18398 21.858C3.43133 21.4745 2.81941 20.8626 2.43591 20.1099C2.18862 19.6246 2.09006 19.1079 2.04413 18.5458C1.99992 18.0046 1.99993 17.3402 1.99994 16.5352L1.99994 12.2939C1.99994 11.7417 2.44766 11.2939 2.99994 11.2939Z"
|
||||
fill="#3370FF" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.9 KiB |