mirror of
https://github.com/labring/FastGPT.git
synced 2025-07-23 21:13:50 +00:00
4.8.10 test (#2470)
* i18n * perf: invoice type * fix: helper line change error * perf: base64 image * perf: app list ui * perf: upload max size check * perf: init system plugin * perf: dataset list ui * perf: http node ui * perf: ui * perf: invoice tip * fix: ts * perf: invoice table * perf: null check
This commit is contained in:
@@ -34,8 +34,10 @@ STORE_LOG_LEVEL=warn
|
|||||||
7. 商业版新增 - SSO 定制
|
7. 商业版新增 - SSO 定制
|
||||||
8. 优化 - 知识库集合禁用,目录禁用会递归修改其下所有 children 的禁用状态。
|
8. 优化 - 知识库集合禁用,目录禁用会递归修改其下所有 children 的禁用状态。
|
||||||
9. 优化 - 节点选择,避免切换 tab 时候,path 加载报错。
|
9. 优化 - 节点选择,避免切换 tab 时候,path 加载报错。
|
||||||
10. 修复 - Prompt 模式调用工具,stream=false 模式下,会携带 0: 开头标记。
|
10. 优化 - 最新 React Markdown 组件,支持 Base64 图片。
|
||||||
11. 修复 - 对话日志鉴权问题:仅为 APP 管理员的用户,无法查看对话日志详情。
|
11. 优化 - 知识库列表 UI。
|
||||||
12. 修复 - 选择 Milvus 部署时,无法导出知识库。
|
12. 修复 - Prompt 模式调用工具,stream=false 模式下,会携带 0: 开头标记。
|
||||||
13. 修复 - 创建 APP 副本,无法复制系统配置。
|
13. 修复 - 对话日志鉴权问题:仅为 APP 管理员的用户,无法查看对话日志详情。
|
||||||
14. 修复 - 图片识别模式下,自动解析图片链接正则不够严谨问题。
|
14. 修复 - 选择 Milvus 部署时,无法导出知识库。
|
||||||
|
15. 修复 - 创建 APP 副本,无法复制系统配置。
|
||||||
|
16. 修复 - 图片识别模式下,自动解析图片链接正则不够严谨问题。
|
||||||
|
@@ -49,8 +49,8 @@ export const HttpNode468: FlowNodeTemplateType = {
|
|||||||
renderTypeList: [FlowNodeInputTypeEnum.custom],
|
renderTypeList: [FlowNodeInputTypeEnum.custom],
|
||||||
valueType: WorkflowIOValueTypeEnum.number,
|
valueType: WorkflowIOValueTypeEnum.number,
|
||||||
label: '',
|
label: '',
|
||||||
value: 120,
|
value: 30,
|
||||||
min: 30,
|
min: 5,
|
||||||
max: 600,
|
max: 600,
|
||||||
required: true
|
required: true
|
||||||
},
|
},
|
||||||
|
10
packages/global/support/user/team/type.d.ts
vendored
10
packages/global/support/user/team/type.d.ts
vendored
@@ -94,11 +94,11 @@ export type LafAccountType = {
|
|||||||
export type TeamInvoiceHeaderType = {
|
export type TeamInvoiceHeaderType = {
|
||||||
teamName: string;
|
teamName: string;
|
||||||
unifiedCreditCode: string;
|
unifiedCreditCode: string;
|
||||||
companyAddress: string;
|
companyAddress?: string;
|
||||||
companyPhone: string;
|
companyPhone?: string;
|
||||||
bankName: string;
|
bankName?: string;
|
||||||
bankAccount: string;
|
bankAccount?: string;
|
||||||
needSpecialInvoice?: boolean;
|
needSpecialInvoice: boolean;
|
||||||
emailAddress: string;
|
emailAddress: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -36,9 +36,10 @@ export type InvoiceType = {
|
|||||||
} & TeamInvoiceHeaderType;
|
} & TeamInvoiceHeaderType;
|
||||||
|
|
||||||
export type InvoiceSchemaType = {
|
export type InvoiceSchemaType = {
|
||||||
teamId: string;
|
|
||||||
_id: string;
|
_id: string;
|
||||||
|
teamId: string;
|
||||||
status: 1 | 2;
|
status: 1 | 2;
|
||||||
createTime: Date;
|
createTime: Date;
|
||||||
finishTime?: Date;
|
finishTime?: Date;
|
||||||
|
file?: Buffer;
|
||||||
} & InvoiceType;
|
} & InvoiceType;
|
||||||
|
@@ -14,8 +14,12 @@ type FileType = {
|
|||||||
size: number;
|
size: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
maxSize: File max size (MB)
|
||||||
|
*/
|
||||||
export const getUploadModel = ({ maxSize = 500 }: { maxSize?: number }) => {
|
export const getUploadModel = ({ maxSize = 500 }: { maxSize?: number }) => {
|
||||||
maxSize *= 1024 * 1024;
|
maxSize *= 1024 * 1024;
|
||||||
|
|
||||||
class UploadModel {
|
class UploadModel {
|
||||||
uploader = multer({
|
uploader = multer({
|
||||||
limits: {
|
limits: {
|
||||||
|
@@ -31,6 +31,7 @@ type HttpRequestProps = ModuleDispatchProps<{
|
|||||||
[NodeInputKeyEnum.httpParams]: PropsArrType[];
|
[NodeInputKeyEnum.httpParams]: PropsArrType[];
|
||||||
[NodeInputKeyEnum.httpJsonBody]: string;
|
[NodeInputKeyEnum.httpJsonBody]: string;
|
||||||
[NodeInputKeyEnum.addInputParam]: Record<string, any>;
|
[NodeInputKeyEnum.addInputParam]: Record<string, any>;
|
||||||
|
[NodeInputKeyEnum.httpTimeout]?: number;
|
||||||
[key: string]: any;
|
[key: string]: any;
|
||||||
}>;
|
}>;
|
||||||
type HttpResponse = DispatchNodeResultType<{
|
type HttpResponse = DispatchNodeResultType<{
|
||||||
@@ -57,7 +58,7 @@ export const dispatchHttp468Request = async (props: HttpRequestProps): Promise<H
|
|||||||
system_httpHeader: httpHeader,
|
system_httpHeader: httpHeader,
|
||||||
system_httpParams: httpParams = [],
|
system_httpParams: httpParams = [],
|
||||||
system_httpJsonBody: httpJsonBody,
|
system_httpJsonBody: httpJsonBody,
|
||||||
system_httpTimeout: httpTimeout,
|
system_httpTimeout: httpTimeout = 60,
|
||||||
[NodeInputKeyEnum.addInputParam]: dynamicInput,
|
[NodeInputKeyEnum.addInputParam]: dynamicInput,
|
||||||
...body
|
...body
|
||||||
}
|
}
|
||||||
|
@@ -20,6 +20,7 @@
|
|||||||
"external_read_url": "External read url",
|
"external_read_url": "External read url",
|
||||||
"external_read_url_tip": "You can configure the reading address of your file library. This allows users to read and authenticate. You can currently use the {{fileId}} variable to refer to the external file ID.",
|
"external_read_url_tip": "You can configure the reading address of your file library. This allows users to read and authenticate. You can currently use the {{fileId}} variable to refer to the external file ID.",
|
||||||
"external_url": "File read url",
|
"external_url": "File read url",
|
||||||
|
"file_model_function_tip": "For enhanced indexing and QA generation",
|
||||||
"filename": "filename",
|
"filename": "filename",
|
||||||
"folder_dataset": "Folder",
|
"folder_dataset": "Folder",
|
||||||
"rebuild_embedding_start_tip": "The task of switching index models has begun",
|
"rebuild_embedding_start_tip": "The task of switching index models has begun",
|
||||||
|
@@ -1,4 +1,7 @@
|
|||||||
{
|
{
|
||||||
|
"bill": {
|
||||||
|
"not_need_invoice": "Balance payment, unable to issue invoice"
|
||||||
|
},
|
||||||
"bind_inform_account_error": "Abnormal binding notification account",
|
"bind_inform_account_error": "Abnormal binding notification account",
|
||||||
"bind_inform_account_success": "Binding notification account successful",
|
"bind_inform_account_success": "Binding notification account successful",
|
||||||
"code_error": {
|
"code_error": {
|
||||||
|
@@ -617,8 +617,7 @@
|
|||||||
"success": "开始同步"
|
"success": "开始同步"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"training": {
|
"training": {}
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"data": {
|
"data": {
|
||||||
"Auxiliary Data": "辅助数据",
|
"Auxiliary Data": "辅助数据",
|
||||||
|
@@ -20,6 +20,7 @@
|
|||||||
"external_read_url": "外部预览地址",
|
"external_read_url": "外部预览地址",
|
||||||
"external_read_url_tip": "可以配置你文件库的阅读地址。便于对用户进行阅读鉴权操作。目前可以使用 {{fileId}} 变量来指代外部文件 ID。",
|
"external_read_url_tip": "可以配置你文件库的阅读地址。便于对用户进行阅读鉴权操作。目前可以使用 {{fileId}} 变量来指代外部文件 ID。",
|
||||||
"external_url": "文件访问 URL",
|
"external_url": "文件访问 URL",
|
||||||
|
"file_model_function_tip": "用于增强索引和 QA 生成",
|
||||||
"filename": "文件名",
|
"filename": "文件名",
|
||||||
"folder_dataset": "文件夹",
|
"folder_dataset": "文件夹",
|
||||||
"rebuild_embedding_start_tip": "切换索引模型任务已开始",
|
"rebuild_embedding_start_tip": "切换索引模型任务已开始",
|
||||||
|
@@ -1,4 +1,7 @@
|
|||||||
{
|
{
|
||||||
|
"bill": {
|
||||||
|
"not_need_invoice": "余额支付,无法开票"
|
||||||
|
},
|
||||||
"bind_inform_account_error": "绑定通知账号异常",
|
"bind_inform_account_error": "绑定通知账号异常",
|
||||||
"bind_inform_account_success": "绑定通知账号成功",
|
"bind_inform_account_success": "绑定通知账号成功",
|
||||||
"delete": {
|
"delete": {
|
||||||
|
@@ -32,7 +32,7 @@ SANDBOX_URL=http://localhost:3001
|
|||||||
PRO_URL=
|
PRO_URL=
|
||||||
# 首页路径
|
# 首页路径
|
||||||
HOME_URL=/
|
HOME_URL=/
|
||||||
|
|
||||||
# 日志等级: debug, info, warn, error
|
# 日志等级: debug, info, warn, error
|
||||||
LOG_LEVEL=debug
|
LOG_LEVEL=debug
|
||||||
STORE_LOG_LEVEL=warn
|
STORE_LOG_LEVEL=warn
|
||||||
# Loki Log Path
|
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { ImageProps, Skeleton } from '@chakra-ui/react';
|
import { Box, ImageProps, Skeleton } from '@chakra-ui/react';
|
||||||
import MyPhotoView from '@fastgpt/web/components/common/Image/PhotoView';
|
import MyPhotoView from '@fastgpt/web/components/common/Image/PhotoView';
|
||||||
import { useBoolean } from 'ahooks';
|
import { useBoolean } from 'ahooks';
|
||||||
|
|
||||||
@@ -8,6 +8,10 @@ const MdImage = ({ src, ...props }: { src?: string } & ImageProps) => {
|
|||||||
|
|
||||||
const [renderSrc, setRenderSrc] = useState(src);
|
const [renderSrc, setRenderSrc] = useState(src);
|
||||||
|
|
||||||
|
if (src?.includes('base64') && !src.startsWith('data:image')) {
|
||||||
|
return <Box>Invalid base64 image</Box>;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Skeleton isLoaded={isLoaded}>
|
<Skeleton isLoaded={isLoaded}>
|
||||||
<MyPhotoView
|
<MyPhotoView
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import React, { useMemo } from 'react';
|
import React, { useCallback, useMemo } from 'react';
|
||||||
import ReactMarkdown from 'react-markdown';
|
import ReactMarkdown from 'react-markdown';
|
||||||
import 'katex/dist/katex.min.css';
|
import 'katex/dist/katex.min.css';
|
||||||
import RemarkMath from 'remark-math'; // Math syntax
|
import RemarkMath from 'remark-math'; // Math syntax
|
||||||
@@ -52,6 +52,10 @@ const Markdown = ({
|
|||||||
return formatSource;
|
return formatSource;
|
||||||
}, [source]);
|
}, [source]);
|
||||||
|
|
||||||
|
const urlTransform = useCallback((val: string) => {
|
||||||
|
return val;
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ReactMarkdown
|
<ReactMarkdown
|
||||||
className={`markdown ${styles.markdown}
|
className={`markdown ${styles.markdown}
|
||||||
@@ -60,6 +64,7 @@ const Markdown = ({
|
|||||||
remarkPlugins={[RemarkMath, [RemarkGfm, { singleTilde: false }], RemarkBreaks]}
|
remarkPlugins={[RemarkMath, [RemarkGfm, { singleTilde: false }], RemarkBreaks]}
|
||||||
rehypePlugins={[RehypeKatex, [RehypeExternalLinks, { target: '_blank' }]]}
|
rehypePlugins={[RehypeKatex, [RehypeExternalLinks, { target: '_blank' }]]}
|
||||||
components={components}
|
components={components}
|
||||||
|
urlTransform={urlTransform}
|
||||||
>
|
>
|
||||||
{formatSource}
|
{formatSource}
|
||||||
</ReactMarkdown>
|
</ReactMarkdown>
|
||||||
|
@@ -9,6 +9,7 @@ const NextHead = ({ title, icon, desc }: { title?: string; icon?: string; desc?:
|
|||||||
name="viewport"
|
name="viewport"
|
||||||
content="width=device-width,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0,user-scalable=no, viewport-fit=cover"
|
content="width=device-width,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0,user-scalable=no, viewport-fit=cover"
|
||||||
/>
|
/>
|
||||||
|
<meta httpEquiv="Content-Security-Policy" content="img-src * data:;" />
|
||||||
{desc && <meta name="description" content={desc} />}
|
{desc && <meta name="description" content={desc} />}
|
||||||
{icon && <link rel="icon" href={icon} />}
|
{icon && <link rel="icon" href={icon} />}
|
||||||
</Head>
|
</Head>
|
||||||
|
@@ -409,7 +409,7 @@ const PlanUsage = () => {
|
|||||||
|
|
||||||
return standardPlan ? (
|
return standardPlan ? (
|
||||||
<Box mt={[6, 0]}>
|
<Box mt={[6, 0]}>
|
||||||
<Flex fontSize={'lg'} h={'30px'}>
|
<Flex fontSize={['md', 'lg']} h={'30px'}>
|
||||||
<Flex alignItems={'center'}>
|
<Flex alignItems={'center'}>
|
||||||
<MyIcon mr={2} name={'support/account/plans'} w={'20px'} />
|
<MyIcon mr={2} name={'support/account/plans'} w={'20px'} />
|
||||||
{t('common:support.wallet.subscription.Team plan and usage')}
|
{t('common:support.wallet.subscription.Team plan and usage')}
|
||||||
@@ -428,7 +428,7 @@ const PlanUsage = () => {
|
|||||||
borderColor={'borderColor.low'}
|
borderColor={'borderColor.low'}
|
||||||
borderRadius={'md'}
|
borderRadius={'md'}
|
||||||
>
|
>
|
||||||
<Flex px={[5, 7]} py={[3, 6]}>
|
<Flex px={[5, 7]} py={[3, 6]} whiteSpace={'nowrap'}>
|
||||||
<Box flex={'1 0 0'}>
|
<Box flex={'1 0 0'}>
|
||||||
<Box color={'myGray.600'} fontSize="sm">
|
<Box color={'myGray.600'} fontSize="sm">
|
||||||
{t('common:support.wallet.subscription.Current plan')}
|
{t('common:support.wallet.subscription.Current plan')}
|
||||||
@@ -475,8 +475,10 @@ const PlanUsage = () => {
|
|||||||
>
|
>
|
||||||
<Flex>
|
<Flex>
|
||||||
<Flex flex={'1 0 0'} alignItems={'flex-end'}>
|
<Flex flex={'1 0 0'} alignItems={'flex-end'}>
|
||||||
<Box fontSize={'md'}>{t('common:info.resource')}</Box>
|
<Box fontSize={'md'} fontWeight={'bold'} color={'myGray.900'}>
|
||||||
<Box fontSize={'xs'} color={'myGray.500'}>
|
{t('common:info.resource')}
|
||||||
|
</Box>
|
||||||
|
<Box ml={1} display={['none', 'block']} fontSize={'xs'} color={'myGray.500'}>
|
||||||
{t('common:info.include')}
|
{t('common:info.include')}
|
||||||
</Box>
|
</Box>
|
||||||
</Flex>
|
</Flex>
|
||||||
|
@@ -32,52 +32,25 @@ import MyBox from '@fastgpt/web/components/common/MyBox';
|
|||||||
import { getTeamInvoiceHeader } from '@/web/support/user/team/api';
|
import { getTeamInvoiceHeader } from '@/web/support/user/team/api';
|
||||||
import { useToast } from '@fastgpt/web/hooks/useToast';
|
import { useToast } from '@fastgpt/web/hooks/useToast';
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/router';
|
||||||
|
import { useForm } from 'react-hook-form';
|
||||||
|
|
||||||
type chosenBillDataType = {
|
type chosenBillDataType = {
|
||||||
_id: string;
|
_id: string;
|
||||||
price: number;
|
price: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
const ApplyInvoiceModal = ({ onClose }: { onClose: () => void }) => {
|
const ApplyInvoiceModal = ({ onClose }: { onClose: () => void }) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { toast } = useToast();
|
const router = useRouter();
|
||||||
|
|
||||||
const [chosenBillDataList, setChosenBillDataList] = useState<chosenBillDataType[]>([]);
|
const [chosenBillDataList, setChosenBillDataList] = useState<chosenBillDataType[]>([]);
|
||||||
const [totalPrice, setTotalPrice] = useState(0);
|
const [totalPrice, setTotalPrice] = useState(0);
|
||||||
const [formData, setFormData] = useState<TeamInvoiceHeaderType>({
|
|
||||||
teamName: '',
|
|
||||||
unifiedCreditCode: '',
|
|
||||||
companyAddress: '',
|
|
||||||
companyPhone: '',
|
|
||||||
bankName: '',
|
|
||||||
bankAccount: '',
|
|
||||||
needSpecialInvoice: undefined,
|
|
||||||
emailAddress: ''
|
|
||||||
});
|
|
||||||
|
|
||||||
const router = useRouter();
|
|
||||||
const {
|
const {
|
||||||
isOpen: isOpenSettleModal,
|
isOpen: isOpenSettleModal,
|
||||||
onOpen: onOpenSettleModal,
|
onOpen: onOpenSettleModal,
|
||||||
onClose: onCloseSettleModal
|
onClose: onCloseSettleModal
|
||||||
} = useDisclosure();
|
} = useDisclosure();
|
||||||
|
|
||||||
const handleChange = useCallback((e: any) => {
|
|
||||||
const { name, value } = e.target;
|
|
||||||
setFormData((prev) => ({ ...prev, [name]: value }));
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const handleRatiosChange = useCallback((v: string) => {
|
|
||||||
setFormData((prev) => ({ ...prev, needSpecialInvoice: v === 'true' }));
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const isHeaderValid = useCallback((v: TeamInvoiceHeaderType) => {
|
|
||||||
const emailRegex = /\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/;
|
|
||||||
for (const [key, value] of Object.entries(v)) {
|
|
||||||
if (typeof value === 'string' && value.trim() === '') {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return emailRegex.test(v.emailAddress);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
loading: isLoading,
|
loading: isLoading,
|
||||||
data: billsList,
|
data: billsList,
|
||||||
@@ -86,12 +59,23 @@ const ApplyInvoiceModal = ({ onClose }: { onClose: () => void }) => {
|
|||||||
manual: false
|
manual: false
|
||||||
});
|
});
|
||||||
|
|
||||||
const { run: handleSubmitInvoice, loading: isSubmitting } = useRequest2(
|
const handleSingleCheck = useCallback(
|
||||||
() =>
|
(item: invoiceBillDataType) => {
|
||||||
|
if (chosenBillDataList.find((bill) => bill._id === item._id)) {
|
||||||
|
setChosenBillDataList(chosenBillDataList.filter((bill) => bill._id !== item._id));
|
||||||
|
} else {
|
||||||
|
setChosenBillDataList([...chosenBillDataList, { _id: item._id, price: item.price }]);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[chosenBillDataList]
|
||||||
|
);
|
||||||
|
|
||||||
|
const { runAsync: onSubmitApply, loading: isSubmitting } = useRequest2(
|
||||||
|
(data) =>
|
||||||
submitInvoice({
|
submitInvoice({
|
||||||
amount: totalPrice,
|
amount: totalPrice,
|
||||||
billIdList: chosenBillDataList.map((item) => item._id),
|
billIdList: chosenBillDataList.map((item) => item._id),
|
||||||
...formData
|
...data
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
manual: true,
|
manual: true,
|
||||||
@@ -104,39 +88,29 @@ const ApplyInvoiceModal = ({ onClose }: { onClose: () => void }) => {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const inputForm = useForm<TeamInvoiceHeaderType>({
|
||||||
|
defaultValues: {
|
||||||
|
teamName: '',
|
||||||
|
unifiedCreditCode: '',
|
||||||
|
companyAddress: '',
|
||||||
|
companyPhone: '',
|
||||||
|
bankName: '',
|
||||||
|
bankAccount: '',
|
||||||
|
needSpecialInvoice: false,
|
||||||
|
emailAddress: ''
|
||||||
|
}
|
||||||
|
});
|
||||||
const { loading: isLoadingHeader } = useRequest2(() => getTeamInvoiceHeader(), {
|
const { loading: isLoadingHeader } = useRequest2(() => getTeamInvoiceHeader(), {
|
||||||
manual: false,
|
manual: false,
|
||||||
onSuccess: (res) => setFormData(res)
|
onSuccess: (res) => inputForm.reset(res)
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleSubmit = useCallback(async () => {
|
|
||||||
if (!isHeaderValid(formData)) {
|
|
||||||
toast({
|
|
||||||
title: t('common:support.wallet.invoice_data.in_valid'),
|
|
||||||
status: 'info'
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
handleSubmitInvoice();
|
|
||||||
}, [formData, handleSubmitInvoice, isHeaderValid, t, toast]);
|
|
||||||
|
|
||||||
const handleBack = useCallback(() => {
|
const handleBack = useCallback(() => {
|
||||||
setChosenBillDataList([]);
|
setChosenBillDataList([]);
|
||||||
getInvoiceBills();
|
getInvoiceBills();
|
||||||
onCloseSettleModal();
|
onCloseSettleModal();
|
||||||
}, [getInvoiceBills, onCloseSettleModal]);
|
}, [getInvoiceBills, onCloseSettleModal]);
|
||||||
|
|
||||||
const handleSingleCheck = useCallback(
|
|
||||||
(item: invoiceBillDataType) => {
|
|
||||||
if (chosenBillDataList.find((bill) => bill._id === item._id)) {
|
|
||||||
setChosenBillDataList(chosenBillDataList.filter((bill) => bill._id !== item._id));
|
|
||||||
} else {
|
|
||||||
setChosenBillDataList([...chosenBillDataList, { _id: item._id, price: item.price }]);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[chosenBillDataList]
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<MyModal
|
<MyModal
|
||||||
isOpen={true}
|
isOpen={true}
|
||||||
@@ -258,11 +232,7 @@ const ApplyInvoiceModal = ({ onClose }: { onClose: () => void }) => {
|
|||||||
</Box>
|
</Box>
|
||||||
<MyBox isLoading={isLoadingHeader}>
|
<MyBox isLoading={isLoadingHeader}>
|
||||||
<Flex justify={'center'}>
|
<Flex justify={'center'}>
|
||||||
<InvoiceHeaderSingleForm
|
<InvoiceHeaderSingleForm inputForm={inputForm} />
|
||||||
formData={formData}
|
|
||||||
handleChange={handleChange}
|
|
||||||
handleRatiosChange={handleRatiosChange}
|
|
||||||
/>
|
|
||||||
</Flex>
|
</Flex>
|
||||||
</MyBox>
|
</MyBox>
|
||||||
<Flex
|
<Flex
|
||||||
@@ -289,7 +259,7 @@ const ApplyInvoiceModal = ({ onClose }: { onClose: () => void }) => {
|
|||||||
</Box>
|
</Box>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Button>
|
</Button>
|
||||||
<Button isLoading={isSubmitting} px="0" onClick={handleSubmit}>
|
<Button isLoading={isSubmitting} px="0" onClick={inputForm.handleSubmit(onSubmitApply)}>
|
||||||
<Flex alignItems={'center'}>
|
<Flex alignItems={'center'}>
|
||||||
<Box px={'1.25rem'} py={'0.5rem'}>
|
<Box px={'1.25rem'} py={'0.5rem'}>
|
||||||
{t('common:common.Confirm')}
|
{t('common:common.Confirm')}
|
||||||
|
@@ -6,19 +6,22 @@ import { useTranslation } from 'next-i18next';
|
|||||||
import ApplyInvoiceModal from './ApplyInvoiceModal';
|
import ApplyInvoiceModal from './ApplyInvoiceModal';
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/router';
|
||||||
|
|
||||||
export const InvoiceTabEnum = {
|
export enum InvoiceTabEnum {
|
||||||
bill: 'bill',
|
bill = 'bill',
|
||||||
invoice: 'invoice',
|
invoice = 'invoice',
|
||||||
invoiceHeader: 'invoiceHeader'
|
invoiceHeader = 'invoiceHeader'
|
||||||
};
|
}
|
||||||
|
|
||||||
const BillTable = dynamic(() => import('./BillTable'));
|
const BillTable = dynamic(() => import('./BillTable'));
|
||||||
const InvoiceHeaderForm = dynamic(() => import('./InvoiceHeaderForm'));
|
const InvoiceHeaderForm = dynamic(() => import('./InvoiceHeaderForm'));
|
||||||
const InvoiceTable = dynamic(() => import('./InvoiceTable'));
|
const InvoiceTable = dynamic(() => import('./InvoiceTable'));
|
||||||
const BillAndInvoice = () => {
|
const BillAndInvoice = () => {
|
||||||
const [isOpenInvoiceModal, setIsOpenInvoiceModal] = useState(false);
|
|
||||||
const router = useRouter();
|
|
||||||
const invoiceTab = (router.query.invoiceTab as string) || InvoiceTabEnum.bill;
|
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
const router = useRouter();
|
||||||
|
const { invoiceTab = InvoiceTabEnum.bill } = router.query as { invoiceTab: `${InvoiceTabEnum}` };
|
||||||
|
|
||||||
|
const [isOpenInvoiceModal, setIsOpenInvoiceModal] = useState(false);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Box p={['1rem', '2rem']}>
|
<Box p={['1rem', '2rem']}>
|
||||||
@@ -36,7 +39,7 @@ const BillAndInvoice = () => {
|
|||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
router.replace({
|
router.replace({
|
||||||
query: {
|
query: {
|
||||||
currentTab: router.query.currentTab,
|
...router.query,
|
||||||
invoiceTab: e
|
invoiceTab: e
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@@ -101,6 +101,7 @@ const BillTable = () => {
|
|||||||
isLoading={isLoading || isRefreshing}
|
isLoading={isLoading || isRefreshing}
|
||||||
position={'relative'}
|
position={'relative'}
|
||||||
h={'100%'}
|
h={'100%'}
|
||||||
|
minH={'50vh'}
|
||||||
overflow={'overlay'}
|
overflow={'overlay'}
|
||||||
>
|
>
|
||||||
<TableContainer>
|
<TableContainer>
|
||||||
@@ -198,6 +199,10 @@ function BillDetailModal({ bill, onClose }: { bill: BillSchemaType; onClose: ()
|
|||||||
<FormLabel flex={'0 0 120px'}>{t('common:support.wallet.usage.Time')}:</FormLabel>
|
<FormLabel flex={'0 0 120px'}>{t('common:support.wallet.usage.Time')}:</FormLabel>
|
||||||
<Box>{dayjs(bill.createTime).format('YYYY/MM/DD HH:mm:ss')}</Box>
|
<Box>{dayjs(bill.createTime).format('YYYY/MM/DD HH:mm:ss')}</Box>
|
||||||
</Flex>
|
</Flex>
|
||||||
|
<Flex alignItems={'center'} pb={4}>
|
||||||
|
<FormLabel flex={'0 0 120px'}>{t('common:support.wallet.bill.Type')}:</FormLabel>
|
||||||
|
<Box>{t(billTypeMap[bill.type]?.label as any)}</Box>
|
||||||
|
</Flex>
|
||||||
<Flex alignItems={'center'} pb={4}>
|
<Flex alignItems={'center'} pb={4}>
|
||||||
<FormLabel flex={'0 0 120px'}>{t('common:support.wallet.bill.Status')}:</FormLabel>
|
<FormLabel flex={'0 0 120px'}>{t('common:support.wallet.bill.Status')}:</FormLabel>
|
||||||
<Box>{t(billStatusMap[bill.status]?.label as any)}</Box>
|
<Box>{t(billStatusMap[bill.status]?.label as any)}</Box>
|
||||||
@@ -212,14 +217,18 @@ function BillDetailModal({ bill, onClose }: { bill: BillSchemaType; onClose: ()
|
|||||||
<FormLabel flex={'0 0 120px'}>{t('common:support.wallet.Amount')}:</FormLabel>
|
<FormLabel flex={'0 0 120px'}>{t('common:support.wallet.Amount')}:</FormLabel>
|
||||||
<Box>{commonT('common:pay.yuan', { amount: formatStorePrice2Read(bill.price) })}</Box>
|
<Box>{commonT('common:pay.yuan', { amount: formatStorePrice2Read(bill.price) })}</Box>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Flex alignItems={'center'} pb={4}>
|
{bill.metadata && (
|
||||||
<FormLabel flex={'0 0 120px'}>{t('common:support.wallet.bill.Type')}:</FormLabel>
|
|
||||||
<Box>{t(billTypeMap[bill.type]?.label as any)}</Box>
|
|
||||||
</Flex>
|
|
||||||
<Flex alignItems={'center'} pb={4}>
|
<Flex alignItems={'center'} pb={4}>
|
||||||
<FormLabel flex={'0 0 120px'}>{t('common:support.wallet.has_invoice')}:</FormLabel>
|
<FormLabel flex={'0 0 120px'}>{t('common:support.wallet.has_invoice')}:</FormLabel>
|
||||||
<Box>{bill.hasInvoice ? t('common:yes') : t('common:no')}</Box>
|
{bill.metadata.payWay === 'balance' ? (
|
||||||
|
t('user:bill.not_need_invoice')
|
||||||
|
) : (
|
||||||
|
<Box>
|
||||||
|
{(bill.metadata.payWay = bill.hasInvoice ? t('common:yes') : t('common:no'))}
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
</Flex>
|
</Flex>
|
||||||
|
)}
|
||||||
{!!bill.metadata?.subMode && (
|
{!!bill.metadata?.subMode && (
|
||||||
<Flex alignItems={'center'} pb={4}>
|
<Flex alignItems={'center'} pb={4}>
|
||||||
<FormLabel flex={'0 0 120px'}>
|
<FormLabel flex={'0 0 120px'}>
|
||||||
|
@@ -1,56 +1,28 @@
|
|||||||
import Divider from '@/pages/app/detail/components/WorkflowComponents/Flow/components/Divider';
|
import Divider from '@/pages/app/detail/components/WorkflowComponents/Flow/components/Divider';
|
||||||
import { getTeamInvoiceHeader, updateTeamInvoiceHeader } from '@/web/support/user/team/api';
|
import { getTeamInvoiceHeader, updateTeamInvoiceHeader } from '@/web/support/user/team/api';
|
||||||
import { Box, Button, Flex, Input, Radio, RadioGroup, Stack } from '@chakra-ui/react';
|
import { Box, Button, Flex, HStack, Input, InputProps, Radio, RadioGroup } from '@chakra-ui/react';
|
||||||
import { TeamInvoiceHeaderType } from '@fastgpt/global/support/user/team/type';
|
import { TeamInvoiceHeaderType } from '@fastgpt/global/support/user/team/type';
|
||||||
import MyBox from '@fastgpt/web/components/common/MyBox';
|
import MyBox from '@fastgpt/web/components/common/MyBox';
|
||||||
import { useRequest2 } from '@fastgpt/web/hooks/useRequest';
|
import { useRequest2 } from '@fastgpt/web/hooks/useRequest';
|
||||||
import { useCallback, useState } from 'react';
|
|
||||||
import { useTranslation } from 'next-i18next';
|
import { useTranslation } from 'next-i18next';
|
||||||
import { useToast } from '@fastgpt/web/hooks/useToast';
|
import { UseFormReturn, useForm } from 'react-hook-form';
|
||||||
|
import FormLabel from '@fastgpt/web/components/common/MyBox/FormLabel';
|
||||||
const InputItem = ({
|
|
||||||
label,
|
|
||||||
value,
|
|
||||||
onChange,
|
|
||||||
name
|
|
||||||
}: {
|
|
||||||
label: string;
|
|
||||||
value: string;
|
|
||||||
onChange: (e: any) => void;
|
|
||||||
name: string;
|
|
||||||
}) => {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Flex justify={'space-between'} flexDir={['column', 'row']}>
|
|
||||||
<Box fontSize={'14px'} lineHeight={'2rem'}>
|
|
||||||
{label}
|
|
||||||
</Box>
|
|
||||||
<Input
|
|
||||||
bg={'myGray.50'}
|
|
||||||
border={'1px solid'}
|
|
||||||
borderColor={'myGray.200'}
|
|
||||||
w={'21.25rem'}
|
|
||||||
focusBorderColor="myGray.200"
|
|
||||||
placeholder={label}
|
|
||||||
value={value}
|
|
||||||
onChange={onChange}
|
|
||||||
name={name}
|
|
||||||
/>
|
|
||||||
</Flex>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const InvoiceHeaderSingleForm = ({
|
export const InvoiceHeaderSingleForm = ({
|
||||||
formData,
|
inputForm
|
||||||
handleChange,
|
|
||||||
handleRatiosChange
|
|
||||||
}: {
|
}: {
|
||||||
formData: TeamInvoiceHeaderType;
|
inputForm: UseFormReturn<TeamInvoiceHeaderType, any>;
|
||||||
handleChange: (e: any) => void;
|
|
||||||
handleRatiosChange: (v: string) => void;
|
|
||||||
}) => {
|
}) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
const { watch, register } = inputForm;
|
||||||
|
const needSpecialInvoice = watch('needSpecialInvoice');
|
||||||
|
|
||||||
|
const styles: InputProps = {
|
||||||
|
bg: 'myGray.50',
|
||||||
|
w: '21.25rem'
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Flex
|
<Flex
|
||||||
@@ -61,138 +33,185 @@ export const InvoiceHeaderSingleForm = ({
|
|||||||
color={'myGray.900'}
|
color={'myGray.900'}
|
||||||
fontSize={'14px'}
|
fontSize={'14px'}
|
||||||
>
|
>
|
||||||
<InputItem
|
<Flex
|
||||||
label={t('common:support.wallet.invoice_data.organization_name')}
|
justify={'space-between'}
|
||||||
value={formData.teamName}
|
alignItems={['flex-start', 'center']}
|
||||||
onChange={handleChange}
|
flexDir={['column', 'row']}
|
||||||
name="teamName"
|
>
|
||||||
|
<FormLabel required>
|
||||||
|
{t('common:support.wallet.invoice_data.organization_name')}
|
||||||
|
</FormLabel>
|
||||||
|
<Input
|
||||||
|
{...styles}
|
||||||
|
placeholder={t('common:support.wallet.invoice_data.organization_name')}
|
||||||
|
{...register('teamName', { required: true })}
|
||||||
/>
|
/>
|
||||||
<InputItem
|
</Flex>
|
||||||
label={t('common:support.wallet.invoice_data.unit_code')}
|
<Flex
|
||||||
value={formData.unifiedCreditCode}
|
justify={'space-between'}
|
||||||
onChange={handleChange}
|
alignItems={['flex-start', 'center']}
|
||||||
name="unifiedCreditCode"
|
flexDir={['column', 'row']}
|
||||||
|
>
|
||||||
|
<FormLabel required>{t('common:support.wallet.invoice_data.unit_code')}</FormLabel>
|
||||||
|
<Input
|
||||||
|
{...styles}
|
||||||
|
placeholder={t('common:support.wallet.invoice_data.unit_code')}
|
||||||
|
{...register('unifiedCreditCode', { required: true })}
|
||||||
/>
|
/>
|
||||||
<InputItem
|
</Flex>
|
||||||
label={t('common:support.wallet.invoice_data.company_address')}
|
<Flex
|
||||||
value={formData.companyAddress}
|
justify={'space-between'}
|
||||||
onChange={handleChange}
|
alignItems={['flex-start', 'center']}
|
||||||
name="companyAddress"
|
flexDir={['column', 'row']}
|
||||||
|
>
|
||||||
|
<FormLabel required={!!needSpecialInvoice}>
|
||||||
|
{t('common:support.wallet.invoice_data.company_address')}
|
||||||
|
</FormLabel>
|
||||||
|
<Input
|
||||||
|
{...styles}
|
||||||
|
placeholder={t('common:support.wallet.invoice_data.company_address')}
|
||||||
|
{...register('companyAddress', { required: !!needSpecialInvoice })}
|
||||||
/>
|
/>
|
||||||
<InputItem
|
</Flex>
|
||||||
label={t('common:support.wallet.invoice_data.company_phone')}
|
<Flex
|
||||||
value={formData.companyPhone}
|
justify={'space-between'}
|
||||||
onChange={handleChange}
|
alignItems={['flex-start', 'center']}
|
||||||
name="companyPhone"
|
flexDir={['column', 'row']}
|
||||||
|
>
|
||||||
|
<FormLabel required={!!needSpecialInvoice}>
|
||||||
|
{t('common:support.wallet.invoice_data.company_phone')}
|
||||||
|
</FormLabel>
|
||||||
|
<Input
|
||||||
|
{...styles}
|
||||||
|
placeholder={t('common:support.wallet.invoice_data.company_phone')}
|
||||||
|
{...register('companyPhone', { required: !!needSpecialInvoice })}
|
||||||
/>
|
/>
|
||||||
<InputItem
|
</Flex>
|
||||||
label={t('common:support.wallet.invoice_data.bank')}
|
<Flex
|
||||||
value={formData.bankName}
|
justify={'space-between'}
|
||||||
onChange={handleChange}
|
alignItems={['flex-start', 'center']}
|
||||||
name="bankName"
|
flexDir={['column', 'row']}
|
||||||
|
>
|
||||||
|
<FormLabel required={!!needSpecialInvoice}>
|
||||||
|
{t('common:support.wallet.invoice_data.bank')}
|
||||||
|
</FormLabel>
|
||||||
|
<Input
|
||||||
|
{...styles}
|
||||||
|
placeholder={t('common:support.wallet.invoice_data.bank')}
|
||||||
|
{...register('bankName', { required: !!needSpecialInvoice })}
|
||||||
/>
|
/>
|
||||||
<InputItem
|
</Flex>
|
||||||
label={t('common:support.wallet.invoice_data.bank_account')}
|
<Flex
|
||||||
value={formData.bankAccount}
|
justify={'space-between'}
|
||||||
onChange={handleChange}
|
alignItems={['flex-start', 'center']}
|
||||||
name="bankAccount"
|
flexDir={['column', 'row']}
|
||||||
|
>
|
||||||
|
<FormLabel required={!!needSpecialInvoice}>
|
||||||
|
{t('common:support.wallet.invoice_data.bank_account')}
|
||||||
|
</FormLabel>
|
||||||
|
<Input
|
||||||
|
{...styles}
|
||||||
|
placeholder={t('common:support.wallet.invoice_data.bank_account')}
|
||||||
|
{...register('bankAccount', { required: !!needSpecialInvoice })}
|
||||||
/>
|
/>
|
||||||
<Flex justify={'space-between'} flexDir={['column', 'row']}>
|
</Flex>
|
||||||
<Box fontSize={'14px'} lineHeight={'2rem'}>
|
<Flex
|
||||||
|
justify={'space-between'}
|
||||||
|
alignItems={['flex-start', 'center']}
|
||||||
|
flexDir={['column', 'row']}
|
||||||
|
>
|
||||||
|
<FormLabel required>
|
||||||
{t('common:support.wallet.invoice_data.need_special_invoice')}
|
{t('common:support.wallet.invoice_data.need_special_invoice')}
|
||||||
</Box>
|
</FormLabel>
|
||||||
|
{/* @ts-ignore */}
|
||||||
<RadioGroup
|
<RadioGroup
|
||||||
value={
|
value={`${needSpecialInvoice}`}
|
||||||
formData.needSpecialInvoice === undefined
|
onChange={(e) => {
|
||||||
? ''
|
inputForm.setValue('needSpecialInvoice', e === 'true');
|
||||||
: formData.needSpecialInvoice.toString()
|
}}
|
||||||
}
|
|
||||||
onChange={handleRatiosChange}
|
|
||||||
w={'21.25rem'}
|
w={'21.25rem'}
|
||||||
>
|
>
|
||||||
<Stack direction="row" h={'2rem'}>
|
<HStack h={'2rem'}>
|
||||||
<Radio value="true" pr={'1rem'}>
|
<Radio value="true" pr={'1rem'}>
|
||||||
<Box fontSize={'14px'}>{t('common:yes')}</Box>
|
<Box fontSize={'14px'}>{t('common:yes')}</Box>
|
||||||
</Radio>
|
</Radio>
|
||||||
<Radio value="false">
|
<Radio value="false">
|
||||||
<Box fontSize={'14px'}>{t('common:no')}</Box>
|
<Box fontSize={'14px'}>{t('common:no')}</Box>
|
||||||
</Radio>
|
</Radio>
|
||||||
</Stack>
|
</HStack>
|
||||||
</RadioGroup>
|
</RadioGroup>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Box w={'100%'}>
|
<Box w={'100%'}>
|
||||||
<Divider showBorderBottom={false} />
|
<Divider showBorderBottom={false} />
|
||||||
</Box>
|
</Box>
|
||||||
<InputItem
|
<Flex
|
||||||
label={t('common:support.wallet.invoice_data.email')}
|
justify={'space-between'}
|
||||||
value={formData.emailAddress}
|
alignItems={['flex-start', 'center']}
|
||||||
onChange={handleChange}
|
flexDir={['column', 'row']}
|
||||||
name="emailAddress"
|
>
|
||||||
|
<FormLabel required>{t('common:support.wallet.invoice_data.email')}</FormLabel>
|
||||||
|
<Input
|
||||||
|
{...styles}
|
||||||
|
placeholder={t('common:support.wallet.invoice_data.email')}
|
||||||
|
{...register('emailAddress', {
|
||||||
|
required: true,
|
||||||
|
pattern: {
|
||||||
|
value: /(^[A-Za-z0-9]+([_\.][A-Za-z0-9]+)*@([A-Za-z0-9\-]+\.)+[A-Za-z]{2,6}$)/,
|
||||||
|
message: t('user:password.email_phone_error')
|
||||||
|
}
|
||||||
|
})}
|
||||||
/>
|
/>
|
||||||
</Flex>
|
</Flex>
|
||||||
|
</Flex>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const InvoiceHeaderForm = () => {
|
const InvoiceHeaderForm = () => {
|
||||||
const [formData, setFormData] = useState<TeamInvoiceHeaderType>({
|
const inputForm = useForm<TeamInvoiceHeaderType>({
|
||||||
|
defaultValues: {
|
||||||
teamName: '',
|
teamName: '',
|
||||||
unifiedCreditCode: '',
|
unifiedCreditCode: '',
|
||||||
companyAddress: '',
|
companyAddress: '',
|
||||||
companyPhone: '',
|
companyPhone: '',
|
||||||
bankName: '',
|
bankName: '',
|
||||||
bankAccount: '',
|
bankAccount: '',
|
||||||
needSpecialInvoice: undefined,
|
needSpecialInvoice: false,
|
||||||
emailAddress: ''
|
emailAddress: ''
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const { loading: isLoading } = useRequest2(() => getTeamInvoiceHeader(), {
|
const { loading: isLoading } = useRequest2(() => getTeamInvoiceHeader(), {
|
||||||
manual: false,
|
manual: false,
|
||||||
onSuccess: (data) => {
|
onSuccess: (data) => {
|
||||||
setFormData(data);
|
console.log(data, '--');
|
||||||
|
inputForm.reset(data);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { toast } = useToast();
|
|
||||||
const handleChange = useCallback((e: any) => {
|
const { loading: isSubmitting, runAsync: onUpdateHeader } = useRequest2(
|
||||||
const { name, value } = e.target;
|
(data: TeamInvoiceHeaderType) => updateTeamInvoiceHeader(data),
|
||||||
setFormData((prev) => ({ ...prev, [name]: value }));
|
|
||||||
}, []);
|
|
||||||
const handleRatiosChange = useCallback((v: string) => {
|
|
||||||
setFormData((prev) => ({ ...prev, needSpecialInvoice: v === 'true' }));
|
|
||||||
}, []);
|
|
||||||
const isHeaderValid = useCallback((v: TeamInvoiceHeaderType) => {
|
|
||||||
const emailRegex = /\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/;
|
|
||||||
return emailRegex.test(v.emailAddress);
|
|
||||||
}, []);
|
|
||||||
const { loading: isSubmitting, run: handleSubmit } = useRequest2(
|
|
||||||
() => updateTeamInvoiceHeader(formData),
|
|
||||||
{
|
{
|
||||||
manual: true,
|
manual: true,
|
||||||
successToast: t('common:common.Save Success'),
|
successToast: t('common:common.Save Success'),
|
||||||
errorToast: t('common:common.Save Failed')
|
errorToast: t('common:common.Save Failed')
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
const onSubmit = useCallback(() => {
|
|
||||||
if (!isHeaderValid(formData)) {
|
|
||||||
toast({
|
|
||||||
title: t('common:support.wallet.invoice_data.in_valid'),
|
|
||||||
status: 'info'
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
handleSubmit();
|
|
||||||
}, [handleSubmit, formData, isHeaderValid, toast, t]);
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<MyBox isLoading={isLoading} pt={['1rem', '3.5rem']}>
|
<MyBox isLoading={isLoading} pt={['1rem', '3.5rem']}>
|
||||||
<Flex w={'100%'} overflow={'auto'} justify={'center'} flexDir={'column'} align={'center'}>
|
<Flex w={'100%'} overflow={'auto'} justify={'center'} flexDir={'column'} align={'center'}>
|
||||||
<InvoiceHeaderSingleForm
|
<InvoiceHeaderSingleForm inputForm={inputForm} />
|
||||||
formData={formData}
|
|
||||||
handleChange={handleChange}
|
|
||||||
handleRatiosChange={handleRatiosChange}
|
|
||||||
/>
|
|
||||||
<Flex w={'100%'} justify={'center'} mt={'3rem'}>
|
<Flex w={'100%'} justify={'center'} mt={'3rem'}>
|
||||||
<Button variant={'primary'} px="0" onClick={onSubmit} isLoading={isSubmitting}>
|
<Button
|
||||||
|
variant={'primary'}
|
||||||
|
px="0"
|
||||||
|
onClick={inputForm.handleSubmit(onUpdateHeader)}
|
||||||
|
isLoading={isSubmitting}
|
||||||
|
>
|
||||||
<Flex alignItems={'center'} px={'20px'}>
|
<Flex alignItems={'center'} px={'20px'}>
|
||||||
<Box px={'1.25rem'} py={'0.5rem'}>
|
<Box px={'1.25rem'} py={'0.5rem'}>
|
||||||
{t('common:common.Save')}
|
{t('common:common.Save')}
|
||||||
|
@@ -197,11 +197,11 @@ function InvoiceDetailModal({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function LabelItem({ label, value }: { label: string; value: string }) {
|
function LabelItem({ label, value }: { label: string; value?: string }) {
|
||||||
return (
|
return (
|
||||||
<Flex alignItems={'center'} justify={'space-between'}>
|
<Flex alignItems={'center'} justify={'space-between'}>
|
||||||
<FormLabel flex={'0 0 120px'}>{label}</FormLabel>
|
<FormLabel flex={'0 0 120px'}>{label}</FormLabel>
|
||||||
<Box>{value}</Box>
|
<Box>{value || '-'}</Box>
|
||||||
</Flex>
|
</Flex>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@@ -26,7 +26,7 @@ async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
|
|||||||
const start = Date.now();
|
const start = Date.now();
|
||||||
/* Creates the multer uploader */
|
/* Creates the multer uploader */
|
||||||
const upload = getUploadModel({
|
const upload = getUploadModel({
|
||||||
maxSize: (global.feConfigs?.uploadFileMaxSize || 500) * 1024 * 1024
|
maxSize: global.feConfigs?.uploadFileMaxSize
|
||||||
});
|
});
|
||||||
const { file, bucketName, metadata } = await upload.doUpload(req, res);
|
const { file, bucketName, metadata } = await upload.doUpload(req, res);
|
||||||
filePaths.push(file.path);
|
filePaths.push(file.path);
|
||||||
|
@@ -30,7 +30,7 @@ async function handler(req: NextApiRequest, res: NextApiResponse<any>): CreateCo
|
|||||||
* Creates the multer uploader
|
* Creates the multer uploader
|
||||||
*/
|
*/
|
||||||
const upload = getUploadModel({
|
const upload = getUploadModel({
|
||||||
maxSize: (global.feConfigs?.uploadFileMaxSize || 500) * 1024 * 1024
|
maxSize: global.feConfigs?.uploadFileMaxSize
|
||||||
});
|
});
|
||||||
let filePaths: string[] = [];
|
let filePaths: string[] = [];
|
||||||
|
|
||||||
|
@@ -279,7 +279,7 @@ export const useWorkflow = () => {
|
|||||||
const [helperLineHorizontal, setHelperLineHorizontal] = useState<THelperLine>();
|
const [helperLineHorizontal, setHelperLineHorizontal] = useState<THelperLine>();
|
||||||
const [helperLineVertical, setHelperLineVertical] = useState<THelperLine>();
|
const [helperLineVertical, setHelperLineVertical] = useState<THelperLine>();
|
||||||
|
|
||||||
const customApplyNodeChanges = (changes: NodeChange[], nodes: Node[]): Node[] => {
|
const customApplyNodeChanges = (changes: NodeChange[], nodes: Node[]) => {
|
||||||
const positionChange =
|
const positionChange =
|
||||||
changes[0].type === 'position' && changes[0].dragging ? changes[0] : undefined;
|
changes[0].type === 'position' && changes[0].dragging ? changes[0] : undefined;
|
||||||
|
|
||||||
@@ -316,14 +316,10 @@ export const useWorkflow = () => {
|
|||||||
setHelperLineHorizontal(undefined);
|
setHelperLineHorizontal(undefined);
|
||||||
setHelperLineVertical(undefined);
|
setHelperLineVertical(undefined);
|
||||||
}
|
}
|
||||||
|
|
||||||
return applyNodeChanges(changes, nodes);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* node */
|
/* node */
|
||||||
const handleNodesChange = (changes: NodeChange[]) => {
|
const handleNodesChange = (changes: NodeChange[]) => {
|
||||||
setNodes((nodes) => customApplyNodeChanges(changes, nodes));
|
|
||||||
|
|
||||||
for (const change of changes) {
|
for (const change of changes) {
|
||||||
if (change.type === 'remove') {
|
if (change.type === 'remove') {
|
||||||
const node = nodes.find((n) => n.id === change.id);
|
const node = nodes.find((n) => n.id === change.id);
|
||||||
@@ -345,6 +341,8 @@ export const useWorkflow = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
customApplyNodeChanges(changes, nodes);
|
||||||
|
|
||||||
onNodesChange(changes);
|
onNodesChange(changes);
|
||||||
};
|
};
|
||||||
const handleEdgeChange = useCallback(
|
const handleEdgeChange = useCallback(
|
||||||
|
@@ -390,8 +390,7 @@ const RenderHttpTimeout = ({
|
|||||||
const onChangeNode = useContextSelector(WorkflowContext, (v) => v.onChangeNode);
|
const onChangeNode = useContextSelector(WorkflowContext, (v) => v.onChangeNode);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box>
|
<Flex alignItems={'center'} justifyContent={'space-between'}>
|
||||||
<Box mb={2} display={'flex'} justifyContent={'space-between'}>
|
|
||||||
<Box fontWeight={'medium'} color={'myGray.600'}>
|
<Box fontWeight={'medium'} color={'myGray.600'}>
|
||||||
{t('common:core.module.Http timeout')}
|
{t('common:core.module.Http timeout')}
|
||||||
</Box>
|
</Box>
|
||||||
@@ -401,6 +400,7 @@ const RenderHttpTimeout = ({
|
|||||||
defaultValue={timeout.value}
|
defaultValue={timeout.value}
|
||||||
min={timeout.min}
|
min={timeout.min}
|
||||||
max={timeout.max}
|
max={timeout.max}
|
||||||
|
bg={'white'}
|
||||||
onBlur={() => setIsEditTimeout(false)}
|
onBlur={() => setIsEditTimeout(false)}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
onChangeNode({
|
onChangeNode({
|
||||||
@@ -414,7 +414,7 @@ const RenderHttpTimeout = ({
|
|||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<NumberInputField bg={'white'} px={3} borderRadius={'sm'} />
|
<NumberInputField autoFocus bg={'white'} px={3} borderRadius={'sm'} />
|
||||||
<NumberInputStepper>
|
<NumberInputStepper>
|
||||||
<NumberIncrementStepper />
|
<NumberIncrementStepper />
|
||||||
<NumberDecrementStepper />
|
<NumberDecrementStepper />
|
||||||
@@ -422,14 +422,13 @@ const RenderHttpTimeout = ({
|
|||||||
</NumberInput>
|
</NumberInput>
|
||||||
) : (
|
) : (
|
||||||
<Button
|
<Button
|
||||||
variant={'ghost'}
|
variant={'whiteBase'}
|
||||||
color={'myGray.600'}
|
color={'myGray.600'}
|
||||||
onClick={() => setIsEditTimeout(true)}
|
onClick={() => setIsEditTimeout(true)}
|
||||||
>{`${timeout?.value} s`}</Button>
|
>{`${timeout?.value} s`}</Button>
|
||||||
)}
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Flex>
|
||||||
</Box>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
const RenderForm = ({
|
const RenderForm = ({
|
||||||
|
@@ -201,7 +201,7 @@ const NodeCard = (props: Props) => {
|
|||||||
</Button>
|
</Button>
|
||||||
</MyTooltip>
|
</MyTooltip>
|
||||||
)}
|
)}
|
||||||
{!!nodeTemplate?.diagram && (
|
{!!nodeTemplate?.diagram && !hasNewVersion && (
|
||||||
<MyTooltip
|
<MyTooltip
|
||||||
label={
|
label={
|
||||||
<Image src={nodeTemplate?.diagram} w={'100%'} minH={['auto', '200px']} alt={''} />
|
<Image src={nodeTemplate?.diagram} w={'100%'} minH={['auto', '200px']} alt={''} />
|
||||||
|
@@ -149,8 +149,8 @@ const ListItem = () => {
|
|||||||
app.type === AppTypeEnum.folder
|
app.type === AppTypeEnum.folder
|
||||||
? t('common:common.folder.Open folder')
|
? t('common:common.folder.Open folder')
|
||||||
: app.permission.hasWritePer
|
: app.permission.hasWritePer
|
||||||
? appT('edit_app')
|
? t('app:edit_app')
|
||||||
: appT('go_to_chat')
|
: t('app:go_to_chat')
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<MyBox
|
<MyBox
|
||||||
|
@@ -138,7 +138,7 @@ const MyApps = () => {
|
|||||||
flex={'1 0 0'}
|
flex={'1 0 0'}
|
||||||
flexDirection={'column'}
|
flexDirection={'column'}
|
||||||
h={'100%'}
|
h={'100%'}
|
||||||
pr={folderDetail ? [4, 2] : [4, 10]}
|
pr={folderDetail ? [3, 2] : [3, 10]}
|
||||||
pl={3}
|
pl={3}
|
||||||
overflowY={'auto'}
|
overflowY={'auto'}
|
||||||
overflowX={'hidden'}
|
overflowX={'hidden'}
|
||||||
|
@@ -143,9 +143,10 @@ const Info = ({ datasetId }: { datasetId: string }) => {
|
|||||||
<Box flex={1}>{datasetDetail._id}</Box>
|
<Box flex={1}>{datasetDetail._id}</Box>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Flex mt={8} w={'100%'} alignItems={'center'} flexWrap={'wrap'}>
|
<Flex mt={8} w={'100%'} alignItems={'center'} flexWrap={'wrap'}>
|
||||||
<FormLabel flex={['0 0 90px', '0 0 160px']} w={0}>
|
<HStack flex={['0 0 90px', '0 0 160px']} w={0} spacing={1}>
|
||||||
{t('common:core.ai.model.Vector Model')}
|
<FormLabel>{t('common:core.ai.model.Vector Model')}</FormLabel>
|
||||||
</FormLabel>
|
<QuestionTip label={t('common:core.dataset.embedding model tip')} />
|
||||||
|
</HStack>
|
||||||
<Box flex={[1, '0 0 320px']}>
|
<Box flex={[1, '0 0 320px']}>
|
||||||
<AIModelSelector
|
<AIModelSelector
|
||||||
w={'100%'}
|
w={'100%'}
|
||||||
@@ -177,9 +178,10 @@ const Info = ({ datasetId }: { datasetId: string }) => {
|
|||||||
<Box flex={[1, '0 0 320px']}>{vectorModel.maxToken}</Box>
|
<Box flex={[1, '0 0 320px']}>{vectorModel.maxToken}</Box>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Flex mt={6} alignItems={'center'} flexWrap={'wrap'}>
|
<Flex mt={6} alignItems={'center'} flexWrap={'wrap'}>
|
||||||
<FormLabel flex={['0 0 90px', '0 0 160px']} w={0}>
|
<HStack flex={['0 0 90px', '0 0 160px']} w={0} spacing={1}>
|
||||||
{t('common:core.ai.model.Dataset Agent Model')}
|
<FormLabel>{t('common:core.ai.model.Dataset Agent Model')}</FormLabel>
|
||||||
</FormLabel>
|
<QuestionTip label={t('dataset:file_model_function_tip')} />
|
||||||
|
</HStack>
|
||||||
<Box flex={[1, '0 0 320px']}>
|
<Box flex={[1, '0 0 320px']}>
|
||||||
<AIModelSelector
|
<AIModelSelector
|
||||||
w={'100%'}
|
w={'100%'}
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
import React, { useCallback, useMemo } from 'react';
|
import React, { useCallback, useMemo } from 'react';
|
||||||
import { Box, Flex, Button, ModalFooter, ModalBody, Input } from '@chakra-ui/react';
|
import { Box, Flex, Button, ModalFooter, ModalBody, Input, HStack } from '@chakra-ui/react';
|
||||||
import { useSelectFile } from '@/web/common/file/hooks/useSelectFile';
|
import { useSelectFile } from '@/web/common/file/hooks/useSelectFile';
|
||||||
import { useForm } from 'react-hook-form';
|
import { useForm } from 'react-hook-form';
|
||||||
import { compressImgFileAndUpload } from '@/web/common/file/controller';
|
import { compressImgFileAndUpload } from '@/web/common/file/controller';
|
||||||
@@ -19,6 +19,7 @@ import { MongoImageTypeEnum } from '@fastgpt/global/common/file/image/constants'
|
|||||||
import AIModelSelector from '@/components/Select/AIModelSelector';
|
import AIModelSelector from '@/components/Select/AIModelSelector';
|
||||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||||
import { useSystem } from '@fastgpt/web/hooks/useSystem';
|
import { useSystem } from '@fastgpt/web/hooks/useSystem';
|
||||||
|
import QuestionTip from '@fastgpt/web/components/common/MyTooltip/QuestionTip';
|
||||||
|
|
||||||
export type CreateDatasetType =
|
export type CreateDatasetType =
|
||||||
| DatasetTypeEnum.dataset
|
| DatasetTypeEnum.dataset
|
||||||
@@ -163,19 +164,18 @@ const CreateModal = ({
|
|||||||
justify={'space-between'}
|
justify={'space-between'}
|
||||||
flexDir={['column', 'row']}
|
flexDir={['column', 'row']}
|
||||||
>
|
>
|
||||||
<Flex
|
<HStack
|
||||||
|
spacing={1}
|
||||||
alignItems={'center'}
|
alignItems={'center'}
|
||||||
flex={['', '0 0 100px']}
|
flex={['', '0 0 110px']}
|
||||||
fontSize={'sm'}
|
fontSize={'sm'}
|
||||||
color={'myGray.900'}
|
color={'myGray.900'}
|
||||||
fontWeight={500}
|
fontWeight={500}
|
||||||
pb={['12px', '0']}
|
pb={['12px', '0']}
|
||||||
>
|
>
|
||||||
{t('common:core.ai.model.Vector Model')}
|
<Box>{t('common:core.ai.model.Vector Model')}</Box>
|
||||||
<MyTooltip label={t('common:core.dataset.embedding model tip')}>
|
<QuestionTip label={t('common:core.dataset.embedding model tip')} />
|
||||||
<MyIcon w={'16px'} h={'16px'} color={'myGray.500'} ml={'4px'} name="common/help" />
|
</HStack>
|
||||||
</MyTooltip>
|
|
||||||
</Flex>
|
|
||||||
<Box w={['100%', '300px']}>
|
<Box w={['100%', '300px']}>
|
||||||
<AIModelSelector
|
<AIModelSelector
|
||||||
w={['100%', '300px']}
|
w={['100%', '300px']}
|
||||||
@@ -198,15 +198,17 @@ const CreateModal = ({
|
|||||||
justify={'space-between'}
|
justify={'space-between'}
|
||||||
flexDir={['column', 'row']}
|
flexDir={['column', 'row']}
|
||||||
>
|
>
|
||||||
<Box
|
<HStack
|
||||||
flex={['', '0 0 100px']}
|
spacing={1}
|
||||||
|
flex={['', '0 0 110px']}
|
||||||
fontSize={'sm'}
|
fontSize={'sm'}
|
||||||
color={'myGray.900'}
|
color={'myGray.900'}
|
||||||
fontWeight={500}
|
fontWeight={500}
|
||||||
pb={['12px', '0']}
|
pb={['12px', '0']}
|
||||||
>
|
>
|
||||||
{t('common:core.ai.model.Dataset Agent Model')}
|
<Box>{t('common:core.ai.model.Dataset Agent Model')}</Box>
|
||||||
</Box>
|
<QuestionTip label={t('dataset:file_model_function_tip')} />
|
||||||
|
</HStack>
|
||||||
<Box w={['100%', '300px']}>
|
<Box w={['100%', '300px']}>
|
||||||
<AIModelSelector
|
<AIModelSelector
|
||||||
w={['100%', '300px']}
|
w={['100%', '300px']}
|
||||||
@@ -224,7 +226,7 @@ const CreateModal = ({
|
|||||||
)}
|
)}
|
||||||
</ModalBody>
|
</ModalBody>
|
||||||
|
|
||||||
<ModalFooter pt={'0px'} pb={'24px'}>
|
<ModalFooter px={'36px'}>
|
||||||
<Button variant={'whiteBase'} mr={3} onClick={onClose}>
|
<Button variant={'whiteBase'} mr={3} onClick={onClose}>
|
||||||
{t('common:common.Close')}
|
{t('common:common.Close')}
|
||||||
</Button>
|
</Button>
|
||||||
|
@@ -1,6 +1,5 @@
|
|||||||
import React, { useMemo, useRef, useState } from 'react';
|
import React, { useMemo, useRef, useState } from 'react';
|
||||||
import { resumeInheritPer } from '@/web/core/dataset/api';
|
import { resumeInheritPer } from '@/web/core/dataset/api';
|
||||||
import { useDatasetStore } from '@/web/core/dataset/store/dataset';
|
|
||||||
import { Box, Flex, Grid, HStack } from '@chakra-ui/react';
|
import { Box, Flex, Grid, HStack } from '@chakra-ui/react';
|
||||||
import { DatasetTypeEnum, DatasetTypeMap } from '@fastgpt/global/core/dataset/constants';
|
import { DatasetTypeEnum, DatasetTypeMap } from '@fastgpt/global/core/dataset/constants';
|
||||||
import MyMenu from '@fastgpt/web/components/common/MyMenu';
|
import MyMenu from '@fastgpt/web/components/common/MyMenu';
|
||||||
@@ -39,6 +38,8 @@ import { formatTimeToChatTime } from '@fastgpt/global/common/string/time';
|
|||||||
import { useSystem } from '@fastgpt/web/hooks/useSystem';
|
import { useSystem } from '@fastgpt/web/hooks/useSystem';
|
||||||
import SideTag from './SideTag';
|
import SideTag from './SideTag';
|
||||||
|
|
||||||
|
const EditResourceModal = dynamic(() => import('@/components/common/Modal/EditResourceModal'));
|
||||||
|
|
||||||
function List() {
|
function List() {
|
||||||
const { setLoading } = useSystemStore();
|
const { setLoading } = useSystemStore();
|
||||||
const { toast } = useToast();
|
const { toast } = useToast();
|
||||||
@@ -76,7 +77,7 @@ function List() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const { data: members = [], loading: isLoadMembers } = useRequest2(loadAndGetTeamMembers, {
|
const { data: members = [] } = useRequest2(loadAndGetTeamMembers, {
|
||||||
manual: false
|
manual: false
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -111,8 +112,6 @@ function List() {
|
|||||||
errorToast: t('common:dataset.Export Dataset Limit Error')
|
errorToast: t('common:dataset.Export Dataset Limit Error')
|
||||||
});
|
});
|
||||||
|
|
||||||
const EditResourceModal = dynamic(() => import('@/components/common/Modal/EditResourceModal'));
|
|
||||||
|
|
||||||
const DeleteTipsMap = useRef({
|
const DeleteTipsMap = useRef({
|
||||||
[DatasetTypeEnum.folder]: t('common:dataset.deleteFolderTips'),
|
[DatasetTypeEnum.folder]: t('common:dataset.deleteFolderTips'),
|
||||||
[DatasetTypeEnum.dataset]: t('common:core.dataset.Delete Confirm'),
|
[DatasetTypeEnum.dataset]: t('common:core.dataset.Delete Confirm'),
|
||||||
@@ -161,8 +160,7 @@ function List() {
|
|||||||
gridGap={5}
|
gridGap={5}
|
||||||
alignItems={'stretch'}
|
alignItems={'stretch'}
|
||||||
>
|
>
|
||||||
{!isLoadMembers &&
|
{formatDatasets.map((dataset, index) => {
|
||||||
formatDatasets.map((dataset, index) => {
|
|
||||||
const owner = members.find((v) => v.tmbId === dataset.tmbId);
|
const owner = members.find((v) => v.tmbId === dataset.tmbId);
|
||||||
return (
|
return (
|
||||||
<MyTooltip
|
<MyTooltip
|
||||||
@@ -171,8 +169,8 @@ function List() {
|
|||||||
<Flex flexDirection={'column'} alignItems={'center'}>
|
<Flex flexDirection={'column'} alignItems={'center'}>
|
||||||
<Box fontSize={'xs'} color={'myGray.500'}>
|
<Box fontSize={'xs'} color={'myGray.500'}>
|
||||||
{dataset.type === DatasetTypeEnum.folder
|
{dataset.type === DatasetTypeEnum.folder
|
||||||
? t('common.folder.Open folder')
|
? t('common:common.folder.Open folder')
|
||||||
: t('common.folder.open_dataset')}
|
: t('common:common.folder.open_dataset')}
|
||||||
</Box>
|
</Box>
|
||||||
</Flex>
|
</Flex>
|
||||||
}
|
}
|
||||||
@@ -290,9 +288,7 @@ function List() {
|
|||||||
{isPc && (
|
{isPc && (
|
||||||
<HStack spacing={1} className="time">
|
<HStack spacing={1} className="time">
|
||||||
<MyIcon name={'history'} w={'0.85rem'} color={'myGray.400'} />
|
<MyIcon name={'history'} w={'0.85rem'} color={'myGray.400'} />
|
||||||
<Box color={'myGray.500'}>
|
<Box color={'myGray.500'}>{formatTimeToChatTime(dataset.updateTime)}</Box>
|
||||||
{formatTimeToChatTime(dataset.updateTime)}
|
|
||||||
</Box>
|
|
||||||
</HStack>
|
</HStack>
|
||||||
)}
|
)}
|
||||||
{dataset.permission.hasWritePer && (
|
{dataset.permission.hasWritePer && (
|
||||||
@@ -415,7 +411,6 @@ function List() {
|
|||||||
intro: data.intro,
|
intro: data.intro,
|
||||||
avatar: data.avatar
|
avatar: data.avatar
|
||||||
});
|
});
|
||||||
setEditedDataset(undefined);
|
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
@@ -11,18 +11,15 @@ const SideTag = ({ type, ...props }: { type: `${DatasetTypeEnum}` } & FlexProps)
|
|||||||
return {
|
return {
|
||||||
[DatasetTypeEnum.dataset]: {
|
[DatasetTypeEnum.dataset]: {
|
||||||
icon: 'core/dataset/commonDatasetOutline',
|
icon: 'core/dataset/commonDatasetOutline',
|
||||||
label: t('dataset:common_dataset'),
|
label: t('dataset:common_dataset')
|
||||||
collectionLabel: 'common.File'
|
|
||||||
},
|
},
|
||||||
[DatasetTypeEnum.websiteDataset]: {
|
[DatasetTypeEnum.websiteDataset]: {
|
||||||
icon: 'core/dataset/websiteDatasetOutline',
|
icon: 'core/dataset/websiteDatasetOutline',
|
||||||
label: t('dataset:website_dataset'),
|
label: t('dataset:website_dataset')
|
||||||
collectionLabel: 'common.Website'
|
|
||||||
},
|
},
|
||||||
[DatasetTypeEnum.externalFile]: {
|
[DatasetTypeEnum.externalFile]: {
|
||||||
icon: 'core/dataset/externalDatasetOutline',
|
icon: 'core/dataset/externalDatasetOutline',
|
||||||
label: t('dataset:external_file'),
|
label: t('dataset:external_file')
|
||||||
collectionLabel: 'common.File'
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}, [t]);
|
}, [t]);
|
||||||
@@ -31,8 +28,6 @@ const SideTag = ({ type, ...props }: { type: `${DatasetTypeEnum}` } & FlexProps)
|
|||||||
return (
|
return (
|
||||||
<Flex
|
<Flex
|
||||||
bg={'myGray.100'}
|
bg={'myGray.100'}
|
||||||
borderWidth={'1px'}
|
|
||||||
borderColor={'myGray.200'}
|
|
||||||
py={'3px'}
|
py={'3px'}
|
||||||
pl={'8px'}
|
pl={'8px'}
|
||||||
pr={'12px'}
|
pr={'12px'}
|
||||||
@@ -43,7 +38,6 @@ const SideTag = ({ type, ...props }: { type: `${DatasetTypeEnum}` } & FlexProps)
|
|||||||
>
|
>
|
||||||
<MyIcon name={item.icon as any} w={'0.8rem'} color={'myGray.400'} />
|
<MyIcon name={item.icon as any} w={'0.8rem'} color={'myGray.400'} />
|
||||||
<Box fontSize={'mini'} ml={1}>
|
<Box fontSize={'mini'} ml={1}>
|
||||||
{/* @ts-ignore */}
|
|
||||||
{item.label}
|
{item.label}
|
||||||
</Box>
|
</Box>
|
||||||
</Flex>
|
</Flex>
|
||||||
|
@@ -12,7 +12,7 @@ import { startMongoWatch } from './common/system/volumnMongoWatch';
|
|||||||
import { startTrainingQueue } from './core/dataset/training/utils';
|
import { startTrainingQueue } from './core/dataset/training/utils';
|
||||||
import { systemStartCb } from '@fastgpt/service/common/system/tools';
|
import { systemStartCb } from '@fastgpt/service/common/system/tools';
|
||||||
import { addLog } from '@fastgpt/service/common/system/log';
|
import { addLog } from '@fastgpt/service/common/system/log';
|
||||||
import { getSystemPluginCb } from './core/app/plugin';
|
import { getSystemPluginCb, getSystemPlugins } from './core/app/plugin';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function is equivalent to the entry to the service
|
* This function is equivalent to the entry to the service
|
||||||
@@ -32,7 +32,13 @@ export function connectToDatabase() {
|
|||||||
systemStartCb();
|
systemStartCb();
|
||||||
|
|
||||||
//init system config;init vector database;init root user
|
//init system config;init vector database;init root user
|
||||||
await Promise.all([getInitConfig(), getSystemPluginCb(), initVectorStore(), initRootUser()]);
|
await Promise.all([
|
||||||
|
getInitConfig(),
|
||||||
|
getSystemPluginCb(),
|
||||||
|
getSystemPlugins(),
|
||||||
|
initVectorStore(),
|
||||||
|
initRootUser()
|
||||||
|
]);
|
||||||
|
|
||||||
startMongoWatch();
|
startMongoWatch();
|
||||||
// cron
|
// cron
|
||||||
|
Reference in New Issue
Block a user